auth
29:5bf0a5fd1d01 Browse Files
Implement GrantStore for Memstore. Fix bug in GrantStore that asks for a UUID when it really wants a string. Implement GrantStore interface in Memstore, including unit tests for successful (i.e., works-as-intended) scenarios.
grant.go grant_test.go memstore.go
1.1 --- a/grant.go Mon Sep 01 09:21:31 2014 -0400 1.2 +++ b/grant.go Mon Sep 01 09:49:23 2014 -0400 1.3 @@ -1,11 +1,17 @@ 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 + ErrGrantNotFound = errors.New("Grant not found in GrantStore.") 1.15 + ErrGrantAlreadyExists = errors.New("Grant already exists in GrantStore.") 1.16 +) 1.17 + 1.18 type Grant struct { 1.19 Code string 1.20 Created time.Time 1.21 @@ -19,5 +25,37 @@ 1.22 type GrantStore interface { 1.23 GetGrant(code string) (Grant, error) 1.24 SaveGrant(grant Grant) error 1.25 - DeleteGrant(id uuid.ID) error 1.26 + DeleteGrant(code string) error 1.27 } 1.28 + 1.29 +func (m *Memstore) GetGrant(code string) (Grant, error) { 1.30 + m.grantLock.RLock() 1.31 + defer m.grantLock.RUnlock() 1.32 + grant, ok := m.grants[code] 1.33 + if !ok { 1.34 + return Grant{}, ErrGrantNotFound 1.35 + } 1.36 + return grant, nil 1.37 +} 1.38 + 1.39 +func (m *Memstore) SaveGrant(grant Grant) error { 1.40 + m.grantLock.Lock() 1.41 + defer m.grantLock.Unlock() 1.42 + _, ok := m.grants[grant.Code] 1.43 + if ok { 1.44 + return ErrGrantAlreadyExists 1.45 + } 1.46 + m.grants[grant.Code] = grant 1.47 + return nil 1.48 +} 1.49 + 1.50 +func (m *Memstore) DeleteGrant(code string) error { 1.51 + m.grantLock.Lock() 1.52 + defer m.grantLock.Unlock() 1.53 + _, ok := m.grants[code] 1.54 + if !ok { 1.55 + return ErrGrantNotFound 1.56 + } 1.57 + delete(m.grants, code) 1.58 + return nil 1.59 +}
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/grant_test.go Mon Sep 01 09:49:23 2014 -0400 2.3 @@ -0,0 +1,42 @@ 2.4 +package auth 2.5 + 2.6 +import ( 2.7 + "testing" 2.8 + "time" 2.9 + 2.10 + "secondbit.org/uuid" 2.11 +) 2.12 + 2.13 +var grantStores = []GrantStore{NewMemstore()} 2.14 + 2.15 +func TestGrantStoreSuccess(t *testing.T) { 2.16 + grant := Grant{ 2.17 + Code: "code", 2.18 + Created: time.Now(), 2.19 + ExpiresIn: 180, 2.20 + ClientID: uuid.NewID(), 2.21 + Scope: "scope", 2.22 + RedirectURI: "redirectURI", 2.23 + State: "state", 2.24 + } 2.25 + for pos, store := range grantStores { 2.26 + err := store.SaveGrant(grant) 2.27 + if err != nil { 2.28 + t.Errorf("Error saving grant in GrantStore #%d: %s", pos, err) 2.29 + } 2.30 + retrieved, err := store.GetGrant(grant.Code) 2.31 + if err != nil { 2.32 + t.Errorf("Error retrieving grant in GrantStore #%d: %s", pos, err) 2.33 + } 2.34 + t.Log(retrieved) 2.35 + // TODO: compare retrieved to grant 2.36 + err = store.DeleteGrant(grant.Code) 2.37 + if err != nil { 2.38 + t.Errorf("Error removing grant from GrantStore #%d: %s", pos, err) 2.39 + } 2.40 + retrieved, err = store.GetGrant(grant.Code) 2.41 + if err != ErrGrantNotFound { 2.42 + t.Errorf("Expected ErrGrantNotFound from GrantStore #%d, got %+v and %+v", pos, retrieved, err) 2.43 + } 2.44 + } 2.45 +}
3.1 --- a/memstore.go Mon Sep 01 09:21:31 2014 -0400 3.2 +++ b/memstore.go Mon Sep 01 09:49:23 2014 -0400 3.3 @@ -7,6 +7,9 @@ 3.4 refreshTokenLookup map[string]string 3.5 profileTokenLookup map[string][]string 3.6 tokenLock sync.RWMutex 3.7 + 3.8 + grants map[string]Grant 3.9 + grantLock sync.RWMutex 3.10 } 3.11 3.12 func NewMemstore() *Memstore { 3.13 @@ -14,6 +17,7 @@ 3.14 tokens: map[string]Token{}, 3.15 refreshTokenLookup: map[string]string{}, 3.16 profileTokenLookup: map[string][]string{}, 3.17 + grants: map[string]Grant{}, 3.18 } 3.19 } 3.20