1use serde::{Deserialize, Deserializer, de::Error as DeError};
4use std::ffi::OsString;
5use url::Url;
6
7#[derive(Debug, Clone, Deserialize, Default)]
9#[serde(rename_all = "camelCase")]
10pub struct WindowsConfig {
11 #[serde(
13 default,
14 alias = "installer-args",
15 deserialize_with = "deserialize_os_string"
16 )]
17 pub installer_args: Vec<OsString>,
18}
19
20#[derive(Debug, Clone, Default)]
27pub struct Config {
28 pub dangerous_insecure_transport_protocol: bool,
30 pub dangerous_accept_invalid_certs: bool,
32 pub dangerous_accept_invalid_hostnames: bool,
34 pub endpoints: Vec<Url>,
36 pub pubkey: String,
38 pub windows: Option<WindowsConfig>,
40}
41
42impl Config {
43 pub fn validate(&self) -> crate::Result<()> {
48 validate_endpoints(&self.endpoints, self.dangerous_insecure_transport_protocol)
49 }
50}
51
52fn deserialize_os_string<'de, D>(deserializer: D) -> Result<Vec<OsString>, D::Error>
53where
54 D: Deserializer<'de>,
55{
56 Ok(Vec::<String>::deserialize(deserializer)?
57 .into_iter()
58 .map(OsString::from)
59 .collect())
60}
61
62impl<'de> Deserialize<'de> for Config {
63 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
64 where
65 D: Deserializer<'de>,
66 {
67 #[derive(Deserialize)]
68 #[serde(rename_all = "camelCase")]
69 struct InnerConfig {
70 #[serde(default, alias = "dangerous-insecure-transport-protocol")]
71 dangerous_insecure_transport_protocol: bool,
72 #[serde(default, alias = "dangerous-accept-invalid-certs")]
73 dangerous_accept_invalid_certs: bool,
74 #[serde(default, alias = "dangerous-accept-invalid-hostnames")]
75 dangerous_accept_invalid_hostnames: bool,
76 #[serde(default)]
77 endpoints: Vec<Url>,
78 pubkey: String,
79 windows: Option<WindowsConfig>,
80 }
81
82 let config = InnerConfig::deserialize(deserializer)?;
83 validate_endpoints(
84 &config.endpoints,
85 config.dangerous_insecure_transport_protocol,
86 )
87 .map_err(DeError::custom)?;
88
89 Ok(Self {
90 dangerous_insecure_transport_protocol: config.dangerous_insecure_transport_protocol,
91 dangerous_accept_invalid_certs: config.dangerous_accept_invalid_certs,
92 dangerous_accept_invalid_hostnames: config.dangerous_accept_invalid_hostnames,
93 endpoints: config.endpoints,
94 pubkey: config.pubkey,
95 windows: config.windows,
96 })
97 }
98}
99
100pub(crate) fn validate_endpoints(
101 endpoints: &[Url],
102 dangerous_insecure_transport_protocol: bool,
103) -> crate::Result<()> {
104 if !dangerous_insecure_transport_protocol {
105 for url in endpoints {
106 if url.scheme() != "https" {
107 return Err(crate::Error::InsecureTransportProtocol);
108 }
109 }
110 }
111
112 Ok(())
113}