auth
auth/profile.go
Add TODOs. Add TODO comments where functionality is stubbed out or anticipated, but work is needed to implement it.
| paddy@27 | 1 package auth |
| paddy@27 | 2 |
| paddy@27 | 3 import ( |
| paddy@38 | 4 "errors" |
| paddy@27 | 5 "time" |
| paddy@27 | 6 |
| paddy@27 | 7 "secondbit.org/uuid" |
| paddy@27 | 8 ) |
| paddy@27 | 9 |
| paddy@38 | 10 var ( |
| paddy@38 | 11 ErrProfileAlreadyExists = errors.New("profile already exists in ProfileStore") |
| paddy@38 | 12 ErrProfileNotFound = errors.New("profile not found in ProfileStore") |
| paddy@38 | 13 ) |
| paddy@38 | 14 |
| paddy@27 | 15 type Profile struct { |
| paddy@38 | 16 ID uuid.ID |
| paddy@38 | 17 Name string |
| paddy@38 | 18 Passphrase string |
| paddy@38 | 19 Iterations int64 |
| paddy@38 | 20 Salt string |
| paddy@38 | 21 PassphraseScheme int |
| paddy@38 | 22 Compromised bool |
| paddy@38 | 23 LockedUntil time.Time |
| paddy@38 | 24 PassphraseReset string |
| paddy@38 | 25 PassphraseResetCreated time.Time |
| paddy@38 | 26 Created time.Time |
| paddy@38 | 27 LastSeen time.Time |
| paddy@38 | 28 } |
| paddy@38 | 29 |
| paddy@38 | 30 func (p *Profile) ApplyChange(change ProfileChange) { |
| paddy@38 | 31 if change.Name != nil { |
| paddy@38 | 32 p.Name = *change.Name |
| paddy@38 | 33 } |
| paddy@38 | 34 if change.Passphrase != nil { |
| paddy@38 | 35 p.Passphrase = *change.Passphrase |
| paddy@38 | 36 } |
| paddy@38 | 37 if change.Iterations != nil { |
| paddy@38 | 38 p.Iterations = *change.Iterations |
| paddy@38 | 39 } |
| paddy@38 | 40 if change.Salt != nil { |
| paddy@38 | 41 p.Salt = *change.Salt |
| paddy@38 | 42 } |
| paddy@38 | 43 if change.PassphraseScheme != nil { |
| paddy@38 | 44 p.PassphraseScheme = *change.PassphraseScheme |
| paddy@38 | 45 } |
| paddy@38 | 46 if change.Compromised != nil { |
| paddy@38 | 47 p.Compromised = *change.Compromised |
| paddy@38 | 48 } |
| paddy@38 | 49 if change.LockedUntil != nil { |
| paddy@38 | 50 p.LockedUntil = *change.LockedUntil |
| paddy@38 | 51 } |
| paddy@38 | 52 if change.PassphraseReset != nil { |
| paddy@38 | 53 p.PassphraseReset = *change.PassphraseReset |
| paddy@38 | 54 } |
| paddy@38 | 55 if change.PassphraseResetCreated != nil { |
| paddy@38 | 56 p.PassphraseResetCreated = *change.PassphraseResetCreated |
| paddy@38 | 57 } |
| paddy@38 | 58 if change.LastSeen != nil { |
| paddy@38 | 59 p.LastSeen = *change.LastSeen |
| paddy@38 | 60 } |
| paddy@38 | 61 } |
| paddy@38 | 62 |
| paddy@38 | 63 type ProfileChange struct { |
| paddy@38 | 64 Name *string |
| paddy@38 | 65 Passphrase *string |
| paddy@38 | 66 Iterations *int64 |
| paddy@38 | 67 Salt *string |
| paddy@38 | 68 PassphraseScheme *int |
| paddy@38 | 69 Compromised *bool |
| paddy@38 | 70 LockedUntil *time.Time |
| paddy@38 | 71 PassphraseReset *string |
| paddy@38 | 72 PassphraseResetCreated *time.Time |
| paddy@38 | 73 LastSeen *time.Time |
| paddy@38 | 74 } |
| paddy@38 | 75 |
| paddy@38 | 76 func (c ProfileChange) Validate() error { |
| paddy@40 | 77 // TODO: validate profile changes |
| paddy@38 | 78 return nil |
| paddy@27 | 79 } |
| paddy@27 | 80 |
| paddy@27 | 81 type Login struct { |
| paddy@27 | 82 Type string |
| paddy@27 | 83 Value string |
| paddy@27 | 84 ProfileID uuid.ID |
| paddy@27 | 85 Created time.Time |
| paddy@27 | 86 LastUsed time.Time |
| paddy@27 | 87 } |
| paddy@27 | 88 |
| paddy@27 | 89 type ProfileStore interface { |
| paddy@27 | 90 GetProfileByID(id uuid.ID) (Profile, error) |
| paddy@38 | 91 GetProfileByLogin(login Login) (Profile, error) |
| paddy@38 | 92 SaveProfile(profile Profile) error |
| paddy@38 | 93 UpdateProfile(id uuid.ID, change ProfileChange) error |
| paddy@27 | 94 DeleteProfile(id uuid.ID) error |
| paddy@38 | 95 } |
| paddy@27 | 96 |
| paddy@38 | 97 func (m *Memstore) GetProfileByID(id uuid.ID) (Profile, error) { |
| paddy@38 | 98 m.profileLock.RLock() |
| paddy@38 | 99 defer m.profileLock.RUnlock() |
| paddy@38 | 100 p, ok := m.profiles[id.String()] |
| paddy@38 | 101 if !ok { |
| paddy@38 | 102 return Profile{}, ErrProfileNotFound |
| paddy@38 | 103 } |
| paddy@38 | 104 return p, nil |
| paddy@27 | 105 } |
| paddy@38 | 106 |
| paddy@38 | 107 func (m *Memstore) GetProfileByLogin(login Login) (Profile, error) { |
| paddy@40 | 108 // TODO: get profile by login |
| paddy@38 | 109 return Profile{}, nil |
| paddy@38 | 110 } |
| paddy@38 | 111 |
| paddy@38 | 112 func (m *Memstore) SaveProfile(profile Profile) error { |
| paddy@38 | 113 m.profileLock.Lock() |
| paddy@38 | 114 defer m.profileLock.Unlock() |
| paddy@38 | 115 _, ok := m.profiles[profile.ID.String()] |
| paddy@38 | 116 if ok { |
| paddy@38 | 117 return ErrProfileAlreadyExists |
| paddy@38 | 118 } |
| paddy@38 | 119 m.profiles[profile.ID.String()] = profile |
| paddy@38 | 120 return nil |
| paddy@38 | 121 } |
| paddy@38 | 122 |
| paddy@38 | 123 func (m *Memstore) UpdateProfile(id uuid.ID, change ProfileChange) error { |
| paddy@38 | 124 m.profileLock.Lock() |
| paddy@38 | 125 defer m.profileLock.Unlock() |
| paddy@38 | 126 p, ok := m.profiles[id.String()] |
| paddy@38 | 127 if !ok { |
| paddy@38 | 128 return ErrProfileNotFound |
| paddy@38 | 129 } |
| paddy@38 | 130 p.ApplyChange(change) |
| paddy@38 | 131 m.profiles[id.String()] = p |
| paddy@38 | 132 return nil |
| paddy@38 | 133 } |
| paddy@38 | 134 |
| paddy@38 | 135 func (m *Memstore) DeleteProfile(id uuid.ID) error { |
| paddy@38 | 136 m.profileLock.Lock() |
| paddy@38 | 137 defer m.profileLock.Unlock() |
| paddy@38 | 138 _, ok := m.profiles[id.String()] |
| paddy@38 | 139 if !ok { |
| paddy@38 | 140 return ErrProfileNotFound |
| paddy@38 | 141 } |
| paddy@38 | 142 delete(m.profiles, id.String()) |
| paddy@38 | 143 return nil |
| paddy@38 | 144 } |
| paddy@40 | 145 |
| paddy@40 | 146 // TODO: login store |
| paddy@40 | 147 // TODO: login delete |
| paddy@40 | 148 // TODO: login update |