122 lines
2.6 KiB
Go
122 lines
2.6 KiB
Go
package session
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"time"
|
|
|
|
"astraltech.xyz/accountmanager/src/logging"
|
|
"github.com/redis/go-redis/v9"
|
|
)
|
|
|
|
type RedisStore struct {
|
|
client *redis.Client
|
|
ctx context.Context
|
|
}
|
|
|
|
func RedisHash(sessionID string) string {
|
|
return "selfservicedashboard_" + hashSession(sessionID)
|
|
}
|
|
|
|
func NewRedisStore() *RedisStore {
|
|
logging.Debug("Creating new redis session store")
|
|
|
|
// this will be replaced with a URL that can be parsed in the config file
|
|
redis_server := "redis://localhost:6379/0"
|
|
|
|
opts, err := redis.ParseURL(redis_server)
|
|
if err != nil {
|
|
logging.Errorf("Failed to parse redis url %s", err.Error())
|
|
}
|
|
|
|
rdb := redis.NewClient(opts)
|
|
|
|
ctx := context.Background()
|
|
if err := rdb.Ping(ctx).Err(); err != nil {
|
|
logging.Errorf("Failed to connect to redis server %s", redis_server)
|
|
} else {
|
|
logging.Infof("Successfully connected to redis server %s", redis_server)
|
|
}
|
|
|
|
store := &RedisStore{
|
|
client: rdb,
|
|
ctx: ctx,
|
|
}
|
|
return store
|
|
}
|
|
|
|
// return rdb.Set(ctx, key, data, 0).Err()
|
|
|
|
func (m *RedisStore) Create(sessionID string, session *SessionData) (err error) {
|
|
hashedSession := RedisHash(sessionID)
|
|
|
|
data, err := json.Marshal(*session)
|
|
if err != nil {
|
|
return ErrSessionBackend
|
|
}
|
|
|
|
created, err := m.client.SetNX(m.ctx, hashedSession, data, time.Hour).Result()
|
|
if err != nil {
|
|
logging.Error(err.Error())
|
|
return ErrSessionBackend
|
|
}
|
|
|
|
if !created {
|
|
return ErrSessionAlreadyExists
|
|
}
|
|
return nil
|
|
}
|
|
func (m *RedisStore) Get(sessionID string) (*SessionData, error) {
|
|
hashed := RedisHash(sessionID)
|
|
|
|
data, err := m.client.Get(m.ctx, hashed).Bytes()
|
|
if err == redis.Nil {
|
|
return nil, ErrSessionNotFound
|
|
} else if err != nil {
|
|
logging.Error(err.Error())
|
|
return nil, ErrSessionBackend
|
|
}
|
|
|
|
var session_data SessionData
|
|
if err := json.Unmarshal(data, &session_data); err != nil {
|
|
logging.Error(err.Error())
|
|
return nil, ErrSessionBackend
|
|
}
|
|
|
|
if time.Now().After(session_data.ExpiresAt) {
|
|
_ = m.Delete(sessionID)
|
|
return nil, ErrSessionBackend
|
|
}
|
|
return &session_data, nil
|
|
}
|
|
|
|
func (m *RedisStore) Update(sessionID string, session *SessionData) error {
|
|
hashedSession := RedisHash(sessionID)
|
|
|
|
data, err := json.Marshal(*session)
|
|
if err != nil {
|
|
return ErrSessionBackend
|
|
}
|
|
|
|
updated, err := m.client.SetXX(m.ctx, hashedSession, data, time.Hour).Result()
|
|
if err != nil {
|
|
logging.Error(err.Error())
|
|
return ErrSessionBackend
|
|
}
|
|
|
|
if !updated {
|
|
return ErrSessionNotFound
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (m *RedisStore) Delete(sessionID string) error {
|
|
hashedSession := RedisHash(sessionID)
|
|
err := m.client.Del(m.ctx, hashedSession).Err()
|
|
if err != nil {
|
|
logging.Error(err.Error())
|
|
return ErrSessionBackend
|
|
}
|
|
return nil
|
|
}
|