Skip to content

Commit

Permalink
feat(updater)!: add option to use insecure transport protocol (#1814)
Browse files Browse the repository at this point in the history
  • Loading branch information
amrbashir authored Sep 24, 2024
1 parent e564e2a commit 04a0aea
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 28 deletions.
5 changes: 5 additions & 0 deletions .changes/updater-endpoints-result.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"updater": patch
---

**Breaking change**, Changed `UpdaterBuilder::endpoints` method to return a `Result`.
5 changes: 5 additions & 0 deletions .changes/updater-insecure-transport-protocol.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"updater": patch
---

Add `dangerousInsecureTransportProtocol` config option to allow using insecure transport protocols, like `http`
72 changes: 47 additions & 25 deletions plugins/updater/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,47 +91,69 @@ where
}

/// Updater configuration.
#[derive(Debug, Clone, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
#[derive(Debug, Clone, Default)]
pub struct Config {
/// Dangerously allow using insecure transport protocols for update endpoints.
pub dangerous_insecure_transport_protocol: bool,
/// Updater endpoints.
#[serde(default)]
pub endpoints: Vec<UpdaterEndpoint>,
pub endpoints: Vec<Url>,
/// Signature public key.
pub pubkey: String,
/// The Windows configuration for the updater.
pub windows: Option<WindowsConfig>,
}

/// A URL to an updater server.
///
/// The URL must use the `https` scheme on production.
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct UpdaterEndpoint(pub Url);

impl std::fmt::Display for UpdaterEndpoint {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}

impl<'de> Deserialize<'de> for UpdaterEndpoint {
impl<'de> Deserialize<'de> for Config {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let url = Url::deserialize(deserializer)?;
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Config {
#[serde(default, alias = "dangerous-insecure-transport-protocol")]
pub dangerous_insecure_transport_protocol: bool,
#[serde(default)]
pub endpoints: Vec<Url>,
pub pubkey: String,
pub windows: Option<WindowsConfig>,
}

let config = Config::deserialize(deserializer)?;

if url.scheme() != "https" {
validate_endpoints(
&config.endpoints,
config.dangerous_insecure_transport_protocol,
)
.map_err(serde::de::Error::custom)?;

Ok(Self {
dangerous_insecure_transport_protocol: config.dangerous_insecure_transport_protocol,
endpoints: config.endpoints,
pubkey: config.pubkey,
windows: config.windows,
})
}
}

pub(crate) fn validate_endpoints(
endpoints: &[Url],
dangerous_insecure_transport_protocol: bool,
) -> crate::Result<()> {
if !dangerous_insecure_transport_protocol {
for url in endpoints {
#[cfg(debug_assertions)]
#[cfg(debug_assertions)]
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.");
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.");
#[cfg(debug_assertions)]
eprintln!("[\x1b[33mWARNING\x1b[0m] if this is a desired behavior, you can enable `dangerousInsecureTransportProtocol` in the plugin configuration");

#[cfg(not(debug_assertions))]
return Err(serde::de::Error::custom(
"The configured updater endpoint must use the `https` protocol.",
));
if url.scheme() != "https" {
return Err(crate::Error::InsecureTransportProtocol);
}
}

Ok(Self(url))
}

Ok(())
}
3 changes: 3 additions & 0 deletions plugins/updater/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ pub enum Error {
InvalidHeaderValue(#[from] http::header::InvalidHeaderValue),
#[error(transparent)]
InvalidHeaderName(#[from] http::header::InvalidHeaderName),
/// The configured updater endpoint must use a secure protocol like `https`
#[error("The configured updater endpoint must use a secure protocol like `https`.")]
InsecureTransportProtocol,
#[error(transparent)]
Tauri(#[from] tauri::Error),
}
Expand Down
11 changes: 8 additions & 3 deletions plugins/updater/src/updater.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,14 @@ impl UpdaterBuilder {
self
}

pub fn endpoints(mut self, endpoints: Vec<Url>) -> Self {
pub fn endpoints(mut self, endpoints: Vec<Url>) -> Result<Self> {
crate::config::validate_endpoints(
&endpoints,
self.config.dangerous_insecure_transport_protocol,
)?;

self.endpoints.replace(endpoints);
self
Ok(self)
}

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

if endpoints.is_empty() {
return Err(Error::EmptyEndpoints);
Expand Down

0 comments on commit 04a0aea

Please sign in to comment.