Registry JMAP API

This commit is contained in:
mdecimus
2026-02-15 19:48:51 +00:00
parent 726e8d9c79
commit 72db209d66
52 changed files with 1786 additions and 576 deletions

View File

@@ -5,11 +5,11 @@
*/
use common::auth::AccessToken;
use registry::schema::enums::Permission;
use jmap_proto::request::{
CopyRequestMethod, GetRequestMethod, ParseRequestMethod, QueryChangesRequestMethod,
QueryRequestMethod, RequestMethod, SetRequestMethod, method::MethodObject,
};
use registry::schema::enums::Permission;
use types::{collection::Collection, id::Id};
pub trait JmapAuthorization {
@@ -80,6 +80,10 @@ impl JmapAuthorization for AccessToken {
}
GetRequestMethod::ParticipantIdentity(_) => Permission::JmapParticipantIdentityGet,
GetRequestMethod::ShareNotification(_) => Permission::JmapShareNotificationGet,
GetRequestMethod::Registry(request) => {
let todo = "map registry objects to permissions";
Permission::JmapEmailGet
}
},
RequestMethod::Set(m) => match &m {
SetRequestMethod::Email(_) => Permission::JmapEmailSet,
@@ -99,6 +103,10 @@ impl JmapAuthorization for AccessToken {
Permission::JmapCalendarEventNotificationSet
}
SetRequestMethod::ParticipantIdentity(_) => Permission::JmapParticipantIdentitySet,
SetRequestMethod::Registry(other) => {
let todo = "map registry objects to permissions";
Permission::JmapEmailSet
}
},
RequestMethod::Changes(_) => match object {
MethodObject::Email => Permission::JmapEmailChanges,
@@ -123,7 +131,8 @@ impl JmapAuthorization for AccessToken {
| MethodObject::SearchSnippet
| MethodObject::VacationResponse
| MethodObject::SieveScript
| MethodObject::AddressBook => Permission::JmapEmailChanges,
| MethodObject::AddressBook
| MethodObject::Registry(_) => Permission::JmapEmailChanges,
},
RequestMethod::Copy(m) => match &m {
CopyRequestMethod::Email(_) => Permission::JmapEmailCopy,
@@ -174,6 +183,10 @@ impl JmapAuthorization for AccessToken {
Permission::JmapCalendarEventNotificationQuery
}
QueryRequestMethod::ShareNotification(_) => Permission::JmapShareNotificationQuery,
QueryRequestMethod::Registry(other) => {
let todo = "map registry objects to permissions";
Permission::JmapShareNotificationQuery
}
},
RequestMethod::SearchSnippet(_) => Permission::JmapSearchSnippet,
RequestMethod::ValidateScript(_) => Permission::JmapSieveScriptValidate,

View File

@@ -33,6 +33,7 @@ use crate::{
principal::{availability::PrincipalGetAvailability, get::PrincipalGet, query::PrincipalQuery},
push::{get::PushSubscriptionFetch, set::PushSubscriptionSet},
quota::{get::QuotaGet, query::QuotaQuery},
registry::{get::RegistryGet, query::RegistryQuery, set::RegistrySet},
share_notification::{
get::ShareNotificationGet, query::ShareNotificationQuery, set::ShareNotificationSet,
},
@@ -165,6 +166,9 @@ impl RequestHandler for Server {
set_response.update_created_ids(&mut response);
}
SetResponseMethod::CalendarEventNotification(_) => {}
SetResponseMethod::Registry(set_response) => {
set_response.update_created_ids(&mut response);
}
}
}
ResponseMethod::ImportEmail(import_response) => {
@@ -343,6 +347,12 @@ impl RequestHandler for Server {
self.share_notification_get(req).await?.into()
}
GetRequestMethod::Registry(mut req) => {
set_account_id_if_missing(&mut req.account_id, access_token);
access_token.assert_is_member(req.account_id)?;
self.registry_get(req, access_token).await?.into()
}
},
RequestMethod::Query(req) => match req {
QueryRequestMethod::Email(mut req) => {
@@ -410,6 +420,12 @@ impl RequestHandler for Server {
self.share_notification_query(req).await?.into()
}
QueryRequestMethod::Registry(mut req) => {
set_account_id_if_missing(&mut req.account_id, access_token);
access_token.assert_is_member(req.account_id)?;
self.registry_query(req, access_token).await?.into()
}
},
RequestMethod::Set(req) => match req {
SetRequestMethod::Email(mut req) => {
@@ -512,6 +528,12 @@ impl RequestHandler for Server {
self.participant_identity_set(req).await?.into()
}
SetRequestMethod::Registry(mut req) => {
set_account_id_if_missing(&mut req.account_id, access_token);
access_token.assert_is_member(req.account_id)?;
self.registry_set(req, access_token).await?.into()
}
},
RequestMethod::Changes(mut req) => {
set_account_id_if_missing(&mut req.account_id, access_token);

View File

@@ -329,7 +329,8 @@ impl IntermediateChangesResponse {
| MethodObject::VacationResponse
| MethodObject::SieveScript
| MethodObject::Principal
| MethodObject::Quota => unreachable!(),
| MethodObject::Quota
| MethodObject::Registry(_) => unreachable!(),
})
}
}

View File

@@ -22,6 +22,7 @@ pub mod participant_identity;
pub mod principal;
pub mod push;
pub mod quota;
pub mod registry;
pub mod share_notification;
pub mod sieve;
pub mod submission;

View File

@@ -0,0 +1,29 @@
/*
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <hello@stalw.art>
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
*/
use common::{Server, auth::AccessToken};
use jmap_proto::{
method::get::{GetRequest, GetResponse},
object::registry::Registry,
};
pub trait RegistryGet: Sync + Send {
fn registry_get(
&self,
request: GetRequest<Registry>,
access_token: &AccessToken,
) -> impl Future<Output = trc::Result<GetResponse<Registry>>> + Send;
}
impl RegistryGet for Server {
async fn registry_get(
&self,
mut request: GetRequest<Registry>,
access_token: &AccessToken,
) -> trc::Result<GetResponse<Registry>> {
todo!()
}
}

View File

@@ -0,0 +1,9 @@
/*
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <hello@stalw.art>
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
*/
pub mod get;
pub mod query;
pub mod set;

View File

@@ -0,0 +1,29 @@
/*
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <hello@stalw.art>
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
*/
use common::{Server, auth::AccessToken};
use jmap_proto::{
method::query::{QueryRequest, QueryResponse},
object::registry::Registry,
};
pub trait RegistryQuery: Sync + Send {
fn registry_query(
&self,
request: QueryRequest<Registry>,
access_token: &AccessToken,
) -> impl Future<Output = trc::Result<QueryResponse>> + Send;
}
impl RegistryQuery for Server {
async fn registry_query(
&self,
mut request: QueryRequest<Registry>,
access_token: &AccessToken,
) -> trc::Result<QueryResponse> {
todo!()
}
}

View File

@@ -0,0 +1,29 @@
/*
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <hello@stalw.art>
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
*/
use common::{Server, auth::AccessToken};
use jmap_proto::{
method::set::{SetRequest, SetResponse},
object::registry::Registry,
};
pub trait RegistrySet: Sync + Send {
fn registry_set(
&self,
request: SetRequest<'_, Registry>,
access_token: &AccessToken,
) -> impl Future<Output = trc::Result<SetResponse<Registry>>> + Send;
}
impl RegistrySet for Server {
async fn registry_set(
&self,
mut request: SetRequest<'_, Registry>,
access_token: &AccessToken,
) -> trc::Result<SetResponse<Registry>> {
todo!()
}
}