auth
auth/profile.go
Update profiles and add tests. Add tests for profile storage. Make Memstore implement the profilestore interface. Get the groundwork of profiles laid.
1.1 --- a/profile.go Sun Sep 07 19:07:48 2014 -0400 1.2 +++ b/profile.go Sun Sep 07 19:09:01 2014 -0400 1.3 @@ -1,18 +1,80 @@ 1.4 package auth 1.5 1.6 import ( 1.7 + "errors" 1.8 "time" 1.9 1.10 "secondbit.org/uuid" 1.11 ) 1.12 1.13 +var ( 1.14 + ErrProfileAlreadyExists = errors.New("profile already exists in ProfileStore") 1.15 + ErrProfileNotFound = errors.New("profile not found in ProfileStore") 1.16 +) 1.17 + 1.18 type Profile struct { 1.19 - ID uuid.ID 1.20 - Name string 1.21 - Passphrase string 1.22 - Email string 1.23 - Created time.Time 1.24 - LastSeen time.Time 1.25 + ID uuid.ID 1.26 + Name string 1.27 + Passphrase string 1.28 + Iterations int64 1.29 + Salt string 1.30 + PassphraseScheme int 1.31 + Compromised bool 1.32 + LockedUntil time.Time 1.33 + PassphraseReset string 1.34 + PassphraseResetCreated time.Time 1.35 + Created time.Time 1.36 + LastSeen time.Time 1.37 +} 1.38 + 1.39 +func (p *Profile) ApplyChange(change ProfileChange) { 1.40 + if change.Name != nil { 1.41 + p.Name = *change.Name 1.42 + } 1.43 + if change.Passphrase != nil { 1.44 + p.Passphrase = *change.Passphrase 1.45 + } 1.46 + if change.Iterations != nil { 1.47 + p.Iterations = *change.Iterations 1.48 + } 1.49 + if change.Salt != nil { 1.50 + p.Salt = *change.Salt 1.51 + } 1.52 + if change.PassphraseScheme != nil { 1.53 + p.PassphraseScheme = *change.PassphraseScheme 1.54 + } 1.55 + if change.Compromised != nil { 1.56 + p.Compromised = *change.Compromised 1.57 + } 1.58 + if change.LockedUntil != nil { 1.59 + p.LockedUntil = *change.LockedUntil 1.60 + } 1.61 + if change.PassphraseReset != nil { 1.62 + p.PassphraseReset = *change.PassphraseReset 1.63 + } 1.64 + if change.PassphraseResetCreated != nil { 1.65 + p.PassphraseResetCreated = *change.PassphraseResetCreated 1.66 + } 1.67 + if change.LastSeen != nil { 1.68 + p.LastSeen = *change.LastSeen 1.69 + } 1.70 +} 1.71 + 1.72 +type ProfileChange struct { 1.73 + Name *string 1.74 + Passphrase *string 1.75 + Iterations *int64 1.76 + Salt *string 1.77 + PassphraseScheme *int 1.78 + Compromised *bool 1.79 + LockedUntil *time.Time 1.80 + PassphraseReset *string 1.81 + PassphraseResetCreated *time.Time 1.82 + LastSeen *time.Time 1.83 +} 1.84 + 1.85 +func (c ProfileChange) Validate() error { 1.86 + return nil 1.87 } 1.88 1.89 type Login struct { 1.90 @@ -25,12 +87,56 @@ 1.91 1.92 type ProfileStore interface { 1.93 GetProfileByID(id uuid.ID) (Profile, error) 1.94 - GetProfileByLogin(loginType, value, passphrase string) (Profile, error) 1.95 - SaveProfile(user Profile) error 1.96 - UpdateProfile(id uuid.ID, name, passphrase, email *string) error 1.97 + GetProfileByLogin(login Login) (Profile, error) 1.98 + SaveProfile(profile Profile) error 1.99 + UpdateProfile(id uuid.ID, change ProfileChange) error 1.100 DeleteProfile(id uuid.ID) error 1.101 +} 1.102 1.103 - SaveLogin(login Login) error 1.104 - DeleteLogin(login Login) error 1.105 - UpdateLogin(id uuid.ID, lastUsed time.Time) error 1.106 +func (m *Memstore) GetProfileByID(id uuid.ID) (Profile, error) { 1.107 + m.profileLock.RLock() 1.108 + defer m.profileLock.RUnlock() 1.109 + p, ok := m.profiles[id.String()] 1.110 + if !ok { 1.111 + return Profile{}, ErrProfileNotFound 1.112 + } 1.113 + return p, nil 1.114 } 1.115 + 1.116 +func (m *Memstore) GetProfileByLogin(login Login) (Profile, error) { 1.117 + return Profile{}, nil 1.118 +} 1.119 + 1.120 +func (m *Memstore) SaveProfile(profile Profile) error { 1.121 + m.profileLock.Lock() 1.122 + defer m.profileLock.Unlock() 1.123 + _, ok := m.profiles[profile.ID.String()] 1.124 + if ok { 1.125 + return ErrProfileAlreadyExists 1.126 + } 1.127 + m.profiles[profile.ID.String()] = profile 1.128 + return nil 1.129 +} 1.130 + 1.131 +func (m *Memstore) UpdateProfile(id uuid.ID, change ProfileChange) error { 1.132 + m.profileLock.Lock() 1.133 + defer m.profileLock.Unlock() 1.134 + p, ok := m.profiles[id.String()] 1.135 + if !ok { 1.136 + return ErrProfileNotFound 1.137 + } 1.138 + p.ApplyChange(change) 1.139 + m.profiles[id.String()] = p 1.140 + return nil 1.141 +} 1.142 + 1.143 +func (m *Memstore) DeleteProfile(id uuid.ID) error { 1.144 + m.profileLock.Lock() 1.145 + defer m.profileLock.Unlock() 1.146 + _, ok := m.profiles[id.String()] 1.147 + if !ok { 1.148 + return ErrProfileNotFound 1.149 + } 1.150 + delete(m.profiles, id.String()) 1.151 + return nil 1.152 +}