auth

Paddy 2015-04-11 Parent:3e8964a914ef Child:73e12d5a1124

157:202e991accc2 Go to Latest

auth/scope.go

Wire up the postgres database for authd. Have authd use the AUTH_PG_DB environment variable to detect support for the postgres *Stores, and if postgres is supported, use it. If postgres isn't supported, fall back on the in-memory store. Also create-if-not-exists the test scopes, instead of panicking when the scope already exists.

History
paddy@134 1 package auth
paddy@134 2
paddy@134 3 import (
paddy@134 4 "errors"
paddy@134 5 "sort"
paddy@134 6 )
paddy@134 7
paddy@134 8 var (
paddy@153 9 ErrNoScopeStore = errors.New("scopeStore not set in Context")
paddy@153 10 ErrScopeNotFound = errors.New("scope not found")
paddy@153 11 ErrScopeAlreadyExists = errors.New("scope already exists")
paddy@134 12 )
paddy@134 13
paddy@134 14 // Scope represents a limit on the access that a grant provides.
paddy@134 15 type Scope struct {
paddy@134 16 ID string
paddy@134 17 Name string
paddy@134 18 Description string
paddy@134 19 }
paddy@134 20
paddy@134 21 func (s *Scope) ApplyChange(change ScopeChange) {
paddy@134 22 if change.Name != nil {
paddy@134 23 s.Name = *change.Name
paddy@134 24 }
paddy@134 25 if change.Description != nil {
paddy@134 26 s.Description = *change.Description
paddy@134 27 }
paddy@134 28 }
paddy@134 29
paddy@134 30 type sortedScopes []Scope
paddy@134 31
paddy@134 32 func (s sortedScopes) Len() int {
paddy@134 33 return len(s)
paddy@134 34 }
paddy@134 35
paddy@134 36 func (s sortedScopes) Swap(i, j int) {
paddy@134 37 s[i], s[j] = s[j], s[i]
paddy@134 38 }
paddy@134 39
paddy@134 40 func (s sortedScopes) Less(i, j int) bool {
paddy@134 41 return s[i].ID < s[j].ID
paddy@134 42 }
paddy@134 43
paddy@134 44 // ScopeChange represents a change to a Scope.
paddy@134 45 type ScopeChange struct {
paddy@134 46 Name *string
paddy@134 47 Description *string
paddy@134 48 }
paddy@134 49
paddy@152 50 func (s ScopeChange) Empty() bool {
paddy@152 51 return s.Name == nil && s.Description == nil
paddy@152 52 }
paddy@152 53
paddy@134 54 type scopeStore interface {
paddy@134 55 createScopes(scopes []Scope) error
paddy@134 56 getScopes(ids []string) ([]Scope, error)
paddy@152 57 updateScope(id string, change ScopeChange) error
paddy@134 58 removeScopes(ids []string) error
paddy@134 59 listScopes() ([]Scope, error)
paddy@134 60 }
paddy@134 61
paddy@134 62 func (m *memstore) createScopes(scopes []Scope) error {
paddy@134 63 m.scopeLock.Lock()
paddy@134 64 defer m.scopeLock.Unlock()
paddy@134 65
paddy@153 66 for _, scope := range scopes {
paddy@134 67 if _, ok := m.scopes[scope.ID]; ok {
paddy@153 68 return ErrScopeAlreadyExists
paddy@134 69 }
paddy@134 70 }
paddy@134 71 for _, scope := range scopes {
paddy@134 72 m.scopes[scope.ID] = scope
paddy@134 73 }
paddy@134 74 return nil
paddy@134 75 }
paddy@134 76
paddy@134 77 func (m *memstore) getScopes(ids []string) ([]Scope, error) {
paddy@134 78 m.scopeLock.RLock()
paddy@134 79 defer m.scopeLock.RUnlock()
paddy@134 80
paddy@134 81 scopes := []Scope{}
paddy@153 82 for _, id := range ids {
paddy@134 83 scope, ok := m.scopes[id]
paddy@134 84 if !ok {
paddy@153 85 continue
paddy@134 86 }
paddy@134 87 scopes = append(scopes, scope)
paddy@134 88 }
paddy@134 89 sorted := sortedScopes(scopes)
paddy@134 90 sort.Sort(sorted)
paddy@134 91 scopes = sorted
paddy@134 92 return scopes, nil
paddy@134 93 }
paddy@134 94
paddy@152 95 func (m *memstore) updateScope(id string, change ScopeChange) error {
paddy@134 96 m.scopeLock.Lock()
paddy@134 97 defer m.scopeLock.Unlock()
paddy@134 98
paddy@152 99 scope, ok := m.scopes[id]
paddy@152 100 if !ok {
paddy@153 101 return ErrScopeNotFound
paddy@134 102 }
paddy@152 103 scope.ApplyChange(change)
paddy@152 104 m.scopes[id] = scope
paddy@152 105 return nil
paddy@134 106 }
paddy@134 107
paddy@134 108 func (m *memstore) removeScopes(ids []string) error {
paddy@134 109 m.scopeLock.Lock()
paddy@134 110 defer m.scopeLock.Unlock()
paddy@134 111
paddy@153 112 for _, id := range ids {
paddy@134 113 if _, ok := m.scopes[id]; !ok {
paddy@153 114 return ErrScopeNotFound
paddy@134 115 }
paddy@134 116 }
paddy@134 117 for _, id := range ids {
paddy@134 118 delete(m.scopes, id)
paddy@134 119 }
paddy@134 120 return nil
paddy@134 121 }
paddy@134 122
paddy@134 123 func (m *memstore) listScopes() ([]Scope, error) {
paddy@134 124 m.scopeLock.RLock()
paddy@134 125 defer m.scopeLock.RUnlock()
paddy@134 126
paddy@134 127 scopes := []Scope{}
paddy@134 128 for _, scope := range m.scopes {
paddy@134 129 scopes = append(scopes, scope)
paddy@134 130 }
paddy@134 131 sorted := sortedScopes(scopes)
paddy@134 132 sort.Sort(sorted)
paddy@134 133 scopes = sorted
paddy@134 134 return scopes, nil
paddy@134 135 }