Mailbox ACLs
parent
c085cf5c89
commit
8b7cfda3d7
|
@ -30,7 +30,7 @@ pub enum Credentials {
|
|||
pub struct Client {
|
||||
session: Session,
|
||||
session_url: String,
|
||||
session_outdated: AtomicBool,
|
||||
session_updated: AtomicBool,
|
||||
#[cfg(feature = "websockets")]
|
||||
pub(crate) authorization: String,
|
||||
upload_url: Vec<URLPart<blob::URLParameter>>,
|
||||
|
@ -91,7 +91,7 @@ impl Client {
|
|||
event_source_url: URLPart::parse(session.event_source_url())?,
|
||||
session,
|
||||
session_url: url.to_string(),
|
||||
session_outdated: false.into(),
|
||||
session_updated: true.into(),
|
||||
#[cfg(feature = "websockets")]
|
||||
authorization,
|
||||
timeout: DEFAULT_TIMEOUT_MS,
|
||||
|
@ -147,7 +147,7 @@ impl Client {
|
|||
)?;
|
||||
|
||||
if response.session_state() != self.session.state() {
|
||||
self.session_outdated.store(true, Ordering::Relaxed);
|
||||
self.session_updated.store(false, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
Ok(response)
|
||||
|
@ -172,12 +172,12 @@ impl Client {
|
|||
self.upload_url = URLPart::parse(session.upload_url())?;
|
||||
self.event_source_url = URLPart::parse(session.event_source_url())?;
|
||||
self.session = session;
|
||||
self.session_outdated.store(false, Ordering::Relaxed);
|
||||
self.session_updated.store(true, Ordering::Relaxed);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
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 {
|
||||
|
|
|
@ -143,7 +143,7 @@ impl Client {
|
|||
pub async fn email_query(
|
||||
&self,
|
||||
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> {
|
||||
let mut request = self.build();
|
||||
let query_request = request.query_email();
|
||||
|
|
|
@ -181,8 +181,8 @@ pub struct Email<State = Get> {
|
|||
|
||||
#[serde(flatten)]
|
||||
#[serde(skip_deserializing)]
|
||||
#[serde(skip_serializing_if = "HashMap::is_empty")]
|
||||
patch: HashMap<String, bool>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
patch: Option<HashMap<String, bool>>,
|
||||
}
|
||||
|
||||
#[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 {
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -47,7 +49,9 @@ impl Email<Set> {
|
|||
|
||||
pub fn keyword(&mut self, keyword: &str, set: bool) -> &mut Self {
|
||||
self.keywords = None;
|
||||
self.patch.insert(format!("keywords/{}", keyword), set);
|
||||
self.patch
|
||||
.get_or_insert_with(HashMap::new)
|
||||
.insert(format!("keywords/{}", keyword), set);
|
||||
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> {
|
||||
pub fn id(&self) -> &str {
|
||||
|
@ -47,40 +49,70 @@ impl Mailbox<Get> {
|
|||
*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 {
|
||||
self.my_rights.as_ref().unwrap().may_read_items
|
||||
self.may_read_items
|
||||
}
|
||||
|
||||
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 {
|
||||
self.my_rights.as_ref().unwrap().may_remove_items
|
||||
self.may_remove_items
|
||||
}
|
||||
|
||||
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 {
|
||||
self.my_rights.as_ref().unwrap().may_set_keywords
|
||||
self.may_set_keywords
|
||||
}
|
||||
|
||||
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 {
|
||||
self.my_rights.as_ref().unwrap().may_rename
|
||||
self.may_rename
|
||||
}
|
||||
|
||||
pub fn may_delete(&self) -> bool {
|
||||
self.my_rights.as_ref().unwrap().may_delete
|
||||
self.may_delete
|
||||
}
|
||||
|
||||
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},
|
||||
set::{SetObject, SetRequest},
|
||||
},
|
||||
principal::ACL,
|
||||
Get, Method, Set,
|
||||
};
|
||||
|
||||
|
@ -75,6 +76,20 @@ impl Client {
|
|||
.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(
|
||||
&self,
|
||||
id: &str,
|
||||
|
@ -104,7 +119,7 @@ impl Client {
|
|||
pub async fn mailbox_get(
|
||||
&self,
|
||||
id: &str,
|
||||
properties: Option<Vec<Property>>,
|
||||
properties: Option<impl IntoIterator<Item = Property>>,
|
||||
) -> crate::Result<Option<Mailbox>> {
|
||||
let mut request = self.build();
|
||||
let get_request = request.get_mailbox().ids([id]);
|
||||
|
|
|
@ -3,12 +3,14 @@ pub mod helpers;
|
|||
pub mod query;
|
||||
pub mod set;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::Display;
|
||||
|
||||
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::mailbox::set::role_not_set;
|
||||
use crate::principal::ACL;
|
||||
use crate::{Get, Set};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
@ -84,6 +86,14 @@ pub struct Mailbox<State = Get> {
|
|||
#[serde(rename = "isSubscribed")]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
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)]
|
||||
|
@ -93,7 +103,7 @@ pub enum Role {
|
|||
Archive,
|
||||
#[serde(rename = "drafts", alias = "DRAFTS")]
|
||||
Drafts,
|
||||
#[serde(rename = "importante", alias = "IMPORTANT")]
|
||||
#[serde(rename = "important", alias = "IMPORTANT")]
|
||||
Important,
|
||||
#[serde(rename = "inbox", alias = "INBOX")]
|
||||
Inbox,
|
||||
|
@ -160,6 +170,8 @@ pub enum Property {
|
|||
MyRights,
|
||||
#[serde(rename = "isSubscribed")]
|
||||
IsSubscribed,
|
||||
#[serde(rename = "acl")]
|
||||
ACL,
|
||||
}
|
||||
|
||||
impl Display for Property {
|
||||
|
@ -176,6 +188,7 @@ impl Display for Property {
|
|||
Property::UnreadThreads => write!(f, "unreadThreads"),
|
||||
Property::MyRights => write!(f, "myRights"),
|
||||
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};
|
||||
|
||||
|
@ -31,6 +33,27 @@ impl Mailbox<Set> {
|
|||
self.sort_order = sort_order.into();
|
||||
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 {
|
||||
|
@ -55,6 +78,8 @@ impl SetObject for Mailbox<Set> {
|
|||
unread_threads: None,
|
||||
my_rights: None,
|
||||
is_subscribed: None,
|
||||
acl: HashMap::with_capacity(0).into(),
|
||||
acl_patch: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue