diff --git a/htsget-config/src/config/advanced/allow_guard.rs b/htsget-config/src/config/advanced/allow_guard.rs index 316bc3af6..3394ce938 100644 --- a/htsget-config/src/config/advanced/allow_guard.rs +++ b/htsget-config/src/config/advanced/allow_guard.rs @@ -14,7 +14,7 @@ pub trait QueryAllowed { /// A query guard represents query parameters that can be allowed to storage for a given query. #[derive(Serialize, Clone, Debug, Deserialize, PartialEq, Eq)] -#[serde(default)] +#[serde(default, deny_unknown_fields)] pub struct AllowGuard { allow_reference_names: ReferenceNames, allow_fields: Fields, @@ -39,7 +39,7 @@ impl Default for AllowGuard { /// Reference names that can be matched. #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] -#[serde(untagged)] +#[serde(untagged, deny_unknown_fields)] pub enum ReferenceNames { Tagged(TaggedTypeAll), List(HashSet), diff --git a/htsget-config/src/config/advanced/cors.rs b/htsget-config/src/config/advanced/cors.rs index cd01413cc..a87aee960 100644 --- a/htsget-config/src/config/advanced/cors.rs +++ b/htsget-config/src/config/advanced/cors.rs @@ -18,6 +18,7 @@ const CORS_MAX_AGE: usize = 2592000; /// Tagged allow headers for cors config, either Mirror or Any. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(deny_unknown_fields)] pub enum TaggedAllowTypes { #[serde(alias = "mirror", alias = "MIRROR")] Mirror, @@ -27,7 +28,7 @@ pub enum TaggedAllowTypes { /// Allowed type for cors config which is used to configure cors behaviour. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] -#[serde(untagged)] +#[serde(untagged, deny_unknown_fields)] pub enum AllowType { Tagged(Tagged), #[serde(bound(serialize = "T: Display", deserialize = "T: FromStr, T::Err: Display"))] @@ -159,7 +160,7 @@ impl Display for HeaderValue { /// Cors configuration for the htsget server. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] -#[serde(default)] +#[serde(default, deny_unknown_fields)] pub struct CorsConfig { allow_credentials: bool, allow_origins: AllowType, diff --git a/htsget-config/src/config/advanced/mod.rs b/htsget-config/src/config/advanced/mod.rs index a23342deb..7ab2b0742 100644 --- a/htsget-config/src/config/advanced/mod.rs +++ b/htsget-config/src/config/advanced/mod.rs @@ -11,6 +11,7 @@ pub mod url; /// Determines which tracing formatting style to use. #[derive(Debug, Copy, Clone, Serialize, Deserialize, Default)] +#[serde(deny_unknown_fields)] pub enum FormattingStyle { #[default] Full, diff --git a/htsget-config/src/config/advanced/regex_location.rs b/htsget-config/src/config/advanced/regex_location.rs index c3f332b8e..d8bff741e 100644 --- a/htsget-config/src/config/advanced/regex_location.rs +++ b/htsget-config/src/config/advanced/regex_location.rs @@ -9,7 +9,7 @@ use serde::{Deserialize, Serialize}; /// A regex storage is a storage that matches ids using Regex. #[derive(Serialize, Debug, Clone, Deserialize)] -#[serde(default)] +#[serde(default, deny_unknown_fields)] pub struct RegexLocation { #[serde(with = "serde_regex")] regex: Regex, diff --git a/htsget-config/src/config/advanced/url.rs b/htsget-config/src/config/advanced/url.rs index 7b2f4bb0e..d1daa3f54 100644 --- a/htsget-config/src/config/advanced/url.rs +++ b/htsget-config/src/config/advanced/url.rs @@ -15,6 +15,7 @@ use serde::{Deserialize, Serialize}; /// Options for the remote URL server config. #[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(deny_unknown_fields)] pub struct Url { #[serde(with = "http_serde::uri")] url: Uri, diff --git a/htsget-config/src/config/data_server.rs b/htsget-config/src/config/data_server.rs index a5b633cf6..e909f7b53 100644 --- a/htsget-config/src/config/data_server.rs +++ b/htsget-config/src/config/data_server.rs @@ -11,6 +11,7 @@ use std::path::{Path, PathBuf}; /// Tagged allow headers for cors config, either Mirror or Any. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(deny_unknown_fields)] pub enum DataServerTagged { #[serde(alias = "none", alias = "NONE", alias = "null")] None, @@ -18,7 +19,7 @@ pub enum DataServerTagged { /// Whether the data server is enabled or not. #[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(untagged)] +#[serde(untagged, deny_unknown_fields)] #[allow(clippy::large_enum_variant)] pub enum DataServerEnabled { None(DataServerTagged), @@ -38,7 +39,7 @@ impl DataServerEnabled { /// Configuration for the htsget server. #[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(default)] +#[serde(default, deny_unknown_fields)] pub struct DataServerConfig { addr: SocketAddr, local_path: PathBuf, diff --git a/htsget-config/src/config/location.rs b/htsget-config/src/config/location.rs index b9db7b61f..7ca847f41 100644 --- a/htsget-config/src/config/location.rs +++ b/htsget-config/src/config/location.rs @@ -15,7 +15,7 @@ use {crate::config::advanced::url::Url, crate::error, http::Uri}; /// The locations of data. #[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(default, from = "LocationsOneOrMany")] +#[serde(default, deny_unknown_fields, from = "LocationsOneOrMany")] pub struct Locations(Vec); impl Locations { @@ -48,7 +48,7 @@ impl Default for Locations { /// Either simple or regex based location #[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(untagged)] +#[serde(untagged, deny_unknown_fields)] pub enum LocationEither { Simple(Location), Regex(RegexLocation), diff --git a/htsget-config/src/config/mod.rs b/htsget-config/src/config/mod.rs index 7d3de5ffa..087bb4ca0 100644 --- a/htsget-config/src/config/mod.rs +++ b/htsget-config/src/config/mod.rs @@ -50,7 +50,7 @@ struct Args { /// Simplified config. #[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(default)] +#[serde(default, deny_unknown_fields)] pub struct Config { ticket_server: TicketServerConfig, data_server: DataServerEnabled, diff --git a/htsget-config/src/config/service_info.rs b/htsget-config/src/config/service_info.rs index d0d4d259f..1f7d89d9d 100644 --- a/htsget-config/src/config/service_info.rs +++ b/htsget-config/src/config/service_info.rs @@ -8,7 +8,7 @@ use std::collections::HashMap; /// Service info config. #[derive(Serialize, Debug, Clone, Default, PartialEq, Eq)] -#[serde(default)] +#[serde(default, deny_unknown_fields)] pub struct ServiceInfo(HashMap); impl ServiceInfo { diff --git a/htsget-config/src/config/ticket_server.rs b/htsget-config/src/config/ticket_server.rs index 36bc462a1..e23b86431 100644 --- a/htsget-config/src/config/ticket_server.rs +++ b/htsget-config/src/config/ticket_server.rs @@ -8,7 +8,7 @@ use std::net::SocketAddr; /// Configuration for the htsget ticket server. #[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(default)] +#[serde(default, deny_unknown_fields)] pub struct TicketServerConfig { addr: SocketAddr, #[serde(skip_serializing)] diff --git a/htsget-config/src/storage/c4gh/local.rs b/htsget-config/src/storage/c4gh/local.rs index 2f3b75435..696abc8b7 100644 --- a/htsget-config/src/storage/c4gh/local.rs +++ b/htsget-config/src/storage/c4gh/local.rs @@ -9,6 +9,7 @@ use std::path::PathBuf; /// Local C4GH key storage. #[derive(Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(deny_unknown_fields)] pub struct C4GHLocal { private: PathBuf, public: PathBuf, diff --git a/htsget-config/src/storage/c4gh/mod.rs b/htsget-config/src/storage/c4gh/mod.rs index c4bf34a87..1ef593293 100644 --- a/htsget-config/src/storage/c4gh/mod.rs +++ b/htsget-config/src/storage/c4gh/mod.rs @@ -19,7 +19,7 @@ pub mod secrets_manager; /// Config for Crypt4GH keys. #[derive(Deserialize, Debug, Clone)] -#[serde(try_from = "C4GHKeyLocation")] +#[serde(try_from = "C4GHKeyLocation", deny_unknown_fields)] pub struct C4GHKeys { // Store a cloneable future so that it can be resolved outside serde. keys: Shared>>>, @@ -74,7 +74,7 @@ impl TryFrom for C4GHKeys { /// The location of C4GH keys. #[derive(Deserialize, Debug, Clone)] -#[serde(tag = "kind")] +#[serde(tag = "kind", deny_unknown_fields)] #[non_exhaustive] pub enum C4GHKeyLocation { #[serde(alias = "file", alias = "FILE")] diff --git a/htsget-config/src/storage/c4gh/secrets_manager.rs b/htsget-config/src/storage/c4gh/secrets_manager.rs index c5cc4349b..fcba09009 100644 --- a/htsget-config/src/storage/c4gh/secrets_manager.rs +++ b/htsget-config/src/storage/c4gh/secrets_manager.rs @@ -16,6 +16,7 @@ use tempfile::TempDir; /// C4GH secrets manager key storage. #[derive(Deserialize, Debug, Clone)] +#[serde(deny_unknown_fields)] pub struct C4GHSecretsManager { private: String, public: String, diff --git a/htsget-config/src/storage/file.rs b/htsget-config/src/storage/file.rs index db57bbbd5..026aa888f 100644 --- a/htsget-config/src/storage/file.rs +++ b/htsget-config/src/storage/file.rs @@ -15,7 +15,7 @@ use std::str::FromStr; /// Local file based storage. #[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(default)] +#[serde(default, deny_unknown_fields)] pub struct File { scheme: Scheme, #[serde(with = "http_serde::authority")] diff --git a/htsget-config/src/storage/mod.rs b/htsget-config/src/storage/mod.rs index 387775cec..b8dba455b 100644 --- a/htsget-config/src/storage/mod.rs +++ b/htsget-config/src/storage/mod.rs @@ -37,7 +37,7 @@ impl ResolvedId { /// Specify the storage backend to use as config values. #[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(tag = "kind")] +#[serde(tag = "kind", deny_unknown_fields)] #[non_exhaustive] pub enum Backend { #[serde(alias = "file", alias = "FILE")] diff --git a/htsget-config/src/storage/s3.rs b/htsget-config/src/storage/s3.rs index 1dfec5280..7f18e2180 100644 --- a/htsget-config/src/storage/s3.rs +++ b/htsget-config/src/storage/s3.rs @@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize}; /// Configuration struct for S3 storage. #[derive(Serialize, Deserialize, Debug, Clone, Default)] -#[serde(default)] +#[serde(default, deny_unknown_fields)] pub struct S3 { bucket: String, endpoint: Option, diff --git a/htsget-config/src/storage/url.rs b/htsget-config/src/storage/url.rs index 204dd5377..2f9a9928d 100644 --- a/htsget-config/src/storage/url.rs +++ b/htsget-config/src/storage/url.rs @@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize}; /// Remote URL server storage struct. #[derive(Deserialize, Serialize, Debug, Clone)] -#[serde(try_from = "advanced::url::Url")] +#[serde(try_from = "advanced::url::Url", deny_unknown_fields)] pub struct Url { #[serde(with = "http_serde::uri")] url: Uri, diff --git a/htsget-config/src/tls/client.rs b/htsget-config/src/tls/client.rs index 7864543b0..835df3810 100644 --- a/htsget-config/src/tls/client.rs +++ b/htsget-config/src/tls/client.rs @@ -11,7 +11,7 @@ use serde::Deserialize; /// A certificate and key pair used for TLS. Serialization is not implemented because there /// is no way to convert back to a `PathBuf`. #[derive(Deserialize, Debug, Clone, Default)] -#[serde(try_from = "RootCertStorePair")] +#[serde(try_from = "RootCertStorePair", deny_unknown_fields)] pub struct TlsClientConfig { cert: Option>, identity: Option, diff --git a/htsget-config/src/tls/mod.rs b/htsget-config/src/tls/mod.rs index 05ee6ef84..a65d54859 100644 --- a/htsget-config/src/tls/mod.rs +++ b/htsget-config/src/tls/mod.rs @@ -29,7 +29,7 @@ pub trait KeyPairScheme { /// A certificate and key pair used for TLS. Serialization is not implemented because there /// is no way to convert back to a `PathBuf`. #[derive(Deserialize, Debug, Clone)] -#[serde(try_from = "CertificateKeyPairPath")] +#[serde(try_from = "CertificateKeyPairPath", deny_unknown_fields)] pub struct TlsServerConfig { server_config: ServerConfig, } @@ -49,6 +49,7 @@ impl TlsServerConfig { /// The location of a certificate and key pair used for TLS. /// This is the path to the PEM formatted X.509 certificate and private key. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(deny_unknown_fields)] pub struct CertificateKeyPairPath { cert: PathBuf, key: PathBuf, @@ -76,6 +77,7 @@ impl CertificateKeyPair { /// The location of a certificate and key pair used for TLS. /// This is the path to the PEM formatted X.509 certificate and private key. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(deny_unknown_fields)] pub struct RootCertStorePair { #[serde(flatten)] key_pair: Option, diff --git a/htsget-config/src/types.rs b/htsget-config/src/types.rs index cec385440..3f16341eb 100644 --- a/htsget-config/src/types.rs +++ b/htsget-config/src/types.rs @@ -21,7 +21,7 @@ pub type Result = result::Result; /// An enumeration with all the possible formats. #[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all(serialize = "UPPERCASE"))] +#[serde(rename_all(serialize = "UPPERCASE"), deny_unknown_fields)] pub enum Format { #[serde(alias = "bam", alias = "BAM")] Bam, @@ -112,7 +112,7 @@ impl Display for Format { /// Class component of htsget response. #[derive(Copy, Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] -#[serde(rename_all(serialize = "lowercase"))] +#[serde(rename_all(serialize = "lowercase"), deny_unknown_fields)] pub enum Class { #[serde(alias = "header", alias = "HEADER")] Header, @@ -123,6 +123,7 @@ pub enum Class { /// An interval represents the start (0-based, inclusive) and end (0-based exclusive) ranges of the /// query. #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Deserialize, Serialize)] +#[serde(deny_unknown_fields)] pub struct Interval { start: Option, end: Option, @@ -205,7 +206,7 @@ impl Interval { /// Schemes that can be used with htsget. #[derive(Serialize, Deserialize, Debug, Default, Clone, Copy, PartialEq, Eq)] -#[serde(rename_all = "UPPERCASE")] +#[serde(rename_all = "UPPERCASE", deny_unknown_fields)] pub enum Scheme { #[default] #[serde(alias = "Http", alias = "http")] @@ -225,6 +226,7 @@ impl Display for Scheme { /// Tagged Any allow type for cors config. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] +#[serde(deny_unknown_fields)] pub enum TaggedTypeAll { #[serde(alias = "all", alias = "ALL")] All, @@ -232,7 +234,7 @@ pub enum TaggedTypeAll { /// Possible values for the fields parameter. #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] -#[serde(untagged)] +#[serde(untagged, deny_unknown_fields)] pub enum Fields { /// Include all fields Tagged(TaggedTypeAll), @@ -242,7 +244,7 @@ pub enum Fields { /// Possible values for the tags parameter. #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] -#[serde(untagged)] +#[serde(untagged, deny_unknown_fields)] pub enum Tags { /// Include all tags Tagged(TaggedTypeAll), @@ -252,6 +254,7 @@ pub enum Tags { /// The no tags parameter. #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] +#[serde(deny_unknown_fields)] pub struct NoTags(pub Option>); /// A struct containing the information from the HTTP request. @@ -516,6 +519,7 @@ impl From for HtsGetError { /// The headers that need to be supplied when requesting data from a url. #[derive(Debug, Default, PartialEq, Eq, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] pub struct Headers(HashMap); impl Headers { @@ -585,6 +589,7 @@ impl TryFrom<&HeaderMap> for Headers { /// A url from which raw data can be retrieved. #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] pub struct Url { pub url: String, #[serde(skip_serializing_if = "Option::is_none")] @@ -635,6 +640,7 @@ impl Url { /// Wrapped json response for htsget. #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] pub struct JsonResponse { pub htsget: Response, } @@ -654,6 +660,7 @@ impl From for JsonResponse { /// The response for a HtsGet query. #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] pub struct Response { pub format: Format, pub urls: Vec,