Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions wp_api/src/api_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,20 @@ pub enum WpApiError {
},
}

impl WpApiError {
pub fn status_code(&self) -> Option<u16> {
match self {
WpApiError::InvalidHttpStatusCode { status_code }
| WpApiError::UnknownError { status_code, .. }
| WpApiError::WpError { status_code, .. } => Some(*status_code),
WpApiError::RequestExecutionFailed { status_code, .. } => *status_code,
WpApiError::MediaFileNotFound { .. }
| WpApiError::ResponseParsingError { .. }
| WpApiError::SiteUrlParsingError { .. } => None,
}
}
}

impl MaybeWpError for WpApiError {
fn wp_error_code(&self) -> Option<&WpErrorCode> {
match self {
Expand Down
6 changes: 5 additions & 1 deletion wp_api/src/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::{
use base64::Engine;
use chrono::{DateTime, Utc};
use endpoint::{
ApiEndpointUrl, ApiUrlResolver,
ApiEndpointUrl, ApiUrlResolver, AsNamespace, WpNamespace,
application_passwords_endpoint::{
ApplicationPasswordsRequestBuilder,
ApplicationPasswordsRequestRetrieveCurrentWithEditContextResponse,
Expand Down Expand Up @@ -943,6 +943,10 @@ pub async fn fetch_authentication_state(
api_url_resolver: Arc<dyn ApiUrlResolver>,
authentication_provider: Arc<WpAuthenticationProvider>,
) -> Result<AuthenticationState, WpApiError> {
if !api_url_resolver.can_resolve(WpNamespace::WpV2.namespace_value().to_string()) {
return Ok(AuthenticationState::Unauthorized);
}

let request =
ApplicationPasswordsRequestBuilder::new(api_url_resolver, authentication_provider)
.retrieve_current_with_edit_context()
Expand Down
6 changes: 6 additions & 0 deletions wp_api/src/request/endpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ impl AsNamespace for WpNamespace {

#[uniffi::export(with_foreign)]
pub trait ApiUrlResolver: Send + Sync {
fn can_resolve(&self, namespace: String) -> bool;

fn resolve(&self, namespace: String, endpoint_segments: Vec<String>) -> Arc<ParsedUrl>;
}

Expand All @@ -140,6 +142,10 @@ impl WpOrgSiteApiUrlResolver {

#[uniffi::export]
impl ApiUrlResolver for WpOrgSiteApiUrlResolver {
fn can_resolve(&self, _namespace: String) -> bool {
true
}

fn resolve(&self, namespace: String, endpoint_segments: Vec<String>) -> Arc<ParsedUrl> {
Arc::new(
self.api_root_url
Expand Down
34 changes: 18 additions & 16 deletions wp_api/src/wp_com/endpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,17 @@ impl WpComDotOrgApiUrlResolver {

#[uniffi::export]
impl ApiUrlResolver for WpComDotOrgApiUrlResolver {
fn can_resolve(&self, namespace: String) -> bool {
WpNamespace::iter().any(|n| n.namespace_value() == namespace)
}

fn resolve(&self, namespace: String, endpoint_segments: Vec<String>) -> Arc<ParsedUrl> {
{
if !WpNamespace::iter().any(|n| n.namespace_value() == namespace) {
panic!(
"`WpComDotOrgApiUrlResolver` doesn't support the namespace `{}`. The supported namespaces are: {:?}",
namespace,
WpNamespace::iter()
);
}
}
assert!(
self.can_resolve(namespace.clone()),
"`WpComDotOrgApiUrlResolver` doesn't support the namespace `{}`. The supported namespaces are: {:?}",
namespace,
WpNamespace::iter()
);

// The API root endpoint needs special handling for WordPress.com
if namespace == WpNamespace::None.namespace_value() && endpoint_segments.is_empty() {
Expand Down Expand Up @@ -91,14 +92,15 @@ impl Default for WpComApiClientInternalUrlResolver {
}

impl ApiUrlResolver for WpComApiClientInternalUrlResolver {
fn can_resolve(&self, namespace: String) -> bool {
!WpNamespace::iter().any(|n| n.namespace_value() == namespace)
}

fn resolve(&self, namespace: String, endpoint_segments: Vec<String>) -> Arc<ParsedUrl> {
{
if WpNamespace::iter().any(|n| n.namespace_value() == namespace) {
panic!(
"`WpComApiClient` doesn't support the namespace `{namespace}`. Try using `WpApiClient` instead.",
);
}
}
assert!(
self.can_resolve(namespace.clone()),
"`WpComApiClient` doesn't support the namespace `{namespace}`. Try using `WpApiClient` instead.",
);
Arc::new(
self.base_url
.by_extending_and_splitting_by_forward_slash(
Expand Down
12 changes: 12 additions & 0 deletions wp_api_integration_tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,18 @@ pub fn wp_com_client() -> WpComApiClient {
})
}

pub fn wp_com_client_with_invalid_token() -> WpComApiClient {
WpComApiClient::new(WpApiClientDelegate {
auth_provider: WpAuthenticationProvider::static_with_auth(WpAuthentication::Bearer {
token: "invalid_token".to_string(),
})
.into(),
request_executor: Arc::new(ReqwestRequestExecutor::default()),
middleware_pipeline: Arc::new(WpApiMiddlewarePipeline::default()),
app_notifier: Arc::new(EmptyAppNotifier),
})
}

pub fn api_client_backed_by_wp_com(site_id: String) -> WpApiClient {
WpApiClient::new(
Arc::new(WpComDotOrgApiUrlResolver::new(
Expand Down
31 changes: 31 additions & 0 deletions wp_api_integration_tests/tests/test_wp_com_immut.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use serial_test::parallel;
use wp_api_integration_tests::wp_com_client_with_invalid_token;

#[tokio::test]
#[parallel]
async fn use_invalid_token_get_me() {
let client = wp_com_client_with_invalid_token();
let result = client.me().get().await;
let err = result.unwrap_err();
let status_code = err.status_code().unwrap();
assert!(
(400..500).contains(&status_code),
"Expected status code in 4xx range, got: {status_code}"
);
}

#[tokio::test]
#[parallel]
async fn use_invalid_token_get_support_conversation_list() {
let client = wp_com_client_with_invalid_token();
let result = client
.support_tickets()
.get_support_conversation_list()
.await;
let err = result.unwrap_err();
let status_code = err.status_code().unwrap();
assert!(
(400..500).contains(&status_code),
"Expected status code in 4xx range, got: {status_code}"
);
}