package storage import ( edgeapi "git.sendico.io/tech/sxchnge/bff/edge/shared/interface/api" edgemongo "git.sendico.io/tech/sxchnge/bff/edge/shared/storage/mongo" "git.sendico.io/tech/sxchnge/bff/edge/shared/storage/ratelimits" "git.sendico.io/tech/sxchnge/bff/edge/shared/storage/refreshtokens" "git.sendico.io/tech/sxchnge/bff/edge/shared/storage/verification" "git.sendico.io/tech/sxchnge/bff/pkg/db" "git.sendico.io/tech/sxchnge/bff/pkg/db/account" "git.sendico.io/tech/sxchnge/bff/pkg/mlogger" "go.uber.org/zap" ) type Stores struct { Accounts account.DB Verification verification.DB RefreshTokens refreshtokens.DB LoginAttempts ratelimits.Store } type TokenStores struct { Verification verification.DB RefreshTokens refreshtokens.DB } type resolvedConfig struct { deps *edgemongo.Dependencies storage edgeapi.AuthStorageConfig } func OpenStores( logger mlogger.Logger, dbf db.Factory, config *edgeapi.AuthStorageConfig, ) (*Stores, error) { resolved, err := resolve(logger, dbf, config) if err != nil { return nil, err } logger.Info( "Auth storage configured", zap.String("accounts_collection", resolved.storage.AccountsCollection), zap.String("refresh_tokens_collection", resolved.storage.RefreshTokensCollection), zap.String("clients_collection", resolved.storage.ClientsCollection), zap.String("verification_tokens_collection", resolved.storage.VerificationTokensCollection), zap.String("login_attempts_collection", resolved.storage.LoginAttemptsCollection), zap.String("verification_rate_limits_collection", resolved.storage.VerificationRateLimitsCollection), ) adb, err := dbf.NewAccountDBWithCollection(resolved.storage.AccountsCollection) if err != nil { logger.Error("Failed to create account database", zap.Error(err), zap.String("collection", resolved.storage.AccountsCollection)) return nil, err } tokens, err := openTokenStores(logger, resolved) if err != nil { return nil, err } attempts, err := ratelimits.Create(logger, resolved.deps.Database, resolved.storage.LoginAttemptsCollection) if err != nil { logger.Error("Failed to create login attempt database", zap.Error(err), zap.String("collection", resolved.storage.LoginAttemptsCollection)) return nil, err } return &Stores{ Accounts: adb, Verification: tokens.Verification, RefreshTokens: tokens.RefreshTokens, LoginAttempts: attempts, }, nil } func OpenTokenStores( logger mlogger.Logger, dbf db.Factory, config *edgeapi.AuthStorageConfig, ) (*TokenStores, error) { resolved, err := resolve(logger, dbf, config) if err != nil { return nil, err } logger.Info( "Auth token storage configured", zap.String("refresh_tokens_collection", resolved.storage.RefreshTokensCollection), zap.String("clients_collection", resolved.storage.ClientsCollection), zap.String("verification_tokens_collection", resolved.storage.VerificationTokensCollection), zap.String("verification_rate_limits_collection", resolved.storage.VerificationRateLimitsCollection), ) return openTokenStores(logger, resolved) } func resolve( logger mlogger.Logger, dbf db.Factory, config *edgeapi.AuthStorageConfig, ) (*resolvedConfig, error) { deps, err := edgemongo.ResolveDependencies(dbf) if err != nil { logger.Error("Failed to resolve local auth storage dependencies", zap.Error(err)) return nil, err } return &resolvedConfig{ deps: deps, storage: config.WithDefaults(), }, nil } func openTokenStores(logger mlogger.Logger, resolved *resolvedConfig) (*TokenStores, error) { rtdb, err := refreshtokens.CreateWithCollections(logger, resolved.deps.Database, refreshtokens.Collections{ RefreshTokens: resolved.storage.RefreshTokensCollection, Clients: resolved.storage.ClientsCollection, }) if err != nil { logger.Error( "Failed to create refresh token management database", zap.Error(err), zap.String("refresh_tokens_collection", resolved.storage.RefreshTokensCollection), zap.String("clients_collection", resolved.storage.ClientsCollection), ) return nil, err } verificationLimits, err := ratelimits.Create(logger, resolved.deps.Database, resolved.storage.VerificationRateLimitsCollection) if err != nil { logger.Error("Failed to create verification rate-limit database", zap.Error(err), zap.String("collection", resolved.storage.VerificationRateLimitsCollection)) return nil, err } cdb, err := verification.CreateWithCollection( logger, resolved.deps.Database, resolved.deps.Transactions, resolved.storage.VerificationTokensCollection, ) if err != nil { logger.Error("Failed to create verification token database", zap.Error(err), zap.String("collection", resolved.storage.VerificationTokensCollection)) return nil, err } cdb.WithIssuanceLimits(verificationLimits) return &TokenStores{ Verification: cdb, RefreshTokens: rtdb, }, nil }