feat: use postgres

This commit is contained in:
Ilia Denisov
2026-04-26 20:34:39 +02:00
committed by GitHub
parent 48b0056b49
commit fe829285a6
365 changed files with 29223 additions and 24049 deletions
+27 -60
View File
@@ -7,6 +7,7 @@ import (
"galaxy/authsession/internal/adapters/local"
"galaxy/authsession/internal/adapters/mail"
redisadapter "galaxy/authsession/internal/adapters/redis"
"galaxy/authsession/internal/adapters/redis/challengestore"
"galaxy/authsession/internal/adapters/redis/configprovider"
"galaxy/authsession/internal/adapters/redis/projectionpublisher"
@@ -26,17 +27,10 @@ import (
"galaxy/authsession/internal/service/sendemailcode"
"galaxy/authsession/internal/telemetry"
"github.com/redis/go-redis/v9"
"go.uber.org/zap"
)
type pinger interface {
Ping(context.Context) error
}
type closer interface {
Close() error
}
// Runtime owns the runnable authsession application plus the adapter cleanup
// functions that must run after the process stops.
type Runtime struct {
@@ -65,91 +59,64 @@ func NewRuntime(ctx context.Context, cfg config.Config, logger *zap.Logger, tele
return nil, errors.Join(err, runtime.Close())
}
challengeStore, err := challengestore.New(challengestore.Config{
Addr: cfg.Redis.Addr,
Username: cfg.Redis.Username,
Password: cfg.Redis.Password,
DB: cfg.Redis.DB,
TLSEnabled: cfg.Redis.TLSEnabled,
redisClient := redisadapter.NewClient(cfg.Redis)
if err := redisadapter.InstrumentClient(redisClient, telemetryRuntime); err != nil {
return cleanupOnError(fmt.Errorf("new authsession runtime: %w", err))
}
runtime.cleanupFns = append(runtime.cleanupFns, func() error {
err := redisClient.Close()
if errors.Is(err, redis.ErrClosed) {
return nil
}
return err
})
if err := redisadapter.Ping(ctx, cfg.Redis, redisClient); err != nil {
return cleanupOnError(fmt.Errorf("new authsession runtime: %w", err))
}
challengeStore, err := challengestore.New(redisClient, challengestore.Config{
KeyPrefix: cfg.Redis.ChallengeKeyPrefix,
OperationTimeout: cfg.Redis.OperationTimeout,
OperationTimeout: cfg.Redis.Conn.OperationTimeout,
})
if err != nil {
return cleanupOnError(fmt.Errorf("new authsession runtime: challenge store: %w", err))
}
runtime.cleanupFns = append(runtime.cleanupFns, challengeStore.Close)
sessionStore, err := sessionstore.New(sessionstore.Config{
Addr: cfg.Redis.Addr,
Username: cfg.Redis.Username,
Password: cfg.Redis.Password,
DB: cfg.Redis.DB,
TLSEnabled: cfg.Redis.TLSEnabled,
sessionStore, err := sessionstore.New(redisClient, sessionstore.Config{
SessionKeyPrefix: cfg.Redis.SessionKeyPrefix,
UserSessionsKeyPrefix: cfg.Redis.UserSessionsKeyPrefix,
UserActiveSessionsKeyPrefix: cfg.Redis.UserActiveSessionsKeyPrefix,
OperationTimeout: cfg.Redis.OperationTimeout,
OperationTimeout: cfg.Redis.Conn.OperationTimeout,
})
if err != nil {
return cleanupOnError(fmt.Errorf("new authsession runtime: session store: %w", err))
}
runtime.cleanupFns = append(runtime.cleanupFns, sessionStore.Close)
configStore, err := configprovider.New(configprovider.Config{
Addr: cfg.Redis.Addr,
Username: cfg.Redis.Username,
Password: cfg.Redis.Password,
DB: cfg.Redis.DB,
TLSEnabled: cfg.Redis.TLSEnabled,
configStore, err := configprovider.New(redisClient, configprovider.Config{
SessionLimitKey: cfg.Redis.SessionLimitKey,
OperationTimeout: cfg.Redis.OperationTimeout,
OperationTimeout: cfg.Redis.Conn.OperationTimeout,
})
if err != nil {
return cleanupOnError(fmt.Errorf("new authsession runtime: config provider: %w", err))
}
runtime.cleanupFns = append(runtime.cleanupFns, configStore.Close)
publisher, err := projectionpublisher.New(projectionpublisher.Config{
Addr: cfg.Redis.Addr,
Username: cfg.Redis.Username,
Password: cfg.Redis.Password,
DB: cfg.Redis.DB,
TLSEnabled: cfg.Redis.TLSEnabled,
publisher, err := projectionpublisher.New(redisClient, projectionpublisher.Config{
SessionCacheKeyPrefix: cfg.Redis.GatewaySessionCacheKeyPrefix,
SessionEventsStream: cfg.Redis.GatewaySessionEventsStream,
StreamMaxLen: cfg.Redis.GatewaySessionEventsStreamMaxLen,
OperationTimeout: cfg.Redis.OperationTimeout,
OperationTimeout: cfg.Redis.Conn.OperationTimeout,
})
if err != nil {
return cleanupOnError(fmt.Errorf("new authsession runtime: projection publisher: %w", err))
}
runtime.cleanupFns = append(runtime.cleanupFns, publisher.Close)
abuseProtector, err := sendemailcodeabuse.New(sendemailcodeabuse.Config{
Addr: cfg.Redis.Addr,
Username: cfg.Redis.Username,
Password: cfg.Redis.Password,
DB: cfg.Redis.DB,
TLSEnabled: cfg.Redis.TLSEnabled,
abuseProtector, err := sendemailcodeabuse.New(redisClient, sendemailcodeabuse.Config{
KeyPrefix: cfg.Redis.SendEmailCodeThrottleKeyPrefix,
OperationTimeout: cfg.Redis.OperationTimeout,
OperationTimeout: cfg.Redis.Conn.OperationTimeout,
})
if err != nil {
return cleanupOnError(fmt.Errorf("new authsession runtime: send email code abuse protector: %w", err))
}
runtime.cleanupFns = append(runtime.cleanupFns, abuseProtector.Close)
for name, dependency := range map[string]pinger{
"challenge store": challengeStore,
"session store": sessionStore,
"config provider": configStore,
"projection publisher": publisher,
"send email code abuse protector": abuseProtector,
} {
if err := dependency.Ping(ctx); err != nil {
return cleanupOnError(fmt.Errorf("new authsession runtime: ping %s: %w", name, err))
}
}
clock := local.Clock{}
idGenerator := local.IDGenerator{}