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
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/profile_test.go	Sun Sep 07 19:09:01 2014 -0400
     1.3 @@ -0,0 +1,223 @@
     1.4 +package auth
     1.5 +
     1.6 +import (
     1.7 +	"fmt"
     1.8 +	"testing"
     1.9 +	"time"
    1.10 +
    1.11 +	"secondbit.org/uuid"
    1.12 +)
    1.13 +
    1.14 +const (
    1.15 +	profileChangeName = 1 << iota
    1.16 +	profileChangePassphrase
    1.17 +	profileChangeIterations
    1.18 +	profileChangeSalt
    1.19 +	profileChangePassphraseScheme
    1.20 +	profileChangeCompromised
    1.21 +	profileChangeLockedUntil
    1.22 +	profileChangePassphraseReset
    1.23 +	profileChangePassphraseResetCreated
    1.24 +	profileChangeLastSeen
    1.25 +)
    1.26 +
    1.27 +var profileStores = []ProfileStore{NewMemstore()}
    1.28 +
    1.29 +func compareProfiles(profile1, profile2 Profile) (success bool, field string, val1, val2 interface{}) {
    1.30 +	if !profile1.ID.Equal(profile2.ID) {
    1.31 +		return false, "ID", profile1.ID, profile2.ID
    1.32 +	}
    1.33 +	if profile1.Name != profile2.Name {
    1.34 +		return false, "name", profile1.Name, profile2.Name
    1.35 +	}
    1.36 +	if profile1.Passphrase != profile2.Passphrase {
    1.37 +		return false, "passphrase", profile1.Passphrase, profile2.Passphrase
    1.38 +	}
    1.39 +	if profile1.Iterations != profile2.Iterations {
    1.40 +		return false, "iterations", profile1.Iterations, profile2.Iterations
    1.41 +	}
    1.42 +	if profile1.Salt != profile2.Salt {
    1.43 +		return false, "salt", profile1.Salt, profile2.Salt
    1.44 +	}
    1.45 +	if profile1.PassphraseScheme != profile2.PassphraseScheme {
    1.46 +		return false, "passphrase scheme", profile1.PassphraseScheme, profile2.PassphraseScheme
    1.47 +	}
    1.48 +	if profile1.Compromised != profile2.Compromised {
    1.49 +		return false, "compromised", profile1.Compromised, profile2.Compromised
    1.50 +	}
    1.51 +	if !profile1.LockedUntil.Equal(profile2.LockedUntil) {
    1.52 +		return false, "locked until", profile1.LockedUntil, profile2.LockedUntil
    1.53 +	}
    1.54 +	if profile1.PassphraseReset != profile2.PassphraseReset {
    1.55 +		return false, "passphrase reset", profile1.PassphraseReset, profile2.PassphraseReset
    1.56 +	}
    1.57 +	if !profile1.PassphraseResetCreated.Equal(profile2.PassphraseResetCreated) {
    1.58 +		return false, "passphrase reset created", profile1.PassphraseResetCreated, profile2.PassphraseResetCreated
    1.59 +	}
    1.60 +	if !profile1.Created.Equal(profile2.Created) {
    1.61 +		return false, "created", profile1.Created, profile2.Created
    1.62 +	}
    1.63 +	if !profile1.LastSeen.Equal(profile2.LastSeen) {
    1.64 +		return false, "last seen", profile1.LastSeen, profile2.LastSeen
    1.65 +	}
    1.66 +	return true, "", nil, nil
    1.67 +}
    1.68 +
    1.69 +func TestProfileStoreSuccess(t *testing.T) {
    1.70 +	t.Parallel()
    1.71 +	profile := Profile{
    1.72 +		ID:                     uuid.NewID(),
    1.73 +		Name:                   "name",
    1.74 +		Passphrase:             "passphrase",
    1.75 +		Iterations:             10000,
    1.76 +		Salt:                   "salt",
    1.77 +		PassphraseScheme:       1,
    1.78 +		Compromised:            false,
    1.79 +		LockedUntil:            time.Now().Add(time.Hour),
    1.80 +		PassphraseReset:        "passphrase reset",
    1.81 +		PassphraseResetCreated: time.Now(),
    1.82 +		Created:                time.Now(),
    1.83 +		LastSeen:               time.Now(),
    1.84 +	}
    1.85 +	for _, store := range profileStores {
    1.86 +		err := store.SaveProfile(profile)
    1.87 +		if err != nil {
    1.88 +			t.Errorf("Error saving profile to %T: %s", store, err)
    1.89 +		}
    1.90 +		err = store.SaveProfile(profile)
    1.91 +		if err != ErrProfileAlreadyExists {
    1.92 +			t.Errorf("Expected ErrProfileAlreadyExists from %T, got %+v", store, err)
    1.93 +		}
    1.94 +		retrieved, err := store.GetProfileByID(profile.ID)
    1.95 +		if err != nil {
    1.96 +			t.Errorf("Error retrieving profile from %T: %s", store, err)
    1.97 +		}
    1.98 +		match, field, expectation, result := compareProfiles(profile, retrieved)
    1.99 +		if !match {
   1.100 +			t.Errorf("Expected `%v` in the `%s` field of profile retrieved from %T, got `%v`", expectation, field, store, result)
   1.101 +		}
   1.102 +		err = store.DeleteProfile(profile.ID)
   1.103 +		if err != nil {
   1.104 +			t.Errorf("Error removing profile from %T: %s", store, err)
   1.105 +		}
   1.106 +		retrieved, err = store.GetProfileByID(profile.ID)
   1.107 +		if err != ErrProfileNotFound {
   1.108 +			t.Errorf("Expected ErrProfileNotFound from %T, got %+v and %+v", store, retrieved, err)
   1.109 +		}
   1.110 +		err = store.DeleteProfile(profile.ID)
   1.111 +		if err != ErrProfileNotFound {
   1.112 +			t.Errorf("Expected ErrProfileNotFound from %T, got %+v", store, err)
   1.113 +		}
   1.114 +	}
   1.115 +}
   1.116 +
   1.117 +func TestProfileUpdates(t *testing.T) {
   1.118 +	t.Parallel()
   1.119 +	variations := 1 << 10
   1.120 +	profile := Profile{
   1.121 +		ID:                     uuid.NewID(),
   1.122 +		Name:                   "name",
   1.123 +		Passphrase:             "passphrase",
   1.124 +		Iterations:             10000,
   1.125 +		Salt:                   "salt",
   1.126 +		PassphraseScheme:       1,
   1.127 +		Compromised:            false,
   1.128 +		LockedUntil:            time.Now().Add(time.Hour),
   1.129 +		PassphraseReset:        "passphrase reset",
   1.130 +		PassphraseResetCreated: time.Now(),
   1.131 +		Created:                time.Now(),
   1.132 +		LastSeen:               time.Now(),
   1.133 +	}
   1.134 +	for i := 0; i < variations; i++ {
   1.135 +		var name, passphrase, salt, passphraseReset string
   1.136 +		var iterations int64
   1.137 +		var lockedUntil, passphraseResetCreated, lastSeen time.Time
   1.138 +		var passphraseScheme int
   1.139 +		var compromised bool
   1.140 +
   1.141 +		change := ProfileChange{}
   1.142 +		expectation := profile
   1.143 +		result := profile
   1.144 +		if i&profileChangeName != 0 {
   1.145 +			name = fmt.Sprintf("name-%d", i)
   1.146 +			change.Name = &name
   1.147 +			expectation.Name = name
   1.148 +		}
   1.149 +		if i&profileChangePassphrase != 0 {
   1.150 +			passphrase = fmt.Sprintf("passphrase-%d", i)
   1.151 +			change.Passphrase = &passphrase
   1.152 +			expectation.Passphrase = passphrase
   1.153 +		}
   1.154 +		if i&profileChangeIterations != 0 {
   1.155 +			iterations = int64(i)
   1.156 +			change.Iterations = &iterations
   1.157 +			expectation.Iterations = iterations
   1.158 +		}
   1.159 +		if i&profileChangeSalt != 0 {
   1.160 +			salt = fmt.Sprintf("salt-%d", i)
   1.161 +			change.Salt = &salt
   1.162 +			expectation.Salt = salt
   1.163 +		}
   1.164 +		if i&profileChangePassphraseScheme != 0 {
   1.165 +			passphraseScheme = i
   1.166 +			change.PassphraseScheme = &passphraseScheme
   1.167 +			expectation.PassphraseScheme = passphraseScheme
   1.168 +		}
   1.169 +		if i&profileChangeCompromised != 0 {
   1.170 +			compromised = i%2 != 0
   1.171 +			change.Compromised = &compromised
   1.172 +			expectation.Compromised = compromised
   1.173 +		}
   1.174 +		if i&profileChangeLockedUntil != 0 {
   1.175 +			lockedUntil = time.Now()
   1.176 +			change.LockedUntil = &lockedUntil
   1.177 +			expectation.LockedUntil = lockedUntil
   1.178 +		}
   1.179 +		if i&profileChangePassphraseReset != 0 {
   1.180 +			passphraseReset = fmt.Sprintf("passphraseReset-%d", i)
   1.181 +			change.PassphraseReset = &passphraseReset
   1.182 +			expectation.PassphraseReset = passphraseReset
   1.183 +		}
   1.184 +		if i&profileChangePassphraseResetCreated != 0 {
   1.185 +			passphraseResetCreated = time.Now()
   1.186 +			change.PassphraseResetCreated = &passphraseResetCreated
   1.187 +			expectation.PassphraseResetCreated = passphraseResetCreated
   1.188 +		}
   1.189 +		if i&profileChangeLastSeen != 0 {
   1.190 +			lastSeen = time.Now()
   1.191 +			change.LastSeen = &lastSeen
   1.192 +			expectation.LastSeen = lastSeen
   1.193 +		}
   1.194 +		result.ApplyChange(change)
   1.195 +		match, field, expected, got := compareProfiles(expectation, result)
   1.196 +		if !match {
   1.197 +			t.Errorf("Expected field `%s` to be `%v`, got `%v`", field, expected, got)
   1.198 +		}
   1.199 +		for _, store := range profileStores {
   1.200 +			err := store.SaveProfile(profile)
   1.201 +			if err != nil {
   1.202 +				t.Errorf("Error saving profile in %T: %s", store, err)
   1.203 +			}
   1.204 +			err = store.UpdateProfile(profile.ID, change)
   1.205 +			if err != nil {
   1.206 +				t.Errorf("Error updating profile in %T: %s", store, err)
   1.207 +			}
   1.208 +			retrieved, err := store.GetProfileByID(profile.ID)
   1.209 +			if err != nil {
   1.210 +				t.Errorf("Error getting profile from %T: %s", store, err)
   1.211 +			}
   1.212 +			match, field, expected, got = compareProfiles(expectation, retrieved)
   1.213 +			if !match {
   1.214 +				t.Errorf("Expected field `%s` to be `%v`, got `%v` from %T", field, expected, got, store)
   1.215 +			}
   1.216 +			err = store.DeleteProfile(profile.ID)
   1.217 +			if err != nil {
   1.218 +				t.Errorf("Error deleting profile from %T: %s", store, err)
   1.219 +			}
   1.220 +			err = store.UpdateProfile(profile.ID, change)
   1.221 +			if err != ErrProfileNotFound {
   1.222 +				t.Errorf("Expected ErrProfileNotFound, got %v from %T", err, store)
   1.223 +			}
   1.224 +		}
   1.225 +	}
   1.226 +}