Skip to content

Commit cf767c6

Browse files
amrbashirgezihuzi
authored andcommitted
feat(updater)!: add option to use insecure transport protocol (tauri-apps#1814)
1 parent c5e693a commit cf767c6

File tree

5 files changed

+68
-28
lines changed

5 files changed

+68
-28
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"updater": patch
3+
---
4+
5+
**Breaking change**, Changed `UpdaterBuilder::endpoints` method to return a `Result`.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"updater": patch
3+
---
4+
5+
Add `dangerousInsecureTransportProtocol` config option to allow using insecure transport protocols, like `http`

plugins/updater/src/config.rs

Lines changed: 47 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -91,47 +91,69 @@ where
9191
}
9292

9393
/// Updater configuration.
94-
#[derive(Debug, Clone, Deserialize, Default)]
95-
#[serde(rename_all = "camelCase")]
94+
#[derive(Debug, Clone, Default)]
9695
pub struct Config {
96+
/// Dangerously allow using insecure transport protocols for update endpoints.
97+
pub dangerous_insecure_transport_protocol: bool,
9798
/// Updater endpoints.
98-
#[serde(default)]
99-
pub endpoints: Vec<UpdaterEndpoint>,
99+
pub endpoints: Vec<Url>,
100100
/// Signature public key.
101101
pub pubkey: String,
102102
/// The Windows configuration for the updater.
103103
pub windows: Option<WindowsConfig>,
104104
}
105105

106-
/// A URL to an updater server.
107-
///
108-
/// The URL must use the `https` scheme on production.
109-
#[derive(Debug, PartialEq, Eq, Clone)]
110-
pub struct UpdaterEndpoint(pub Url);
111-
112-
impl std::fmt::Display for UpdaterEndpoint {
113-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
114-
write!(f, "{}", self.0)
115-
}
116-
}
117-
118-
impl<'de> Deserialize<'de> for UpdaterEndpoint {
106+
impl<'de> Deserialize<'de> for Config {
119107
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
120108
where
121109
D: Deserializer<'de>,
122110
{
123-
let url = Url::deserialize(deserializer)?;
111+
#[derive(Deserialize)]
112+
#[serde(rename_all = "camelCase")]
113+
pub struct Config {
114+
#[serde(default, alias = "dangerous-insecure-transport-protocol")]
115+
pub dangerous_insecure_transport_protocol: bool,
116+
#[serde(default)]
117+
pub endpoints: Vec<Url>,
118+
pub pubkey: String,
119+
pub windows: Option<WindowsConfig>,
120+
}
121+
122+
let config = Config::deserialize(deserializer)?;
124123

125-
if url.scheme() != "https" {
124+
validate_endpoints(
125+
&config.endpoints,
126+
config.dangerous_insecure_transport_protocol,
127+
)
128+
.map_err(serde::de::Error::custom)?;
129+
130+
Ok(Self {
131+
dangerous_insecure_transport_protocol: config.dangerous_insecure_transport_protocol,
132+
endpoints: config.endpoints,
133+
pubkey: config.pubkey,
134+
windows: config.windows,
135+
})
136+
}
137+
}
138+
139+
pub(crate) fn validate_endpoints(
140+
endpoints: &[Url],
141+
dangerous_insecure_transport_protocol: bool,
142+
) -> crate::Result<()> {
143+
if !dangerous_insecure_transport_protocol {
144+
for url in endpoints {
145+
#[cfg(debug_assertions)]
126146
#[cfg(debug_assertions)]
127-
eprintln!("[\x1b[33mWARNING\x1b[0m] The configured updater endpoint doesn't use `https` protocol. This is allowed in development but will fail in release builds.");
147+
eprintln!("[\x1b[33mWARNING\x1b[0m] The updater endpoint \"{url}\" doesn't use `https` protocol. This is allowed in development but will fail in release builds.");
148+
#[cfg(debug_assertions)]
149+
eprintln!("[\x1b[33mWARNING\x1b[0m] if this is a desired behavior, you can enable `dangerousInsecureTransportProtocol` in the plugin configuration");
128150

129151
#[cfg(not(debug_assertions))]
130-
return Err(serde::de::Error::custom(
131-
"The configured updater endpoint must use the `https` protocol.",
132-
));
152+
if url.scheme() != "https" {
153+
return Err(crate::Error::InsecureTransportProtocol);
154+
}
133155
}
134-
135-
Ok(Self(url))
136156
}
157+
158+
Ok(())
137159
}

plugins/updater/src/error.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ pub enum Error {
7171
InvalidHeaderValue(#[from] http::header::InvalidHeaderValue),
7272
#[error(transparent)]
7373
InvalidHeaderName(#[from] http::header::InvalidHeaderName),
74+
/// The configured updater endpoint must use a secure protocol like `https`
75+
#[error("The configured updater endpoint must use a secure protocol like `https`.")]
76+
InsecureTransportProtocol,
7477
#[error(transparent)]
7578
Tauri(#[from] tauri::Error),
7679
}

plugins/updater/src/updater.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,14 @@ impl UpdaterBuilder {
148148
self
149149
}
150150

151-
pub fn endpoints(mut self, endpoints: Vec<Url>) -> Self {
151+
pub fn endpoints(mut self, endpoints: Vec<Url>) -> Result<Self> {
152+
crate::config::validate_endpoints(
153+
&endpoints,
154+
self.config.dangerous_insecure_transport_protocol,
155+
)?;
156+
152157
self.endpoints.replace(endpoints);
153-
self
158+
Ok(self)
154159
}
155160

156161
pub fn executable_path<P: AsRef<Path>>(mut self, p: P) -> Self {
@@ -219,7 +224,7 @@ impl UpdaterBuilder {
219224
pub fn build(self) -> Result<Updater> {
220225
let endpoints = self
221226
.endpoints
222-
.unwrap_or_else(|| self.config.endpoints.iter().map(|e| e.0.clone()).collect());
227+
.unwrap_or_else(|| self.config.endpoints.clone());
223228

224229
if endpoints.is_empty() {
225230
return Err(Error::EmptyEndpoints);

0 commit comments

Comments
 (0)