use crate::error::Result;
use serde::{Deserialize, Serialize};
use typed_builder::TypedBuilder;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RoleInfo {
pub uid: u32,
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub management: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub data_access: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub bdb_roles: Option<Vec<BdbRole>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cluster_roles: Option<Vec<String>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, TypedBuilder)]
pub struct BdbRole {
pub bdb_uid: u32,
#[builder(setter(into))]
pub role: String,
#[serde(skip_serializing_if = "Option::is_none")]
#[builder(default, setter(strip_option))]
pub redis_acl_uid: Option<u32>,
}
#[derive(Debug, Clone, Serialize, Deserialize, TypedBuilder)]
pub struct CreateRoleRequest {
#[builder(setter(into))]
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
#[builder(default, setter(into, strip_option))]
pub management: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
#[builder(default, setter(into, strip_option))]
pub data_access: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
#[builder(default, setter(strip_option))]
pub bdb_roles: Option<Vec<BdbRole>>,
#[serde(skip_serializing_if = "Option::is_none")]
#[builder(default, setter(strip_option))]
pub cluster_roles: Option<Vec<String>>,
}
define_handler!(
pub struct RolesHandler;
);
impl_crud!(RolesHandler {
list => RoleInfo, "/v1/roles";
get(u32) => RoleInfo, "/v1/roles/{}";
delete(u32), "/v1/roles/{}";
create(CreateRoleRequest) => RoleInfo, "/v1/roles";
update(u32, CreateRoleRequest) => RoleInfo, "/v1/roles/{}";
});
impl RolesHandler {
#[deprecated(note = "Redis Software does not register /v1/roles/builtin")]
pub async fn built_in(&self) -> Result<Vec<RoleInfo>> {
crate::error::unsupported_operation("list built-in roles")
}
pub async fn users(&self, uid: u32) -> Result<Vec<u32>> {
let users: Vec<crate::users::User> = self.client.get("/v1/users").await?;
Ok(users
.into_iter()
.filter(|user| {
user.role_uids
.as_ref()
.is_some_and(|role_uids| role_uids.contains(&uid))
})
.map(|user| user.uid)
.collect())
}
}