auth
48:d78418fb9f56 Browse Files
Validate profile changes. Implement validation for ProfileChange and BulkProfileChange structs. Add unit tests to ensure that validation is working as intended.
1.1 --- a/profile.go Sat Sep 27 22:25:06 2014 -0400 1.2 +++ b/profile.go Mon Sep 29 00:58:42 2014 -0400 1.3 @@ -7,11 +7,22 @@ 1.4 "code.secondbit.org/uuid" 1.5 ) 1.6 1.7 +const ( 1.8 + MinPassphraseLength = 6 1.9 + MaxPassphraseLength = 64 1.10 +) 1.11 + 1.12 var ( 1.13 ErrProfileAlreadyExists = errors.New("profile already exists in ProfileStore") 1.14 ErrProfileNotFound = errors.New("profile not found in ProfileStore") 1.15 ErrLoginAlreadyExists = errors.New("login already exists in ProfileStore") 1.16 ErrLoginNotFound = errors.New("login not found in ProfileStore") 1.17 + 1.18 + ErrMissingPassphrase = errors.New("missing passphrase") 1.19 + ErrMissingPassphraseReset = errors.New("missing passphrase reset") 1.20 + ErrMissingPassphraseResetCreated = errors.New("missing passphrase reset created timestamp") 1.21 + ErrPassphraseTooShort = errors.New("passphrase too short") 1.22 + ErrPassphraseTooLong = errors.New("passphrase too long") 1.23 ) 1.24 1.25 type Profile struct { 1.26 @@ -82,7 +93,30 @@ 1.27 } 1.28 1.29 func (c ProfileChange) Validate() error { 1.30 - // TODO: validate profile changes 1.31 + if c.Name == nil && c.Passphrase == nil && c.Iterations == nil && c.Salt == nil && c.PassphraseScheme == nil && c.Compromised == nil && c.LockedUntil == nil && c.PassphraseReset == nil && c.PassphraseResetCreated == nil && c.LastSeen == nil { 1.32 + return ErrEmptyChange 1.33 + } 1.34 + if c.PassphraseScheme != nil && c.Passphrase == nil { 1.35 + return ErrMissingPassphrase 1.36 + } 1.37 + if c.PassphraseReset != nil && c.PassphraseResetCreated == nil { 1.38 + return ErrMissingPassphraseResetCreated 1.39 + } 1.40 + if c.PassphraseReset == nil && c.PassphraseResetCreated != nil { 1.41 + return ErrMissingPassphraseReset 1.42 + } 1.43 + if c.Salt != nil && c.Passphrase == nil { 1.44 + return ErrMissingPassphrase 1.45 + } 1.46 + if c.Iterations != nil && c.Passphrase == nil { 1.47 + return ErrMissingPassphrase 1.48 + } 1.49 + if c.Passphrase != nil && len(*c.Passphrase) < MinPassphraseLength { 1.50 + return ErrPassphraseTooShort 1.51 + } 1.52 + if c.Passphrase != nil && len(*c.Passphrase) > MaxPassphraseLength { 1.53 + return ErrPassphraseTooLong 1.54 + } 1.55 return nil 1.56 } 1.57 1.58 @@ -91,7 +125,9 @@ 1.59 } 1.60 1.61 func (b BulkProfileChange) Validate() error { 1.62 - // TODO: validate bulk profile changs 1.63 + if b.Compromised == nil { 1.64 + return ErrEmptyChange 1.65 + } 1.66 return nil 1.67 } 1.68
2.1 --- a/profile_test.go Sat Sep 27 22:25:06 2014 -0400 2.2 +++ b/profile_test.go Mon Sep 29 00:58:42 2014 -0400 2.3 @@ -404,3 +404,59 @@ 2.4 } 2.5 } 2.6 } 2.7 + 2.8 +func TestProfileChangeValidation(t *testing.T) { 2.9 + t.Parallel() 2.10 + passphraseScheme := 1 2.11 + passphraseReset := "reset" 2.12 + salt := "salt" 2.13 + iterations := int64(100) 2.14 + shortPassphrase := "a" 2.15 + longPassphrase := "this passphrase is much too long for anyone to remember, and therefore should probably be discouraged by the software, don't you think?" 2.16 + emptyName := "" 2.17 + enteredName := "Paddy" 2.18 + okPassphrase := "this is a decent passphrase" 2.19 + compromised := true 2.20 + lockedUntil := time.Now() 2.21 + resetCreated := time.Now() 2.22 + lastSeen := time.Now() 2.23 + changes := map[*ProfileChange]error{ 2.24 + &ProfileChange{}: ErrEmptyChange, 2.25 + &ProfileChange{PassphraseScheme: &passphraseScheme}: ErrMissingPassphrase, 2.26 + &ProfileChange{PassphraseScheme: &passphraseScheme, Passphrase: &okPassphrase}: nil, 2.27 + &ProfileChange{PassphraseReset: &passphraseReset}: ErrMissingPassphraseResetCreated, 2.28 + &ProfileChange{PassphraseReset: &passphraseReset, PassphraseResetCreated: &resetCreated}: nil, 2.29 + &ProfileChange{Salt: &salt}: ErrMissingPassphrase, 2.30 + &ProfileChange{Salt: &salt, Passphrase: &okPassphrase}: nil, 2.31 + &ProfileChange{Iterations: &iterations}: ErrMissingPassphrase, 2.32 + &ProfileChange{Iterations: &iterations, Passphrase: &okPassphrase}: nil, 2.33 + &ProfileChange{Passphrase: &shortPassphrase}: ErrPassphraseTooShort, 2.34 + &ProfileChange{Passphrase: &longPassphrase}: ErrPassphraseTooLong, 2.35 + &ProfileChange{Passphrase: &okPassphrase}: nil, 2.36 + &ProfileChange{Name: &emptyName}: nil, 2.37 + &ProfileChange{Name: &enteredName}: nil, 2.38 + &ProfileChange{Compromised: &compromised}: nil, 2.39 + &ProfileChange{LockedUntil: &lockedUntil}: nil, 2.40 + &ProfileChange{LastSeen: &lastSeen}: nil, 2.41 + &ProfileChange{PassphraseResetCreated: &resetCreated}: ErrMissingPassphraseReset, 2.42 + } 2.43 + for change, expectedErr := range changes { 2.44 + if err := change.Validate(); err != expectedErr { 2.45 + t.Errorf("Expected %+v to give an error of %v, gave %v", change, expectedErr, err) 2.46 + } 2.47 + } 2.48 +} 2.49 + 2.50 +func TestBulkProfileChangeValidation(t *testing.T) { 2.51 + t.Parallel() 2.52 + compromised := true 2.53 + changes := map[*BulkProfileChange]error{ 2.54 + &BulkProfileChange{}: ErrEmptyChange, 2.55 + &BulkProfileChange{Compromised: &compromised}: nil, 2.56 + } 2.57 + for change, expectedErr := range changes { 2.58 + if err := change.Validate(); err != expectedErr { 2.59 + t.Errorf("Expected %+v to give an error of %v, gave %v", change, expectedErr, err) 2.60 + } 2.61 + } 2.62 +}