fix: move sessionstore -> memstore
This commit is contained in:
36
server/memorystore/memory_store.go
Normal file
36
server/memorystore/memory_store.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package memorystore
|
||||
|
||||
import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/authorizerdev/authorizer/server/memorystore/providers"
|
||||
"github.com/authorizerdev/authorizer/server/memorystore/providers/inmemory"
|
||||
"github.com/authorizerdev/authorizer/server/memorystore/providers/redis"
|
||||
)
|
||||
|
||||
// Provider returns the current database provider
|
||||
var Provider providers.Provider
|
||||
|
||||
// InitMemStore initializes the memory store
|
||||
func InitMemStore() error {
|
||||
var err error
|
||||
|
||||
redisURL := RequiredEnvStoreObj.GetRequiredEnv().RedisURL
|
||||
if redisURL != "" {
|
||||
log.Info("Initializing Redis memory store")
|
||||
Provider, err = redis.NewRedisProvider(redisURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Info("using in memory store to save sessions")
|
||||
// if redis url is not set use in memory store
|
||||
Provider, err = inmemory.NewInMemoryProvider()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
72
server/memorystore/providers/inmemory/inmemory.go
Normal file
72
server/memorystore/providers/inmemory/inmemory.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package inmemory
|
||||
|
||||
import "strings"
|
||||
|
||||
// ClearStore clears the in-memory store.
|
||||
func (c *provider) ClearStore() error {
|
||||
c.mutex.Lock()
|
||||
defer c.mutex.Unlock()
|
||||
c.sessionStore = map[string]map[string]string{}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetUserSessions returns all the user session token from the in-memory store.
|
||||
func (c *provider) GetUserSessions(userId string) map[string]string {
|
||||
// c.mutex.Lock()
|
||||
// defer c.mutex.Unlock()
|
||||
res := map[string]string{}
|
||||
for k, v := range c.stateStore {
|
||||
split := strings.Split(v, "@")
|
||||
if split[1] == userId {
|
||||
res[k] = split[0]
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// DeleteAllUserSession deletes all the user sessions from in-memory store.
|
||||
func (c *provider) DeleteAllUserSession(userId string) error {
|
||||
// c.mutex.Lock()
|
||||
// defer c.mutex.Unlock()
|
||||
sessions := c.GetUserSessions(userId)
|
||||
for k := range sessions {
|
||||
c.RemoveState(k)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetState sets the state in the in-memory store.
|
||||
func (c *provider) SetState(key, state string) error {
|
||||
c.mutex.Lock()
|
||||
defer c.mutex.Unlock()
|
||||
|
||||
c.stateStore[key] = state
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetState gets the state from the in-memory store.
|
||||
func (c *provider) GetState(key string) string {
|
||||
c.mutex.Lock()
|
||||
defer c.mutex.Unlock()
|
||||
|
||||
state := ""
|
||||
if stateVal, ok := c.stateStore[key]; ok {
|
||||
state = stateVal
|
||||
}
|
||||
|
||||
return state
|
||||
}
|
||||
|
||||
// RemoveState removes the state from the in-memory store.
|
||||
func (c *provider) RemoveState(key string) error {
|
||||
c.mutex.Lock()
|
||||
defer c.mutex.Unlock()
|
||||
|
||||
delete(c.stateStore, key)
|
||||
|
||||
return nil
|
||||
}
|
18
server/memorystore/providers/inmemory/provider.go
Normal file
18
server/memorystore/providers/inmemory/provider.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package inmemory
|
||||
|
||||
import "sync"
|
||||
|
||||
type provider struct {
|
||||
mutex sync.Mutex
|
||||
sessionStore map[string]map[string]string
|
||||
stateStore map[string]string
|
||||
}
|
||||
|
||||
// NewInMemoryStore returns a new in-memory store.
|
||||
func NewInMemoryProvider() (*provider, error) {
|
||||
return &provider{
|
||||
mutex: sync.Mutex{},
|
||||
sessionStore: map[string]map[string]string{},
|
||||
stateStore: map[string]string{},
|
||||
}, nil
|
||||
}
|
17
server/memorystore/providers/providers.go
Normal file
17
server/memorystore/providers/providers.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package providers
|
||||
|
||||
// Provider defines current memory store provider
|
||||
type Provider interface {
|
||||
// DeleteAllSessions deletes all the sessions from the session store
|
||||
DeleteAllUserSession(userId string) error
|
||||
// GetUserSessions returns all the user sessions from the session store
|
||||
GetUserSessions(userId string) map[string]string
|
||||
// ClearStore clears the session store for authorizer tokens
|
||||
ClearStore() error
|
||||
// SetState sets the login state (key, value form) in the session store
|
||||
SetState(key, state string) error
|
||||
// GetState returns the state from the session store
|
||||
GetState(key string) string
|
||||
// RemoveState removes the social login state from the session store
|
||||
RemoveState(key string) error
|
||||
}
|
75
server/memorystore/providers/redis/provider.go
Normal file
75
server/memorystore/providers/redis/provider.go
Normal file
@@ -0,0 +1,75 @@
|
||||
package redis
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-redis/redis/v8"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// RedisClient is the interface for redis client & redis cluster client
|
||||
type RedisClient interface {
|
||||
HMSet(ctx context.Context, key string, values ...interface{}) *redis.BoolCmd
|
||||
Del(ctx context.Context, keys ...string) *redis.IntCmd
|
||||
HDel(ctx context.Context, key string, fields ...string) *redis.IntCmd
|
||||
HMGet(ctx context.Context, key string, fields ...string) *redis.SliceCmd
|
||||
HGetAll(ctx context.Context, key string) *redis.StringStringMapCmd
|
||||
Set(ctx context.Context, key string, value interface{}, expiration time.Duration) *redis.StatusCmd
|
||||
Get(ctx context.Context, key string) *redis.StringCmd
|
||||
}
|
||||
|
||||
type provider struct {
|
||||
ctx context.Context
|
||||
store RedisClient
|
||||
}
|
||||
|
||||
// NewRedisProvider returns a new redis provider
|
||||
func NewRedisProvider(redisURL string) (*provider, error) {
|
||||
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 nil, 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 nil, err
|
||||
}
|
||||
|
||||
return &provider{
|
||||
ctx: ctx,
|
||||
store: rdb,
|
||||
}, nil
|
||||
}
|
||||
|
||||
opt, err := redis.ParseURL(redisURL)
|
||||
if err != nil {
|
||||
log.Debug("error parsing redis url: ", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rdb := redis.NewClient(opt)
|
||||
ctx := context.Background()
|
||||
_, err = rdb.Ping(ctx).Result()
|
||||
if err != nil {
|
||||
log.Debug("error connecting to redis: ", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &provider{
|
||||
ctx: ctx,
|
||||
store: rdb,
|
||||
}, nil
|
||||
}
|
85
server/memorystore/providers/redis/reids.go
Normal file
85
server/memorystore/providers/redis/reids.go
Normal file
@@ -0,0 +1,85 @@
|
||||
package redis
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// ClearStore clears the redis store for authorizer related tokens
|
||||
func (c *provider) ClearStore() error {
|
||||
err := c.store.Del(c.ctx, "authorizer_*").Err()
|
||||
if err != nil {
|
||||
log.Debug("Error clearing redis store: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetUserSessions returns all the user session token from the redis store.
|
||||
func (c *provider) GetUserSessions(userID string) map[string]string {
|
||||
data, err := c.store.HGetAll(c.ctx, "*").Result()
|
||||
if err != nil {
|
||||
log.Debug("error getting token from redis store: ", err)
|
||||
}
|
||||
|
||||
res := map[string]string{}
|
||||
for k, v := range data {
|
||||
split := strings.Split(v, "@")
|
||||
if split[1] == userID {
|
||||
res[k] = split[0]
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// DeleteAllUserSession deletes all the user session from redis
|
||||
func (c *provider) DeleteAllUserSession(userId string) error {
|
||||
sessions := c.GetUserSessions(userId)
|
||||
for k, v := range sessions {
|
||||
if k == "token" {
|
||||
err := c.store.Del(c.ctx, v).Err()
|
||||
if err != nil {
|
||||
log.Debug("Error deleting redis token: ", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetState sets the state in redis store.
|
||||
func (c *provider) SetState(key, value string) error {
|
||||
err := c.store.Set(c.ctx, "authorizer_"+key, value, 0).Err()
|
||||
if err != nil {
|
||||
log.Debug("Error saving redis token: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetState gets the state from redis store.
|
||||
func (c *provider) GetState(key string) string {
|
||||
state := ""
|
||||
state, err := c.store.Get(c.ctx, "authorizer_"+key).Result()
|
||||
if err != nil {
|
||||
log.Debug("error getting token from redis store: ", err)
|
||||
}
|
||||
|
||||
return state
|
||||
}
|
||||
|
||||
// RemoveState removes the state from redis store.
|
||||
func (c *provider) RemoveState(key string) error {
|
||||
err := c.store.Del(c.ctx, "authorizer_"+key).Err()
|
||||
if err != nil {
|
||||
log.Fatalln("Error deleting redis token: ", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
136
server/memorystore/required_env_store.go
Normal file
136
server/memorystore/required_env_store.go
Normal file
@@ -0,0 +1,136 @@
|
||||
package memorystore
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/authorizerdev/authorizer/server/constants"
|
||||
"github.com/authorizerdev/authorizer/server/envstore"
|
||||
"github.com/authorizerdev/authorizer/server/utils"
|
||||
)
|
||||
|
||||
// RequiredEnv holds information about required envs
|
||||
type RequiredEnv struct {
|
||||
EnvPath string
|
||||
DatabaseURL string
|
||||
DatabaseType string
|
||||
DatabaseName string
|
||||
DatabaseHost string
|
||||
DatabasePort string
|
||||
DatabaseUsername string
|
||||
DatabasePassword string
|
||||
DatabaseCert string
|
||||
DatabaseCertKey string
|
||||
DatabaseCACert string
|
||||
RedisURL string
|
||||
}
|
||||
|
||||
// RequiredEnvObj is a simple in-memory store for sessions.
|
||||
type RequiredEnvStore struct {
|
||||
mutex sync.Mutex
|
||||
requiredEnv RequiredEnv
|
||||
}
|
||||
|
||||
// GetRequiredEnv to get required env
|
||||
func (r *RequiredEnvStore) GetRequiredEnv() RequiredEnv {
|
||||
r.mutex.Lock()
|
||||
defer r.mutex.Unlock()
|
||||
|
||||
return r.requiredEnv
|
||||
}
|
||||
|
||||
// SetRequiredEnv to set required env
|
||||
func (r *RequiredEnvStore) SetRequiredEnv(requiredEnv RequiredEnv) {
|
||||
r.mutex.Lock()
|
||||
defer r.mutex.Unlock()
|
||||
r.requiredEnv = requiredEnv
|
||||
}
|
||||
|
||||
var RequiredEnvStoreObj *RequiredEnvStore
|
||||
|
||||
// InitRequiredEnv to initialize EnvData and through error if required env are not present
|
||||
func InitRequiredEnv() error {
|
||||
envPath := os.Getenv(constants.EnvKeyEnvPath)
|
||||
|
||||
if envPath == "" {
|
||||
if envPath == "" {
|
||||
envPath = `.env`
|
||||
}
|
||||
}
|
||||
|
||||
if utils.ARG_ENV_FILE != nil && *utils.ARG_ENV_FILE != "" {
|
||||
envPath = *utils.ARG_ENV_FILE
|
||||
}
|
||||
log.Info("env path: ", envPath)
|
||||
|
||||
err := godotenv.Load(envPath)
|
||||
if err != nil {
|
||||
log.Info("using OS env instead of %s file", envPath)
|
||||
}
|
||||
|
||||
dbURL := os.Getenv(constants.EnvKeyDatabaseURL)
|
||||
dbType := os.Getenv(constants.EnvKeyDatabaseType)
|
||||
dbName := os.Getenv(constants.EnvKeyDatabaseName)
|
||||
dbPort := os.Getenv(constants.EnvKeyDatabasePort)
|
||||
dbHost := os.Getenv(constants.EnvKeyDatabaseHost)
|
||||
dbUsername := os.Getenv(constants.EnvKeyDatabaseUsername)
|
||||
dbPassword := os.Getenv(constants.EnvKeyDatabasePassword)
|
||||
dbCert := os.Getenv(constants.EnvKeyDatabaseCert)
|
||||
dbCertKey := os.Getenv(constants.EnvKeyDatabaseCertKey)
|
||||
dbCACert := os.Getenv(constants.EnvKeyDatabaseCACert)
|
||||
redisURL := os.Getenv(constants.EnvKeyRedisURL)
|
||||
|
||||
if strings.TrimSpace(dbType) == "" {
|
||||
if utils.ARG_DB_TYPE != nil && *utils.ARG_DB_TYPE != "" {
|
||||
dbType = strings.TrimSpace(*utils.ARG_DB_TYPE)
|
||||
}
|
||||
|
||||
if dbType == "" {
|
||||
log.Debug("DATABASE_TYPE is not set")
|
||||
return errors.New("invalid database type. DATABASE_TYPE is empty")
|
||||
}
|
||||
}
|
||||
|
||||
if strings.TrimSpace(dbURL) == "" && envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyDatabaseURL) == "" {
|
||||
if utils.ARG_DB_URL != nil && *utils.ARG_DB_URL != "" {
|
||||
dbURL = strings.TrimSpace(*utils.ARG_DB_URL)
|
||||
}
|
||||
|
||||
if dbURL == "" && dbPort == "" && dbHost == "" && dbUsername == "" && dbPassword == "" {
|
||||
log.Debug("DATABASE_URL is not set")
|
||||
return errors.New("invalid database url. DATABASE_URL is required")
|
||||
}
|
||||
}
|
||||
|
||||
if dbName == "" {
|
||||
if dbName == "" {
|
||||
dbName = "authorizer"
|
||||
}
|
||||
}
|
||||
|
||||
requiredEnv := RequiredEnv{
|
||||
EnvPath: envPath,
|
||||
DatabaseURL: dbURL,
|
||||
DatabaseType: dbType,
|
||||
DatabaseName: dbName,
|
||||
DatabaseHost: dbHost,
|
||||
DatabasePort: dbPort,
|
||||
DatabaseUsername: dbUsername,
|
||||
DatabasePassword: dbPassword,
|
||||
DatabaseCert: dbCert,
|
||||
DatabaseCertKey: dbCertKey,
|
||||
DatabaseCACert: dbCACert,
|
||||
RedisURL: redisURL,
|
||||
}
|
||||
|
||||
RequiredEnvStoreObj = &RequiredEnvStore{
|
||||
requiredEnv: requiredEnv,
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Reference in New Issue
Block a user