mirror of
https://github.com/bitechdev/ResolveSpec.git
synced 2026-10-05 21:06:28 +00:00
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
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user