diff options
author | mdecimus <mauro@stalw.art> | 2024-09-18 18:08:57 +0200 |
---|---|---|
committer | mdecimus <mauro@stalw.art> | 2024-09-18 18:08:57 +0200 |
commit | e9d12aea44930d5136a67fc9536d55d31d9a1ddc (patch) | |
tree | 7f6cb7fdee263ea3d2fdb0ec7eae321cc3de12b0 /crates/jmap/src | |
parent | d0303aefa8f5c0e8700326f979af17669cb8d325 (diff) |
Permissions & multi-tenancy test suite
Diffstat (limited to 'crates/jmap/src')
-rw-r--r-- | crates/jmap/src/api/http.rs | 16 | ||||
-rw-r--r-- | crates/jmap/src/api/management/mod.rs | 22 | ||||
-rw-r--r-- | crates/jmap/src/api/management/principal.rs | 32 |
3 files changed, 45 insertions, 25 deletions
diff --git a/crates/jmap/src/api/http.rs b/crates/jmap/src/api/http.rs index 8988bbd5..16ad3c39 100644 --- a/crates/jmap/src/api/http.rs +++ b/crates/jmap/src/api/http.rs @@ -818,11 +818,6 @@ impl ToHttpResponse for &trc::Error { fn into_http_response(self) -> HttpResponse { match self.as_ref() { trc::EventType::Manage(cause) => { - let details_or_reason = self - .value(trc::Key::Details) - .or_else(|| self.value(trc::Key::Reason)) - .and_then(|v| v.as_str()); - match cause { trc::ManageEvent::MissingParameter => ManagementApiError::FieldMissing { field: self.value_as_str(trc::Key::Key).unwrap_or_default(), @@ -835,11 +830,18 @@ impl ToHttpResponse for &trc::Error { item: self.value_as_str(trc::Key::Key).unwrap_or_default(), }, trc::ManageEvent::NotSupported => ManagementApiError::Unsupported { - details: details_or_reason.unwrap_or("Requested action is unsupported"), + details: self + .value(trc::Key::Details) + .or_else(|| self.value(trc::Key::Reason)) + .and_then(|v| v.as_str()) + .unwrap_or("Requested action is unsupported"), }, trc::ManageEvent::AssertFailed => ManagementApiError::AssertFailed, trc::ManageEvent::Error => ManagementApiError::Other { - details: details_or_reason.unwrap_or("An error occurred."), + reason: self.value_as_str(trc::Key::Reason), + details: self + .value_as_str(trc::Key::Details) + .unwrap_or("Unknown error"), }, } } diff --git a/crates/jmap/src/api/management/mod.rs b/crates/jmap/src/api/management/mod.rs index b88f78fa..0a3dc0c2 100644 --- a/crates/jmap/src/api/management/mod.rs +++ b/crates/jmap/src/api/management/mod.rs @@ -33,12 +33,24 @@ use crate::JMAP; #[serde(tag = "error")] #[serde(rename_all = "camelCase")] pub enum ManagementApiError<'x> { - FieldAlreadyExists { field: &'x str, value: &'x str }, - FieldMissing { field: &'x str }, - NotFound { item: &'x str }, - Unsupported { details: &'x str }, + FieldAlreadyExists { + field: &'x str, + value: &'x str, + }, + FieldMissing { + field: &'x str, + }, + NotFound { + item: &'x str, + }, + Unsupported { + details: &'x str, + }, AssertFailed, - Other { details: &'x str }, + Other { + details: &'x str, + reason: Option<&'x str>, + }, } impl JMAP { diff --git a/crates/jmap/src/api/management/principal.rs b/crates/jmap/src/api/management/principal.rs index 9302ccfe..f3944a81 100644 --- a/crates/jmap/src/api/management/principal.rs +++ b/crates/jmap/src/api/management/principal.rs @@ -85,7 +85,7 @@ impl JMAP { } // Make sure the current directory supports updates - if matches!(principal.typ(), Type::Individual | Type::Group | Type::List) { + if matches!(principal.typ(), Type::Individual) { self.assert_supported_directory()?; } @@ -315,27 +315,27 @@ impl JMAP { // Validate changes let mut needs_assert = false; - let mut is_password_change = false; + let mut expire_session = false; + let mut expire_token = false; let mut is_role_change = false; for change in &changes { match change.field { - PrincipalField::Name - | PrincipalField::Emails - | PrincipalField::MemberOf - | PrincipalField::Members - | PrincipalField::Lists => { + PrincipalField::Name | PrincipalField::Emails => { + needs_assert = true; + } + PrincipalField::Secrets => { + expire_session = true; needs_assert = true; } PrincipalField::Quota | PrincipalField::UsedQuota | PrincipalField::Description | PrincipalField::Type - | PrincipalField::Picture => (), - PrincipalField::Secrets => { - is_password_change = true; - needs_assert = true; - } + | PrincipalField::Picture + | PrincipalField::MemberOf + | PrincipalField::Members + | PrincipalField::Lists => (), PrincipalField::Tenant => { // Tenants are not allowed to change their tenantId if access_token.tenant.is_some() { @@ -353,6 +353,8 @@ impl JMAP { | PrincipalField::DisabledPermissions => { if matches!(typ, Type::Role | Type::Tenant) { is_role_change = true; + } else { + expire_token = true; } if change.field == PrincipalField::Roles { needs_assert = true; @@ -376,7 +378,7 @@ impl JMAP { ) .await?; - if is_password_change { + if expire_session { // Remove entries from cache self.inner.sessions.retain(|_, id| id.item != account_id); } @@ -390,6 +392,10 @@ impl JMAP { .fetch_add(1, Ordering::Relaxed); } + if expire_token { + self.core.security.access_tokens.remove(&account_id); + } + Ok(JsonResponse::new(json!({ "data": (), })) |