auth

Paddy 2014-10-16 Parent:73a9f7a6af54 Child:e45bfa2abc00

53:28d48fdb0dd1 Go to Latest

auth/token.go

Test all possible successful requests, fix query setting in test. Test all the possible successful requests for an authorization code grant. Fix a bug wherein the query string wasn't actually set for the test.

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