Blocking client and patch support on Principals.

This commit is contained in:
Mauro D
2022-08-09 15:28:55 +00:00
parent 76fe0331a2
commit b0ba1737b1
30 changed files with 1883 additions and 25 deletions

View File

@@ -27,6 +27,10 @@ impl Principal<Get> {
self.description.as_deref()
}
pub fn timezone(&self) -> Option<&str> {
self.timezone.as_deref()
}
pub fn secret(&self) -> Option<&str> {
self.secret.as_deref()
}

View File

@@ -202,7 +202,7 @@ impl Client {
pub async fn principal_get(
&self,
id: &str,
properties: Option<Vec<Property>>,
properties: Option<impl IntoIterator<Item = Property>>,
) -> crate::Result<Option<Principal>> {
let mut request = self.build();
let get_request = request.get_principal().ids([id]);

View File

@@ -0,0 +1,276 @@
use crate::{
client::Client,
core::{
changes::{ChangesRequest, ChangesResponse},
get::GetRequest,
query::{Comparator, Filter, QueryRequest, QueryResponse},
query_changes::{QueryChangesRequest, QueryChangesResponse},
request::{Arguments, Request},
response::{PrincipalGetResponse, PrincipalSetResponse},
set::{SetObject, SetRequest},
},
Get, Method, Set,
};
use super::{Principal, Property, Type};
impl Client {
pub fn individual_create(
&self,
email: impl Into<String>,
secret: impl Into<String>,
name: impl Into<String>,
) -> crate::Result<Principal> {
let mut request = self.build();
let id = request
.set_principal()
.create()
.name(name)
.secret(secret)
.email(email)
.ptype(Type::Individual)
.create_id()
.unwrap();
request.send_single::<PrincipalSetResponse>()?.created(&id)
}
pub fn domain_create(&self, name: impl Into<String>) -> crate::Result<Principal> {
let mut request = self.build();
let id = request
.set_principal()
.create()
.name(name)
.ptype(Type::Domain)
.create_id()
.unwrap();
request.send_single::<PrincipalSetResponse>()?.created(&id)
}
pub fn list_create(
&self,
email: impl Into<String>,
name: impl Into<String>,
members: impl IntoIterator<Item = impl Into<String>>,
) -> crate::Result<Principal> {
let mut request = self.build();
let id = request
.set_principal()
.create()
.name(name)
.email(email)
.ptype(Type::List)
.members(members.into())
.create_id()
.unwrap();
request.send_single::<PrincipalSetResponse>()?.created(&id)
}
pub fn group_create(
&self,
email: impl Into<String>,
name: impl Into<String>,
members: impl IntoIterator<Item = impl Into<String>>,
) -> crate::Result<Principal> {
let mut request = self.build();
let id = request
.set_principal()
.create()
.name(name)
.email(email)
.ptype(Type::Group)
.members(members.into())
.create_id()
.unwrap();
request.send_single::<PrincipalSetResponse>()?.created(&id)
}
pub fn principal_set_name(
&self,
id: &str,
name: impl Into<String>,
) -> crate::Result<Option<Principal>> {
let mut request = self.build();
request.set_principal().update(id).name(name);
request.send_single::<PrincipalSetResponse>()?.updated(id)
}
pub fn principal_set_secret(
&self,
id: &str,
secret: impl Into<String>,
) -> crate::Result<Option<Principal>> {
let mut request = self.build();
request.set_principal().update(id).secret(secret);
request.send_single::<PrincipalSetResponse>()?.updated(id)
}
pub fn principal_set_email(
&self,
id: &str,
email: impl Into<String>,
) -> crate::Result<Option<Principal>> {
let mut request = self.build();
request.set_principal().update(id).email(email);
request.send_single::<PrincipalSetResponse>()?.updated(id)
}
pub fn principal_set_timezone(
&self,
id: &str,
timezone: Option<impl Into<String>>,
) -> crate::Result<Option<Principal>> {
let mut request = self.build();
request.set_principal().update(id).timezone(timezone);
request.send_single::<PrincipalSetResponse>()?.updated(id)
}
pub fn principal_set_members(
&self,
id: &str,
members: Option<impl IntoIterator<Item = impl Into<String>>>,
) -> crate::Result<Option<Principal>> {
let mut request = self.build();
request.set_principal().update(id).members(members);
request.send_single::<PrincipalSetResponse>()?.updated(id)
}
pub fn principal_set_aliases(
&self,
id: &str,
aliases: Option<impl IntoIterator<Item = impl Into<String>>>,
) -> crate::Result<Option<Principal>> {
let mut request = self.build();
request.set_principal().update(id).aliases(aliases);
request.send_single::<PrincipalSetResponse>()?.updated(id)
}
pub fn principal_set_capabilities(
&self,
id: &str,
capabilities: Option<impl IntoIterator<Item = impl Into<String>>>,
) -> crate::Result<Option<Principal>> {
let mut request = self.build();
request
.set_principal()
.update(id)
.capabilities(capabilities);
request.send_single::<PrincipalSetResponse>()?.updated(id)
}
pub fn principal_destroy(&self, id: &str) -> crate::Result<()> {
let mut request = self.build();
request.set_principal().destroy([id]).arguments();
request.send_single::<PrincipalSetResponse>()?.destroyed(id)
}
pub fn principal_get(
&self,
id: &str,
properties: Option<impl IntoIterator<Item = Property>>,
) -> crate::Result<Option<Principal>> {
let mut request = self.build();
let get_request = request.get_principal().ids([id]);
if let Some(properties) = properties {
get_request.properties(properties.into_iter());
}
request
.send_single::<PrincipalGetResponse>()
.map(|mut r| r.take_list().pop())
}
pub fn principal_query(
&self,
filter: Option<impl Into<Filter<super::query::Filter>>>,
sort: Option<impl IntoIterator<Item = Comparator<super::query::Comparator>>>,
) -> crate::Result<QueryResponse> {
let mut request = self.build();
let query_request = request.query_principal();
if let Some(filter) = filter {
query_request.filter(filter);
}
if let Some(sort) = sort {
query_request.sort(sort.into_iter());
}
request.send_single::<QueryResponse>()
}
pub fn principal_changes(
&self,
since_state: impl Into<String>,
max_changes: usize,
) -> crate::Result<ChangesResponse<Principal<Get>>> {
let mut request = self.build();
request
.changes_principal(since_state)
.max_changes(max_changes);
request.send_single()
}
}
impl Request<'_> {
pub fn get_principal(&mut self) -> &mut GetRequest<Principal<Set>> {
self.add_method_call(
Method::GetPrincipal,
Arguments::principal_get(self.params(Method::GetPrincipal)),
)
.principal_get_mut()
}
pub fn send_get_principal(self) -> crate::Result<PrincipalGetResponse> {
self.send_single()
}
pub fn changes_principal(&mut self, since_state: impl Into<String>) -> &mut ChangesRequest {
self.add_method_call(
Method::ChangesPrincipal,
Arguments::changes(self.params(Method::ChangesPrincipal), since_state.into()),
)
.changes_mut()
}
pub fn send_changes_principal(self) -> crate::Result<ChangesResponse<Principal<Get>>> {
self.send_single()
}
pub fn query_principal(&mut self) -> &mut QueryRequest<Principal<Set>> {
self.add_method_call(
Method::QueryPrincipal,
Arguments::principal_query(self.params(Method::QueryPrincipal)),
)
.principal_query_mut()
}
pub fn send_query_principal(self) -> crate::Result<QueryResponse> {
self.send_single()
}
pub fn query_principal_changes(
&mut self,
since_query_state: impl Into<String>,
) -> &mut QueryChangesRequest<Principal<Set>> {
self.add_method_call(
Method::QueryChangesPrincipal,
Arguments::principal_query_changes(
self.params(Method::QueryChangesPrincipal),
since_query_state.into(),
),
)
.principal_query_changes_mut()
}
pub fn send_query_principal_changes(self) -> crate::Result<QueryChangesResponse> {
self.send_single()
}
pub fn set_principal(&mut self) -> &mut SetRequest<Principal<Set>> {
self.add_method_call(
Method::SetPrincipal,
Arguments::principal_set(self.params(Method::SetPrincipal)),
)
.principal_set_mut()
}
pub fn send_set_principal(self) -> crate::Result<PrincipalSetResponse> {
self.send_single()
}
}

View File

@@ -1,5 +1,8 @@
pub mod get;
#[cfg(feature = "async")]
pub mod helpers;
#[cfg(feature = "blocking")]
pub mod helpers_blocking;
pub mod query;
pub mod set;
@@ -23,33 +26,51 @@ pub struct Principal<State = Get> {
#[serde(skip_serializing_if = "Option::is_none")]
id: Option<String>,
#[serde(rename = "type")]
#[serde(skip_serializing_if = "Option::is_none")]
ptype: Option<Type>,
#[serde(skip_serializing_if = "string_not_set")]
name: Option<String>,
#[serde(skip_serializing_if = "string_not_set")]
description: Option<String>,
#[serde(skip_serializing_if = "string_not_set")]
email: Option<String>,
#[serde(skip_serializing_if = "string_not_set")]
timezone: Option<String>,
#[serde(skip_serializing_if = "list_not_set")]
capabilities: Option<Vec<String>>,
#[serde(skip_serializing_if = "list_not_set")]
aliases: Option<Vec<String>>,
#[serde(skip_serializing_if = "string_not_set")]
secret: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
dkim: Option<DKIM>,
#[serde(skip_serializing_if = "Option::is_none")]
quota: Option<u32>,
#[serde(skip_serializing_if = "string_not_set")]
picture: Option<String>,
#[serde(skip_serializing_if = "list_not_set")]
members: Option<Vec<String>>,
#[serde(skip_serializing_if = "map_not_set")]
acl: Option<AHashMap<String, Vec<ACL>>>,
#[serde(flatten)]
#[serde(skip_deserializing)]
#[serde(skip_serializing_if = "Option::is_none")]
property_patch: Option<AHashMap<String, bool>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash, Copy)]
@@ -129,9 +150,26 @@ pub enum Type {
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct DKIM {
#[serde(rename = "dkimSelector")]
pub dkim_selector: Option<String>,
dkim_selector: Option<String>,
#[serde(rename = "dkimExpiration")]
pub dkim_expiration: Option<i64>,
dkim_expiration: Option<i64>,
}
impl DKIM {
pub fn new(dkim_selector: Option<String>, dkim_expiration: Option<i64>) -> DKIM {
DKIM {
dkim_selector,
dkim_expiration,
}
}
pub fn selector(&self) -> Option<&str> {
self.dkim_selector.as_deref()
}
pub fn expiration(&self) -> Option<i64> {
self.dkim_expiration
}
}
impl Display for Property {

View File

@@ -18,6 +18,10 @@ pub enum Filter {
#[serde(rename = "name")]
value: String,
},
DomainName {
#[serde(rename = "domainName")]
value: String,
},
Text {
#[serde(rename = "text")]
value: String,
@@ -61,16 +65,25 @@ impl Filter {
value: value.into(),
}
}
pub fn domain_name(value: impl Into<String>) -> Self {
Filter::DomainName {
value: value.into(),
}
}
pub fn email(value: impl Into<String>) -> Self {
Filter::Email {
value: value.into(),
}
}
pub fn text(value: impl Into<String>) -> Self {
Filter::Text {
value: value.into(),
}
}
pub fn timezone(value: impl Into<String>) -> Self {
Filter::Timezone {
value: value.into(),

View File

@@ -1,4 +1,4 @@
use super::{Principal, Type, ACL, DKIM};
use super::{Principal, Property, Type, ACL, DKIM};
use crate::{core::set::SetObject, Get, Set};
use ahash::AHashMap;
@@ -62,6 +62,13 @@ impl Principal<Set> {
self
}
pub fn alias(&mut self, alias: &str, set: bool) -> &mut Self {
self.property_patch
.get_or_insert_with(AHashMap::new)
.insert(format!("{}/{}", Property::Aliases, alias), set);
self
}
pub fn capabilities<T, U>(&mut self, capabilities: Option<T>) -> &mut Self
where
T: IntoIterator<Item = U>,
@@ -79,6 +86,13 @@ impl Principal<Set> {
self.members = members.map(|l| l.into_iter().map(|v| v.into()).collect());
self
}
pub fn member(&mut self, member: &str, set: bool) -> &mut Self {
self.property_patch
.get_or_insert_with(AHashMap::new)
.insert(format!("{}/{}", Property::Members, member), set);
self
}
}
impl SetObject for Principal<Set> {
@@ -102,6 +116,7 @@ impl SetObject for Principal<Set> {
picture: "".to_string().into(),
members: Vec::with_capacity(0).into(),
acl: AHashMap::with_capacity(0).into(),
property_patch: None,
}
}