mirror of
https://github.com/bitechdev/ResolveSpec.git
synced 2026-10-02 19:41:57 +00:00
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
53 lines
1.5 KiB
Go
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
|
|
}
|