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 }