Disallow any unknown fields in configuration files

This will break backwards compatibility of configurations, but
ensures that a previously-configured setting won't get dropped
arbitrarily. Pretty much worth it, I think.
This commit is contained in:
Andreas Fuchs 2024-10-30 11:11:29 -04:00
parent 26ba489aa3
commit a02c551a5e
2 changed files with 20 additions and 2 deletions

View file

@ -29,6 +29,7 @@ pub(crate) static DEFAULT_PATH: Lazy<PathBuf> =
#[allow(clippy::struct_excessive_bools)]
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub(crate) struct Config {
#[serde(default = "false_fn")]
pub(crate) conduit_compat: bool,
@ -77,6 +78,7 @@ pub(crate) struct Config {
}
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub(crate) struct ServerDiscovery {
/// Server-server discovery configuration
#[serde(default)]
@ -88,6 +90,7 @@ pub(crate) struct ServerDiscovery {
/// Server-server discovery configuration
#[derive(Debug, Default, Deserialize)]
#[serde(deny_unknown_fields)]
pub(crate) struct ServerServerDiscovery {
/// The alternative authority to make server-server API requests to
pub(crate) authority: Option<OwnedServerName>,
@ -95,6 +98,7 @@ pub(crate) struct ServerServerDiscovery {
/// Client-server discovery configuration
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub(crate) struct ClientServerDiscovery {
/// The base URL to make client-server API requests to
pub(crate) base_url: Url,
@ -104,6 +108,7 @@ pub(crate) struct ClientServerDiscovery {
}
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub(crate) struct TlsConfig {
pub(crate) certs: String,
pub(crate) key: String,
@ -114,6 +119,7 @@ pub(crate) struct TlsConfig {
)]
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "snake_case")]
#[serde(deny_unknown_fields)]
pub(crate) enum ListenComponent {
Client,
Federation,
@ -129,6 +135,7 @@ impl ListenComponent {
#[derive(Clone, Debug, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
#[serde(deny_unknown_fields)]
pub(crate) enum ListenTransport {
Tcp {
#[serde(default = "default_address")]
@ -171,6 +178,7 @@ impl Display for ListenTransport {
}
#[derive(Clone, Debug, Deserialize)]
// Incompatible with deny_unknown_fields due to serde(flatten).
pub(crate) struct ListenConfig {
#[serde(default = "ListenComponent::all_components")]
pub(crate) components: HashSet<ListenComponent>,
@ -194,6 +202,7 @@ impl Display for ListenConfig {
}
#[derive(Copy, Clone, Default, Debug, Deserialize, clap::ValueEnum)]
#[serde(deny_unknown_fields)]
#[serde(rename_all = "snake_case")]
pub(crate) enum LogFormat {
/// Multiple lines per event, includes all information
@ -222,6 +231,7 @@ impl Display for LogFormat {
}
#[derive(Clone, Debug, Deserialize)]
#[serde(deny_unknown_fields)]
#[serde(default)]
pub(crate) struct TurnConfig {
pub(crate) username: String,
@ -244,6 +254,7 @@ impl Default for TurnConfig {
}
#[derive(Clone, Copy, Debug, Deserialize)]
#[serde(deny_unknown_fields)]
#[serde(rename_all = "lowercase")]
pub(crate) enum DatabaseBackend {
#[cfg(feature = "rocksdb")]
@ -264,6 +275,7 @@ impl Display for DatabaseBackend {
}
#[derive(Clone, Debug, Deserialize)]
#[serde(deny_unknown_fields)]
pub(crate) struct DatabaseConfig {
pub(crate) backend: DatabaseBackend,
pub(crate) path: String,
@ -275,12 +287,14 @@ pub(crate) struct DatabaseConfig {
}
#[derive(Clone, Debug, Default, Deserialize)]
#[serde(deny_unknown_fields)]
#[serde(default)]
pub(crate) struct MetricsConfig {
pub(crate) enable: bool,
}
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
#[serde(default)]
pub(crate) struct OtelTraceConfig {
pub(crate) enable: bool,
@ -301,6 +315,7 @@ impl Default for OtelTraceConfig {
}
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
#[serde(default)]
pub(crate) struct FlameConfig {
pub(crate) enable: bool,
@ -319,6 +334,7 @@ impl Default for FlameConfig {
}
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
#[serde(default)]
pub(crate) struct LogConfig {
pub(crate) filter: EnvFilterClone,
@ -339,6 +355,7 @@ impl Default for LogConfig {
}
#[derive(Debug, Default, Deserialize)]
#[serde(deny_unknown_fields)]
#[serde(default)]
pub(crate) struct ObservabilityConfig {
/// Prometheus metrics
@ -352,6 +369,7 @@ pub(crate) struct ObservabilityConfig {
}
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
#[serde(default)]
pub(crate) struct FederationConfig {
pub(crate) enable: bool,

View file

@ -8,5 +8,5 @@ Error: failed to validate configuration
Caused by: TOML parse error at line 1, column 1
|
1 | some_name = "example.com"
| ^^^^^^^^^^^^^^^^^^^^^^^^^
missing field `server_name`
| ^^^^^^^^^
unknown field `some_name`, expected one of `conduit_compat`, `listen`, `tls`, `server_name`, `server_discovery`, `database`, `federation`, `cache_capacity_modifier`, `pdu_cache_capacity`, `cleanup_second_interval`, `max_request_size`, `allow_registration`, `registration_token`, `allow_encryption`, `allow_room_creation`, `serve_media_unauthenticated`, `default_room_version`, `proxy`, `jwt_secret`, `observability`, `turn`, `emergency_password`