package storage import ( "git.sendico.io/tech/sxchnge/product/auth/config" "git.sendico.io/tech/sxchnge/product/customers/store" "git.sendico.io/tech/sxchnge/product/customers/store/mongo" "git.sendico.io/tech/sxchnge/product/sessions/store" "git.sendico.io/tech/sxchnge/product/verification/store" "git.sendico.io/tech/sxchnge/shared/database" edgemongo "git.sendico.io/tech/sxchnge/shared/database/dependencies" "git.sendico.io/tech/sxchnge/shared/logging" "git.sendico.io/tech/sxchnge/shared/ratelimit/store" "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 middleware.AuthStorageConfig } func OpenStores( logger mlogger.Logger, dbf db.Factory, config *middleware.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 := accountdb.CreateWithCollection(logger, resolved.deps.Database, 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 *middleware.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 *middleware.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 }