authorizer/server/sessionstore/session.go
2022-05-25 15:04:26 +05:30

157 lines
4.4 KiB
Go

package sessionstore
import (
"context"
"strings"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/envstore"
"github.com/go-redis/redis/v8"
)
// SessionStore is a struct that defines available session stores
// If redis store is available, higher preference is given to that store.
// Else in memory store is used.
type SessionStore struct {
InMemoryStoreObj *InMemoryStore
RedisMemoryStoreObj *RedisStore
}
// SessionStoreObj is a global variable that holds the
// reference to various session store instances
var SessionStoreObj SessionStore
// DeleteAllSessions deletes all the sessions from the session store
func DeleteAllUserSession(userId string) {
if SessionStoreObj.RedisMemoryStoreObj != nil {
SessionStoreObj.RedisMemoryStoreObj.DeleteAllUserSession(userId)
}
if SessionStoreObj.InMemoryStoreObj != nil {
SessionStoreObj.InMemoryStoreObj.DeleteAllUserSession(userId)
}
}
// GetUserSessions returns all the user sessions from the session store
func GetUserSessions(userId string) map[string]string {
if SessionStoreObj.RedisMemoryStoreObj != nil {
return SessionStoreObj.RedisMemoryStoreObj.GetUserSessions(userId)
}
if SessionStoreObj.InMemoryStoreObj != nil {
return SessionStoreObj.InMemoryStoreObj.GetUserSessions(userId)
}
return nil
}
// ClearStore clears the session store for authorizer tokens
func ClearStore() {
if SessionStoreObj.RedisMemoryStoreObj != nil {
SessionStoreObj.RedisMemoryStoreObj.ClearStore()
}
if SessionStoreObj.InMemoryStoreObj != nil {
SessionStoreObj.InMemoryStoreObj.ClearStore()
}
}
// SetState sets the login state (key, value form) in the session store
func SetState(key, state string) {
if SessionStoreObj.RedisMemoryStoreObj != nil {
SessionStoreObj.RedisMemoryStoreObj.SetState(key, state)
}
if SessionStoreObj.InMemoryStoreObj != nil {
SessionStoreObj.InMemoryStoreObj.SetState(key, state)
}
}
// GetState returns the state from the session store
func GetState(key string) string {
if SessionStoreObj.RedisMemoryStoreObj != nil {
return SessionStoreObj.RedisMemoryStoreObj.GetState(key)
}
if SessionStoreObj.InMemoryStoreObj != nil {
return SessionStoreObj.InMemoryStoreObj.GetState(key)
}
return ""
}
// RemoveState removes the social login state from the session store
func RemoveState(key string) {
if SessionStoreObj.RedisMemoryStoreObj != nil {
SessionStoreObj.RedisMemoryStoreObj.RemoveState(key)
}
if SessionStoreObj.InMemoryStoreObj != nil {
SessionStoreObj.InMemoryStoreObj.RemoveState(key)
}
}
// InitializeSessionStore initializes the SessionStoreObj based on environment variables
func InitSession() error {
if envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyRedisURL) != "" {
log.Info("using redis store to save sessions")
redisURL := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyRedisURL)
redisURLHostPortsList := strings.Split(redisURL, ",")
if len(redisURLHostPortsList) > 1 {
opt, err := redis.ParseURL(redisURLHostPortsList[0])
if err != nil {
log.Debug("error parsing redis url: ", err)
return err
}
urls := []string{opt.Addr}
urlList := redisURLHostPortsList[1:]
urls = append(urls, urlList...)
clusterOpt := &redis.ClusterOptions{Addrs: urls}
rdb := redis.NewClusterClient(clusterOpt)
ctx := context.Background()
_, err = rdb.Ping(ctx).Result()
if err != nil {
log.Debug("error connecting to redis: ", err)
return err
}
SessionStoreObj.RedisMemoryStoreObj = &RedisStore{
ctx: ctx,
store: rdb,
}
// return on successful initialization
return nil
}
opt, err := redis.ParseURL(envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyRedisURL))
if err != nil {
log.Debug("error parsing redis url: ", err)
return err
}
rdb := redis.NewClient(opt)
ctx := context.Background()
_, err = rdb.Ping(ctx).Result()
if err != nil {
log.Debug("error connecting to redis: ", err)
return err
}
SessionStoreObj.RedisMemoryStoreObj = &RedisStore{
ctx: ctx,
store: rdb,
}
// return on successful initialization
return nil
}
log.Info("using in memory store to save sessions")
// if redis url is not set use in memory store
SessionStoreObj.InMemoryStoreObj = &InMemoryStore{
sessionStore: map[string]map[string]string{},
stateStore: map[string]string{},
}
return nil
}