diff options
| author | David Lönnhager <david.l@mullvad.net> | 2025-03-25 10:19:40 +0100 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2025-03-25 10:37:10 +0100 |
| commit | 6b8d2c7178c8d0c3f8428ee2fad3df59c591454d (patch) | |
| tree | f1d43cd7a87692108bb0cc8b545da686e74de1f3 | |
| parent | 17318aca56f1bb9e409b5c9d8ba68e40f5a289b7 (diff) | |
| download | mullvadvpn-6b8d2c7178c8d0c3f8428ee2fad3df59c591454d.tar.xz mullvadvpn-6b8d2c7178c8d0c3f8428ee2fad3df59c591454d.zip | |
Move version client to module in mullvad-api
| -rw-r--r-- | mullvad-api/src/lib.rs | 97 | ||||
| -rw-r--r-- | mullvad-api/src/version.rs | 96 | ||||
| -rw-r--r-- | mullvad-daemon/src/version_check.rs | 37 |
3 files changed, 115 insertions, 115 deletions
diff --git a/mullvad-api/src/lib.rs b/mullvad-api/src/lib.rs index d7f4585e79..1ced489080 100644 --- a/mullvad-api/src/lib.rs +++ b/mullvad-api/src/lib.rs @@ -3,13 +3,9 @@ use async_trait::async_trait; #[cfg(target_os = "android")] use futures::channel::mpsc; use hyper::body::Incoming; +use mullvad_types::account::{AccountData, AccountNumber, VoucherSubmission}; #[cfg(target_os = "android")] use mullvad_types::account::{PlayPurchase, PlayPurchasePaymentToken}; -use mullvad_types::{ - account::{AccountData, AccountNumber, VoucherSubmission}, - version::AppVersion, -}; -use mullvad_update::version::{VersionInfo, VersionParameters}; use proxy::{ApiConnectionMode, ConnectionModeProvider}; use std::{ collections::BTreeMap, @@ -20,11 +16,12 @@ use std::{ sync::Arc, }; use talpid_types::ErrorExt; -use vec1::vec1; pub mod availability; use availability::ApiAvailability; pub mod rest; +#[cfg(not(target_os = "ios"))] +pub mod version; mod abortable_stream; pub mod access_mode; @@ -700,94 +697,6 @@ impl ProblemReportProxy { } } -#[cfg(not(target_os = "ios"))] -#[derive(Clone)] -pub struct AppVersionProxy { - handle: rest::MullvadRestHandle, -} - -#[cfg(not(target_os = "ios"))] -#[derive(serde::Deserialize, Debug)] -pub struct AppVersionResponse { - pub supported: bool, - pub latest: AppVersion, - pub latest_stable: Option<AppVersion>, - pub latest_beta: AppVersion, -} - -#[cfg(not(target_os = "ios"))] -impl AppVersionProxy { - const VERSION_PROVIDER_PUBKEY: &str = include_str!("../../mullvad-update/stagemole-pubkey"); - - pub fn new(handle: rest::MullvadRestHandle) -> Self { - Self { handle } - } - - pub fn version_check( - &self, - app_version: AppVersion, - platform: &str, - platform_version: String, - ) -> impl Future<Output = Result<AppVersionResponse, rest::Error>> + use<> { - let service = self.handle.service.clone(); - - let path = format!("{APP_URL_PREFIX}/releases/{platform}/{app_version}"); - let request = self.handle.factory.get(&path); - - async move { - let request = request? - .expected_status(&[StatusCode::OK]) - .header("M-Platform-Version", &platform_version)?; - let response = service.request(request).await?; - response.deserialize().await - } - } - - /// Get versions from `/app/releases/<platform>.json` - pub fn version_check_2( - &self, - platform: &str, - architecture: mullvad_update::format::Architecture, - rollout: f32, - lowest_metadata_version: usize, - ) -> impl Future<Output = Result<VersionInfo, rest::Error>> + use<> { - // Maximum size of version response - const SIZE_LIMIT: usize = 1024 * 1024; - - let service = self.handle.service.clone(); - let path = format!("app/releases/{platform}.json"); - let request = self.handle.factory.get(&path); - - let verifying_key = - mullvad_update::format::key::VerifyingKey::from_hex(Self::VERSION_PROVIDER_PUBKEY) - .expect("valid key"); - let verifying_keys = vec1![verifying_key]; - - async move { - let request = request?.expected_status(&[StatusCode::OK]); - let response = service.request(request).await?; - let bytes = response.body_with_max_size(SIZE_LIMIT).await?; - - let response = mullvad_update::format::SignedResponse::deserialize_and_verify( - &verifying_keys, - &bytes, - lowest_metadata_version, - ) - .map_err(|err| rest::Error::FetchVersions(Arc::new(err)))?; - - let params = VersionParameters { - architecture, - rollout, - lowest_metadata_version, - }; - - VersionInfo::try_from_response(¶ms, response.signed) - .map_err(Arc::new) - .map_err(rest::Error::FetchVersions) - } - } -} - #[derive(Clone)] pub struct ApiProxy { handle: rest::MullvadRestHandle, diff --git a/mullvad-api/src/version.rs b/mullvad-api/src/version.rs new file mode 100644 index 0000000000..26cbe1d2d3 --- /dev/null +++ b/mullvad-api/src/version.rs @@ -0,0 +1,96 @@ +use std::future::Future; +use std::sync::Arc; + +use http::StatusCode; +use mullvad_types::version::AppVersion; +use mullvad_update::version::{VersionInfo, VersionParameters}; +use vec1::vec1; + +use super::rest; +use super::APP_URL_PREFIX; + +#[derive(Clone)] +pub struct AppVersionProxy { + handle: super::rest::MullvadRestHandle, +} + +#[derive(serde::Deserialize, Debug)] +pub struct AppVersionResponse { + pub supported: bool, + pub latest: AppVersion, + pub latest_stable: Option<AppVersion>, + pub latest_beta: AppVersion, +} + +impl AppVersionProxy { + /// Public key to use for `version_check_2` response + const VERSION_PROVIDER_PUBKEY: &str = include_str!("../../mullvad-update/stagemole-pubkey"); + + /// Maximum size of `version_check_2` response + const SIZE_LIMIT: usize = 1024 * 1024; + + pub fn new(handle: rest::MullvadRestHandle) -> Self { + Self { handle } + } + + pub fn version_check( + &self, + app_version: AppVersion, + platform: &str, + platform_version: String, + ) -> impl Future<Output = Result<AppVersionResponse, rest::Error>> + use<> { + let service = self.handle.service.clone(); + + let path = format!("{APP_URL_PREFIX}/releases/{platform}/{app_version}"); + let request = self.handle.factory.get(&path); + + async move { + let request = request? + .expected_status(&[StatusCode::OK]) + .header("M-Platform-Version", &platform_version)?; + let response = service.request(request).await?; + response.deserialize().await + } + } + + /// Get versions from `/app/releases/<platform>.json` + pub fn version_check_2( + &self, + platform: &str, + architecture: mullvad_update::format::Architecture, + rollout: f32, + lowest_metadata_version: usize, + ) -> impl Future<Output = Result<VersionInfo, rest::Error>> + use<> { + let service = self.handle.service.clone(); + let path = format!("app/releases/{platform}.json"); + let request = self.handle.factory.get(&path); + + let verifying_key = + mullvad_update::format::key::VerifyingKey::from_hex(Self::VERSION_PROVIDER_PUBKEY) + .expect("valid key"); + let verifying_keys = vec1![verifying_key]; + + async move { + let request = request?.expected_status(&[StatusCode::OK]); + let response = service.request(request).await?; + let bytes = response.body_with_max_size(Self::SIZE_LIMIT).await?; + + let response = mullvad_update::format::SignedResponse::deserialize_and_verify( + &verifying_keys, + &bytes, + lowest_metadata_version, + ) + .map_err(|err| rest::Error::FetchVersions(Arc::new(err)))?; + + let params = VersionParameters { + architecture, + rollout, + lowest_metadata_version, + }; + + VersionInfo::try_from_response(¶ms, response.signed) + .map_err(Arc::new) + .map_err(rest::Error::FetchVersions) + } + } +} diff --git a/mullvad-daemon/src/version_check.rs b/mullvad-daemon/src/version_check.rs index 0539d675f1..a66dbc6903 100644 --- a/mullvad-daemon/src/version_check.rs +++ b/mullvad-daemon/src/version_check.rs @@ -4,7 +4,11 @@ use futures::{ future::{BoxFuture, FusedFuture}, FutureExt, SinkExt, StreamExt, TryFutureExt, }; -use mullvad_api::{availability::ApiAvailability, rest::MullvadRestHandle, AppVersionProxy}; +use mullvad_api::{ + availability::ApiAvailability, + rest::MullvadRestHandle, + version::{AppVersionProxy, AppVersionResponse}, +}; use mullvad_types::version::AppVersionInfo; use mullvad_version::Version; use serde::{Deserialize, Serialize}; @@ -194,11 +198,8 @@ impl VersionUpdaterInner { self.last_app_version_info.as_ref().map(|(info, _)| info) } - /// Convert a [mullvad_api::AppVersionResponse] to an [AppVersionInfo]. - fn response_to_version_info( - &self, - response: mullvad_api::AppVersionResponse, - ) -> AppVersionInfo { + /// Convert a [AppVersionResponse] to an [AppVersionInfo]. + fn response_to_version_info(&self, response: AppVersionResponse) -> AppVersionInfo { let suggested_upgrade = suggested_upgrade( &APP_VERSION, &response.latest_stable, @@ -295,12 +296,9 @@ impl VersionUpdaterInner { mut self, mut rx: mpsc::Receiver<VersionUpdaterCommand>, update: impl Fn(AppVersionInfo) -> BoxFuture<'static, Result<(), Error>>, - do_version_check: impl Fn() - -> BoxFuture<'static, Result<mullvad_api::AppVersionResponse, Error>>, - do_version_check_in_background: impl Fn() -> BoxFuture< - 'static, - Result<mullvad_api::AppVersionResponse, Error>, - >, + do_version_check: impl Fn() -> BoxFuture<'static, Result<AppVersionResponse, Error>>, + do_version_check_in_background: impl Fn() + -> BoxFuture<'static, Result<AppVersionResponse, Error>>, ) { let mut version_is_stale = self.wait_until_version_is_stale(); let mut version_check = futures::future::Fuse::terminated(); @@ -422,9 +420,7 @@ struct ApiContext { } /// Immediately query the API for the latest [AppVersionInfo]. -fn do_version_check( - api: ApiContext, -) -> BoxFuture<'static, Result<mullvad_api::AppVersionResponse, Error>> { +fn do_version_check(api: ApiContext) -> BoxFuture<'static, Result<AppVersionResponse, Error>> { let download_future_factory = move || { api.version_proxy .version_check( @@ -459,7 +455,7 @@ fn do_version_check( /// On any error, this function retries repeatedly every [UPDATE_INTERVAL_ERROR] until success. fn do_version_check_in_background( api: ApiContext, -) -> BoxFuture<'static, Result<mullvad_api::AppVersionResponse, Error>> { +) -> BoxFuture<'static, Result<AppVersionResponse, Error>> { let download_future_factory = move || { let when_available = api.api_handle.wait_background(); let request = api.version_proxy.version_check( @@ -721,12 +717,11 @@ mod test { } } - fn fake_version_check() -> BoxFuture<'static, Result<mullvad_api::AppVersionResponse, Error>> { + fn fake_version_check() -> BoxFuture<'static, Result<AppVersionResponse, Error>> { Box::pin(async { Ok(fake_version_response()) }) } - fn fake_version_check_err() -> BoxFuture<'static, Result<mullvad_api::AppVersionResponse, Error>> - { + fn fake_version_check_err() -> BoxFuture<'static, Result<AppVersionResponse, Error>> { Box::pin(retry_future( || async { Err(Error::Download(mullvad_api::rest::Error::TimeoutError)) }, |_| true, @@ -734,8 +729,8 @@ mod test { )) } - fn fake_version_response() -> mullvad_api::AppVersionResponse { - mullvad_api::AppVersionResponse { + fn fake_version_response() -> AppVersionResponse { + AppVersionResponse { supported: true, latest: "2024.1".to_owned(), latest_stable: None, |
