52 lines
1.3 KiB
Go
52 lines
1.3 KiB
Go
package postgres
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"time"
|
|
|
|
"gardomatic.kleiax.de/internal/auth"
|
|
)
|
|
|
|
// TokenModel stores scoped authentication token hashes in PostgreSQL.
|
|
// TokenModel persists only token hashes; plaintext tokens are returned once to
|
|
// the caller and never stored.
|
|
type TokenModel struct {
|
|
DB *sql.DB
|
|
}
|
|
|
|
// New creates a token and persists only its hash.
|
|
func (m TokenModel) New(userID int, ttl time.Duration, scope string) (auth.Token, error) {
|
|
token := auth.NewToken(userID, ttl, scope)
|
|
|
|
err := m.insert(token)
|
|
return token, err
|
|
}
|
|
|
|
func (m TokenModel) insert(token auth.Token) error {
|
|
query := `
|
|
INSERT INTO tokens (hash, user_id, expiry, scope)
|
|
VALUES ($1, $2, $3, $4)`
|
|
|
|
args := []any{token.Hash, token.UserID, token.Expiry, token.Scope}
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
|
defer cancel()
|
|
|
|
_, err := m.DB.ExecContext(ctx, query, args...)
|
|
return err
|
|
}
|
|
|
|
// DeleteAllForUser revokes every token for one user and scope.
|
|
func (m TokenModel) DeleteAllForUser(scope string, userID int) error {
|
|
query := `
|
|
DELETE FROM tokens
|
|
WHERE scope = $1 AND user_id = $2`
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
|
defer cancel()
|
|
|
|
_, err := m.DB.ExecContext(ctx, query, scope, userID)
|
|
return err
|
|
}
|