internal/store/tokens_test.go

v1.42.0
gitbay/internal/store/tokens_test.go history · blame · raw

115 lines · 3365 bytes

  1package store
  2
  3import (
  4	"slices"
  5	"testing"
  6	"time"
  7)
  8
  9func tokenID(t *testing.T, s *Store, hash string) int64 {
 10	t.Helper()
 11	_, tok, err := s.APITokenUser(hash)
 12	if err != nil {
 13		t.Fatal(err)
 14	}
 15	return tok.ID
 16}
 17
 18// parent made child, child made grandchild and a key; the key belongs
 19// to another account, as admin user create --key makes one.
 20func tokenChain(t *testing.T) (*Store, int64, *[]Revoked) {
 21	t.Helper()
 22	s, uid, got := revokeFixture(t)
 23	bob, err := s.CreateUser("bob", false)
 24	if err != nil {
 25		t.Fatal(err)
 26	}
 27	if err := s.CreateAPIToken(uid, "parent", "h-parent", "full", nil, 0); err != nil {
 28		t.Fatal(err)
 29	}
 30	if err := s.CreateAPIToken(uid, "child", "h-child", "full", nil, tokenID(t, s, "h-parent")); err != nil {
 31		t.Fatal(err)
 32	}
 33	child := tokenID(t, s, "h-child")
 34	if err := s.CreateAPIToken(uid, "grandchild", "h-grand", "read", nil, child); err != nil {
 35		t.Fatal(err)
 36	}
 37	if err := s.AddSSHKeyFrom(bob, "SHA256:k", "ssh-ed25519", []byte("k"), "full", "", KeyOrigin{CreatedByToken: child}); err != nil {
 38		t.Fatal(err)
 39	}
 40	return s, uid, got
 41}
 42
 43func TestTokenRecordsItsCreator(t *testing.T) {
 44	s, uid, _ := tokenChain(t)
 45	toks, err := s.ListAPITokens(uid)
 46	if err != nil {
 47		t.Fatal(err)
 48	}
 49	by := map[string]string{}
 50	for _, tk := range toks {
 51		by[tk.Name] = tk.CreatedBy
 52	}
 53	if by["parent"] != "" || by["child"] != "parent" || by["grandchild"] != "child" {
 54		t.Fatalf("created by: %v", by)
 55	}
 56	bob, _ := s.UserByUsername("bob")
 57	keys, err := s.ListSSHKeys(bob.ID)
 58	if err != nil || len(keys) != 1 || keys[0].CreatedBy != "child" {
 59		t.Fatalf("key created by: %+v %v", keys, err)
 60	}
 61}
 62
 63func TestRevokeAPITokenListsWhatItCreated(t *testing.T) {
 64	s, uid, got := tokenChain(t)
 65	c, err := s.RevokeAPIToken(uid, "parent", false)
 66	if err != nil {
 67		t.Fatal(err)
 68	}
 69	if !slices.Equal(c.Tokens, []string{"child", "grandchild"}) || !slices.Equal(c.Keys, []string{"SHA256:k"}) {
 70		t.Fatalf("created = %+v", c)
 71	}
 72	// Listed, not removed; the link to the revoked parent is gone.
 73	toks, _ := s.ListAPITokens(uid)
 74	if len(toks) != 2 || toks[0].Name != "child" || toks[0].CreatedBy != "" {
 75		t.Fatalf("tokens after revoke: %+v", toks)
 76	}
 77	if _, err := s.SSHKeyByFingerprint("SHA256:k"); err != nil {
 78		t.Fatalf("the key went: %v", err)
 79	}
 80	if len(*got) != 0 {
 81		t.Fatalf("announced %+v with nothing revoked but the token", *got)
 82	}
 83}
 84
 85func TestRevokeAPITokenWithCreated(t *testing.T) {
 86	s, uid, got := tokenChain(t)
 87	k, _ := s.SSHKeyByFingerprint("SHA256:k")
 88	if _, err := s.RevokeAPIToken(uid, "parent", true); err != nil {
 89		t.Fatal(err)
 90	}
 91	if toks, _ := s.ListAPITokens(uid); len(toks) != 0 {
 92		t.Fatalf("tokens left: %+v", toks)
 93	}
 94	if _, err := s.SSHKeyByFingerprint("SHA256:k"); err != ErrNotFound {
 95		t.Fatalf("key left: %v", err)
 96	}
 97	if len(*got) != 1 || !slices.Equal((*got)[0].KeyIDs, []int64{k.ID}) {
 98		t.Fatalf("announced %+v", *got)
 99	}
100	if _, err := s.RevokeAPIToken(uid, "parent", true); err != ErrNotFound {
101		t.Fatalf("second revoke: %v", err)
102	}
103}
104
105func TestAPITokenUserCarriesExpiry(t *testing.T) {
106	s, uid, _ := revokeFixture(t)
107	exp := time.Now().Add(time.Hour)
108	if err := s.CreateAPIToken(uid, "brief", "h-brief", "full", &exp, 0); err != nil {
109		t.Fatal(err)
110	}
111	_, tok, err := s.APITokenUser("h-brief")
112	if err != nil || tok.ExpiresAt == nil || tok.Name != "brief" || tok.ID == 0 {
113		t.Fatalf("token %+v %v", tok, err)
114	}
115}