summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorSteffen Ernst <steffen.ernst@mullvad.net>2025-02-24 10:25:13 +0100
committerSteffen Ernst <steffen.ernst@mullvad.net>2025-02-24 10:26:51 +0100
commit9da84278bc001e189b837ab69e79f500b279f002 (patch)
tree1483f1e6ae19c212f16949046de4784039692299
parentfe84f5813e6bd8e2a3b870cd5cb8be8bc3bd2b34 (diff)
downloadmullvadvpn-mullvad-api-storekit2.tar.xz
mullvadvpn-mullvad-api-storekit2.zip
Move storekit functions into separate modulemullvad-api-storekit2
-rw-r--r--mullvad-ios/src/api_client/api.rs163
-rw-r--r--mullvad-ios/src/api_client/mod.rs1
-rw-r--r--mullvad-ios/src/api_client/storekit.rs179
3 files changed, 180 insertions, 163 deletions
diff --git a/mullvad-ios/src/api_client/api.rs b/mullvad-ios/src/api_client/api.rs
index 1758a54300..79c1a1f744 100644
--- a/mullvad-ios/src/api_client/api.rs
+++ b/mullvad-ios/src/api_client/api.rs
@@ -70,166 +70,3 @@ async fn mullvad_api_get_addresses_inner(
SwiftMullvadApiResponse::with_body(response).await
}
-
-/// # Safety
-///
-/// `api_context` must be pointing to a valid instance of `SwiftApiContext`. A `SwiftApiContext` is created
-/// by calling `mullvad_api_init_new`.
-///
-/// `completion_cookie` must be pointing to a valid instance of `CompletionCookie`. `CompletionCookie` is
-/// safe because the pointer in `MullvadApiCompletion` is valid for the lifetime of the process where this
-/// type is intended to be used.
-///
-/// `account` must be a pointer to a null terminated string to the account number
-///
-/// This function is not safe to call multiple times with the same `CompletionCookie`.
-#[no_mangle]
-pub unsafe extern "C" fn mullvad_api_init_storekit_payment(
- api_context: SwiftApiContext,
- completion_cookie: *mut libc::c_void,
- retry_strategy: SwiftRetryStrategy,
- account: *const u8,
-) -> SwiftCancelHandle {
- let completion_handler = SwiftCompletionHandler::new(CompletionCookie(completion_cookie));
-
- let Ok(tokio_handle) = crate::mullvad_ios_runtime() else {
- completion_handler.finish(SwiftMullvadApiResponse::no_tokio_runtime());
- return SwiftCancelHandle::empty();
- };
-
- let api_context = api_context.into_rust_context();
- let retry_strategy = unsafe { retry_strategy.into_rust() };
-
- let completion = completion_handler.clone();
-
- let account = unsafe { std::ffi::CStr::from_ptr(account.cast()) };
- let Ok(account) = account.to_str() else {
- completion_handler.finish(SwiftMullvadApiResponse::invalid_input(
- c"Invalid account string",
- ));
- return SwiftCancelHandle::empty();
- };
- let account = AccountNumber::from(account);
-
- let task = tokio_handle.clone().spawn(async move {
- match mullvad_api_init_storekit_payment_inner(
- api_context.rest_handle(),
- retry_strategy,
- account,
- )
- .await
- {
- Ok(response) => completion.finish(response),
- Err(err) => {
- log::error!("{err:?}");
- completion.finish(SwiftMullvadApiResponse::rest_error(err));
- }
- }
- });
-
- RequestCancelHandle::new(task, completion_handler.clone()).into_swift()
-}
-
-async fn mullvad_api_init_storekit_payment_inner(
- rest_client: MullvadRestHandle,
- retry_strategy: RetryStrategy,
- account: AccountNumber,
-) -> Result<SwiftMullvadApiResponse, rest::Error> {
- let account_proxy = AccountsProxy::new(rest_client);
-
- let future_factory = || account_proxy.init_storekit_payment(account.clone());
-
- let should_retry = |result: &Result<_, rest::Error>| match result {
- Err(err) => err.is_network_error(),
- Ok(_) => false,
- };
-
- let response = retry_future(future_factory, should_retry, retry_strategy.delays()).await?;
-
- SwiftMullvadApiResponse::with_body(response).await
-}
-
-/// # Safety
-///
-/// `api_context` must be pointing to a valid instance of `SwiftApiContext`. A `SwiftApiContext` is created
-/// by calling `mullvad_api_init_new`.
-///
-/// `completion_cookie` must be pointing to a valid instance of `CompletionCookie`. `CompletionCookie` is
-/// safe because the pointer in `MullvadApiCompletion` is valid for the lifetime of the process where this
-/// type is intended to be used.
-///
-/// `account` must be a pointer to a null terminated string to the account number
-///
-/// `transaction` must be a pointer to a null terminated string to the jws representation of the transaction
-///
-/// This function is not safe to call multiple times with the same `CompletionCookie`.
-#[no_mangle]
-pub unsafe extern "C" fn mullvad_api_check_storekit_payment(
- api_context: SwiftApiContext,
- completion_cookie: *mut libc::c_void,
- retry_strategy: SwiftRetryStrategy,
- account: *const u8,
- body: *const u8,
- body_size: usize,
-) -> SwiftCancelHandle {
- let completion_handler = SwiftCompletionHandler::new(CompletionCookie(completion_cookie));
-
- let Ok(tokio_handle) = crate::mullvad_ios_runtime() else {
- completion_handler.finish(SwiftMullvadApiResponse::no_tokio_runtime());
- return SwiftCancelHandle::empty();
- };
-
- let api_context = api_context.into_rust_context();
- let retry_strategy = unsafe { retry_strategy.into_rust() };
-
- let completion = completion_handler.clone();
-
- let account = unsafe { std::ffi::CStr::from_ptr(account.cast()) };
- let Ok(account) = account.to_str() else {
- completion_handler.finish(SwiftMullvadApiResponse::invalid_input(
- c"Invalid account string",
- ));
- return SwiftCancelHandle::empty();
- };
- let account = AccountNumber::from(account);
-
- let body = unsafe { std::slice::from_raw_parts(body, body_size) }.to_vec();
- let task = tokio_handle.clone().spawn(async move {
- match mullvad_api_check_storekit_payment_inner(
- api_context.rest_handle(),
- retry_strategy,
- account,
- body,
- )
- .await
- {
- Ok(response) => completion.finish(response),
- Err(err) => {
- log::error!("{err:?}");
- completion.finish(SwiftMullvadApiResponse::rest_error(err));
- }
- }
- });
-
- RequestCancelHandle::new(task, completion_handler.clone()).into_swift()
-}
-
-async fn mullvad_api_check_storekit_payment_inner(
- rest_client: MullvadRestHandle,
- retry_strategy: RetryStrategy,
- account: AccountNumber,
- body: Vec<u8>,
-) -> Result<SwiftMullvadApiResponse, rest::Error> {
- let account_proxy = AccountsProxy::new(rest_client);
-
- let future_factory = || account_proxy.check_storekit_payment(account.clone(), body.clone());
-
- let should_retry = |result: &Result<_, rest::Error>| match result {
- Err(err) => err.is_network_error(),
- Ok(_) => false,
- };
-
- let response = retry_future(future_factory, should_retry, retry_strategy.delays()).await?;
-
- SwiftMullvadApiResponse::with_body(response).await
-}
diff --git a/mullvad-ios/src/api_client/mod.rs b/mullvad-ios/src/api_client/mod.rs
index 98443fd0d9..7314af2fe1 100644
--- a/mullvad-ios/src/api_client/mod.rs
+++ b/mullvad-ios/src/api_client/mod.rs
@@ -11,6 +11,7 @@ mod cancellation;
mod completion;
mod response;
mod retry_strategy;
+mod storekit;
#[repr(C)]
pub struct SwiftApiContext(*const ApiContext);
diff --git a/mullvad-ios/src/api_client/storekit.rs b/mullvad-ios/src/api_client/storekit.rs
new file mode 100644
index 0000000000..9e91ed0398
--- /dev/null
+++ b/mullvad-ios/src/api_client/storekit.rs
@@ -0,0 +1,179 @@
+use mullvad_api::{
+ rest::{self, MullvadRestHandle},
+ AccountsProxy,
+};
+use mullvad_types::account::AccountNumber;
+use talpid_future::retry::retry_future;
+
+use super::{
+ cancellation::{RequestCancelHandle, SwiftCancelHandle},
+ completion::{CompletionCookie, SwiftCompletionHandler},
+ response::SwiftMullvadApiResponse,
+ retry_strategy::{RetryStrategy, SwiftRetryStrategy},
+ SwiftApiContext,
+};
+
+/// # Safety
+///
+/// `api_context` must be pointing to a valid instance of `SwiftApiContext`. A `SwiftApiContext` is created
+/// by calling `mullvad_api_init_new`.
+///
+/// `completion_cookie` must be pointing to a valid instance of `CompletionCookie`. `CompletionCookie` is
+/// safe because the pointer in `MullvadApiCompletion` is valid for the lifetime of the process where this
+/// type is intended to be used.
+///
+/// `account` must be a pointer to a null terminated string to the account number
+///
+/// This function is not safe to call multiple times with the same `CompletionCookie`.
+#[no_mangle]
+pub unsafe extern "C" fn mullvad_api_init_storekit_payment(
+ api_context: SwiftApiContext,
+ completion_cookie: *mut libc::c_void,
+ retry_strategy: SwiftRetryStrategy,
+ account: *const u8,
+) -> SwiftCancelHandle {
+ let completion_handler = SwiftCompletionHandler::new(CompletionCookie(completion_cookie));
+
+ let Ok(tokio_handle) = crate::mullvad_ios_runtime() else {
+ completion_handler.finish(SwiftMullvadApiResponse::no_tokio_runtime());
+ return SwiftCancelHandle::empty();
+ };
+
+ let api_context = api_context.into_rust_context();
+ let retry_strategy = unsafe { retry_strategy.into_rust() };
+
+ let completion = completion_handler.clone();
+
+ let account = unsafe { std::ffi::CStr::from_ptr(account.cast()) };
+ let Ok(account) = account.to_str() else {
+ completion_handler.finish(SwiftMullvadApiResponse::invalid_input(
+ c"Invalid account string",
+ ));
+ return SwiftCancelHandle::empty();
+ };
+ let account = AccountNumber::from(account);
+
+ let task = tokio_handle.clone().spawn(async move {
+ match mullvad_api_init_storekit_payment_inner(
+ api_context.rest_handle(),
+ retry_strategy,
+ account,
+ )
+ .await
+ {
+ Ok(response) => completion.finish(response),
+ Err(err) => {
+ log::error!("{err:?}");
+ completion.finish(SwiftMullvadApiResponse::rest_error(err));
+ }
+ }
+ });
+
+ RequestCancelHandle::new(task, completion_handler.clone()).into_swift()
+}
+
+async fn mullvad_api_init_storekit_payment_inner(
+ rest_client: MullvadRestHandle,
+ retry_strategy: RetryStrategy,
+ account: AccountNumber,
+) -> Result<SwiftMullvadApiResponse, rest::Error> {
+ let account_proxy = AccountsProxy::new(rest_client);
+
+ let future_factory = || account_proxy.init_storekit_payment(account.clone());
+
+ let should_retry = |result: &Result<_, rest::Error>| match result {
+ Err(err) => err.is_network_error(),
+ Ok(_) => false,
+ };
+
+ let response = retry_future(future_factory, should_retry, retry_strategy.delays()).await?;
+
+ SwiftMullvadApiResponse::with_body(response).await
+}
+
+/// # Safety
+///
+/// `api_context` must be pointing to a valid instance of `SwiftApiContext`. A `SwiftApiContext` is created
+/// by calling `mullvad_api_init_new`.
+///
+/// `completion_cookie` must be pointing to a valid instance of `CompletionCookie`. `CompletionCookie` is
+/// safe because the pointer in `MullvadApiCompletion` is valid for the lifetime of the process where this
+/// type is intended to be used.
+///
+/// `account` must be a pointer to a null terminated string to the account number
+///
+/// `body` must be a pointer to the body content
+///
+/// `body_size` must be the size of the body
+///
+/// This function is not safe to call multiple times with the same `CompletionCookie`.
+#[no_mangle]
+pub unsafe extern "C" fn mullvad_api_check_storekit_payment(
+ api_context: SwiftApiContext,
+ completion_cookie: *mut libc::c_void,
+ retry_strategy: SwiftRetryStrategy,
+ account: *const u8,
+ body: *const u8,
+ body_size: usize,
+) -> SwiftCancelHandle {
+ let completion_handler = SwiftCompletionHandler::new(CompletionCookie(completion_cookie));
+
+ let Ok(tokio_handle) = crate::mullvad_ios_runtime() else {
+ completion_handler.finish(SwiftMullvadApiResponse::no_tokio_runtime());
+ return SwiftCancelHandle::empty();
+ };
+
+ let api_context = api_context.into_rust_context();
+ let retry_strategy = unsafe { retry_strategy.into_rust() };
+
+ let completion = completion_handler.clone();
+
+ let account = unsafe { std::ffi::CStr::from_ptr(account.cast()) };
+ let Ok(account) = account.to_str() else {
+ completion_handler.finish(SwiftMullvadApiResponse::invalid_input(
+ c"Invalid account string",
+ ));
+ return SwiftCancelHandle::empty();
+ };
+ let account = AccountNumber::from(account);
+
+ let body = unsafe { std::slice::from_raw_parts(body, body_size) }.to_vec();
+ let task = tokio_handle.clone().spawn(async move {
+ match mullvad_api_check_storekit_payment_inner(
+ api_context.rest_handle(),
+ retry_strategy,
+ account,
+ body,
+ )
+ .await
+ {
+ Ok(response) => completion.finish(response),
+ Err(err) => {
+ log::error!("{err:?}");
+ completion.finish(SwiftMullvadApiResponse::rest_error(err));
+ }
+ }
+ });
+
+ RequestCancelHandle::new(task, completion_handler.clone()).into_swift()
+}
+
+async fn mullvad_api_check_storekit_payment_inner(
+ rest_client: MullvadRestHandle,
+ retry_strategy: RetryStrategy,
+ account: AccountNumber,
+ body: Vec<u8>,
+) -> Result<SwiftMullvadApiResponse, rest::Error> {
+ let account_proxy = AccountsProxy::new(rest_client);
+
+ let future_factory = || account_proxy.check_storekit_payment(account.clone(), body.clone());
+
+ let should_retry = |result: &Result<_, rest::Error>| match result {
+ Err(err) => err.is_network_error(),
+ Ok(_) => false,
+ };
+
+ let response = retry_future(future_factory, should_retry, retry_strategy.delays()).await?;
+
+ SwiftMullvadApiResponse::with_body(response).await
+}