use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, PartialOrd)]
pub struct RpItem {
pub eng: String,
pub chn: String,
pub enabled: bool, }
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Default)]
pub struct RpAction {
pub actions: HashMap<String, Vec<RpItem>>, }
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Default)]
pub struct RpConfig {
pub name: String,
pub role: RpInputRole,
pub permission: RpInputPermission,
}
pub type RpInputRole = HashMap<String, Vec<String>>;
pub type RpInputPermission = HashMap<String, HashMap<String, String>>;
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Default)]
pub struct RpGroup {
pub input_permission: RpInputPermission,
pub input_role: RpInputRole,
pub roles: HashMap<String, (RpAction, Vec<String>)>,
}
impl RpGroup {
pub fn get_role(&self) -> HashMap<String, Vec<String>> {
let mut role_map = HashMap::<String, Vec<String>>::default();
for each in self.roles.iter() {
role_map.insert(each.0.clone(), each.1 .1.clone());
}
role_map
}
pub fn get_user_permission(&self, user_account: String) -> HashMap<String, RpAction> {
let mut user_permision = HashMap::<String, RpAction>::default();
for (each_role, (actions, users)) in self.roles.iter() {
if users.contains(&user_account) {
user_permision.insert(each_role.clone(), actions.clone());
}
}
if !user_permision.contains_key("default") {
if let Some(default_actions) = self.roles.get("default") {
user_permision.insert("default".into(), default_actions.0.clone());
} else {
tracing::warn!("default permission is not existed");
}
}
user_permision
}
fn check_user_action_internal(actions: RpAction, page: String, item: String) -> bool {
if let Some(action) = actions.actions.get(&page) {
for each in action.iter() {
if each.eng.eq(&item) && each.enabled {
return true;
}
}
}
false
}
pub fn check_user_action(&self, user_account: String, page: String, action: String) -> bool {
let user_actions = self.get_user_permission(user_account.clone());
for (_role_tmp, role_action) in user_actions.iter() {
let check_status =
Self::check_user_action_internal(role_action.clone(), page.clone(), action.clone());
if check_status {
return true;
}
}
false
}
pub fn create(config: RpConfig) -> anyhow::Result<Self> {
let role = config.role.clone();
let permission = config.permission.clone();
let mut role_permission = RpGroup::default();
role_permission.input_permission = permission.clone();
role_permission.input_role = role.clone();
for (each_role, role_users) in role.iter() {
let mut each_group_permisson = RpAction::default();
let mut role_internal_group_permission = RpAction::default();
for (each_group, action_map) in permission.iter() {
for (each_action, action_info) in action_map.iter() {
if !each_action.contains("-") {
return Err(anyhow::anyhow!(
"action key is not splited by -, need eng and chn name: {}",
each_action
));
}
let each_aciton_split: Vec<&str> = each_action.split("-").collect();
if each_aciton_split.len() != 2 {
return Err(anyhow::anyhow!(
"action key length is not 2 after splitting by -: {}",
each_action
));
}
let aciton_eng = each_aciton_split.get(0).unwrap().to_string();
let aciton_chn = each_aciton_split.get(1).unwrap().to_string();
let mut action_info_list = HashMap::<String, bool>::default();
let action_info_split: Vec<&str> = action_info.split(":").collect();
for action_info_each in action_info_split.iter() {
let action_info_each = action_info_each.to_string();
if !action_info_each.contains("-") {
return Err(anyhow::anyhow!(
"action role value is not splited by -, need role and status: {}",
action_info
));
}
let action_info_each_split: Vec<&str> =
action_info_each.split("-").collect();
if action_info_each_split.len() != 2 {
return Err(anyhow::anyhow!(
"action role value length is not 2 after splitting by -: {}",
action_info
));
}
let action_role = action_info_each_split.get(0).unwrap().to_string();
let action_status = action_info_each_split.get(1).unwrap().to_string();
let action_status = match action_status.as_str() {
"true" => true,
"false" => false,
_ => false,
};
action_info_list.insert(action_role, action_status);
}
let action_item = if action_info_list.contains_key(each_role) {
RpItem {
eng: aciton_eng.clone(),
chn: aciton_chn.clone(),
enabled: action_info_list.get(each_role).unwrap().clone(),
}
} else {
RpItem {
eng: aciton_eng.clone(),
chn: aciton_chn.clone(),
enabled: false,
}
};
if each_group_permisson.actions.contains_key(each_group) {
let key_index = each_group_permisson.actions.get_mut(each_group).unwrap();
key_index.push(action_item);
} else {
each_group_permisson
.actions
.insert(each_group.clone(), vec![action_item]);
}
if role_internal_group_permission
.actions
.contains_key(each_group)
{
let key_index = role_internal_group_permission
.actions
.get_mut(each_group)
.unwrap();
key_index.push(RpItem {
eng: aciton_eng.clone(),
chn: aciton_chn.clone(),
enabled: false,
});
} else {
role_internal_group_permission.actions.insert(
each_group.clone(),
vec![RpItem {
eng: aciton_eng.clone(),
chn: aciton_chn.clone(),
enabled: false,
}],
);
}
}
}
role_permission.roles.insert(
each_role.clone(),
(each_group_permisson.clone(), role_users.clone()),
);
}
Ok(role_permission)
}
}