template-monorepo/internal/model/member/repository/step_up_redis.go

65 lines
1.8 KiB
Go

package repository
import (
"context"
"encoding/json"
"errors"
"fmt"
"time"
redislib "gateway/internal/library/redis"
memberdomain "gateway/internal/model/member/domain"
domrepo "gateway/internal/model/member/domain/repository"
"github.com/zeromicro/go-zero/core/stores/redis"
)
type redisStepUpStore struct {
client *redis.Redis
}
// NewRedisStepUpStore creates a Redis-backed step-up session store.
func NewRedisStepUpStore(client *redislib.Client) domrepo.StepUpStore {
if client == nil || client.Zero() == nil {
panic("member: redis client is required for step-up store")
}
return &redisStepUpStore{client: client.Zero()}
}
func (s *redisStepUpStore) Save(ctx context.Context, session *domrepo.StepUpSession, ttl time.Duration) error {
if session == nil || session.TokenID == "" {
return fmt.Errorf("member: step-up token id is required")
}
raw, err := json.Marshal(session)
if err != nil {
return fmt.Errorf("member: marshal step-up session: %w", err)
}
seconds := int(ttl.Seconds())
if seconds < 1 {
seconds = 1
}
return s.client.SetexCtx(ctx, memberdomain.GetStepUpRedisKey(session.TokenID), string(raw), seconds)
}
func (s *redisStepUpStore) Get(ctx context.Context, tokenID string) (*domrepo.StepUpSession, error) {
val, err := s.client.GetCtx(ctx, memberdomain.GetStepUpRedisKey(tokenID))
if errors.Is(err, redis.Nil) {
return nil, memberdomain.ErrStepUpNotFound
}
if err != nil {
return nil, err
}
var session domrepo.StepUpSession
if err := json.Unmarshal([]byte(val), &session); err != nil {
return nil, fmt.Errorf("member: unmarshal step-up session: %w", err)
}
return &session, nil
}
func (s *redisStepUpStore) Delete(ctx context.Context, tokenID string) error {
_, err := s.client.DelCtx(ctx, memberdomain.GetStepUpRedisKey(tokenID))
return err
}
var _ domrepo.StepUpStore = (*redisStepUpStore)(nil)