49 lines
1.2 KiB
Go
49 lines
1.2 KiB
Go
package api
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
|
|
"github.com/jackc/pgx/v5"
|
|
|
|
"git.dcrubro.com/dcrubro/hammy-backend/internal/db"
|
|
)
|
|
|
|
// PgKeyStore adapts the sqlc-generated queries to the KeyStore interface.
|
|
//
|
|
// The indirection earns its keep twice: the middleware is testable without a
|
|
// database, and adding an unrelated column to api.keys does not ripple into the
|
|
// auth package.
|
|
type PgKeyStore struct {
|
|
Q *db.Queries
|
|
}
|
|
|
|
func (s PgKeyStore) KeyByHash(ctx context.Context, hash []byte) (KeyRecord, error) {
|
|
row, err := s.Q.KeyByHash(ctx, hash)
|
|
if err != nil {
|
|
// pgx returns ErrNoRows for an empty :one result. Translate it so the
|
|
// middleware never has to know which driver is underneath.
|
|
if errors.Is(err, pgx.ErrNoRows) {
|
|
return KeyRecord{}, ErrKeyNotFound
|
|
}
|
|
|
|
return KeyRecord{}, err
|
|
}
|
|
|
|
rec := KeyRecord{
|
|
ID: row.ID,
|
|
OwnerID: row.OwnerID,
|
|
Scopes: row.Scopes,
|
|
QuotaTier: row.QuotaTier,
|
|
Status: row.Status,
|
|
OwnerStatus: row.OwnerStatus,
|
|
}
|
|
|
|
// pgx maps a nullable timestamptz to pgtype.Timestamptz, which carries its
|
|
// own validity flag rather than being nil. db.Time does the conversion so
|
|
// pgtype never leaks past this adapter.
|
|
rec.ExpiresAt = db.Time(row.ExpiresAt)
|
|
|
|
return rec, nil
|
|
}
|