internal/store/revocations.go
Rama main · réplica de lectura del repositorio original.
package store
import (
"context"
"fmt"
"time"
)
const insertRevocation = `
INSERT INTO revoked_sessions (session, until) VALUES (?, ?)
ON CONFLICT (session) DO UPDATE SET until = excluded.until`
const deleteRevocationsBefore = `DELETE FROM revoked_sessions WHERE until <= ?`
const selectRevocations = `SELECT session, until FROM revoked_sessions WHERE until > ?`
func (s *Store) Revoke(ctx context.Context, session string, until, now time.Time) error {
db := s.writer()
if db == nil || session == "" {
return nil
}
tx, err := db.BeginTx(ctx, nil)
if err != nil {
return fmt.Errorf("store: %w", err)
}
_, sweepErr := tx.ExecContext(ctx, deleteRevocationsBefore, now.UTC().UnixMilli())
if sweepErr != nil {
_ = tx.Rollback()
return fmt.Errorf("store: %w", sweepErr)
}
_, writeErr := tx.ExecContext(ctx, insertRevocation, session, until.UTC().UnixMilli())
if writeErr != nil {
_ = tx.Rollback()
return fmt.Errorf("store: %w", writeErr)
}
commitErr := tx.Commit()
if commitErr != nil {
return fmt.Errorf("store: %w", commitErr)
}
return nil
}
func (s *Store) Revocations(ctx context.Context, now time.Time) (map[string]time.Time, error) {
db := s.reader()
if db == nil {
return map[string]time.Time{}, nil
}
rows, err := db.QueryContext(ctx, selectRevocations, now.UTC().UnixMilli())
if err != nil {
return nil, fmt.Errorf("store: %w", err)
}
defer func() {
_ = rows.Close()
}()
out := map[string]time.Time{}
for rows.Next() {
var session string
var until int64
scanErr := rows.Scan(&session, &until)
if scanErr != nil {
return nil, fmt.Errorf("store: %w", scanErr)
}
out[session] = time.UnixMilli(until).UTC()
}
rowsErr := rows.Err()
if rowsErr != nil {
return nil, fmt.Errorf("store: %w", rowsErr)
}
return out, nil
}