Gitfed
bastien-mrq/gitfed / internal / admin / revocation_test.go
package admin

import (
	"crypto/ed25519"
	"crypto/rand"
	"path/filepath"
	"strings"
	"testing"

	gossh "golang.org/x/crypto/ssh"

	"git.neuromancer.ovh/bastien-mrq/gitfed/internal/store"
)

func newTestKey(t *testing.T) (authorized, fingerprint string) {
	t.Helper()
	pub, _, err := ed25519.GenerateKey(rand.Reader)
	if err != nil {
		t.Fatal(err)
	}
	sshPub, err := gossh.NewPublicKey(pub)
	if err != nil {
		t.Fatal(err)
	}
	return strings.TrimSpace(string(gossh.MarshalAuthorizedKey(sshPub))), gossh.FingerprintSHA256(sshPub)
}

// TestDeleteUserRevokesPrincipal checks that deleting a user blocks any cert
// they still hold, and that re-creating the account lifts the block.
func TestDeleteUserRevokesPrincipal(t *testing.T) {
	s, err := store.Open(filepath.Join(t.TempDir(), "gitfed.db"))
	if err != nil {
		t.Fatal(err)
	}
	defer s.Close()
	a := New(s, nil, "local.test", t.TempDir(), testCA(t))
	key, _ := newTestKey(t)

	if err := a.CreateUser("alice", key); err != nil {
		t.Fatal(err)
	}
	if err := a.DeleteUser("alice"); err != nil {
		t.Fatal(err)
	}
	if r, _ := s.IsPrincipalRevoked("alice@local.test"); !r {
		t.Fatal("principal should be revoked after DeleteUser")
	}

	// Re-creating the account must clear the revocation.
	if err := a.CreateUser("alice", key); err != nil {
		t.Fatal(err)
	}
	if r, _ := s.IsPrincipalRevoked("alice@local.test"); r {
		t.Fatal("principal should be un-revoked after re-creation")
	}
}

// TestRemoveUserKeyRevokesKey checks that removing a key revokes certs issued
// for it, and that re-adding it lifts the block.
func TestRemoveUserKeyRevokesKey(t *testing.T) {
	s, err := store.Open(filepath.Join(t.TempDir(), "gitfed.db"))
	if err != nil {
		t.Fatal(err)
	}
	defer s.Close()
	a := New(s, nil, "local.test", t.TempDir(), testCA(t))

	key1, _ := newTestKey(t)
	key2, fp2 := newTestKey(t)

	if err := a.CreateUser("bob", key1); err != nil {
		t.Fatal(err)
	}
	if err := a.AddUserKey("bob", key2); err != nil {
		t.Fatal(err)
	}
	if err := a.RemoveUserKey("bob", key2); err != nil {
		t.Fatal(err)
	}
	if r, _ := s.IsKeyRevoked(fp2); !r {
		t.Fatal("key should be revoked after RemoveUserKey")
	}
	if err := a.AddUserKey("bob", key2); err != nil {
		t.Fatal(err)
	}
	if r, _ := s.IsKeyRevoked(fp2); r {
		t.Fatal("key should be un-revoked after re-adding")
	}
}