auth

Paddy 2014-09-07 Child:3a6a65ed380c

38:1f7b44b130a0 Go to Latest

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.

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