// Package remoteapi assembles dolt.sr.ht's remotesapi subsystem: the gRPC
// authentication/authorization interceptors, the importable remotesrv server
// that serves the bare NBS chunk stores, and the small separate
// CredentialsService (WhoAmI) server that backs `dolt login`.
//
// The two gRPC surfaces run on two ports (nginx path-routes between them):
//
// - the remotesapi ChunkStoreService (clone/push data plane) on ListenAddr,
// wrapped by our per-repo authz interceptors (see interceptors.go);
// - the CredentialsService.WhoAmI RPC on CredsListenAddr (see credsvc.go),
// which lets the dolt CLI discover which SourceHut user a keypair maps to
// while it polls for the key to be associated through the web UI.
package remoteapi
import (
"context"
"database/sql"
"sourcecraft.dev/bigbes/sr-ht-dolt/authn"
"sourcecraft.dev/bigbes/sr-ht-dolt/db"
)
// keyStore adapts the SQL persistence layer (db.Store over the shared *sql.DB
// pool) to the authn.KeyStore interface the Bearer-JWT resolver consumes. It
// wraps the pool rather than a context-bound Store so it can be constructed once
// at startup and shared by both the interceptor path and the credentials
// service; each call binds a fresh db.Store to the pool (which manages
// connection lifetime) and threads ctx for cancellation.
type keyStore struct {
db *sql.DB
}
var _ authn.KeyStore = (*keyStore)(nil)
// newKeyStore builds a keyStore over the shared database pool. pool must be
// non-nil.
func newKeyStore(pool *sql.DB) *keyStore {
if pool == nil {
panic("remoteapi: newKeyStore requires a non-nil *sql.DB")
}
return &keyStore{db: pool}
}
// ByKID resolves a dolt key id to the owner's raw Ed25519 public key and
// username, mapping the db layer's KeyAuth onto authn.KeyStore's contract. A
// missing key surfaces as db.ErrNotFound (returned unchanged), which the JWT
// resolver wraps into an invalid-token rejection.
func (k *keyStore) ByKID(ctx context.Context, kid string) (pubkey []byte, username string, err error) {
ka, err := db.NewStore(k.db).KeyByKID(ctx, kid)
if err != nil {
return nil, "", err
}
return ka.PubKey, ka.Username, nil
}
// TouchLastUsed stamps the key's last_used column after a successful keypair
// authentication.
func (k *keyStore) TouchLastUsed(ctx context.Context, kid string) error {
return db.NewStore(k.db).TouchKeyLastUsed(ctx, kid)
}