auth

Paddy 2014-09-29 Parent:85f1baf7a9ac Child:73a9f7a6af54

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.

profile.go profile_test.go

     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 +}