|
1
|
package auth_test |
|
2
|
|
|
3
|
import ( |
|
4
|
"path/filepath" |
|
5
|
"testing" |
|
6
|
|
|
7
|
"github.com/conflicthq/scuttlebot/internal/auth" |
|
8
|
) |
|
9
|
|
|
10
|
func newStore(t *testing.T) *auth.AdminStore { |
|
11
|
t.Helper() |
|
12
|
s, err := auth.NewAdminStore(filepath.Join(t.TempDir(), "admins.json")) |
|
13
|
if err != nil { |
|
14
|
t.Fatalf("NewAdminStore: %v", err) |
|
15
|
} |
|
16
|
return s |
|
17
|
} |
|
18
|
|
|
19
|
func TestIsEmptyInitially(t *testing.T) { |
|
20
|
s := newStore(t) |
|
21
|
if !s.IsEmpty() { |
|
22
|
t.Error("expected empty store") |
|
23
|
} |
|
24
|
} |
|
25
|
|
|
26
|
func TestAddAndAuthenticate(t *testing.T) { |
|
27
|
s := newStore(t) |
|
28
|
if err := s.Add("alice", "s3cr3t"); err != nil { |
|
29
|
t.Fatalf("Add: %v", err) |
|
30
|
} |
|
31
|
if !s.Authenticate("alice", "s3cr3t") { |
|
32
|
t.Error("expected Authenticate to return true for correct credentials") |
|
33
|
} |
|
34
|
if s.Authenticate("alice", "wrong") { |
|
35
|
t.Error("expected Authenticate to return false for wrong password") |
|
36
|
} |
|
37
|
if s.Authenticate("nobody", "s3cr3t") { |
|
38
|
t.Error("expected Authenticate to return false for unknown user") |
|
39
|
} |
|
40
|
} |
|
41
|
|
|
42
|
func TestAddDuplicateReturnsError(t *testing.T) { |
|
43
|
s := newStore(t) |
|
44
|
if err := s.Add("alice", "pass1"); err != nil { |
|
45
|
t.Fatalf("first Add: %v", err) |
|
46
|
} |
|
47
|
if err := s.Add("alice", "pass2"); err == nil { |
|
48
|
t.Error("expected error on duplicate Add") |
|
49
|
} |
|
50
|
} |
|
51
|
|
|
52
|
func TestIsEmptyAfterAdd(t *testing.T) { |
|
53
|
s := newStore(t) |
|
54
|
_ = s.Add("admin", "pw") |
|
55
|
if s.IsEmpty() { |
|
56
|
t.Error("expected non-empty store after Add") |
|
57
|
} |
|
58
|
} |
|
59
|
|
|
60
|
func TestList(t *testing.T) { |
|
61
|
s := newStore(t) |
|
62
|
_ = s.Add("alice", "pw") |
|
63
|
_ = s.Add("bob", "pw") |
|
64
|
|
|
65
|
list := s.List() |
|
66
|
if len(list) != 2 { |
|
67
|
t.Fatalf("List: got %d, want 2", len(list)) |
|
68
|
} |
|
69
|
names := map[string]bool{list[0].Username: true, list[1].Username: true} |
|
70
|
if !names["alice"] || !names["bob"] { |
|
71
|
t.Errorf("List: unexpected names %v", names) |
|
72
|
} |
|
73
|
} |
|
74
|
|
|
75
|
func TestSetPassword(t *testing.T) { |
|
76
|
s := newStore(t) |
|
77
|
_ = s.Add("alice", "old") |
|
78
|
|
|
79
|
if err := s.SetPassword("alice", "new"); err != nil { |
|
80
|
t.Fatalf("SetPassword: %v", err) |
|
81
|
} |
|
82
|
if s.Authenticate("alice", "old") { |
|
83
|
t.Error("old password should no longer work") |
|
84
|
} |
|
85
|
if !s.Authenticate("alice", "new") { |
|
86
|
t.Error("new password should work") |
|
87
|
} |
|
88
|
} |
|
89
|
|
|
90
|
func TestSetPasswordUnknownUser(t *testing.T) { |
|
91
|
s := newStore(t) |
|
92
|
if err := s.SetPassword("nobody", "pw"); err == nil { |
|
93
|
t.Error("expected error setting password for unknown user") |
|
94
|
} |
|
95
|
} |
|
96
|
|
|
97
|
func TestRemove(t *testing.T) { |
|
98
|
s := newStore(t) |
|
99
|
_ = s.Add("alice", "pw") |
|
100
|
_ = s.Add("bob", "pw") |
|
101
|
|
|
102
|
if err := s.Remove("alice"); err != nil { |
|
103
|
t.Fatalf("Remove: %v", err) |
|
104
|
} |
|
105
|
if len(s.List()) != 1 { |
|
106
|
t.Errorf("List after Remove: got %d, want 1", len(s.List())) |
|
107
|
} |
|
108
|
if s.List()[0].Username != "bob" { |
|
109
|
t.Errorf("expected bob to remain, got %q", s.List()[0].Username) |
|
110
|
} |
|
111
|
} |
|
112
|
|
|
113
|
func TestRemoveUnknown(t *testing.T) { |
|
114
|
s := newStore(t) |
|
115
|
if err := s.Remove("nobody"); err == nil { |
|
116
|
t.Error("expected error removing unknown user") |
|
117
|
} |
|
118
|
} |
|
119
|
|
|
120
|
func TestPersistence(t *testing.T) { |
|
121
|
dir := t.TempDir() |
|
122
|
path := filepath.Join(dir, "admins.json") |
|
123
|
|
|
124
|
s1, err := auth.NewAdminStore(path) |
|
125
|
if err != nil { |
|
126
|
t.Fatalf("create: %v", err) |
|
127
|
} |
|
128
|
_ = s1.Add("alice", "s3cr3t") |
|
129
|
|
|
130
|
// Load a new store from the same file. |
|
131
|
s2, err := auth.NewAdminStore(path) |
|
132
|
if err != nil { |
|
133
|
t.Fatalf("reload: %v", err) |
|
134
|
} |
|
135
|
if s2.IsEmpty() { |
|
136
|
t.Error("reloaded store should not be empty") |
|
137
|
} |
|
138
|
if !s2.Authenticate("alice", "s3cr3t") { |
|
139
|
t.Error("reloaded store should authenticate alice") |
|
140
|
} |
|
141
|
} |
|
142
|
|