diff --git a/src/common/model/mod.rs b/src/common/model/mod.rs index c47c5d30..07408af2 100644 --- a/src/common/model/mod.rs +++ b/src/common/model/mod.rs @@ -1,3 +1,5 @@ +pub mod privilege; + use std::{collections::HashMap, sync::Arc}; use serde::{Deserialize, Serialize}; diff --git a/src/common/model/privilege.rs b/src/common/model/privilege.rs new file mode 100644 index 00000000..2ce2d645 --- /dev/null +++ b/src/common/model/privilege.rs @@ -0,0 +1,94 @@ +use bitflags::bitflags; +use serde::{Deserialize, Serialize}; +use std::collections::HashSet; + +bitflags! { + /// Represents a set of flags. + #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] + pub struct PrivilegeGroupFlags: u8 { + /// The value `ENABLE`, at bit position `0`. + const ENABLE = 0b00000001; + /// The value `WHILE_LIST_IS_ALL`, at bit position `1`. + const WHILE_LIST_IS_ALL = 0b00000010; + /// The value `BLACK_LIST_IS_ALL`, at bit position `2`. + const BLACK_LIST_IS_ALL= 0b00000100; + } +} + +/// +/// 数据权限组 +/// 支持分别设置黑白名单 +#[derive(Clone, Serialize, Deserialize, Default)] +#[serde(rename_all = "camelCase")] +pub struct PrivilegeGroup +where + T: Sized + std::hash::Hash + std::cmp::Eq, +{ + pub enabled: bool, + pub white_list_is_all: bool, + pub whitelist: Option>, + pub black_list_is_all: bool, + pub blacklist: Option>, +} + +impl PrivilegeGroup +where + T: Sized + std::hash::Hash + std::cmp::Eq, +{ + pub fn new( + flags: u8, + whitelist: Option>, + blacklist: Option>, + ) -> PrivilegeGroup { + let enabled = flags & PrivilegeGroupFlags::ENABLE.bits() > 0; + let white_list_is_all = flags & PrivilegeGroupFlags::WHILE_LIST_IS_ALL.bits() > 0; + let black_list_is_all = flags & PrivilegeGroupFlags::BLACK_LIST_IS_ALL.bits() > 0; + Self { + enabled, + white_list_is_all, + black_list_is_all, + whitelist, + blacklist, + } + } + + pub fn empty() -> Self { + Self { + enabled: true, + white_list_is_all: false, + whitelist: None, + black_list_is_all: false, + blacklist: None, + } + } + + pub fn all() -> Self { + Self { + enabled: true, + white_list_is_all: true, + whitelist: None, + black_list_is_all: false, + blacklist: None, + } + } + + pub fn get_flags(&self) -> u8 { + let mut v = 0; + if self.enabled { + v |= PrivilegeGroupFlags::ENABLE.bits(); + } + if self.white_list_is_all { + v |= PrivilegeGroupFlags::WHILE_LIST_IS_ALL.bits(); + } + if self.black_list_is_all { + v |= PrivilegeGroupFlags::BLACK_LIST_IS_ALL.bits(); + } + v + } + + pub fn set_flags(&mut self, flags: u8) { + self.enabled = flags & PrivilegeGroupFlags::ENABLE.bits() > 0; + self.white_list_is_all = flags & PrivilegeGroupFlags::WHILE_LIST_IS_ALL.bits() > 0; + self.black_list_is_all = flags & PrivilegeGroupFlags::BLACK_LIST_IS_ALL.bits() > 0; + } +} diff --git a/src/transfer/mysql/dao/mod.rs b/src/transfer/mysql/dao/mod.rs index e27aa416..f991f421 100644 --- a/src/transfer/mysql/dao/mod.rs +++ b/src/transfer/mysql/dao/mod.rs @@ -29,6 +29,9 @@ impl From for UserDo { roles, extend_info, password_hash: v.password, + namespace_privilege_flags: None, + namespace_white_list: Default::default(), + namespace_black_list: Default::default(), } } } diff --git a/src/transfer/sqlite/mod.rs b/src/transfer/sqlite/mod.rs index 296e19a8..14aa3d77 100644 --- a/src/transfer/sqlite/mod.rs +++ b/src/transfer/sqlite/mod.rs @@ -78,6 +78,9 @@ impl From for UserDo { roles, extend_info, password_hash: v.password_hash, + namespace_privilege_flags: None, + namespace_white_list: Default::default(), + namespace_black_list: Default::default(), } } } diff --git a/src/user/mod.rs b/src/user/mod.rs index 84fbcafa..354cbc03 100644 --- a/src/user/mod.rs +++ b/src/user/mod.rs @@ -234,6 +234,9 @@ impl Handler for UserManager { .collect(), enable: true, extend_info: user.extend_info.unwrap_or_default(), + namespace_privilege_flags: None, + namespace_white_list: Default::default(), + namespace_black_list: Default::default(), }; let user_data = user_do.to_bytes(); let req = TableManagerReq::Set { diff --git a/src/user/model.rs b/src/user/model.rs index 6fba65de..7fe42da8 100644 --- a/src/user/model.rs +++ b/src/user/model.rs @@ -1,8 +1,8 @@ -use std::{collections::HashMap, sync::Arc}; - -use serde::{Deserialize, Serialize}; - +use crate::common::model::privilege::{PrivilegeGroup, PrivilegeGroupFlags}; use crate::user::permission::UserRoleHelper; +use serde::{Deserialize, Serialize}; +use std::collections::HashSet; +use std::{collections::HashMap, sync::Arc}; #[derive(Clone, prost::Message, Serialize, Deserialize)] pub struct UserDo { @@ -25,6 +25,12 @@ pub struct UserDo { ::std::collections::HashMap<::prost::alloc::string::String, ::prost::alloc::string::String>, #[prost(string, optional, tag = "9")] pub password_hash: Option, + #[prost(uint32, optional, tag = "10")] + pub namespace_privilege_flags: Option, + #[prost(string, repeated, tag = "11")] + pub namespace_white_list: ::prost::alloc::vec::Vec, + #[prost(string, repeated, tag = "12")] + pub namespace_black_list: ::prost::alloc::vec::Vec, } impl UserDo { @@ -51,6 +57,7 @@ pub struct UserDto { pub enable: Option, pub roles: Option>>, pub extend_info: Option>, + pub namespace_privilege: Option>>, } impl From for UserDto { @@ -59,6 +66,25 @@ impl From for UserDto { for role in &value.roles { roles.push(UserRoleHelper::get_role(role)); } + let namespace_privilege_flags = value.namespace_privilege_flags.unwrap_or_default() as u8; + let namespace_privilege = + if namespace_privilege_flags & PrivilegeGroupFlags::ENABLE.bits() > 0 { + let mut namespace_whitelist = HashSet::new(); + for item in &value.namespace_white_list { + namespace_whitelist.insert(Arc::new(item.clone())); + } + let mut namespace_black_list = HashSet::new(); + for item in &value.namespace_black_list { + namespace_black_list.insert(Arc::new(item.clone())); + } + Some(PrivilegeGroup::new( + value.namespace_privilege_flags.unwrap_or_default() as u8, + Some(namespace_whitelist), + Some(namespace_black_list), + )) + } else { + Some(PrivilegeGroup::default()) + }; Self { username: Arc::new(value.username), nickname: Some(value.nickname), @@ -71,6 +97,7 @@ impl From for UserDto { enable: Some(value.enable), roles: Some(roles), extend_info: Some(value.extend_info), + namespace_privilege, } } }