mirror of
https://github.com/Alexander-D-Karpov/concord.git
synced 2026-03-16 22:04:15 +03:00
252 lines
6.9 KiB
Go
252 lines
6.9 KiB
Go
package config
|
|
|
|
import (
|
|
"os"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
type Config struct {
|
|
Server ServerConfig
|
|
Database DatabaseConfig
|
|
Auth AuthConfig
|
|
Voice VoiceConfig
|
|
Logging LoggingConfig
|
|
Redis RedisConfig
|
|
RateLimit RateLimitConfig
|
|
Storage StorageConfig
|
|
Email EmailConfig
|
|
}
|
|
|
|
type ServerConfig struct {
|
|
Host string
|
|
Port int
|
|
GRPCPort int
|
|
ReadTimeout time.Duration
|
|
WriteTimeout time.Duration
|
|
IdleTimeout time.Duration
|
|
TLSCertFile string
|
|
TLSKeyFile string
|
|
}
|
|
|
|
type DatabaseConfig struct {
|
|
Host string
|
|
Port int
|
|
User string
|
|
Password string
|
|
Database string
|
|
MaxConns int
|
|
MinConns int
|
|
MaxConnLifetime time.Duration
|
|
MaxConnIdleTime time.Duration
|
|
}
|
|
|
|
type AuthConfig struct {
|
|
JWTSecret string
|
|
JWTExpiration time.Duration
|
|
RefreshExpiration time.Duration
|
|
VoiceJWTSecret string
|
|
VoiceJWTExpiration time.Duration
|
|
OAuth map[string]OAuthProvider
|
|
}
|
|
|
|
type OAuthProvider struct {
|
|
ClientID string
|
|
ClientSecret string
|
|
RedirectURL string
|
|
AuthURL string
|
|
TokenURL string
|
|
UserInfoURL string
|
|
}
|
|
|
|
type VoiceConfig struct {
|
|
UDPHost string
|
|
UDPPortStart int
|
|
UDPPortEnd int
|
|
UDPPortCount int
|
|
ControlPort int
|
|
ServerID string
|
|
Region string
|
|
Secret string
|
|
RegistryURL string
|
|
PublicHost string
|
|
StatusPort int
|
|
}
|
|
|
|
type LoggingConfig struct {
|
|
Level string
|
|
Format string
|
|
Output string
|
|
EnableFile bool
|
|
FilePath string
|
|
}
|
|
|
|
type RedisConfig struct {
|
|
Host string
|
|
Port int
|
|
Password string
|
|
DB int
|
|
Enabled bool
|
|
}
|
|
|
|
type StorageConfig struct {
|
|
Path string
|
|
URL string
|
|
}
|
|
|
|
type RateLimitConfig struct {
|
|
Enabled bool
|
|
RequestsPerMinute int
|
|
Burst int
|
|
BypassToken string
|
|
}
|
|
|
|
type EmailConfig struct {
|
|
SMTPHost string
|
|
SMTPPort int
|
|
Username string
|
|
Password string
|
|
FromAddress string
|
|
FromName string
|
|
}
|
|
|
|
func Load() (*Config, error) {
|
|
cfg := &Config{
|
|
Server: ServerConfig{
|
|
Host: getEnv("SERVER_HOST", "0.0.0.0"),
|
|
Port: getEnvInt("SERVER_PORT", 8080),
|
|
GRPCPort: getEnvInt("GRPC_PORT", 9090),
|
|
ReadTimeout: getEnvDuration("READ_TIMEOUT", 10*time.Second),
|
|
WriteTimeout: getEnvDuration("WRITE_TIMEOUT", 10*time.Second),
|
|
IdleTimeout: getEnvDuration("IDLE_TIMEOUT", 120*time.Second),
|
|
TLSCertFile: getEnv("TLS_CERT_FILE", ""),
|
|
TLSKeyFile: getEnv("TLS_KEY_FILE", ""),
|
|
},
|
|
Database: DatabaseConfig{
|
|
Host: getEnv("DB_HOST", "localhost"),
|
|
Port: getEnvInt("DB_PORT", 5432),
|
|
User: getEnv("DB_USER", "postgres"),
|
|
Password: getEnv("DB_PASSWORD", "postgres"),
|
|
Database: getEnv("DB_NAME", "concord"),
|
|
MaxConns: getEnvInt("DB_MAX_CONNS", 25),
|
|
MinConns: getEnvInt("DB_MIN_CONNS", 5),
|
|
MaxConnLifetime: getEnvDuration("DB_MAX_CONN_LIFETIME", 5*time.Minute),
|
|
MaxConnIdleTime: getEnvDuration("DB_MAX_CONN_IDLE_TIME", 5*time.Minute),
|
|
},
|
|
Auth: AuthConfig{
|
|
JWTSecret: getEnv("JWT_SECRET", "change-me-in-production"),
|
|
JWTExpiration: getEnvDuration("JWT_EXPIRATION", 15*time.Minute),
|
|
RefreshExpiration: getEnvDuration("REFRESH_EXPIRATION", 7*24*time.Hour),
|
|
VoiceJWTSecret: getEnv("VOICE_JWT_SECRET", "change-me-voice-secret"),
|
|
VoiceJWTExpiration: getEnvDuration("VOICE_JWT_EXPIRATION", 5*time.Minute),
|
|
OAuth: loadOAuthProviders(),
|
|
},
|
|
Voice: VoiceConfig{
|
|
UDPHost: getEnv("VOICE_UDP_HOST", "0.0.0.0"),
|
|
UDPPortStart: getEnvInt("VOICE_UDP_PORT_START", 50000),
|
|
UDPPortEnd: getEnvInt("VOICE_UDP_PORT_END", 52000),
|
|
UDPPortCount: getEnvInt("VOICE_UDP_PORT_COUNT", 50),
|
|
ControlPort: getEnvInt("VOICE_CONTROL_PORT", 9091),
|
|
ServerID: getEnv("VOICE_SERVER_ID", ""),
|
|
Region: getEnv("VOICE_REGION", "ru-west"),
|
|
Secret: getEnv("VOICE_SECRET", "change-me-voice-server-secret"),
|
|
RegistryURL: getEnv("REGISTRY_URL", "localhost:9090"),
|
|
PublicHost: getEnv("VOICE_PUBLIC_HOST", "localhost"),
|
|
StatusPort: getEnvInt("VOICE_STATUS_PORT", 9092),
|
|
},
|
|
Logging: LoggingConfig{
|
|
Level: getEnv("LOG_LEVEL", "info"),
|
|
Format: getEnv("LOG_FORMAT", "json"),
|
|
Output: getEnv("LOG_OUTPUT", "stdout"),
|
|
EnableFile: getEnvBool("LOG_ENABLE_FILE", false),
|
|
FilePath: getEnv("LOG_FILE_PATH", "/var/log/concord/app.log"),
|
|
},
|
|
Redis: RedisConfig{
|
|
Host: getEnv("REDIS_HOST", "localhost"),
|
|
Port: getEnvInt("REDIS_PORT", 6379),
|
|
Password: getEnv("REDIS_PASSWORD", ""),
|
|
DB: getEnvInt("REDIS_DB", 0),
|
|
Enabled: getEnvBool("REDIS_ENABLED", true),
|
|
},
|
|
RateLimit: RateLimitConfig{
|
|
Enabled: getEnvBool("RATE_LIMIT_ENABLED", true),
|
|
RequestsPerMinute: getEnvInt("RATE_LIMIT_REQUESTS_PER_MINUTE", 60),
|
|
Burst: getEnvInt("RATE_LIMIT_BURST", 10),
|
|
BypassToken: getEnv("RATE_LIMIT_BYPASS_TOKEN", ""),
|
|
},
|
|
Storage: StorageConfig{
|
|
Path: getEnv("STORAGE_PATH", "./uploads"),
|
|
URL: getEnv("STORAGE_URL", "/files"),
|
|
},
|
|
Email: EmailConfig{
|
|
SMTPHost: getEnv("EMAIL_SMTP_HOST", "smtp.example.com"),
|
|
SMTPPort: getEnvInt("EMAIL_SMTP_PORT", 587),
|
|
Username: getEnv("EMAIL_USERNAME", ""),
|
|
Password: getEnv("EMAIL_PASSWORD", ""),
|
|
},
|
|
}
|
|
return cfg, nil
|
|
}
|
|
|
|
func loadOAuthProviders() map[string]OAuthProvider {
|
|
providers := make(map[string]OAuthProvider)
|
|
|
|
if clientID := getEnv("OAUTH_GOOGLE_CLIENT_ID", ""); clientID != "" {
|
|
providers["google"] = OAuthProvider{
|
|
ClientID: clientID,
|
|
ClientSecret: getEnv("OAUTH_GOOGLE_CLIENT_SECRET", ""),
|
|
RedirectURL: getEnv("OAUTH_GOOGLE_REDIRECT_URL", ""),
|
|
AuthURL: "https://accounts.google.com/o/oauth2/auth",
|
|
TokenURL: "https://oauth2.googleapis.com/token",
|
|
UserInfoURL: "https://www.googleapis.com/oauth2/v2/userinfo",
|
|
}
|
|
}
|
|
|
|
if clientID := getEnv("OAUTH_GITHUB_CLIENT_ID", ""); clientID != "" {
|
|
providers["github"] = OAuthProvider{
|
|
ClientID: clientID,
|
|
ClientSecret: getEnv("OAUTH_GITHUB_CLIENT_SECRET", ""),
|
|
RedirectURL: getEnv("OAUTH_GITHUB_REDIRECT_URL", ""),
|
|
AuthURL: "https://github.com/login/oauth/authorize",
|
|
TokenURL: "https://github.com/login/oauth/access_token",
|
|
UserInfoURL: "https://api.github.com/user",
|
|
}
|
|
}
|
|
|
|
return providers
|
|
}
|
|
|
|
func getEnv(key, fallback string) string {
|
|
if value := os.Getenv(key); value != "" {
|
|
return value
|
|
}
|
|
return fallback
|
|
}
|
|
|
|
func getEnvInt(key string, fallback int) int {
|
|
if value := os.Getenv(key); value != "" {
|
|
if intVal, err := strconv.Atoi(value); err == nil {
|
|
return intVal
|
|
}
|
|
}
|
|
return fallback
|
|
}
|
|
|
|
func getEnvBool(key string, fallback bool) bool {
|
|
if value := os.Getenv(key); value != "" {
|
|
if boolVal, err := strconv.ParseBool(value); err == nil {
|
|
return boolVal
|
|
}
|
|
}
|
|
return fallback
|
|
}
|
|
|
|
func getEnvDuration(key string, fallback time.Duration) time.Duration {
|
|
if value := os.Getenv(key); value != "" {
|
|
if duration, err := time.ParseDuration(value); err == nil {
|
|
return duration
|
|
}
|
|
}
|
|
return fallback
|
|
}
|