Fix/backup restore with invalid settings (#1793)
* Fix typo in setting validation error message * Convert value to internal type before validating it * Only update setting in case value is valid * Ignore settings validation errors on backup restore * Remove potential not privacy safe value from logs
This commit is contained in:
@@ -9,6 +9,8 @@ import kotlin.reflect.KProperty1
|
||||
import kotlin.reflect.full.memberProperties
|
||||
|
||||
object SettingsUpdater {
|
||||
private val logger = KotlinLogging.logger { }
|
||||
|
||||
private fun updateSetting(
|
||||
name: String,
|
||||
value: Any,
|
||||
@@ -30,12 +32,21 @@ object SettingsUpdater {
|
||||
?.convertToInternalType
|
||||
?.invoke(value) ?: value
|
||||
|
||||
val validationError = SettingsValidator.validate(name, maybeConvertedValue)
|
||||
val isValid = validationError == null
|
||||
|
||||
if (!isValid) {
|
||||
logger.warn { "Invalid value for setting $name: $validationError. Ignoring update." }
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Normal update - MigratedConfigValue handles deprecated mappings automatically
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
(stateFlow as MutableStateFlow<Any>).value = maybeConvertedValue
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
KotlinLogging.logger { }.error(e) { "Failed to update setting $name due to" }
|
||||
logger.error(e) { "Failed to update setting $name due to" }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,24 +3,32 @@ package suwayomi.tachidesk.server.settings
|
||||
import suwayomi.tachidesk.graphql.types.Settings
|
||||
|
||||
object SettingsValidator {
|
||||
private fun validateSingle(
|
||||
fun validate(
|
||||
name: String,
|
||||
value: Any?,
|
||||
): String? {
|
||||
val metadata = SettingsRegistry.get(name) ?: return null
|
||||
return metadata.validator?.invoke(value)
|
||||
|
||||
val maybeConvertedValue =
|
||||
if (value != null) {
|
||||
metadata.typeInfo.convertToInternalType?.invoke(value) ?: value
|
||||
} else {
|
||||
value
|
||||
}
|
||||
|
||||
return metadata.validator?.invoke(maybeConvertedValue)
|
||||
}
|
||||
|
||||
private fun validateAll(
|
||||
fun validate(
|
||||
values: Map<String, Any?>,
|
||||
ignoreNull: Boolean?,
|
||||
): List<String> =
|
||||
values
|
||||
.filterValues { value -> ignoreNull == false || value != null }
|
||||
.mapNotNull { (name, value) -> validateSingle(name, value)?.let { error -> "$name: $error" } }
|
||||
.mapNotNull { (name, value) -> validate(name, value)?.let { error -> "$name: $error" } }
|
||||
|
||||
fun validate(
|
||||
settings: Settings,
|
||||
ignoreNull: Boolean = false,
|
||||
): List<String> = validateAll(settings.asMap(), ignoreNull)
|
||||
): List<String> = validate(settings.asMap(), ignoreNull)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user