Skip to content

Commit 02c0ebb

Browse files
committed
fix: session storage
1 parent 9a284c0 commit 02c0ebb

22 files changed

+291
-138
lines changed

server/handlers/authorize.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ func AuthorizeHandler() gin.HandlerFunc {
194194
// rollover the session for security
195195
go memorystore.Provider.DeleteUserSession(sessionKey, claims.Nonce)
196196
if responseType == constants.ResponseTypeCode {
197-
newSessionTokenData, newSessionToken, err := token.CreateSessionToken(user, nonce, claims.Roles, scope, claims.LoginMethod)
197+
newSessionTokenData, newSessionToken, newSessionExpiresAt, err := token.CreateSessionToken(user, nonce, claims.Roles, scope, claims.LoginMethod)
198198
if err != nil {
199199
log.Debug("CreateSessionToken failed: ", err)
200200
handleResponse(gc, responseMode, loginURL, redirectURI, loginError, http.StatusOK)
@@ -215,7 +215,7 @@ func AuthorizeHandler() gin.HandlerFunc {
215215
return
216216
}
217217

218-
if err := memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+newSessionTokenData.Nonce, newSessionToken); err != nil {
218+
if err := memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+newSessionTokenData.Nonce, newSessionToken, newSessionExpiresAt); err != nil {
219219
log.Debug("SetUserSession failed: ", err)
220220
handleResponse(gc, responseMode, loginURL, redirectURI, loginError, http.StatusOK)
221221
return
@@ -271,13 +271,13 @@ func AuthorizeHandler() gin.HandlerFunc {
271271
return
272272
}
273273

274-
if err := memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+nonce, authToken.FingerPrintHash); err != nil {
274+
if err := memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+nonce, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt); err != nil {
275275
log.Debug("SetUserSession failed: ", err)
276276
handleResponse(gc, responseMode, loginURL, redirectURI, loginError, http.StatusOK)
277277
return
278278
}
279279

280-
if err := memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+nonce, authToken.AccessToken.Token); err != nil {
280+
if err := memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+nonce, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt); err != nil {
281281
log.Debug("SetUserSession failed: ", err)
282282
handleResponse(gc, responseMode, loginURL, redirectURI, loginError, http.StatusOK)
283283
return
@@ -305,7 +305,7 @@ func AuthorizeHandler() gin.HandlerFunc {
305305
if authToken.RefreshToken != nil {
306306
res["refresh_token"] = authToken.RefreshToken.Token
307307
params += "&refresh_token=" + authToken.RefreshToken.Token
308-
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token)
308+
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
309309
}
310310

311311
if responseMode == constants.ResponseModeQuery {

server/handlers/logout.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,14 @@ func LogoutHandler() gin.HandlerFunc {
4747
return
4848
}
4949

50-
memorystore.Provider.DeleteUserSession(sessionData.Subject, sessionData.Nonce)
50+
userID := sessionData.Subject
51+
loginMethod := sessionData.LoginMethod
52+
sessionToken := userID
53+
if loginMethod != "" {
54+
sessionToken = loginMethod + ":" + userID
55+
}
56+
57+
memorystore.Provider.DeleteUserSession(sessionToken, sessionData.Nonce)
5158
cookie.DeleteSession(gc)
5259

5360
if redirectURL != "" {

server/handlers/oauth_callback.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -249,12 +249,12 @@ func OAuthCallbackHandler() gin.HandlerFunc {
249249

250250
sessionKey := provider + ":" + user.ID
251251
cookie.SetSession(ctx, authToken.FingerPrintHash)
252-
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash)
253-
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token)
252+
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
253+
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
254254

255255
if authToken.RefreshToken != nil {
256256
params += `&refresh_token=` + authToken.RefreshToken.Token
257-
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token)
257+
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
258258
}
259259

260260
go func() {

server/handlers/token.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -247,8 +247,8 @@ func TokenHandler() gin.HandlerFunc {
247247
return
248248
}
249249

250-
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash)
251-
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token)
250+
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
251+
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
252252
cookie.SetSession(gc, authToken.FingerPrintHash)
253253

254254
expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
@@ -266,7 +266,7 @@ func TokenHandler() gin.HandlerFunc {
266266

267267
if authToken.RefreshToken != nil {
268268
res["refresh_token"] = authToken.RefreshToken.Token
269-
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token)
269+
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
270270
}
271271

272272
gc.JSON(http.StatusOK, res)

server/handlers/verify_email.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,12 +154,12 @@ func VerifyEmailHandler() gin.HandlerFunc {
154154

155155
sessionKey := loginMethod + ":" + user.ID
156156
cookie.SetSession(c, authToken.FingerPrintHash)
157-
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash)
158-
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token)
157+
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
158+
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
159159

