2022-01-22 19:54:41 +00:00
|
|
|
package sessionstore
|
2021-07-14 18:43:19 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"log"
|
2022-02-17 14:24:15 +00:00
|
|
|
"strings"
|
2021-07-14 18:43:19 +00:00
|
|
|
|
2021-07-23 16:27:44 +00:00
|
|
|
"github.com/authorizerdev/authorizer/server/constants"
|
2022-01-17 06:02:13 +00:00
|
|
|
"github.com/authorizerdev/authorizer/server/envstore"
|
2021-07-14 18:43:19 +00:00
|
|
|
"github.com/go-redis/redis/v8"
|
|
|
|
)
|
|
|
|
|
2022-01-17 06:02:13 +00:00
|
|
|
// 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.
|
2021-07-14 18:43:19 +00:00
|
|
|
type SessionStore struct {
|
2021-07-17 16:29:50 +00:00
|
|
|
InMemoryStoreObj *InMemoryStore
|
|
|
|
RedisMemoryStoreObj *RedisStore
|
2021-07-14 18:43:19 +00:00
|
|
|
}
|
|
|
|
|
2022-01-17 06:02:13 +00:00
|
|
|
// SessionStoreObj is a global variable that holds the
|
|
|
|
// reference to various session store instances
|
2021-07-14 18:43:19 +00:00
|
|
|
var SessionStoreObj SessionStore
|
|
|
|
|
2022-01-17 06:02:13 +00:00
|
|
|
// SetUserSession sets the user session in the session store
|
2022-01-22 19:54:41 +00:00
|
|
|
func SetUserSession(userId, fingerprint, refreshToken string) {
|
2021-10-27 17:45:38 +00:00
|
|
|
if SessionStoreObj.RedisMemoryStoreObj != nil {
|
2022-01-22 19:54:41 +00:00
|
|
|
SessionStoreObj.RedisMemoryStoreObj.AddUserSession(userId, fingerprint, refreshToken)
|
2021-10-27 17:45:38 +00:00
|
|
|
}
|
|
|
|
if SessionStoreObj.InMemoryStoreObj != nil {
|
2022-01-22 19:54:41 +00:00
|
|
|
SessionStoreObj.InMemoryStoreObj.AddUserSession(userId, fingerprint, refreshToken)
|
2021-10-27 17:45:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-17 06:02:13 +00:00
|
|
|
// DeleteUserSession deletes the particular user session from the session store
|
2022-01-22 19:54:41 +00:00
|
|
|
func DeleteUserSession(userId, fingerprint string) {
|
2021-07-17 16:29:50 +00:00
|
|
|
if SessionStoreObj.RedisMemoryStoreObj != nil {
|
2022-01-22 19:54:41 +00:00
|
|
|
SessionStoreObj.RedisMemoryStoreObj.DeleteUserSession(userId, fingerprint)
|
2021-07-14 18:43:19 +00:00
|
|
|
}
|
2021-07-17 16:29:50 +00:00
|
|
|
if SessionStoreObj.InMemoryStoreObj != nil {
|
2022-01-22 19:54:41 +00:00
|
|
|
SessionStoreObj.InMemoryStoreObj.DeleteUserSession(userId, fingerprint)
|
2021-07-14 18:43:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-17 06:02:13 +00:00
|
|
|
// DeleteAllSessions deletes all the sessions from the session store
|
|
|
|
func DeleteAllUserSession(userId string) {
|
2021-07-17 16:29:50 +00:00
|
|
|
if SessionStoreObj.RedisMemoryStoreObj != nil {
|
2022-01-17 06:02:13 +00:00
|
|
|
SessionStoreObj.RedisMemoryStoreObj.DeleteAllUserSession(userId)
|
2021-07-14 18:43:19 +00:00
|
|
|
}
|
2021-07-17 16:29:50 +00:00
|
|
|
if SessionStoreObj.InMemoryStoreObj != nil {
|
2022-01-17 06:02:13 +00:00
|
|
|
SessionStoreObj.InMemoryStoreObj.DeleteAllUserSession(userId)
|
2021-07-14 18:43:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-17 06:02:13 +00:00
|
|
|
// GetUserSession returns the user session from the session store
|
2022-01-22 19:54:41 +00:00
|
|
|
func GetUserSession(userId, fingerprint string) string {
|
2021-07-17 16:29:50 +00:00
|
|
|
if SessionStoreObj.RedisMemoryStoreObj != nil {
|
2022-01-22 19:54:41 +00:00
|
|
|
return SessionStoreObj.RedisMemoryStoreObj.GetUserSession(userId, fingerprint)
|
2021-07-14 18:43:19 +00:00
|
|
|
}
|
2021-07-17 16:29:50 +00:00
|
|
|
if SessionStoreObj.InMemoryStoreObj != nil {
|
2022-01-22 19:54:41 +00:00
|
|
|
return SessionStoreObj.InMemoryStoreObj.GetUserSession(userId, fingerprint)
|
2021-07-14 18:43:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
2022-01-22 19:54:41 +00:00
|
|
|
// 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
|
|
|
|
}
|
|
|
|
|
2022-01-17 06:02:13 +00:00
|
|
|
// ClearStore clears the session store for authorizer tokens
|
2021-07-14 18:43:19 +00:00
|
|
|
func ClearStore() {
|
2021-07-17 16:29:50 +00:00
|
|
|
if SessionStoreObj.RedisMemoryStoreObj != nil {
|
|
|
|
SessionStoreObj.RedisMemoryStoreObj.ClearStore()
|
2021-07-14 18:43:19 +00:00
|
|
|
}
|
2021-07-17 16:29:50 +00:00
|
|
|
if SessionStoreObj.InMemoryStoreObj != nil {
|
|
|
|
SessionStoreObj.InMemoryStoreObj.ClearStore()
|
2021-07-14 18:43:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-17 06:02:13 +00:00
|
|
|
// SetSocialLoginState sets the social login state in the session store
|
2021-10-27 17:45:38 +00:00
|
|
|
func SetSocailLoginState(key, state string) {
|
|
|
|
if SessionStoreObj.RedisMemoryStoreObj != nil {
|
|
|
|
SessionStoreObj.RedisMemoryStoreObj.SetSocialLoginState(key, state)
|
|
|
|
}
|
|
|
|
if SessionStoreObj.InMemoryStoreObj != nil {
|
|
|
|
SessionStoreObj.InMemoryStoreObj.SetSocialLoginState(key, state)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-17 06:02:13 +00:00
|
|
|
// GetSocialLoginState returns the social login state from the session store
|
2021-10-27 17:45:38 +00:00
|
|
|
func GetSocailLoginState(key string) string {
|
|
|
|
if SessionStoreObj.RedisMemoryStoreObj != nil {
|
|
|
|
return SessionStoreObj.RedisMemoryStoreObj.GetSocialLoginState(key)
|
|
|
|
}
|
|
|
|
if SessionStoreObj.InMemoryStoreObj != nil {
|
|
|
|
return SessionStoreObj.InMemoryStoreObj.GetSocialLoginState(key)
|
|
|
|
}
|
|
|
|
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
2022-01-17 06:02:13 +00:00
|
|
|
// RemoveSocialLoginState removes the social login state from the session store
|
2021-10-27 17:45:38 +00:00
|
|
|
func RemoveSocialLoginState(key string) {
|
|
|
|
if SessionStoreObj.RedisMemoryStoreObj != nil {
|
|
|
|
SessionStoreObj.RedisMemoryStoreObj.RemoveSocialLoginState(key)
|
|
|
|
}
|
|
|
|
if SessionStoreObj.InMemoryStoreObj != nil {
|
|
|
|
SessionStoreObj.InMemoryStoreObj.RemoveSocialLoginState(key)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-17 06:02:13 +00:00
|
|
|
// InitializeSessionStore initializes the SessionStoreObj based on environment variables
|
2021-07-28 06:23:37 +00:00
|
|
|
func InitSession() {
|
2022-01-20 11:22:37 +00:00
|
|
|
if envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyRedisURL) != "" {
|
2021-12-17 15:55:07 +00:00
|
|
|
log.Println("using redis store to save sessions")
|
2022-02-17 14:24:15 +00:00
|
|
|
if isCluster(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyRedisURL)) {
|
|
|
|
clusterOpt, err := getClusterOptions(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyRedisURL))
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalln("Error parsing redis url:", err)
|
|
|
|
}
|
|
|
|
rdb := redis.NewClusterClient(clusterOpt)
|
|
|
|
ctx := context.Background()
|
|
|
|
_, err = rdb.Ping(ctx).Result()
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalln("Error connecting to redis cluster server", err)
|
|
|
|
}
|
|
|
|
SessionStoreObj.RedisMemoryStoreObj = &RedisStore{
|
|
|
|
ctx: ctx,
|
|
|
|
store: rdb,
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
2022-01-20 11:22:37 +00:00
|
|
|
opt, err := redis.ParseURL(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyRedisURL))
|
2021-07-14 18:43:19 +00:00
|
|
|
if err != nil {
|
|
|
|
log.Fatalln("Error parsing redis url:", err)
|
|
|
|
}
|
|
|
|
rdb := redis.NewClient(opt)
|
|
|
|
ctx := context.Background()
|
|
|
|
_, err = rdb.Ping(ctx).Result()
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalln("Error connecting to redis server", err)
|
|
|
|
}
|
2021-07-17 16:29:50 +00:00
|
|
|
SessionStoreObj.RedisMemoryStoreObj = &RedisStore{
|
2021-07-14 18:43:19 +00:00
|
|
|
ctx: ctx,
|
|
|
|
store: rdb,
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
2021-07-17 16:29:50 +00:00
|
|
|
SessionStoreObj.InMemoryStoreObj = &InMemoryStore{
|
2021-10-27 17:45:38 +00:00
|
|
|
store: map[string]map[string]string{},
|
|
|
|
socialLoginState: map[string]string{},
|
2021-07-14 18:43:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-02-17 14:24:15 +00:00
|
|
|
|
|
|
|
func isCluster(url string) bool {
|
|
|
|
return len(strings.Split(url, ",")) > 1
|
|
|
|
}
|
|
|
|
|
|
|
|
func getClusterOptions(url string) (*redis.ClusterOptions, error) {
|
|
|
|
hostPortsList := strings.Split(url, ",")
|
|
|
|
opt, err := redis.ParseURL(hostPortsList[0])
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
urls := []string{opt.Addr}
|
|
|
|
urlList := hostPortsList[1:]
|
|
|
|
urls = append(urls, urlList...)
|
|
|
|
return &redis.ClusterOptions{Addrs: urls}, nil
|
|
|
|
}
|