Files
AstralDashboard/src/session/session_redis.go
T

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
}