160160
if authToken.RefreshToken != nil {
161161
params = params + `&refresh_token=` + authToken.RefreshToken.Token
162-
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token)
162+
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
163163
}
164164

165165
if redirectURL == "" {
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package inmemory
2+
3+
import (
4+
"testing"
5+
6+
"github.com/authorizerdev/authorizer/server/memorystore/providers"
7+
"github.com/stretchr/testify/assert"
8+
)
9+
10+
func TestInMemoryProvider(t *testing.T) {
11+
p, err := NewInMemoryProvider()
12+
assert.NoError(t, err)
13+
providers.ProviderTests(t, p)
14+
}

server/memorystore/providers/inmemory/store.go

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,39 +8,31 @@ import (
88
)
99

1010
// SetUserSession sets the user session for given user identifier in form recipe:user_id
11-
func (c *provider) SetUserSession(userId, key, token string) error {
12-
c.sessionStore.Set(userId, key, token)
11+
func (c *provider) SetUserSession(userId, key, token string, expiration int64) error {
12+
c.sessionStore.Set(userId, key, token, expiration)
1313
return nil
1414
}
1515

1616
// GetUserSession returns value for given session token
1717
func (c *provider) GetUserSession(userId, sessionToken string) (string, error) {
18-
return c.sessionStore.Get(userId, sessionToken), nil
18+
val := c.sessionStore.Get(userId, sessionToken)
19+
if val == "" {
20+
return "", fmt.Errorf("Not found")
21+
}
22+
return val, nil
1923
}
2024

2125
// DeleteAllUserSessions deletes all the user sessions from in-memory store.
2226
func (c *provider) DeleteAllUserSessions(userId string) error {
23-
namespaces := []string{
24-
constants.AuthRecipeMethodBasicAuth,
25-
constants.AuthRecipeMethodMagicLinkLogin,
26-
constants.AuthRecipeMethodApple,
27-
constants.AuthRecipeMethodFacebook,
28-
constants.AuthRecipeMethodGithub,
29-
constants.AuthRecipeMethodGoogle,
30-
constants.AuthRecipeMethodLinkedIn,
31-
constants.AuthRecipeMethodTwitter,
32-
constants.AuthRecipeMethodMicrosoft,
33-
}
34-
35-
for _, namespace := range namespaces {
36-
c.sessionStore.RemoveAll(namespace + ":" + userId)
37-
}
27+
c.sessionStore.RemoveAll(userId)
3828
return nil
3929
}
4030

4131
// DeleteUserSession deletes the user session from the in-memory store.
4232
func (c *provider) DeleteUserSession(userId, sessionToken string) error {
43-
c.sessionStore.Remove(userId, sessionToken)
33+
c.sessionStore.Remove(userId, constants.TokenTypeSessionToken+"_"+sessionToken)
34+
c.sessionStore.Remove(userId, constants.TokenTypeAccessToken+"_"+sessionToken)
35+
c.sessionStore.Remove(userId, constants.TokenTypeRefreshToken+"_"+sessionToken)
4436
return nil
4537
}
4638

server/memorystore/providers/inmemory/stores/session_store.go

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
package stores
22

33
import (
4+
"fmt"
45
"strings"
56
"sync"
7+
"time"
8+
)
9+
10+
const (
11+
// Maximum entries to keep in session storage
12+
maxCacheSize = 1000
613
)
714

815
// SessionEntry is the struct for entry stored in store
@@ -13,69 +20,76 @@ type SessionEntry struct {
1320

1421
// SessionStore struct to store the env variables
1522
type SessionStore struct {
16-
mutex sync.Mutex
17-
store map[string]map[string]*SessionEntry
23+
mutex sync.Mutex
24+
store map[string]*SessionEntry
25+
itemsToEvict []string
1826
}
1927

2028
// NewSessionStore create a new session store
2129
func NewSessionStore() *SessionStore {
2230
return &SessionStore{
2331
mutex: sync.Mutex{},
24-
store: make(map[string]map[string]*SessionEntry),
32+
store: make(map[string]*SessionEntry),
2533
}
2634
}
2735

2836
// Get returns the value of the key in state store
2937
func (s *SessionStore) Get(key, subKey string) string {
3038
s.mutex.Lock()
3139
defer s.mutex.Unlock()
32-
return s.store[key][subKey].Value
40+
currentTime := time.Now().Unix()
41+
k := fmt.Sprintf("%s:%s", key, subKey)
42+
if v, ok := s.store[k]; ok {
43+
if v.ExpiresAt > currentTime {
44+
return v.Value
45+
}
46+
s.itemsToEvict = append(s.itemsToEvict, k)
47+
}
48+
return ""
3349
}
3450

3551
// Set sets the value of the key in state store
36-
func (s *SessionStore) Set(key string, subKey, value string) {
52+
func (s *SessionStore) Set(key string, subKey, value string, expiration int64) {
3753
s.mutex.Lock()
3854
defer s.mutex.Unlock()
39-
40-
if _, ok := s.store[key]; !ok {
41-
s.store[key] = make(map[string]string)
55+
k := fmt.Sprintf("%s:%s", key, subKey)
56+
if _, ok := s.store[k]; !ok {
57+
s.store[k] = &SessionEntry{
58+
Value: value,
59+
ExpiresAt: expiration,
60+
// TODO add expire time
61+
}
62+
}
63+
s.store[k] = &SessionEntry{
64+
Value: value,
65+
ExpiresAt: expiration,
66+
// TODO add expire time
4267
}
43-
s.store[key][subKey] = value
4468
}
4569

4670
// RemoveAll all values for given key
4771
func (s *SessionStore) RemoveAll(key string) {
4872
s.mutex.Lock()
4973
defer s.mutex.Unlock()
50-
51-
delete(s.store, key)
74+
for k := range s.store {
75+
if strings.Contains(k, key) {
76+
delete(s.store, k)
77+
}
78+
}
5279
}
5380

5481
// Remove value for given key and subkey
5582
func (s *SessionStore) Remove(key, subKey string) {
5683
s.mutex.Lock()
5784
defer s.mutex.Unlock()
58-
if _, ok := s.store[key]; ok {
59-
delete(s.store[key], subKey)
60-
}
61-
}
62-
63-
// Get all the values for given key
64-
func (s *SessionStore) GetAll(key string) map[string]string {
65-
s.mutex.Lock()
66-
defer s.mutex.Unlock()
67-
68-
if _, ok := s.store[key]; !ok {
69-
s.store[key] = make(map[string]string)
70-
}
71-
return s.store[key]
85+
k := fmt.Sprintf("%s:%s", key, subKey)
86+
delete(s.store, k)
7287
}
7388

7489
// RemoveByNamespace to delete session for a given namespace example google,github
7590
func (s *SessionStore) RemoveByNamespace(namespace string) error {
7691
s.mutex.Lock()
7792
defer s.mutex.Unlock()
78-
7993
for key := range s.store {
8094
if strings.Contains(key, namespace+":") {
8195
delete(s.store, key)

0 commit comments

Comments
 (0)