use crate::types::{EntityId, Namespace, UserPolicies, ValidationError};
use crate::{Result, TreetopError};
use super::inner::{Client, CorrelationId};
pub struct UserPoliciesRequest<'a, Capability> {
client: &'a Client<Capability>,
user: String,
groups: Vec<String>,
namespaces: Vec<String>,
correlation_id: Option<CorrelationId>,
}
impl<'a, Capability> UserPoliciesRequest<'a, Capability> {
pub(super) fn new(client: &'a Client<Capability>, user: impl Into<String>) -> Result<Self> {
let user = user.into();
validate_user(&user)?;
Ok(Self {
client,
user,
groups: Vec::new(),
namespaces: Vec::new(),
correlation_id: None,
})
}
pub fn group(mut self, group: impl Into<String>) -> Result<Self> {
let group = group.into();
EntityId::new(&group).validate("user policies group")?;
self.groups.push(group);
Ok(self)
}
pub fn namespace(mut self, namespace: impl Into<String>) -> Result<Self> {
let namespace = namespace.into();
Namespace::new(namespace.split("::").map(str::to_string).collect())
.validate("user policies namespace")?;
self.namespaces.push(namespace);
Ok(self)
}
pub fn correlation_id(mut self, id: impl Into<String>) -> Result<Self> {
self.correlation_id = Some(CorrelationId::parse(id.into())?);
Ok(self)
}
pub fn raw(self) -> RawUserPoliciesRequest<'a, Capability> {
RawUserPoliciesRequest { inner: self }
}
pub async fn send(self) -> Result<UserPolicies> {
self.client
.send_user_policies(
&self.user,
&self.groups,
&self.namespaces,
false,
self.correlation_id.as_ref(),
)
.await
}
}
pub struct RawUserPoliciesRequest<'a, Capability> {
inner: UserPoliciesRequest<'a, Capability>,
}
impl<Capability> RawUserPoliciesRequest<'_, Capability> {
pub async fn send(self) -> Result<String> {
self.inner
.client
.send_user_policies_raw(
&self.inner.user,
&self.inner.groups,
&self.inner.namespaces,
true,
self.inner.correlation_id.as_ref(),
)
.await
}
}
fn validate_user(user: &str) -> Result<()> {
EntityId::new(user).validate("user policies user")?;
if user.is_empty() || matches!(user, "." | "..") {
return Err(TreetopError::from(ValidationError::InvalidPathSegment {
field: "user policies user",
value: user.to_string(),
}));
}
Ok(())
}