All checks were successful
Build and Push App Image / build-and-push (push) Successful in 1m27s
115 lines
2.3 KiB
Go
115 lines
2.3 KiB
Go
package auth
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"time"
|
|
|
|
"github.com/redis/go-redis/v9"
|
|
)
|
|
|
|
// SessionData stores authenticated identity data in Redis.
|
|
type SessionData struct {
|
|
UserID string `json:"user_id"`
|
|
Email string `json:"email"`
|
|
Username string `json:"username"`
|
|
}
|
|
|
|
// SessionManager handles Redis-backed session lifecycle operations.
|
|
type SessionManager struct {
|
|
redis *redis.Client
|
|
ttl time.Duration
|
|
prefix string
|
|
}
|
|
|
|
func NewSessionManager(redisClient *redis.Client, ttl time.Duration) *SessionManager {
|
|
if ttl <= 0 {
|
|
ttl = 7 * 24 * time.Hour
|
|
}
|
|
|
|
return &SessionManager{
|
|
redis: redisClient,
|
|
ttl: ttl,
|
|
prefix: "session:",
|
|
}
|
|
}
|
|
|
|
func (m *SessionManager) TTL() time.Duration {
|
|
return m.ttl
|
|
}
|
|
|
|
func (m *SessionManager) CreateSession(ctx context.Context, data *SessionData) (string, error) {
|
|
if data == nil {
|
|
return "", errors.New("session data is required")
|
|
}
|
|
|
|
sessionID, err := GenerateRandomToken(32)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
payload, err := json.Marshal(data)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
if err := m.redis.Set(ctx, m.key(sessionID), payload, m.ttl).Err(); err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return sessionID, nil
|
|
}
|
|
|
|
func (m *SessionManager) GetSession(ctx context.Context, sessionID string) (*SessionData, error) {
|
|
if sessionID == "" {
|
|
return nil, errors.New("session id is required")
|
|
}
|
|
|
|
payload, err := m.redis.Get(ctx, m.key(sessionID)).Result()
|
|
if err != nil {
|
|
if errors.Is(err, redis.Nil) {
|
|
return nil, errors.New("session not found")
|
|
}
|
|
return nil, err
|
|
}
|
|
|
|
var data SessionData
|
|
if err := json.Unmarshal([]byte(payload), &data); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &data, nil
|
|
}
|
|
|
|
func (m *SessionManager) RefreshSession(ctx context.Context, sessionID string) error {
|
|
if sessionID == "" {
|
|
return errors.New("session id is required")
|
|
}
|
|
|
|
if err := m.redis.Expire(ctx, m.key(sessionID), m.ttl).Err(); err != nil {
|
|
if errors.Is(err, redis.Nil) {
|
|
return errors.New("session not found")
|
|
}
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (m *SessionManager) DeleteSession(ctx context.Context, sessionID string) error {
|
|
if sessionID == "" {
|
|
return nil
|
|
}
|
|
|
|
if err := m.redis.Del(ctx, m.key(sessionID)).Err(); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (m *SessionManager) key(sessionID string) string {
|
|
return m.prefix + sessionID
|
|
}
|