Files
ResolveSpec/pkg/security/lookup_bridge.go
T
Hein c9fa8c60f2 refactor(security): move all database access into pkg/security/lookup
pkg/security no longer contains SQL. Every provider calls a store interface
from lookup, implemented by a procedure backend (Postgres stored procedures,
the default there) and a direct backend (dialect-driven SQL for postgres,
sqlite, mysql and mssql with configurable table and column names).

- add sectypes, lookup, lookup/{dialect,procedure,direct,backends,ddl,conformance}
- split totp and providers sub packages out of the core package
- replace SQLNames/TableNames/QueryMode with lookup.Config (see breaking_changes.md)
- direct backend now covers column/row security and API-key login
- move txsettings SQL to lookup.ApplyTxSettings; remove password.go
- move schema scripts under lookup/, add reference DDL per dialect
- add a shared conformance suite; run it on sqlite, and on Postgres in a
  podman/docker container (RESOLVESPEC_TEST_CONTAINERS=1)
- fix procedure schema bugs found on real Postgres: duplicate p_data
  parameter, JSON null arrays, expires_at timezone casts, passkey list
  GROUP BY, missing resolvespec_passkey_login; accept zone-less timestamps
2026-10-01 13:19:44 +02:00

53 lines
1.5 KiB
Go

package security
import (
"database/sql"
"sync"
"github.com/bitechdev/ResolveSpec/pkg/logger"
"github.com/bitechdev/ResolveSpec/pkg/security/lookup"
"github.com/bitechdev/ResolveSpec/pkg/security/lookup/backends"
)
// lookupSource builds the lookup.Provider a security component uses, on first use, so the
// With* builders can still change the configuration after construction. An explicit Provider
// bypasses the build.
type lookupSource struct {
db *sql.DB
cfg lookup.Config
opts backends.Options
provider *lookup.Provider
once sync.Once
built *lookup.Provider
}
func newLookupSource(db *sql.DB) *lookupSource { return &lookupSource{db: db} }
// get returns the provider. A bad configuration is logged once and yields a provider that
// returns the error from every call, so the component fails closed.
func (s *lookupSource) get() *lookup.Provider {
if s.provider != nil {
return s.provider
}
s.once.Do(func() { s.built = resolveLookup(s.db, s.cfg, s.opts) })
return s.built
}
// resolveLookup builds a provider for db. When the dialect is not configured and cannot be
// detected from the driver it falls back to postgres, the stored-procedure default.
func resolveLookup(db *sql.DB, cfg lookup.Config, opts backends.Options) *lookup.Provider {
if db != nil && cfg.Dialect == "" {
if _, err := cfg.ResolveDialect(db); err != nil {
cfg.Dialect = "postgres"
}
}
p, err := backends.New(db, cfg, opts)
if err != nil {
logger.Error("security: lookup configuration invalid: %v", err)
return backends.Failed(err)
}
return p
}