ms-auth/internal/storage/session.go
2024-08-14 20:24:57 +05:00

126 lines
2.6 KiB
Go

package storage
import (
"context"
"git.sch9.ru/new_gate/ms-auth/internal/lib"
"git.sch9.ru/new_gate/ms-auth/internal/models"
"github.com/valkey-io/valkey-go"
"go.uber.org/zap"
"time"
)
type SessionStorage struct {
db valkey.Client
cfg lib.Config
logger *zap.Logger
}
func NewSessionStorage(db valkey.Client, cfg lib.Config, logger *zap.Logger) *SessionStorage {
return &SessionStorage{
db: db,
cfg: cfg,
logger: logger,
}
}
const sessionLifetime = time.Minute * 40
func (storage *SessionStorage) CreateSession(ctx context.Context, userId int32) error {
session := models.NewSession(userId)
resp := storage.db.Do(ctx, storage.db.
B().Set().
Key(string(*session.UserId)).
Value(*session.Id).
Nx().
Exat(time.Now().Add(sessionLifetime)).
Build(),
)
if err := resp.Error(); err != nil {
return lib.ErrInternal
}
return nil
}
func (storage *SessionStorage) ReadSessionByToken(ctx context.Context, token string) (*models.Session, error) {
session, err := models.Parse(token, storage.cfg.JWTSecret)
if err != nil {
return nil, err
}
sessionRecord, err := storage.ReadSessionByUserId(ctx, *session.UserId)
if err != nil {
return nil, err
}
if *session.Id != *sessionRecord.Id {
return nil, lib.ErrInternal
}
return session, err
}
func (storage *SessionStorage) ReadSessionByUserId(ctx context.Context, userId int32) (*models.Session, error) {
resp := storage.db.Do(ctx, storage.db.B().Get().Key(string(userId)).Build())
if err := resp.Error(); err != nil {
return nil, lib.ErrInternal
}
id, err := resp.ToString()
if err != nil {
return nil, lib.ErrInternal
}
return &models.Session{
Id: &id,
UserId: &userId,
}, err
}
func (storage *SessionStorage) UpdateSession(ctx context.Context, session *models.Session) error {
resp := storage.db.Do(ctx, storage.db.
B().Set().
Key(string(*session.UserId)).
Value(*session.Id).
Xx().
Exat(time.Now().Add(sessionLifetime)).
Build(),
)
if err := resp.Error(); err != nil {
return lib.ErrInternal
}
return nil
}
func (storage *SessionStorage) DeleteSessionByToken(ctx context.Context, token string) error {
session, err := models.Parse(token, storage.cfg.JWTSecret)
if err != nil {
return err
}
err = storage.DeleteSessionByUserId(ctx, *session.UserId)
if err != nil {
return err
}
return nil
}
func (storage *SessionStorage) DeleteSessionByUserId(ctx context.Context, userId int32) error {
resp := storage.db.Do(ctx, storage.db.
B().Del().
Key(string(userId)).
Build(),
)
if err := resp.Error(); err != nil {
return lib.ErrInternal
}
return nil
}