auth
2014-09-07
Child:3a6a65ed380c
auth/profile_test.go
Update profiles and add tests. Add tests for profile storage. Make Memstore implement the profilestore interface. Get the groundwork of profiles laid.
1 package auth
3 import (
4 "fmt"
5 "testing"
6 "time"
8 "secondbit.org/uuid"
9 )
11 const (
12 profileChangeName = 1 << iota
13 profileChangePassphrase
14 profileChangeIterations
15 profileChangeSalt
16 profileChangePassphraseScheme
17 profileChangeCompromised
18 profileChangeLockedUntil
19 profileChangePassphraseReset
20 profileChangePassphraseResetCreated
21 profileChangeLastSeen
22 )
24 var profileStores = []ProfileStore{NewMemstore()}
26 func compareProfiles(profile1, profile2 Profile) (success bool, field string, val1, val2 interface{}) {
27 if !profile1.ID.Equal(profile2.ID) {
28 return false, "ID", profile1.ID, profile2.ID
29 }
30 if profile1.Name != profile2.Name {
31 return false, "name", profile1.Name, profile2.Name
32 }
33 if profile1.Passphrase != profile2.Passphrase {
34 return false, "passphrase", profile1.Passphrase, profile2.Passphrase
35 }
36 if profile1.Iterations != profile2.Iterations {
37 return false, "iterations", profile1.Iterations, profile2.Iterations
38 }
39 if profile1.Salt != profile2.Salt {
40 return false, "salt", profile1.Salt, profile2.Salt
41 }
42 if profile1.PassphraseScheme != profile2.PassphraseScheme {
43 return false, "passphrase scheme", profile1.PassphraseScheme, profile2.PassphraseScheme
44 }
45 if profile1.Compromised != profile2.Compromised {
46 return false, "compromised", profile1.Compromised, profile2.Compromised
47 }
48 if !profile1.LockedUntil.Equal(profile2.LockedUntil) {
49 return false, "locked until", profile1.LockedUntil, profile2.LockedUntil
50 }
51 if profile1.PassphraseReset != profile2.PassphraseReset {
52 return false, "passphrase reset", profile1.PassphraseReset, profile2.PassphraseReset
53 }
54 if !profile1.PassphraseResetCreated.Equal(profile2.PassphraseResetCreated) {
55 return false, "passphrase reset created", profile1.PassphraseResetCreated, profile2.PassphraseResetCreated
56 }
57 if !profile1.Created.Equal(profile2.Created) {
58 return false, "created", profile1.Created, profile2.Created
59 }
60 if !profile1.LastSeen.Equal(profile2.LastSeen) {
61 return false, "last seen", profile1.LastSeen, profile2.LastSeen
62 }
63 return true, "", nil, nil
64 }
66 func TestProfileStoreSuccess(t *testing.T) {
67 t.Parallel()
68 profile := Profile{
69 ID: uuid.NewID(),
70 Name: "name",
71 Passphrase: "passphrase",
72 Iterations: 10000,
73 Salt: "salt",
74 PassphraseScheme: 1,
75 Compromised: false,
76 LockedUntil: time.Now().Add(time.Hour),
77 PassphraseReset: "passphrase reset",
78 PassphraseResetCreated: time.Now(),
79 Created: time.Now(),
80 LastSeen: time.Now(),
81 }
82 for _, store := range profileStores {
83 err := store.SaveProfile(profile)
84 if err != nil {
85 t.Errorf("Error saving profile to %T: %s", store, err)
86 }
87 err = store.SaveProfile(profile)
88 if err != ErrProfileAlreadyExists {
89 t.Errorf("Expected ErrProfileAlreadyExists from %T, got %+v", store, err)
90 }
91 retrieved, err := store.GetProfileByID(profile.ID)
92 if err != nil {
93 t.Errorf("Error retrieving profile from %T: %s", store, err)
94 }
95 match, field, expectation, result := compareProfiles(profile, retrieved)
96 if !match {
97 t.Errorf("Expected `%v` in the `%s` field of profile retrieved from %T, got `%v`", expectation, field, store, result)
98 }
99 err = store.DeleteProfile(profile.ID)
100 if err != nil {
101 t.Errorf("Error removing profile from %T: %s", store, err)
102 }
103 retrieved, err = store.GetProfileByID(profile.ID)
104 if err != ErrProfileNotFound {
105 t.Errorf("Expected ErrProfileNotFound from %T, got %+v and %+v", store, retrieved, err)
106 }
107 err = store.DeleteProfile(profile.ID)
108 if err != ErrProfileNotFound {
109 t.Errorf("Expected ErrProfileNotFound from %T, got %+v", store, err)
110 }
111 }
112 }
114 func TestProfileUpdates(t *testing.T) {
115 t.Parallel()
116 variations := 1 << 10
117 profile := Profile{
118 ID: uuid.NewID(),
119 Name: "name",
120 Passphrase: "passphrase",
121 Iterations: 10000,
122 Salt: "salt",
123 PassphraseScheme: 1,
124 Compromised: false,
125 LockedUntil: time.Now().Add(time.Hour),
126 PassphraseReset: "passphrase reset",
127 PassphraseResetCreated: time.Now(),
128 Created: time.Now(),
129 LastSeen: time.Now(),
130 }
131 for i := 0; i < variations; i++ {
132 var name, passphrase, salt, passphraseReset string
133 var iterations int64
134 var lockedUntil, passphraseResetCreated, lastSeen time.Time
135 var passphraseScheme int
136 var compromised bool
138 change := ProfileChange{}
139 expectation := profile
140 result := profile
141 if i&profileChangeName != 0 {
142 name = fmt.Sprintf("name-%d", i)
143 change.Name = &name
144 expectation.Name = name
145 }
146 if i&profileChangePassphrase != 0 {
147 passphrase = fmt.Sprintf("passphrase-%d", i)
148 change.Passphrase = &passphrase
149 expectation.Passphrase = passphrase
150 }
151 if i&profileChangeIterations != 0 {
152 iterations = int64(i)
153 change.Iterations = &iterations
154 expectation.Iterations = iterations
155 }
156 if i&profileChangeSalt != 0 {
157 salt = fmt.Sprintf("salt-%d", i)
158 change.Salt = &salt
159 expectation.Salt = salt
160 }
161 if i&profileChangePassphraseScheme != 0 {
162 passphraseScheme = i
163 change.PassphraseScheme = &passphraseScheme
164 expectation.PassphraseScheme = passphraseScheme
165 }
166 if i&profileChangeCompromised != 0 {
167 compromised = i%2 != 0
168 change.Compromised = &compromised
169 expectation.Compromised = compromised
170 }
171 if i&profileChangeLockedUntil != 0 {
172 lockedUntil = time.Now()
173 change.LockedUntil = &lockedUntil
174 expectation.LockedUntil = lockedUntil
175 }
176 if i&profileChangePassphraseReset != 0 {
177 passphraseReset = fmt.Sprintf("passphraseReset-%d", i)
178 change.PassphraseReset = &passphraseReset
179 expectation.PassphraseReset = passphraseReset
180 }
181 if i&profileChangePassphraseResetCreated != 0 {
182 passphraseResetCreated = time.Now()
183 change.PassphraseResetCreated = &passphraseResetCreated
184 expectation.PassphraseResetCreated = passphraseResetCreated
185 }
186 if i&profileChangeLastSeen != 0 {
187 lastSeen = time.Now()
188 change.LastSeen = &lastSeen
189 expectation.LastSeen = lastSeen
190 }
191 result.ApplyChange(change)
192 match, field, expected, got := compareProfiles(expectation, result)
193 if !match {
194 t.Errorf("Expected field `%s` to be `%v`, got `%v`", field, expected, got)
195 }
196 for _, store := range profileStores {
197 err := store.SaveProfile(profile)
198 if err != nil {
199 t.Errorf("Error saving profile in %T: %s", store, err)
200 }
201 err = store.UpdateProfile(profile.ID, change)
202 if err != nil {
203 t.Errorf("Error updating profile in %T: %s", store, err)
204 }
205 retrieved, err := store.GetProfileByID(profile.ID)
206 if err != nil {
207 t.Errorf("Error getting profile from %T: %s", store, err)
208 }
209 match, field, expected, got = compareProfiles(expectation, retrieved)
210 if !match {
211 t.Errorf("Expected field `%s` to be `%v`, got `%v` from %T", field, expected, got, store)
212 }
213 err = store.DeleteProfile(profile.ID)
214 if err != nil {
215 t.Errorf("Error deleting profile from %T: %s", store, err)
216 }
217 err = store.UpdateProfile(profile.ID, change)
218 if err != ErrProfileNotFound {
219 t.Errorf("Expected ErrProfileNotFound, got %v from %T", err, store)
220 }
221 }
222 }
223 }