package casbin import ( "os" "time" mongodbadapter "github.com/casbin/mongodb-adapter/v3" "github.com/tech/sendico/pkg/merrors" "github.com/tech/sendico/pkg/mlogger" "go.uber.org/zap" ) type AdapterConfig struct { DatabaseName *string `mapstructure:"database_name"` DatabaseNameEnv *string `mapstructure:"database_name_env"` CollectionName *string `mapstructure:"collection_name"` CollectionNameEnv *string `mapstructure:"collection_name_env"` TimeoutSeconds *int `mapstructure:"timeout_seconds"` TimeoutSecondsEnv *string `mapstructure:"timeout_seconds_env"` IsFiltered *bool `mapstructure:"is_filtered"` IsFilteredEnv *string `mapstructure:"is_filtered_env"` } type Config struct { ModelPath *string `mapstructure:"model_path"` ModelPathEnv *string `mapstructure:"model_path_env"` Adapter *AdapterConfig `mapstructure:"adapter"` } type EnforcerConfig struct { ModelPath string Adapter *mongodbadapter.AdapterConfig } func getEnvValue(logger mlogger.Logger, varName, envVarName string, value, envValue *string) string { if value != nil && envValue != nil { logger.Warn("Both variable and environment variable are set, using environment variable value", zap.String("variable", varName), zap.String("environment_variable", envVarName), zap.String("value", *value), zap.String("env_value", os.Getenv(*envValue))) } if envValue != nil { return os.Getenv(*envValue) } if value != nil { return *value } return "" } func getEnvIntValue(logger mlogger.Logger, varName, envVarName string, value *int, envValue *string) int { if value != nil && envValue != nil { logger.Warn("Both variable and environment variable are set, using environment variable value", zap.String("variable", varName), zap.String("environment_variable", envVarName), zap.Int("value", *value), zap.String("env_value", os.Getenv(*envValue))) } if envValue != nil { envStr := os.Getenv(*envValue) if envStr != "" { if parsed, err := time.ParseDuration(envStr + "s"); err == nil { return int(parsed.Seconds()) } logger.Warn("Invalid environment variable value for timeout", zap.String("environment_variable", envVarName), zap.String("value", envStr)) } } if value != nil { return *value } return 30 // Default timeout in seconds } func getEnvBoolValue(logger mlogger.Logger, varName, envVarName string, value *bool, envValue *string) bool { if value != nil && envValue != nil { logger.Warn("Both variable and environment variable are set, using environment variable value", zap.String("variable", varName), zap.String("environment_variable", envVarName), zap.Bool("value", *value), zap.String("env_value", os.Getenv(*envValue))) } if envValue != nil { envStr := os.Getenv(*envValue) if envStr == "true" || envStr == "1" { return true } else if envStr == "false" || envStr == "0" { return false } logger.Warn("Invalid environment variable value for boolean", zap.String("environment_variable", envVarName), zap.String("value", envStr)) } if value != nil { return *value } return false // Default for boolean } func PrepareConfig(logger mlogger.Logger, config *Config) (*EnforcerConfig, error) { if config == nil { return nil, merrors.Internal("No configuration provided") } adapter := &mongodbadapter.AdapterConfig{ DatabaseName: getEnvValue(logger, "database_name", "database_name_env", config.Adapter.DatabaseName, config.Adapter.DatabaseNameEnv), CollectionName: getEnvValue(logger, "collection_name", "collection_name_env", config.Adapter.CollectionName, config.Adapter.CollectionNameEnv), Timeout: time.Duration(getEnvIntValue(logger, "timeout_seconds", "timeout_seconds_env", config.Adapter.TimeoutSeconds, config.Adapter.TimeoutSecondsEnv)) * time.Second, IsFiltered: getEnvBoolValue(logger, "is_filtered", "is_filtered_env", config.Adapter.IsFiltered, config.Adapter.IsFilteredEnv), } if len(adapter.DatabaseName) == 0 { logger.Error("Database name is not set") return nil, merrors.InvalidArgument("database name must be provided", "adapter.databaseName") } path := getEnvValue(logger, "model_path", "model_path_env", config.ModelPath, config.ModelPathEnv) logger.Info("Configuration prepared", zap.String("model_path", path), zap.String("database_name", adapter.DatabaseName), zap.String("collection_name", adapter.CollectionName), zap.Duration("timeout", adapter.Timeout), zap.Bool("is_filtered", adapter.IsFiltered), ) return &EnforcerConfig{ModelPath: path, Adapter: adapter}, nil }