Mailbox ACLs
parent
c085cf5c89
commit
8b7cfda3d7
|
@ -30,7 +30,7 @@ pub enum Credentials {
|
||||||
pub struct Client {
|
pub struct Client {
|
||||||
session: Session,
|
session: Session,
|
||||||
session_url: String,
|
session_url: String,
|
||||||
session_outdated: AtomicBool,
|
session_updated: AtomicBool,
|
||||||
#[cfg(feature = "websockets")]
|
#[cfg(feature = "websockets")]
|
||||||
pub(crate) authorization: String,
|
pub(crate) authorization: String,
|
||||||
upload_url: Vec<URLPart<blob::URLParameter>>,
|
upload_url: Vec<URLPart<blob::URLParameter>>,
|
||||||
|
@ -91,7 +91,7 @@ impl Client {
|
||||||
event_source_url: URLPart::parse(session.event_source_url())?,
|
event_source_url: URLPart::parse(session.event_source_url())?,
|
||||||
session,
|
session,
|
||||||
session_url: url.to_string(),
|
session_url: url.to_string(),
|
||||||
session_outdated: false.into(),
|
session_updated: true.into(),
|
||||||
#[cfg(feature = "websockets")]
|
#[cfg(feature = "websockets")]
|
||||||
authorization,
|
authorization,
|
||||||
timeout: DEFAULT_TIMEOUT_MS,
|
timeout: DEFAULT_TIMEOUT_MS,
|
||||||
|
@ -147,7 +147,7 @@ impl Client {
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
if response.session_state() != self.session.state() {
|
if response.session_state() != self.session.state() {
|
||||||
self.session_outdated.store(true, Ordering::Relaxed);
|
self.session_updated.store(false, Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(response)
|
Ok(response)
|
||||||
|
@ -172,12 +172,12 @@ impl Client {
|
||||||
self.upload_url = URLPart::parse(session.upload_url())?;
|
self.upload_url = URLPart::parse(session.upload_url())?;
|
||||||
self.event_source_url = URLPart::parse(session.event_source_url())?;
|
self.event_source_url = URLPart::parse(session.event_source_url())?;
|
||||||
self.session = session;
|
self.session = session;
|
||||||
self.session_outdated.store(false, Ordering::Relaxed);
|
self.session_updated.store(true, Ordering::Relaxed);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_session_updated(&self) -> bool {
|
pub fn is_session_updated(&self) -> bool {
|
||||||
!self.session_outdated.load(Ordering::Relaxed)
|
self.session_updated.load(Ordering::Relaxed)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_default_account_id(&mut self, defaul_account_id: impl Into<String>) -> &mut Self {
|
pub fn set_default_account_id(&mut self, defaul_account_id: impl Into<String>) -> &mut Self {
|
||||||
|
|
|
@ -143,7 +143,7 @@ impl Client {
|
||||||
pub async fn email_query(
|
pub async fn email_query(
|
||||||
&self,
|
&self,
|
||||||
filter: Option<impl Into<Filter<super::query::Filter>>>,
|
filter: Option<impl Into<Filter<super::query::Filter>>>,
|
||||||
sort: Option<Vec<Comparator<super::query::Comparator>>>,
|
sort: Option<impl IntoIterator<Item = Comparator<super::query::Comparator>>>,
|
||||||
) -> crate::Result<QueryResponse> {
|
) -> crate::Result<QueryResponse> {
|
||||||
let mut request = self.build();
|
let mut request = self.build();
|
||||||
let query_request = request.query_email();
|
let query_request = request.query_email();
|
||||||
|
|
|
@ -181,8 +181,8 @@ pub struct Email<State = Get> {
|
||||||
|
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
#[serde(skip_deserializing)]
|
#[serde(skip_deserializing)]
|
||||||
#[serde(skip_serializing_if = "HashMap::is_empty")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
patch: HashMap<String, bool>,
|
patch: Option<HashMap<String, bool>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
|
|
@ -32,7 +32,9 @@ impl Email<Set> {
|
||||||
|
|
||||||
pub fn mailbox_id(&mut self, mailbox_id: &str, set: bool) -> &mut Self {
|
pub fn mailbox_id(&mut self, mailbox_id: &str, set: bool) -> &mut Self {
|
||||||
self.mailbox_ids = None;
|
self.mailbox_ids = None;
|
||||||
self.patch.insert(format!("mailboxIds/{}", mailbox_id), set);
|
self.patch
|
||||||
|
.get_or_insert_with(HashMap::new)
|
||||||
|
.insert(format!("mailboxIds/{}", mailbox_id), set);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +49,9 @@ impl Email<Set> {
|
||||||
|
|
||||||
pub fn keyword(&mut self, keyword: &str, set: bool) -> &mut Self {
|
pub fn keyword(&mut self, keyword: &str, set: bool) -> &mut Self {
|
||||||
self.keywords = None;
|
self.keywords = None;
|
||||||
self.patch.insert(format!("keywords/{}", keyword), set);
|
self.patch
|
||||||
|
.get_or_insert_with(HashMap::new)
|
||||||
|
.insert(format!("keywords/{}", keyword), set);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
use crate::{core::get::GetObject, Get, Set};
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use super::{Mailbox, Role};
|
use crate::{core::get::GetObject, principal::ACL, Get, Set};
|
||||||
|
|
||||||
|
use super::{Mailbox, MailboxRights, Role};
|
||||||
|
|
||||||
impl Mailbox<Get> {
|
impl Mailbox<Get> {
|
||||||
pub fn id(&self) -> &str {
|
pub fn id(&self) -> &str {
|
||||||
|
@ -47,40 +49,70 @@ impl Mailbox<Get> {
|
||||||
*self.is_subscribed.as_ref().unwrap_or(&false)
|
*self.is_subscribed.as_ref().unwrap_or(&false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn my_rights(&self) -> Option<&MailboxRights> {
|
||||||
|
self.my_rights.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn acl(&self) -> Option<&HashMap<String, Vec<ACL>>> {
|
||||||
|
self.acl.as_ref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MailboxRights {
|
||||||
pub fn may_read_items(&self) -> bool {
|
pub fn may_read_items(&self) -> bool {
|
||||||
self.my_rights.as_ref().unwrap().may_read_items
|
self.may_read_items
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn may_add_items(&self) -> bool {
|
pub fn may_add_items(&self) -> bool {
|
||||||
self.my_rights.as_ref().unwrap().may_add_items
|
self.may_add_items
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn may_remove_items(&self) -> bool {
|
pub fn may_remove_items(&self) -> bool {
|
||||||
self.my_rights.as_ref().unwrap().may_remove_items
|
self.may_remove_items
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn may_set_seen(&self) -> bool {
|
pub fn may_set_seen(&self) -> bool {
|
||||||
self.my_rights.as_ref().unwrap().may_set_seen
|
self.may_set_seen
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn may_set_keywords(&self) -> bool {
|
pub fn may_set_keywords(&self) -> bool {
|
||||||
self.my_rights.as_ref().unwrap().may_set_keywords
|
self.may_set_keywords
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn may_create_child(&self) -> bool {
|
pub fn may_create_child(&self) -> bool {
|
||||||
self.my_rights.as_ref().unwrap().may_create_child
|
self.may_create_child
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn may_rename(&self) -> bool {
|
pub fn may_rename(&self) -> bool {
|
||||||
self.my_rights.as_ref().unwrap().may_rename
|
self.may_rename
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn may_delete(&self) -> bool {
|
pub fn may_delete(&self) -> bool {
|
||||||
self.my_rights.as_ref().unwrap().may_delete
|
self.may_delete
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn may_submit(&self) -> bool {
|
pub fn may_submit(&self) -> bool {
|
||||||
self.my_rights.as_ref().unwrap().may_submit
|
self.may_submit
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn acl_list(&self) -> Vec<ACL> {
|
||||||
|
let mut acl_list = Vec::new();
|
||||||
|
for (is_set, acl) in [
|
||||||
|
(self.may_read_items, ACL::ReadItems),
|
||||||
|
(self.may_add_items, ACL::AddItems),
|
||||||
|
(self.may_remove_items, ACL::RemoveItems),
|
||||||
|
(self.may_set_seen, ACL::SetSeen),
|
||||||
|
(self.may_set_keywords, ACL::SetKeywords),
|
||||||
|
(self.may_create_child, ACL::CreateChild),
|
||||||
|
(self.may_rename, ACL::Modify),
|
||||||
|
(self.may_delete, ACL::Delete),
|
||||||
|
(self.may_submit, ACL::Submit),
|
||||||
|
] {
|
||||||
|
if is_set {
|
||||||
|
acl_list.push(acl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
acl_list
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ use crate::{
|
||||||
response::{MailboxGetResponse, MailboxSetResponse},
|
response::{MailboxGetResponse, MailboxSetResponse},
|
||||||
set::{SetObject, SetRequest},
|
set::{SetObject, SetRequest},
|
||||||
},
|
},
|
||||||
|
principal::ACL,
|
||||||
Get, Method, Set,
|
Get, Method, Set,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -75,6 +76,20 @@ impl Client {
|
||||||
.updated(id)
|
.updated(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn mailbox_update_acl(
|
||||||
|
&self,
|
||||||
|
id: &str,
|
||||||
|
account_id: &str,
|
||||||
|
acl: impl IntoIterator<Item = ACL>,
|
||||||
|
) -> crate::Result<Option<Mailbox>> {
|
||||||
|
let mut request = self.build();
|
||||||
|
request.set_mailbox().update(id).acl(account_id, acl);
|
||||||
|
request
|
||||||
|
.send_single::<MailboxSetResponse>()
|
||||||
|
.await?
|
||||||
|
.updated(id)
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn mailbox_update_sort_order(
|
pub async fn mailbox_update_sort_order(
|
||||||
&self,
|
&self,
|
||||||
id: &str,
|
id: &str,
|
||||||
|
@ -104,7 +119,7 @@ impl Client {
|
||||||
pub async fn mailbox_get(
|
pub async fn mailbox_get(
|
||||||
&self,
|
&self,
|
||||||
id: &str,
|
id: &str,
|
||||||
properties: Option<Vec<Property>>,
|
properties: Option<impl IntoIterator<Item = Property>>,
|
||||||
) -> crate::Result<Option<Mailbox>> {
|
) -> crate::Result<Option<Mailbox>> {
|
||||||
let mut request = self.build();
|
let mut request = self.build();
|
||||||
let get_request = request.get_mailbox().ids([id]);
|
let get_request = request.get_mailbox().ids([id]);
|
||||||
|
|
|
@ -3,12 +3,14 @@ pub mod helpers;
|
||||||
pub mod query;
|
pub mod query;
|
||||||
pub mod set;
|
pub mod set;
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
|
||||||
use crate::core::changes::ChangesObject;
|
use crate::core::changes::ChangesObject;
|
||||||
use crate::core::set::string_not_set;
|
use crate::core::set::{map_not_set, string_not_set};
|
||||||
use crate::core::Object;
|
use crate::core::Object;
|
||||||
use crate::mailbox::set::role_not_set;
|
use crate::mailbox::set::role_not_set;
|
||||||
|
use crate::principal::ACL;
|
||||||
use crate::{Get, Set};
|
use crate::{Get, Set};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
@ -84,6 +86,14 @@ pub struct Mailbox<State = Get> {
|
||||||
#[serde(rename = "isSubscribed")]
|
#[serde(rename = "isSubscribed")]
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
is_subscribed: Option<bool>,
|
is_subscribed: Option<bool>,
|
||||||
|
|
||||||
|
#[serde(skip_serializing_if = "map_not_set")]
|
||||||
|
acl: Option<HashMap<String, Vec<ACL>>>,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
#[serde(skip_deserializing)]
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
acl_patch: Option<HashMap<String, Vec<ACL>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
@ -93,7 +103,7 @@ pub enum Role {
|
||||||
Archive,
|
Archive,
|
||||||
#[serde(rename = "drafts", alias = "DRAFTS")]
|
#[serde(rename = "drafts", alias = "DRAFTS")]
|
||||||
Drafts,
|
Drafts,
|
||||||
#[serde(rename = "importante", alias = "IMPORTANT")]
|
#[serde(rename = "important", alias = "IMPORTANT")]
|
||||||
Important,
|
Important,
|
||||||
#[serde(rename = "inbox", alias = "INBOX")]
|
#[serde(rename = "inbox", alias = "INBOX")]
|
||||||
Inbox,
|
Inbox,
|
||||||
|
@ -160,6 +170,8 @@ pub enum Property {
|
||||||
MyRights,
|
MyRights,
|
||||||
#[serde(rename = "isSubscribed")]
|
#[serde(rename = "isSubscribed")]
|
||||||
IsSubscribed,
|
IsSubscribed,
|
||||||
|
#[serde(rename = "acl")]
|
||||||
|
ACL,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for Property {
|
impl Display for Property {
|
||||||
|
@ -176,6 +188,7 @@ impl Display for Property {
|
||||||
Property::UnreadThreads => write!(f, "unreadThreads"),
|
Property::UnreadThreads => write!(f, "unreadThreads"),
|
||||||
Property::MyRights => write!(f, "myRights"),
|
Property::MyRights => write!(f, "myRights"),
|
||||||
Property::IsSubscribed => write!(f, "isSubscribed"),
|
Property::IsSubscribed => write!(f, "isSubscribed"),
|
||||||
|
Property::ACL => write!(f, "acl"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
use crate::{core::set::SetObject, Get, Set};
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use crate::{core::set::SetObject, principal::ACL, Get, Set};
|
||||||
|
|
||||||
use super::{Mailbox, Role, SetArguments};
|
use super::{Mailbox, Role, SetArguments};
|
||||||
|
|
||||||
|
@ -31,6 +33,27 @@ impl Mailbox<Set> {
|
||||||
self.sort_order = sort_order.into();
|
self.sort_order = sort_order.into();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn acls<T, U, V>(&mut self, acls: T) -> &mut Self
|
||||||
|
where
|
||||||
|
T: IntoIterator<Item = (U, V)>,
|
||||||
|
U: Into<String>,
|
||||||
|
V: IntoIterator<Item = ACL>,
|
||||||
|
{
|
||||||
|
self.acl = Some(
|
||||||
|
acls.into_iter()
|
||||||
|
.map(|(id, acls)| (id.into(), acls.into_iter().collect()))
|
||||||
|
.collect(),
|
||||||
|
);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn acl(&mut self, id: &str, acl: impl IntoIterator<Item = ACL>) -> &mut Self {
|
||||||
|
self.acl_patch
|
||||||
|
.get_or_insert_with(HashMap::new)
|
||||||
|
.insert(format!("acl/{}", id), acl.into_iter().collect());
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn role_not_set(role: &Option<Role>) -> bool {
|
pub fn role_not_set(role: &Option<Role>) -> bool {
|
||||||
|
@ -55,6 +78,8 @@ impl SetObject for Mailbox<Set> {
|
||||||
unread_threads: None,
|
unread_threads: None,
|
||||||
my_rights: None,
|
my_rights: None,
|
||||||
is_subscribed: None,
|
is_subscribed: None,
|
||||||
|
acl: HashMap::with_capacity(0).into(),
|
||||||
|
acl_patch: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue