auth

Paddy 2014-09-07 Parent:75cf37088852 Child:3a6a65ed380c

34:14599a5c7819 Go to Latest

auth/token.go

Further grant testing. Use the %T format to return the name of the GrantStore that failed the test, rather than just returning the position of the store. Test that storing a grant twice yields an ErrGrantAlreadyExists. Test that retrieving a grant that doesn't exist yields an ErrGrantNotFound. Compare returned grants against expectations.

History
paddy@28 1 package auth
paddy@28 2
paddy@28 3 import (
paddy@28 4 "errors"
paddy@28 5 "time"
paddy@28 6
paddy@28 7 "secondbit.org/uuid"
paddy@28 8 )
paddy@28 9
paddy@28 10 var (
paddy@28 11 ErrTokenNotFound = errors.New("Token not found in TokenStore.")
paddy@28 12 ErrTokenAlreadyExists = errors.New("Token already exists in TokenStore.")
paddy@28 13 )
paddy@28 14
paddy@28 15 type Token struct {
paddy@28 16 AccessToken string
paddy@28 17 RefreshToken string
paddy@28 18 Created time.Time
paddy@28 19 ExpiresIn int32
paddy@28 20 TokenType string
paddy@28 21 Scope string
paddy@28 22 ProfileID uuid.ID
paddy@28 23 }
paddy@28 24
paddy@28 25 type TokenStore interface {
paddy@28 26 GetToken(token string, refresh bool) (Token, error)
paddy@28 27 SaveToken(token Token) error
paddy@28 28 RemoveToken(token string) error
paddy@28 29 GetTokensByProfileID(profileID uuid.ID, num, offset int) ([]Token, error)
paddy@28 30 }
paddy@28 31
paddy@28 32 func (m *Memstore) GetToken(token string, refresh bool) (Token, error) {
paddy@28 33 if refresh {
paddy@28 34 t, err := m.lookupTokenByRefresh(token)
paddy@28 35 if err != nil {
paddy@28 36 return Token{}, err
paddy@28 37 }
paddy@28 38 token = t
paddy@28 39 }
paddy@28 40 m.tokenLock.RLock()
paddy@28 41 defer m.tokenLock.RUnlock()
paddy@28 42 result, ok := m.tokens[token]
paddy@28 43 if !ok {
paddy@28 44 return Token{}, ErrTokenNotFound
paddy@28 45 }
paddy@28 46 return result, nil
paddy@28 47 }
paddy@28 48
paddy@28 49 func (m *Memstore) SaveToken(token Token) error {
paddy@28 50 m.tokenLock.Lock()
paddy@28 51 defer m.tokenLock.Unlock()
paddy@28 52 _, ok := m.tokens[token.AccessToken]
paddy@28 53 if ok {
paddy@28 54 return ErrTokenAlreadyExists
paddy@28 55 }
paddy@28 56 m.tokens[token.AccessToken] = token
paddy@28 57 if token.RefreshToken != "" {
paddy@28 58 m.refreshTokenLookup[token.RefreshToken] = token.AccessToken
paddy@28 59 }
paddy@28 60 if _, ok = m.profileTokenLookup[token.ProfileID.String()]; ok {
paddy@28 61 m.profileTokenLookup[token.ProfileID.String()] = append(m.profileTokenLookup[token.ProfileID.String()], token.AccessToken)
paddy@28 62 } else {
paddy@28 63 m.profileTokenLookup[token.ProfileID.String()] = []string{token.AccessToken}
paddy@28 64 }
paddy@28 65 return nil
paddy@28 66 }
paddy@28 67
paddy@28 68 func (m *Memstore) RemoveToken(token string) error {
paddy@28 69 m.tokenLock.Lock()
paddy@28 70 defer m.tokenLock.Unlock()
paddy@28 71 t, ok := m.tokens[token]
paddy@28 72 if !ok {
paddy@28 73 return ErrTokenNotFound
paddy@28 74 }
paddy@28 75 delete(m.tokens, token)
paddy@28 76 if t.RefreshToken != "" {
paddy@28 77 delete(m.refreshTokenLookup, t.RefreshToken)
paddy@28 78 }
paddy@28 79 pos := -1
paddy@28 80 for p, item := range m.profileTokenLookup[t.ProfileID.String()] {
paddy@28 81 if item == token {
paddy@28 82 pos = p
paddy@28 83 break
paddy@28 84 }
paddy@28 85 }
paddy@28 86 if pos >= 0 {
paddy@28 87 m.profileTokenLookup[t.ProfileID.String()] = append(m.profileTokenLookup[t.ProfileID.String()][:pos], m.profileTokenLookup[t.ProfileID.String()][pos+1:]...)
paddy@28 88 }
paddy@28 89 return nil
paddy@28 90 }
paddy@28 91
paddy@28 92 func (m *Memstore) GetTokensByProfileID(profileID uuid.ID, num, offset int) ([]Token, error) {
paddy@28 93 ids, err := m.lookupTokensByProfileID(profileID.String())
paddy@28 94 if err != nil {
paddy@28 95 return []Token{}, err
paddy@28 96 }
paddy@28 97 if len(ids) > num+offset {
paddy@28 98 ids = ids[offset : num+offset]
paddy@28 99 } else if len(ids) > offset {
paddy@28 100 ids = ids[offset:]
paddy@28 101 } else {
paddy@28 102 return []Token{}, nil
paddy@28 103 }
paddy@28 104 tokens := []Token{}
paddy@28 105 for _, id := range ids {
paddy@28 106 token, err := m.GetToken(id, false)
paddy@28 107 if err != nil {
paddy@28 108 return []Token{}, err
paddy@28 109 }
paddy@28 110 tokens = append(tokens, token)
paddy@28 111 }
paddy@28 112 return tokens, nil
paddy@28 113 }