use serde_json::Value;
use crate::client::Client;
use crate::client::transport::{Request, encode_segment};
use crate::error::{Error, Result};
use crate::model::admin::{Role, Subject};
#[derive(Debug, Clone)]
pub struct Admin {
client: Client,
}
impl Admin {
pub(crate) const fn new(client: Client) -> Self {
Self { client }
}
pub async fn subjects(&self) -> Result<Vec<Subject>> {
self.client
.inner
.execute(Request::get(
"api/v2/authorization/subjects",
"api/v2/authorization/subjects",
))
.await?
.json()
}
pub async fn create_subject(&self, subject: &Subject) -> Result<()> {
self.client
.inner
.execute(
Request::post(
"api/v2/authorization/subjects",
"api/v2/authorization/subjects",
)
.json(subject)?,
)
.await
.map(|_| ())
}
pub async fn update_subject(&self, subject: &Subject) -> Result<()> {
if subject.id.is_none() {
return Err(Error::InvalidInput("the subject has no _id".into()));
}
self.client
.inner
.execute(
Request::put(
"api/v2/authorization/subjects",
"api/v2/authorization/subjects",
)
.json(subject)?,
)
.await
.map(|_| ())
}
pub async fn delete_subject(&self, id: &str) -> Result<()> {
self.client
.inner
.execute(Request::delete(
format!("api/v2/authorization/subjects/{}", encode_segment(id)),
"api/v2/authorization/subjects/{id}",
))
.await
.map(|_| ())
}
pub async fn roles(&self) -> Result<Vec<Role>> {
self.client
.inner
.execute(Request::get(
"api/v2/authorization/roles",
"api/v2/authorization/roles",
))
.await?
.json()
}
pub async fn create_role(&self, role: &Role) -> Result<()> {
self.client
.inner
.execute(
Request::post("api/v2/authorization/roles", "api/v2/authorization/roles")
.json(role)?,
)
.await
.map(|_| ())
}
pub async fn update_role(&self, role: &Role) -> Result<()> {
if role.id.is_none() {
return Err(Error::InvalidInput("the role has no _id".into()));
}
self.client
.inner
.execute(
Request::put("api/v2/authorization/roles", "api/v2/authorization/roles")
.json(role)?,
)
.await
.map(|_| ())
}
pub async fn delete_role(&self, id: &str) -> Result<()> {
self.client
.inner
.execute(Request::delete(
format!("api/v2/authorization/roles/{}", encode_segment(id)),
"api/v2/authorization/roles/{id}",
))
.await
.map(|_| ())
}
pub async fn permissions(&self) -> Result<Vec<String>> {
let value: Value = self
.client
.inner
.execute(Request::get(
"api/v2/authorization/permissions",
"api/v2/authorization/permissions",
))
.await?
.json()?;
Ok(match value {
Value::Array(items) => items
.into_iter()
.filter_map(|v| v.as_str().map(str::to_owned))
.collect(),
Value::Object(map) => map.keys().cloned().collect(),
_ => Vec::new(),
})
}
pub async fn check(&self, permission: &str) -> Result<bool> {
let req = Request::get(
format!(
"api/v2/authorization/debug/check/{}",
encode_segment(permission)
),
"api/v2/authorization/debug/check/{permission}",
);
match self.client.inner.execute(req).await {
Ok(_) => Ok(true),
Err(Error::Unauthorized { .. } | Error::Forbidden { .. }) => Ok(false),
Err(err) => Err(err),
}
}
}