From 93819d58945f2ee41154b36f62ba131f7c52ab41 Mon Sep 17 00:00:00 2001 From: MaysWind Date: Sun, 14 Jul 2024 15:44:48 +0800 Subject: [PATCH] check whether the setting value is valid and modify the allowed minimum value of settings --- conf/ezbookkeeping.ini | 13 ++++---- pkg/errs/setting.go | 24 +++++++++----- pkg/settings/setting.go | 70 +++++++++++++++++++++++++++++++++++------ 3 files changed, 83 insertions(+), 24 deletions(-) diff --git a/conf/ezbookkeeping.ini b/conf/ezbookkeeping.ini index b2e15e11..4ccf77e9 100644 --- a/conf/ezbookkeeping.ini +++ b/conf/ezbookkeeping.ini @@ -103,7 +103,7 @@ server_id = 0 # Duplicate checker type, supports "in_memory" currently checker_type = in_memory -# For "in_memory" only, cleanup expired data interval seconds (0 - 4294967295), default is 60 (1 minutes) +# For "in_memory" only, cleanup expired data interval seconds (1 - 4294967295), default is 60 (1 minutes) cleanup_interval = 60 # The minimum interval seconds (0 - 4294967295) between duplicate submissions on the same page (exiting and re-entering the page is considered as a new session) @@ -117,16 +117,16 @@ secret_key = # Set to true to enable two-factor authorization enable_two_factor = true -# Token expired seconds (0 - 4294967295), default is 2592000 (30 days) +# Token expired seconds (60 - 4294967295), default is 2592000 (30 days) token_expired_time = 2592000 -# Temporary token expired seconds (0 - 4294967295), default is 300 (5 minutes) +# Temporary token expired seconds (60 - 4294967295), default is 300 (5 minutes) temporary_token_expired_time = 300 -# Email verify token expired seconds (0 - 4294967295), default is 3600 (60 minutes) +# Email verify token expired seconds (60 - 4294967295), default is 3600 (60 minutes) email_verify_token_expired_time = 3600 -# Password reset token expired seconds (0 - 4294967295), default is 3600 (60 minutes) +# Password reset token expired seconds (60 - 4294967295), default is 3600 (60 minutes) password_reset_token_expired_time = 3600 # Add X-Request-Id header to response to track user request or error, default is true @@ -226,7 +226,8 @@ custom_map_tile_server_default_zoom_level = 14 # "monetary_authority_of_singapore" data_source = euro_central_bank -# Requesting exchange rates data timeout (0 - 4294967295 milliseconds), default is 10000 (10 seconds) +# Requesting exchange rates data timeout (0 - 4294967295 milliseconds) +# Set to 0 to disable timeout for requesting exchange rates data, default is 10000 (10 seconds) request_timeout = 10000 # Proxy to request exchange rates data, supports "system" (use system proxy), "none" (do not use proxy), or proxy URL which starts with "http://", "https://" or "socks5://", default is "system" diff --git a/pkg/errs/setting.go b/pkg/errs/setting.go index ac316e39..458eba8e 100644 --- a/pkg/errs/setting.go +++ b/pkg/errs/setting.go @@ -4,12 +4,20 @@ import "net/http" // Error codes related to settings var ( - ErrInvalidProtocol = NewSystemError(SystemSubcategorySetting, 0, http.StatusInternalServerError, "invalid server protocol") - ErrInvalidLogMode = NewSystemError(SystemSubcategorySetting, 1, http.StatusInternalServerError, "invalid log mode") - ErrGettingLocalAddress = NewSystemError(SystemSubcategorySetting, 2, http.StatusInternalServerError, "failed to get local address") - ErrInvalidUuidMode = NewSystemError(SystemSubcategorySetting, 3, http.StatusInternalServerError, "invalid uuid mode") - ErrInvalidExchangeRatesDataSource = NewSystemError(SystemSubcategorySetting, 4, http.StatusInternalServerError, "invalid exchange rates data source") - ErrInvalidMapProvider = NewSystemError(SystemSubcategorySetting, 5, http.StatusInternalServerError, "invalid map provider") - ErrInvalidAmapSecurityVerificationMethod = NewSystemError(SystemSubcategorySetting, 6, http.StatusInternalServerError, "invalid amap security verification method") - ErrInvalidDuplicateCheckerType = NewSystemError(SystemSubcategorySetting, 7, http.StatusInternalServerError, "invalid duplicate checker type") + ErrInvalidServerMode = NewSystemError(SystemSubcategorySetting, 0, http.StatusInternalServerError, "invalid server mode") + ErrInvalidProtocol = NewSystemError(SystemSubcategorySetting, 1, http.StatusInternalServerError, "invalid server protocol") + ErrInvalidLogMode = NewSystemError(SystemSubcategorySetting, 2, http.StatusInternalServerError, "invalid log mode") + ErrInvalidLogLevel = NewSystemError(SystemSubcategorySetting, 3, http.StatusInternalServerError, "invalid log level") + ErrGettingLocalAddress = NewSystemError(SystemSubcategorySetting, 4, http.StatusInternalServerError, "failed to get local address") + ErrInvalidUuidMode = NewSystemError(SystemSubcategorySetting, 5, http.StatusInternalServerError, "invalid uuid mode") + ErrInvalidDuplicateCheckerType = NewSystemError(SystemSubcategorySetting, 6, http.StatusInternalServerError, "invalid duplicate checker type") + ErrInvalidInMemoryDuplicateCheckerCleanupInterval = NewSystemError(SystemSubcategorySetting, 7, http.StatusInternalServerError, "invalid in-memory duplicate checker cleanup interval") + ErrInvalidTokenExpiredTime = NewSystemError(SystemSubcategorySetting, 8, http.StatusInternalServerError, "invalid token expired time") + ErrInvalidTemporaryTokenExpiredTime = NewSystemError(SystemSubcategorySetting, 9, http.StatusInternalServerError, "invalid temporary token expired time") + ErrInvalidEmailVerifyTokenExpiredTime = NewSystemError(SystemSubcategorySetting, 10, http.StatusInternalServerError, "invalid email verify token expired time") + ErrInvalidAvatarProvider = NewSystemError(SystemSubcategorySetting, 11, http.StatusInternalServerError, "invalid avatar provider") + ErrInvalidMapProvider = NewSystemError(SystemSubcategorySetting, 12, http.StatusInternalServerError, "invalid map provider") + ErrInvalidAmapSecurityVerificationMethod = NewSystemError(SystemSubcategorySetting, 13, http.StatusInternalServerError, "invalid amap security verification method") + ErrInvalidPasswordResetTokenExpiredTime = NewSystemError(SystemSubcategorySetting, 14, http.StatusInternalServerError, "invalid password reset token expired time") + ErrInvalidExchangeRatesDataSource = NewSystemError(SystemSubcategorySetting, 15, http.StatusInternalServerError, "invalid exchange rates data source") ) diff --git a/pkg/settings/setting.go b/pkg/settings/setting.go index 41edf2be..bd3a06b2 100644 --- a/pkg/settings/setting.go +++ b/pkg/settings/setting.go @@ -117,8 +117,7 @@ const ( defaultDatabaseMaxOpenConn uint16 = 0 defaultDatabaseConnMaxLifetime uint32 = 14400 - defaultLogMode string = "console" - defaultLoglevel Level = LOGLEVEL_INFO + defaultLogMode string = "console" defaultInMemoryDuplicateCheckerCleanupInterval uint32 = 60 // 1 minutes defaultDuplicateSubmissionsInterval uint32 = 300 // 5 minutes @@ -372,10 +371,13 @@ func GetDefaultConfigFilePath() (string, error) { func loadGlobalConfiguration(config *Config, configFile *ini.File, sectionName string) error { config.AppName = getConfigItemStringValue(configFile, sectionName, "app_name", defaultAppName) - config.Mode = MODE_PRODUCTION - if getConfigItemStringValue(configFile, sectionName, "mode") == "development" { + if getConfigItemStringValue(configFile, sectionName, "mode") == "production" { + config.Mode = MODE_PRODUCTION + } else if getConfigItemStringValue(configFile, sectionName, "mode") == "development" { config.Mode = MODE_DEVELOPMENT + } else { + return errs.ErrInvalidServerMode } return nil @@ -429,6 +431,13 @@ func loadDatabaseConfiguration(config *Config, configFile *ini.File, sectionName dbConfig := &DatabaseConfig{} dbConfig.DatabaseType = getConfigItemStringValue(configFile, sectionName, "type", MySqlDbType) + + if dbConfig.DatabaseType != MySqlDbType && + dbConfig.DatabaseType != PostgresDbType && + dbConfig.DatabaseType != Sqlite3DbType { + return errs.ErrDatabaseTypeInvalid + } + dbConfig.DatabaseHost = getConfigItemStringValue(configFile, sectionName, "host", defaultDatabaseHost) dbConfig.DatabaseName = getConfigItemStringValue(configFile, sectionName, "name", defaultDatabaseName) dbConfig.DatabaseUser = getConfigItemStringValue(configFile, sectionName, "user") @@ -486,7 +495,19 @@ func loadLogConfiguration(config *Config, configFile *ini.File, sectionName stri } } - config.LogLevel = getLogLevel(getConfigItemStringValue(configFile, sectionName, "level"), defaultLoglevel) + var err error + config.LogLevel, err = getLogLevel(getConfigItemStringValue(configFile, sectionName, "level")) + + if err != nil { + return err + } + + if config.LogLevel != LOGLEVEL_DEBUG && + config.LogLevel != LOGLEVEL_INFO && + config.LogLevel != LOGLEVEL_WARN && + config.LogLevel != LOGLEVEL_ERROR { + return errs.ErrInvalidLogLevel + } if config.EnableFileLog { fileLogPath := getConfigItemStringValue(configFile, sectionName, "log_path") @@ -517,6 +538,11 @@ func loadDuplicateCheckerConfiguration(config *Config, configFile *ini.File, sec } config.InMemoryDuplicateCheckerCleanupInterval = getConfigItemUint32Value(configFile, sectionName, "cleanup_interval", defaultInMemoryDuplicateCheckerCleanupInterval) + + if config.InMemoryDuplicateCheckerCleanupInterval < 1 { + return errs.ErrInvalidInMemoryDuplicateCheckerCleanupInterval + } + config.InMemoryDuplicateCheckerCleanupIntervalDuration = time.Duration(config.InMemoryDuplicateCheckerCleanupInterval) * time.Second duplicateSubmissionsInterval := getConfigItemUint32Value(configFile, sectionName, "duplicate_submissions_interval", defaultDuplicateSubmissionsInterval) @@ -539,15 +565,35 @@ func loadSecurityConfiguration(config *Config, configFile *ini.File, sectionName config.EnableTwoFactor = getConfigItemBoolValue(configFile, sectionName, "enable_two_factor", true) config.TokenExpiredTime = getConfigItemUint32Value(configFile, sectionName, "token_expired_time", defaultTokenExpiredTime) + + if config.TokenExpiredTime < 60 { + return errs.ErrInvalidTokenExpiredTime + } + config.TokenExpiredTimeDuration = time.Duration(config.TokenExpiredTime) * time.Second config.TemporaryTokenExpiredTime = getConfigItemUint32Value(configFile, sectionName, "temporary_token_expired_time", defaultTemporaryTokenExpiredTime) + + if config.TemporaryTokenExpiredTime < 60 { + return errs.ErrInvalidTemporaryTokenExpiredTime + } + config.TemporaryTokenExpiredTimeDuration = time.Duration(config.TemporaryTokenExpiredTime) * time.Second config.EmailVerifyTokenExpiredTime = getConfigItemUint32Value(configFile, sectionName, "email_verify_token_expired_time", defaultEmailVerifyTokenExpiredTime) + + if config.EmailVerifyTokenExpiredTime < 60 { + return errs.ErrInvalidEmailVerifyTokenExpiredTime + } + config.EmailVerifyTokenExpiredTimeDuration = time.Duration(config.EmailVerifyTokenExpiredTime) * time.Second config.PasswordResetTokenExpiredTime = getConfigItemUint32Value(configFile, sectionName, "password_reset_token_expired_time", defaultPasswordResetTokenExpiredTime) + + if config.PasswordResetTokenExpiredTime < 60 { + return errs.ErrInvalidPasswordResetTokenExpiredTime + } + config.PasswordResetTokenExpiredTimeDuration = time.Duration(config.PasswordResetTokenExpiredTime) * time.Second config.EnableRequestIdHeader = getConfigItemBoolValue(configFile, sectionName, "request_id_header", true) @@ -566,6 +612,8 @@ func loadUserConfiguration(config *Config, configFile *ini.File, sectionName str config.AvatarProvider = "" } else if getConfigItemStringValue(configFile, sectionName, "avatar_provider") == GravatarProvider { config.AvatarProvider = GravatarProvider + } else { + return errs.ErrInvalidAvatarProvider } return nil @@ -813,14 +861,16 @@ func getEnvironmentKey(sectionName string, itemName string) string { return fmt.Sprintf("%s_%s_%s", ebkEnvNamePrefix, strings.ToUpper(sectionName), strings.ToUpper(itemName)) } -func getLogLevel(logLevelStr string, defaultLogLevel Level) Level { +func getLogLevel(logLevelStr string) (Level, error) { if logLevelStr == "debug" { - return LOGLEVEL_DEBUG + return LOGLEVEL_DEBUG, nil + } else if logLevelStr == "info" { + return LOGLEVEL_INFO, nil } else if logLevelStr == "warn" { - return LOGLEVEL_WARN + return LOGLEVEL_WARN, nil } else if logLevelStr == "error" { - return LOGLEVEL_ERROR + return LOGLEVEL_ERROR, nil } - return defaultLogLevel + return "", errs.ErrInvalidLogLevel }