auth
auth/memstore.go
Store salts and passphrases as hex-encoded strings. Update our passphraseScheme.create function signature to return strings. Hex encode our passphrases and salts when encrypthing them so they're easier to store safely. Decode our salt before using it to check candidate passphrases.
| paddy@28 | 1 package auth |
| paddy@28 | 2 |
| paddy@31 | 3 import ( |
| paddy@31 | 4 "sync" |
| paddy@31 | 5 |
| paddy@45 | 6 "code.secondbit.org/uuid" |
| paddy@31 | 7 ) |
| paddy@28 | 8 |
| paddy@57 | 9 type memstore struct { |
| paddy@28 | 10 tokens map[string]Token |
| paddy@28 | 11 refreshTokenLookup map[string]string |
| paddy@28 | 12 profileTokenLookup map[string][]string |
| paddy@28 | 13 tokenLock sync.RWMutex |
| paddy@29 | 14 |
| paddy@87 | 15 authCodes map[string]AuthorizationCode |
| paddy@87 | 16 authCodeLock sync.RWMutex |
| paddy@31 | 17 |
| paddy@31 | 18 clients map[string]Client |
| paddy@31 | 19 profileClientLookup map[string][]uuid.ID |
| paddy@31 | 20 clientLock sync.RWMutex |
| paddy@38 | 21 |
| paddy@41 | 22 endpoints map[string][]Endpoint |
| paddy@41 | 23 endpointLock sync.RWMutex |
| paddy@41 | 24 |
| paddy@38 | 25 profiles map[string]Profile |
| paddy@38 | 26 profileLock sync.RWMutex |
| paddy@44 | 27 |
| paddy@44 | 28 logins map[string]Login |
| paddy@44 | 29 profileLoginLookup map[string][]string |
| paddy@44 | 30 loginLock sync.RWMutex |
| paddy@77 | 31 |
| paddy@77 | 32 sessions map[string]Session |
| paddy@77 | 33 sessionLock sync.RWMutex |
| paddy@28 | 34 } |
| paddy@28 | 35 |
| paddy@57 | 36 // NewMemstore returns an in-memory version of our datastores, |
| paddy@57 | 37 // which is handy for tests. Though the implementation is concurrency-safe, |
| paddy@57 | 38 // if makes no attempt to persist the data, and therefore it is inadvisable |
| paddy@57 | 39 // to use it in a production setting. |
| paddy@57 | 40 func NewMemstore() *memstore { |
| paddy@57 | 41 return &memstore{ |
| paddy@31 | 42 tokens: map[string]Token{}, |
| paddy@31 | 43 refreshTokenLookup: map[string]string{}, |
| paddy@31 | 44 profileTokenLookup: map[string][]string{}, |
| paddy@87 | 45 authCodes: map[string]AuthorizationCode{}, |
| paddy@31 | 46 clients: map[string]Client{}, |
| paddy@31 | 47 profileClientLookup: map[string][]uuid.ID{}, |
| paddy@41 | 48 endpoints: map[string][]Endpoint{}, |
| paddy@38 | 49 profiles: map[string]Profile{}, |
| paddy@44 | 50 logins: map[string]Login{}, |
| paddy@44 | 51 profileLoginLookup: map[string][]string{}, |
| paddy@77 | 52 sessions: map[string]Session{}, |
| paddy@28 | 53 } |
| paddy@28 | 54 } |
| paddy@28 | 55 |
| paddy@57 | 56 func (m *memstore) lookupTokenByRefresh(token string) (string, error) { |
| paddy@28 | 57 m.tokenLock.RLock() |
| paddy@28 | 58 defer m.tokenLock.RUnlock() |
| paddy@28 | 59 t, ok := m.refreshTokenLookup[token] |
| paddy@28 | 60 if !ok { |
| paddy@28 | 61 return "", ErrTokenNotFound |
| paddy@28 | 62 } |
| paddy@28 | 63 return t, nil |
| paddy@28 | 64 } |
| paddy@28 | 65 |
| paddy@57 | 66 func (m *memstore) lookupTokensByProfileID(id string) ([]string, error) { |
| paddy@28 | 67 m.tokenLock.RLock() |
| paddy@28 | 68 defer m.tokenLock.RUnlock() |
| paddy@28 | 69 return m.profileTokenLookup[id], nil |
| paddy@28 | 70 } |
| paddy@31 | 71 |
| paddy@57 | 72 func (m *memstore) lookupClientsByProfileID(id string) []uuid.ID { |
| paddy@31 | 73 m.clientLock.RLock() |
| paddy@31 | 74 defer m.clientLock.RUnlock() |
| paddy@33 | 75 c, ok := m.profileClientLookup[id] |
| paddy@33 | 76 if !ok { |
| paddy@33 | 77 return []uuid.ID{} |
| paddy@33 | 78 } |
| paddy@33 | 79 return c |
| paddy@31 | 80 } |