auth
auth/memstore.go
Added validation for clients, split endpoints out. Split endpoints out into their own type and added associated methods to the ClientStores, so now each client can have more than one redirect endpoint. Added unit testing for endpoint methods. Added validation code to validate client changes.
| paddy@28 | 1 package auth |
| paddy@28 | 2 |
| paddy@31 | 3 import ( |
| paddy@31 | 4 "sync" |
| paddy@31 | 5 |
| paddy@31 | 6 "secondbit.org/uuid" |
| paddy@31 | 7 ) |
| paddy@28 | 8 |
| paddy@28 | 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@29 | 15 grants map[string]Grant |
| paddy@29 | 16 grantLock 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@28 | 27 } |
| paddy@28 | 28 |
| paddy@28 | 29 func NewMemstore() *Memstore { |
| paddy@28 | 30 return &Memstore{ |
| paddy@31 | 31 tokens: map[string]Token{}, |
| paddy@31 | 32 refreshTokenLookup: map[string]string{}, |
| paddy@31 | 33 profileTokenLookup: map[string][]string{}, |
| paddy@31 | 34 grants: map[string]Grant{}, |
| paddy@31 | 35 clients: map[string]Client{}, |
| paddy@31 | 36 profileClientLookup: map[string][]uuid.ID{}, |
| paddy@41 | 37 endpoints: map[string][]Endpoint{}, |
| paddy@38 | 38 profiles: map[string]Profile{}, |
| paddy@28 | 39 } |
| paddy@28 | 40 } |
| paddy@28 | 41 |
| paddy@28 | 42 func (m *Memstore) lookupTokenByRefresh(token string) (string, error) { |
| paddy@28 | 43 m.tokenLock.RLock() |
| paddy@28 | 44 defer m.tokenLock.RUnlock() |
| paddy@28 | 45 t, ok := m.refreshTokenLookup[token] |
| paddy@28 | 46 if !ok { |
| paddy@28 | 47 return "", ErrTokenNotFound |
| paddy@28 | 48 } |
| paddy@28 | 49 return t, nil |
| paddy@28 | 50 } |
| paddy@28 | 51 |
| paddy@28 | 52 func (m *Memstore) lookupTokensByProfileID(id string) ([]string, error) { |
| paddy@28 | 53 m.tokenLock.RLock() |
| paddy@28 | 54 defer m.tokenLock.RUnlock() |
| paddy@28 | 55 return m.profileTokenLookup[id], nil |
| paddy@28 | 56 } |
| paddy@31 | 57 |
| paddy@33 | 58 func (m *Memstore) lookupClientsByProfileID(id string) []uuid.ID { |
| paddy@31 | 59 m.clientLock.RLock() |
| paddy@31 | 60 defer m.clientLock.RUnlock() |
| paddy@33 | 61 c, ok := m.profileClientLookup[id] |
| paddy@33 | 62 if !ok { |
| paddy@33 | 63 return []uuid.ID{} |
| paddy@33 | 64 } |
| paddy@33 | 65 return c |
| paddy@31 | 66 } |