feat: use postgres
This commit is contained in:
@@ -11,10 +11,13 @@ import (
|
||||
|
||||
"galaxy/authsession/internal/api/internalhttp"
|
||||
"galaxy/authsession/internal/api/publichttp"
|
||||
"galaxy/redisconn"
|
||||
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
const authsessionRedisEnvPrefix = "AUTHSESSION"
|
||||
|
||||
const (
|
||||
shutdownTimeoutEnvVar = "AUTHSESSION_SHUTDOWN_TIMEOUT"
|
||||
logLevelEnvVar = "AUTHSESSION_LOG_LEVEL"
|
||||
@@ -31,13 +34,6 @@ const (
|
||||
internalHTTPIdleTimeoutEnvVar = "AUTHSESSION_INTERNAL_HTTP_IDLE_TIMEOUT"
|
||||
internalHTTPRequestTimeoutEnvVar = "AUTHSESSION_INTERNAL_HTTP_REQUEST_TIMEOUT"
|
||||
|
||||
redisAddrEnvVar = "AUTHSESSION_REDIS_ADDR"
|
||||
redisUsernameEnvVar = "AUTHSESSION_REDIS_USERNAME"
|
||||
redisPasswordEnvVar = "AUTHSESSION_REDIS_PASSWORD"
|
||||
redisDBEnvVar = "AUTHSESSION_REDIS_DB"
|
||||
redisTLSEnabledEnvVar = "AUTHSESSION_REDIS_TLS_ENABLED"
|
||||
redisOperationTimeoutEnvVar = "AUTHSESSION_REDIS_OPERATION_TIMEOUT"
|
||||
|
||||
redisChallengeKeyPrefixEnvVar = "AUTHSESSION_REDIS_CHALLENGE_KEY_PREFIX"
|
||||
redisSessionKeyPrefixEnvVar = "AUTHSESSION_REDIS_SESSION_KEY_PREFIX"
|
||||
redisUserSessionsKeyPrefixEnvVar = "AUTHSESSION_REDIS_USER_SESSIONS_KEY_PREFIX"
|
||||
@@ -67,8 +63,6 @@ const (
|
||||
|
||||
defaultShutdownTimeout = 5 * time.Second
|
||||
defaultLogLevel = "info"
|
||||
defaultRedisDB = 0
|
||||
defaultRedisOperationTimeout = 250 * time.Millisecond
|
||||
defaultChallengeKeyPrefix = "authsession:challenge:"
|
||||
defaultSessionKeyPrefix = "authsession:session:"
|
||||
defaultUserSessionsKeyPrefix = "authsession:user-sessions:"
|
||||
@@ -128,23 +122,10 @@ type LoggingConfig struct {
|
||||
|
||||
// RedisConfig configures the Redis-backed authsession adapters.
|
||||
type RedisConfig struct {
|
||||
// Addr is the shared Redis address used by the authsession adapters.
|
||||
Addr string
|
||||
|
||||
// Username is the optional Redis ACL username.
|
||||
Username string
|
||||
|
||||
// Password is the optional Redis ACL password.
|
||||
Password string
|
||||
|
||||
// DB is the Redis logical database index.
|
||||
DB int
|
||||
|
||||
// TLSEnabled configures whether Redis connections use TLS.
|
||||
TLSEnabled bool
|
||||
|
||||
// OperationTimeout bounds each adapter Redis round trip.
|
||||
OperationTimeout time.Duration
|
||||
// Conn carries the master/replica/password connection topology shared by
|
||||
// every authsession Redis adapter, sourced from the AUTHSESSION_REDIS_*
|
||||
// environment variables managed by `pkg/redisconn`.
|
||||
Conn redisconn.Config
|
||||
|
||||
// ChallengeKeyPrefix namespaces the challenge source-of-truth records.
|
||||
ChallengeKeyPrefix string
|
||||
@@ -248,8 +229,7 @@ func DefaultConfig() Config {
|
||||
PublicHTTP: publichttp.DefaultConfig(),
|
||||
InternalHTTP: internalhttp.DefaultConfig(),
|
||||
Redis: RedisConfig{
|
||||
DB: defaultRedisDB,
|
||||
OperationTimeout: defaultRedisOperationTimeout,
|
||||
Conn: redisconn.DefaultConfig(),
|
||||
ChallengeKeyPrefix: defaultChallengeKeyPrefix,
|
||||
SessionKeyPrefix: defaultSessionKeyPrefix,
|
||||
UserSessionsKeyPrefix: defaultUserSessionsKeyPrefix,
|
||||
@@ -329,21 +309,11 @@ func LoadFromEnv() (Config, error) {
|
||||
return Config{}, fmt.Errorf("load authsession config: %w", err)
|
||||
}
|
||||
|
||||
cfg.Redis.Addr = loadStringEnvWithDefault(redisAddrEnvVar, cfg.Redis.Addr)
|
||||
cfg.Redis.Username = os.Getenv(redisUsernameEnvVar)
|
||||
cfg.Redis.Password = os.Getenv(redisPasswordEnvVar)
|
||||
cfg.Redis.DB, err = loadIntEnvWithDefault(redisDBEnvVar, cfg.Redis.DB)
|
||||
if err != nil {
|
||||
return Config{}, fmt.Errorf("load authsession config: %w", err)
|
||||
}
|
||||
cfg.Redis.TLSEnabled, err = loadBoolEnvWithDefault(redisTLSEnabledEnvVar, cfg.Redis.TLSEnabled)
|
||||
if err != nil {
|
||||
return Config{}, fmt.Errorf("load authsession config: %w", err)
|
||||
}
|
||||
cfg.Redis.OperationTimeout, err = loadDurationEnvWithDefault(redisOperationTimeoutEnvVar, cfg.Redis.OperationTimeout)
|
||||
redisConn, err := redisconn.LoadFromEnv(authsessionRedisEnvPrefix)
|
||||
if err != nil {
|
||||
return Config{}, fmt.Errorf("load authsession config: %w", err)
|
||||
}
|
||||
cfg.Redis.Conn = redisConn
|
||||
cfg.Redis.ChallengeKeyPrefix = loadStringEnvWithDefault(redisChallengeKeyPrefixEnvVar, cfg.Redis.ChallengeKeyPrefix)
|
||||
cfg.Redis.SessionKeyPrefix = loadStringEnvWithDefault(redisSessionKeyPrefixEnvVar, cfg.Redis.SessionKeyPrefix)
|
||||
cfg.Redis.UserSessionsKeyPrefix = loadStringEnvWithDefault(redisUserSessionsKeyPrefixEnvVar, cfg.Redis.UserSessionsKeyPrefix)
|
||||
@@ -404,15 +374,13 @@ func LoadFromEnv() (Config, error) {
|
||||
// Validate reports whether cfg contains a consistent authsession process
|
||||
// configuration.
|
||||
func (cfg Config) Validate() error {
|
||||
switch {
|
||||
case cfg.ShutdownTimeout <= 0:
|
||||
if cfg.ShutdownTimeout <= 0 {
|
||||
return fmt.Errorf("load authsession config: %s must be positive", shutdownTimeoutEnvVar)
|
||||
case strings.TrimSpace(cfg.Redis.Addr) == "":
|
||||
return fmt.Errorf("load authsession config: %s must not be empty", redisAddrEnvVar)
|
||||
case cfg.Redis.DB < 0:
|
||||
return fmt.Errorf("load authsession config: %s must not be negative", redisDBEnvVar)
|
||||
case cfg.Redis.OperationTimeout <= 0:
|
||||
return fmt.Errorf("load authsession config: %s must be positive", redisOperationTimeoutEnvVar)
|
||||
}
|
||||
if err := cfg.Redis.Conn.Validate(); err != nil {
|
||||
return fmt.Errorf("load authsession config: redis: %w", err)
|
||||
}
|
||||
switch {
|
||||
case strings.TrimSpace(cfg.Redis.ChallengeKeyPrefix) == "":
|
||||
return fmt.Errorf("load authsession config: %s must not be empty", redisChallengeKeyPrefixEnvVar)
|
||||
case strings.TrimSpace(cfg.Redis.SessionKeyPrefix) == "":
|
||||
|
||||
@@ -8,8 +8,24 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
const (
|
||||
testRedisMasterAddrEnvVar = "AUTHSESSION_REDIS_MASTER_ADDR"
|
||||
testRedisPasswordEnvVar = "AUTHSESSION_REDIS_PASSWORD"
|
||||
testRedisReplicaEnvVar = "AUTHSESSION_REDIS_REPLICA_ADDRS"
|
||||
testRedisDBEnvVar = "AUTHSESSION_REDIS_DB"
|
||||
testRedisOpTimeoutEnvVar = "AUTHSESSION_REDIS_OPERATION_TIMEOUT"
|
||||
testRedisTLSEnabledEnvVar = "AUTHSESSION_REDIS_TLS_ENABLED"
|
||||
testRedisUsernameEnvVar = "AUTHSESSION_REDIS_USERNAME"
|
||||
)
|
||||
|
||||
func setRequiredRedisEnv(t *testing.T) {
|
||||
t.Helper()
|
||||
t.Setenv(testRedisMasterAddrEnvVar, "127.0.0.1:6379")
|
||||
t.Setenv(testRedisPasswordEnvVar, "secret")
|
||||
}
|
||||
|
||||
func TestLoadFromEnvUsesDefaults(t *testing.T) {
|
||||
t.Setenv(redisAddrEnvVar, "127.0.0.1:6379")
|
||||
setRequiredRedisEnv(t)
|
||||
|
||||
cfg, err := LoadFromEnv()
|
||||
require.NoError(t, err)
|
||||
@@ -19,9 +35,11 @@ func TestLoadFromEnvUsesDefaults(t *testing.T) {
|
||||
assert.Equal(t, defaults.Logging.Level, cfg.Logging.Level)
|
||||
assert.Equal(t, defaults.PublicHTTP, cfg.PublicHTTP)
|
||||
assert.Equal(t, defaults.InternalHTTP, cfg.InternalHTTP)
|
||||
assert.Equal(t, "127.0.0.1:6379", cfg.Redis.Addr)
|
||||
assert.Equal(t, defaults.Redis.DB, cfg.Redis.DB)
|
||||
assert.Equal(t, defaults.Redis.OperationTimeout, cfg.Redis.OperationTimeout)
|
||||
assert.Equal(t, "127.0.0.1:6379", cfg.Redis.Conn.MasterAddr)
|
||||
assert.Equal(t, "secret", cfg.Redis.Conn.Password)
|
||||
assert.Equal(t, defaults.Redis.Conn.DB, cfg.Redis.Conn.DB)
|
||||
assert.Equal(t, defaults.Redis.Conn.OperationTimeout, cfg.Redis.Conn.OperationTimeout)
|
||||
assert.Empty(t, cfg.Redis.Conn.ReplicaAddrs)
|
||||
assert.Equal(t, defaults.UserService, cfg.UserService)
|
||||
assert.Equal(t, defaults.MailService, cfg.MailService)
|
||||
assert.Equal(t, defaults.Telemetry.ServiceName, cfg.Telemetry.ServiceName)
|
||||
@@ -36,12 +54,11 @@ func TestLoadFromEnvAppliesOverrides(t *testing.T) {
|
||||
t.Setenv(logLevelEnvVar, "debug")
|
||||
t.Setenv(publicHTTPAddrEnvVar, "127.0.0.1:18080")
|
||||
t.Setenv(internalHTTPAddrEnvVar, "127.0.0.1:18081")
|
||||
t.Setenv(redisAddrEnvVar, "127.0.0.1:6380")
|
||||
t.Setenv(redisUsernameEnvVar, "alice")
|
||||
t.Setenv(redisPasswordEnvVar, "secret")
|
||||
t.Setenv(redisDBEnvVar, "3")
|
||||
t.Setenv(redisTLSEnabledEnvVar, "true")
|
||||
t.Setenv(redisOperationTimeoutEnvVar, "750ms")
|
||||
t.Setenv(testRedisMasterAddrEnvVar, "127.0.0.1:6380")
|
||||
t.Setenv(testRedisPasswordEnvVar, "secret")
|
||||
t.Setenv(testRedisReplicaEnvVar, "127.0.0.1:6381,127.0.0.1:6382")
|
||||
t.Setenv(testRedisDBEnvVar, "3")
|
||||
t.Setenv(testRedisOpTimeoutEnvVar, "750ms")
|
||||
t.Setenv(userServiceModeEnvVar, "rest")
|
||||
t.Setenv(userServiceBaseURLEnvVar, "http://127.0.0.1:19090")
|
||||
t.Setenv(userServiceRequestTimeoutEnvVar, "900ms")
|
||||
@@ -62,12 +79,11 @@ func TestLoadFromEnvAppliesOverrides(t *testing.T) {
|
||||
assert.Equal(t, "debug", cfg.Logging.Level)
|
||||
assert.Equal(t, "127.0.0.1:18080", cfg.PublicHTTP.Addr)
|
||||
assert.Equal(t, "127.0.0.1:18081", cfg.InternalHTTP.Addr)
|
||||
assert.Equal(t, "127.0.0.1:6380", cfg.Redis.Addr)
|
||||
assert.Equal(t, "alice", cfg.Redis.Username)
|
||||
assert.Equal(t, "secret", cfg.Redis.Password)
|
||||
assert.Equal(t, 3, cfg.Redis.DB)
|
||||
assert.True(t, cfg.Redis.TLSEnabled)
|
||||
assert.Equal(t, 750*time.Millisecond, cfg.Redis.OperationTimeout)
|
||||
assert.Equal(t, "127.0.0.1:6380", cfg.Redis.Conn.MasterAddr)
|
||||
assert.Equal(t, "secret", cfg.Redis.Conn.Password)
|
||||
assert.Equal(t, []string{"127.0.0.1:6381", "127.0.0.1:6382"}, cfg.Redis.Conn.ReplicaAddrs)
|
||||
assert.Equal(t, 3, cfg.Redis.Conn.DB)
|
||||
assert.Equal(t, 750*time.Millisecond, cfg.Redis.Conn.OperationTimeout)
|
||||
assert.Equal(t, UserServiceConfig{
|
||||
Mode: "rest",
|
||||
BaseURL: "http://127.0.0.1:19090",
|
||||
@@ -104,10 +120,8 @@ func TestLoadFromEnvRejectsInvalidValues(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Setenv(redisAddrEnvVar, "127.0.0.1:6379")
|
||||
setRequiredRedisEnv(t)
|
||||
t.Setenv(tt.envName, tt.envVal)
|
||||
if tt.envName == otelExporterOTLPTracesProtocolEnvVar {
|
||||
t.Setenv(otelTracesExporterEnvVar, "otlp")
|
||||
@@ -121,7 +135,7 @@ func TestLoadFromEnvRejectsInvalidValues(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLoadFromEnvRejectsInvalidRESTUserServiceConfiguration(t *testing.T) {
|
||||
t.Setenv(redisAddrEnvVar, "127.0.0.1:6379")
|
||||
setRequiredRedisEnv(t)
|
||||
t.Setenv(userServiceModeEnvVar, "rest")
|
||||
|
||||
t.Run("missing base url", func(t *testing.T) {
|
||||
@@ -141,7 +155,7 @@ func TestLoadFromEnvRejectsInvalidRESTUserServiceConfiguration(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLoadFromEnvRejectsInvalidRESTMailServiceConfiguration(t *testing.T) {
|
||||
t.Setenv(redisAddrEnvVar, "127.0.0.1:6379")
|
||||
setRequiredRedisEnv(t)
|
||||
t.Setenv(mailServiceModeEnvVar, "rest")
|
||||
|
||||
t.Run("missing base url", func(t *testing.T) {
|
||||
@@ -159,3 +173,40 @@ func TestLoadFromEnvRejectsInvalidRESTMailServiceConfiguration(t *testing.T) {
|
||||
assert.Contains(t, err.Error(), mailServiceRequestTimeoutEnvVar)
|
||||
})
|
||||
}
|
||||
|
||||
func TestLoadFromEnvRejectsDeprecatedRedisVars(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
envName string
|
||||
}{
|
||||
{name: "tls enabled deprecated", envName: testRedisTLSEnabledEnvVar},
|
||||
{name: "username deprecated", envName: testRedisUsernameEnvVar},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
setRequiredRedisEnv(t)
|
||||
t.Setenv(tt.envName, "true")
|
||||
|
||||
_, err := LoadFromEnv()
|
||||
require.Error(t, err)
|
||||
assert.Contains(t, err.Error(), tt.envName)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadFromEnvRequiresRedisMasterAddr(t *testing.T) {
|
||||
t.Setenv(testRedisPasswordEnvVar, "secret")
|
||||
|
||||
_, err := LoadFromEnv()
|
||||
require.Error(t, err)
|
||||
assert.Contains(t, err.Error(), testRedisMasterAddrEnvVar)
|
||||
}
|
||||
|
||||
func TestLoadFromEnvRequiresRedisPassword(t *testing.T) {
|
||||
t.Setenv(testRedisMasterAddrEnvVar, "127.0.0.1:6379")
|
||||
|
||||
_, err := LoadFromEnv()
|
||||
require.Error(t, err)
|
||||
assert.Contains(t, err.Error(), testRedisPasswordEnvVar)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user