1
21
22 package storage
23
24 import (
25 "context"
26 "sync"
27 "time"
28
29 "gopkg.in/square/go-jose.v2"
30
31 "github.com/ory/fosite"
32 )
33
34 type MemoryUserRelation struct {
35 Username string
36 Password string
37 }
38
39 type IssuerPublicKeys struct {
40 Issuer string
41 KeysBySub map[string]SubjectPublicKeys
42 }
43
44 type SubjectPublicKeys struct {
45 Subject string
46 Keys map[string]PublicKeyScopes
47 }
48
49 type PublicKeyScopes struct {
50 Key *jose.JSONWebKey
51 Scopes []string
52 }
53
54 type MemoryStore struct {
55 Clients map[string]fosite.Client
56 AuthorizeCodes map[string]StoreAuthorizeCode
57 IDSessions map[string]fosite.Requester
58 AccessTokens map[string]fosite.Requester
59 RefreshTokens map[string]StoreRefreshToken
60 PKCES map[string]fosite.Requester
61 Users map[string]MemoryUserRelation
62 BlacklistedJTIs map[string]time.Time
63
64 AccessTokenRequestIDs map[string]string
65 RefreshTokenRequestIDs map[string]string
66
67 IssuerPublicKeys map[string]IssuerPublicKeys
68
69 clientsMutex sync.RWMutex
70 authorizeCodesMutex sync.RWMutex
71 idSessionsMutex sync.RWMutex
72 accessTokensMutex sync.RWMutex
73 refreshTokensMutex sync.RWMutex
74 pkcesMutex sync.RWMutex
75 usersMutex sync.RWMutex
76 blacklistedJTIsMutex sync.RWMutex
77 accessTokenRequestIDsMutex sync.RWMutex
78 refreshTokenRequestIDsMutex sync.RWMutex
79 issuerPublicKeysMutex sync.RWMutex
80 }
81
82 func NewMemoryStore() *MemoryStore {
83 return &MemoryStore{
84 Clients: make(map[string]fosite.Client),
85 AuthorizeCodes: make(map[string]StoreAuthorizeCode),
86 IDSessions: make(map[string]fosite.Requester),
87 AccessTokens: make(map[string]fosite.Requester),
88 RefreshTokens: make(map[string]StoreRefreshToken),
89 PKCES: make(map[string]fosite.Requester),
90 Users: make(map[string]MemoryUserRelation),
91 AccessTokenRequestIDs: make(map[string]string),
92 RefreshTokenRequestIDs: make(map[string]string),
93 BlacklistedJTIs: make(map[string]time.Time),
94 IssuerPublicKeys: make(map[string]IssuerPublicKeys),
95 }
96 }
97
98 type StoreAuthorizeCode struct {
99 active bool
100 fosite.Requester
101 }
102
103 type StoreRefreshToken struct {
104 active bool
105 fosite.Requester
106 }
107
108 func NewExampleStore() *MemoryStore {
109 return &MemoryStore{
110 IDSessions: make(map[string]fosite.Requester),
111 Clients: map[string]fosite.Client{
112 "my-client": &fosite.DefaultClient{
113 ID: "my-client",
114 Secret: []byte(`$2a$10$IxMdI6d.LIRZPpSfEwNoeu4rY3FhDREsxFJXikcgdRRAStxUlsuEO`),
115 RotatedSecrets: [][]byte{[]byte(`$2y$10$X51gLxUQJ.hGw1epgHTE5u0bt64xM0COU7K9iAp.OFg8p2pUd.1zC `)},
116 RedirectURIs: []string{"http://localhost:3846/callback"},
117 ResponseTypes: []string{"id_token", "code", "token", "id_token token", "code id_token", "code token", "code id_token token"},
118 GrantTypes: []string{"implicit", "refresh_token", "authorization_code", "password", "client_credentials"},
119 Scopes: []string{"fosite", "openid", "photos", "offline"},
120 },
121 "encoded:client": &fosite.DefaultClient{
122 ID: "encoded:client",
123 Secret: []byte(`$2a$10$A7M8b65dSSKGHF0H2sNkn.9Z0hT8U1Nv6OWPV3teUUaczXkVkxuDS`),
124 RotatedSecrets: nil,
125 RedirectURIs: []string{"http://localhost:3846/callback"},
126 ResponseTypes: []string{"id_token", "code", "token", "id_token token", "code id_token", "code token", "code id_token token"},
127 GrantTypes: []string{"implicit", "refresh_token", "authorization_code", "password", "client_credentials"},
128 Scopes: []string{"fosite", "openid", "photos", "offline"},
129 },
130 },
131 Users: map[string]MemoryUserRelation{
132 "peter": {
133
134
135 Username: "peter",
136 Password: "secret",
137 },
138 },
139 AuthorizeCodes: map[string]StoreAuthorizeCode{},
140 AccessTokens: map[string]fosite.Requester{},
141 RefreshTokens: map[string]StoreRefreshToken{},
142 PKCES: map[string]fosite.Requester{},
143 AccessTokenRequestIDs: map[string]string{},
144 RefreshTokenRequestIDs: map[string]string{},
145 IssuerPublicKeys: map[string]IssuerPublicKeys{},
146 }
147 }
148
149 func (s *MemoryStore) CreateOpenIDConnectSession(_ context.Context, authorizeCode string, requester fosite.Requester) error {
150 s.idSessionsMutex.Lock()
151 defer s.idSessionsMutex.Unlock()
152
153 s.IDSessions[authorizeCode] = requester
154 return nil
155 }
156
157 func (s *MemoryStore) GetOpenIDConnectSession(_ context.Context, authorizeCode string, requester fosite.Requester) (fosite.Requester, error) {
158 s.idSessionsMutex.RLock()
159 defer s.idSessionsMutex.RUnlock()
160
161 cl, ok := s.IDSessions[authorizeCode]
162 if !ok {
163 return nil, fosite.ErrNotFound
164 }
165 return cl, nil
166 }
167
168
169 func (s *MemoryStore) DeleteOpenIDConnectSession(_ context.Context, authorizeCode string) error {
170 s.idSessionsMutex.Lock()
171 defer s.idSessionsMutex.Unlock()
172
173 delete(s.IDSessions, authorizeCode)
174 return nil
175 }
176
177 func (s *MemoryStore) GetClient(_ context.Context, id string) (fosite.Client, error) {
178 s.clientsMutex.RLock()
179 defer s.clientsMutex.RUnlock()
180
181 cl, ok := s.Clients[id]
182 if !ok {
183 return nil, fosite.ErrNotFound
184 }
185 return cl, nil
186 }
187
188 func (s *MemoryStore) ClientAssertionJWTValid(_ context.Context, jti string) error {
189 s.blacklistedJTIsMutex.RLock()
190 defer s.blacklistedJTIsMutex.RUnlock()
191
192 if exp, exists := s.BlacklistedJTIs[jti]; exists && exp.After(time.Now()) {
193 return fosite.ErrJTIKnown
194 }
195
196 return nil
197 }
198
199 func (s *MemoryStore) SetClientAssertionJWT(_ context.Context, jti string, exp time.Time) error {
200 s.blacklistedJTIsMutex.Lock()
201 defer s.blacklistedJTIsMutex.Unlock()
202
203
204 for j, e := range s.BlacklistedJTIs {
205 if e.Before(time.Now()) {
206 delete(s.BlacklistedJTIs, j)
207 }
208 }
209
210 if _, exists := s.BlacklistedJTIs[jti]; exists {
211 return fosite.ErrJTIKnown
212 }
213
214 s.BlacklistedJTIs[jti] = exp
215 return nil
216 }
217
218 func (s *MemoryStore) CreateAuthorizeCodeSession(_ context.Context, code string, req fosite.Requester) error {
219 s.authorizeCodesMutex.Lock()
220 defer s.authorizeCodesMutex.Unlock()
221
222 s.AuthorizeCodes[code] = StoreAuthorizeCode{active: true, Requester: req}
223 return nil
224 }
225
226 func (s *MemoryStore) GetAuthorizeCodeSession(_ context.Context, code string, _ fosite.Session) (fosite.Requester, error) {
227 s.authorizeCodesMutex.RLock()
228 defer s.authorizeCodesMutex.RUnlock()
229
230 rel, ok := s.AuthorizeCodes[code]
231 if !ok {
232 return nil, fosite.ErrNotFound
233 }
234 if !rel.active {
235 return rel, fosite.ErrInvalidatedAuthorizeCode
236 }
237
238 return rel.Requester, nil
239 }
240
241 func (s *MemoryStore) InvalidateAuthorizeCodeSession(ctx context.Context, code string) error {
242 s.authorizeCodesMutex.Lock()
243 defer s.authorizeCodesMutex.Unlock()
244
245 rel, ok := s.AuthorizeCodes[code]
246 if !ok {
247 return fosite.ErrNotFound
248 }
249 rel.active = false
250 s.AuthorizeCodes[code] = rel
251 return nil
252 }
253
254 func (s *MemoryStore) CreatePKCERequestSession(_ context.Context, code string, req fosite.Requester) error {
255 s.pkcesMutex.Lock()
256 defer s.pkcesMutex.Unlock()
257
258 s.PKCES[code] = req
259 return nil
260 }
261
262 func (s *MemoryStore) GetPKCERequestSession(_ context.Context, code string, _ fosite.Session) (fosite.Requester, error) {
263 s.pkcesMutex.RLock()
264 defer s.pkcesMutex.RUnlock()
265
266 rel, ok := s.PKCES[code]
267 if !ok {
268 return nil, fosite.ErrNotFound
269 }
270 return rel, nil
271 }
272
273 func (s *MemoryStore) DeletePKCERequestSession(_ context.Context, code string) error {
274 s.pkcesMutex.Lock()
275 defer s.pkcesMutex.Unlock()
276
277 delete(s.PKCES, code)
278 return nil
279 }
280
281 func (s *MemoryStore) CreateAccessTokenSession(_ context.Context, signature string, req fosite.Requester) error {
282
283
284 s.accessTokenRequestIDsMutex.Lock()
285 defer s.accessTokenRequestIDsMutex.Unlock()
286 s.accessTokensMutex.Lock()
287 defer s.accessTokensMutex.Unlock()
288
289 s.AccessTokens[signature] = req
290 s.AccessTokenRequestIDs[req.GetID()] = signature
291 return nil
292 }
293
294 func (s *MemoryStore) GetAccessTokenSession(_ context.Context, signature string, _ fosite.Session) (fosite.Requester, error) {
295 s.accessTokensMutex.RLock()
296 defer s.accessTokensMutex.RUnlock()
297
298 rel, ok := s.AccessTokens[signature]
299 if !ok {
300 return nil, fosite.ErrNotFound
301 }
302 return rel, nil
303 }
304
305 func (s *MemoryStore) DeleteAccessTokenSession(_ context.Context, signature string) error {
306 s.accessTokensMutex.Lock()
307 defer s.accessTokensMutex.Unlock()
308
309 delete(s.AccessTokens, signature)
310 return nil
311 }
312
313 func (s *MemoryStore) CreateRefreshTokenSession(_ context.Context, signature string, req fosite.Requester) error {
314
315
316 s.refreshTokenRequestIDsMutex.Lock()
317 defer s.refreshTokenRequestIDsMutex.Unlock()
318 s.refreshTokensMutex.Lock()
319 defer s.refreshTokensMutex.Unlock()
320
321 s.RefreshTokens[signature] = StoreRefreshToken{active: true, Requester: req}
322 s.RefreshTokenRequestIDs[req.GetID()] = signature
323 return nil
324 }
325
326 func (s *MemoryStore) GetRefreshTokenSession(_ context.Context, signature string, _ fosite.Session) (fosite.Requester, error) {
327 s.refreshTokensMutex.RLock()
328 defer s.refreshTokensMutex.RUnlock()
329
330 rel, ok := s.RefreshTokens[signature]
331 if !ok {
332 return nil, fosite.ErrNotFound
333 }
334 if !rel.active {
335 return rel, fosite.ErrInactiveToken
336 }
337 return rel, nil
338 }
339
340 func (s *MemoryStore) DeleteRefreshTokenSession(_ context.Context, signature string) error {
341 s.refreshTokensMutex.Lock()
342 defer s.refreshTokensMutex.Unlock()
343
344 delete(s.RefreshTokens, signature)
345 return nil
346 }
347
348 func (s *MemoryStore) Authenticate(_ context.Context, name string, secret string) error {
349 s.usersMutex.RLock()
350 defer s.usersMutex.RUnlock()
351
352 rel, ok := s.Users[name]
353 if !ok {
354 return fosite.ErrNotFound
355 }
356 if rel.Password != secret {
357 return fosite.ErrNotFound.WithDebug("Invalid credentials")
358 }
359 return nil
360 }
361
362 func (s *MemoryStore) RevokeRefreshToken(ctx context.Context, requestID string) error {
363 s.refreshTokenRequestIDsMutex.Lock()
364 defer s.refreshTokenRequestIDsMutex.Unlock()
365
366 if signature, exists := s.RefreshTokenRequestIDs[requestID]; exists {
367 rel, ok := s.RefreshTokens[signature]
368 if !ok {
369 return fosite.ErrNotFound
370 }
371 rel.active = false
372 s.RefreshTokens[signature] = rel
373 }
374 return nil
375 }
376
377 func (s *MemoryStore) RevokeRefreshTokenMaybeGracePeriod(ctx context.Context, requestID string, signature string) error {
378
379 return s.RevokeRefreshToken(ctx, requestID)
380 }
381
382 func (s *MemoryStore) RevokeAccessToken(ctx context.Context, requestID string) error {
383 s.accessTokenRequestIDsMutex.RLock()
384 defer s.accessTokenRequestIDsMutex.RUnlock()
385
386 if signature, exists := s.AccessTokenRequestIDs[requestID]; exists {
387 if err := s.DeleteAccessTokenSession(ctx, signature); err != nil {
388 return err
389 }
390 }
391 return nil
392 }
393
394 func (s *MemoryStore) GetPublicKey(ctx context.Context, issuer string, subject string, keyId string) (*jose.JSONWebKey, error) {
395 s.issuerPublicKeysMutex.RLock()
396 defer s.issuerPublicKeysMutex.RUnlock()
397
398 if issuerKeys, ok := s.IssuerPublicKeys[issuer]; ok {
399 if subKeys, ok := issuerKeys.KeysBySub[subject]; ok {
400 if keyScopes, ok := subKeys.Keys[keyId]; ok {
401 return keyScopes.Key, nil
402 }
403 }
404 }
405
406 return nil, fosite.ErrNotFound
407 }
408 func (s *MemoryStore) GetPublicKeys(ctx context.Context, issuer string, subject string) (*jose.JSONWebKeySet, error) {
409 s.issuerPublicKeysMutex.RLock()
410 defer s.issuerPublicKeysMutex.RUnlock()
411
412 if issuerKeys, ok := s.IssuerPublicKeys[issuer]; ok {
413 if subKeys, ok := issuerKeys.KeysBySub[subject]; ok {
414 if len(subKeys.Keys) == 0 {
415 return nil, fosite.ErrNotFound
416 }
417
418 keys := make([]jose.JSONWebKey, 0, len(subKeys.Keys))
419 for _, keyScopes := range subKeys.Keys {
420 keys = append(keys, *keyScopes.Key)
421 }
422
423 return &jose.JSONWebKeySet{Keys: keys}, nil
424 }
425 }
426
427 return nil, fosite.ErrNotFound
428 }
429
430 func (s *MemoryStore) GetPublicKeyScopes(ctx context.Context, issuer string, subject string, keyId string) ([]string, error) {
431 s.issuerPublicKeysMutex.RLock()
432 defer s.issuerPublicKeysMutex.RUnlock()
433
434 if issuerKeys, ok := s.IssuerPublicKeys[issuer]; ok {
435 if subKeys, ok := issuerKeys.KeysBySub[subject]; ok {
436 if keyScopes, ok := subKeys.Keys[keyId]; ok {
437 return keyScopes.Scopes, nil
438 }
439 }
440 }
441
442 return nil, fosite.ErrNotFound
443 }
444
445 func (s *MemoryStore) IsJWTUsed(ctx context.Context, jti string) (bool, error) {
446 err := s.ClientAssertionJWTValid(ctx, jti)
447 if err != nil {
448 return true, nil
449 }
450
451 return false, nil
452 }
453
454 func (s *MemoryStore) MarkJWTUsedForTime(ctx context.Context, jti string, exp time.Time) error {
455 return s.SetClientAssertionJWT(ctx, jti, exp)
456 }
457
View as plain text