Skip to content

Commit

Permalink
调整raft user逻辑,支持维护用户角色、是否启用功能 issure #29
Browse files Browse the repository at this point in the history
  • Loading branch information
heqingpan committed Dec 6, 2023
1 parent 4a8f3d8 commit e83d687
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 85 deletions.
6 changes: 3 additions & 3 deletions src/common/model/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::collections::HashMap;
use std::{collections::HashMap, sync::Arc};

use serde::{Deserialize, Serialize};

Expand Down Expand Up @@ -44,8 +44,8 @@ pub struct PageResult<T> {

#[derive(Debug, Default, Clone, Deserialize, Serialize)]
pub struct UserSession {
pub username: String,
pub username: Arc<String>,
pub nickname: String,
pub roles: Vec<String>,
pub roles: Vec<Arc<String>>,
pub extend_infos: HashMap<String, String>,
}
2 changes: 1 addition & 1 deletion src/console/login_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ pub async fn login(
);
let session = Arc::new(UserSession {
username: user.username,
nickname: user.nickname,
nickname: user.nickname.unwrap_or_default(),
..Default::default()
});
let cache_req = CacheManagerReq::Set {
Expand Down
10 changes: 6 additions & 4 deletions src/console/user_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::{
appdata::AppShareData,
model::{ApiResult, UserSession},
},
user::{UserManagerReq, UserManagerResult},
user::{model::UserDto, UserManagerReq, UserManagerResult},
};

#[derive(Debug, Deserialize, Serialize)]
Expand Down Expand Up @@ -49,9 +49,11 @@ pub async fn reset_password(
UserManagerResult::CheckUserResult(valid, _user) => {
if valid {
let msg = UserManagerReq::UpdateUser {
name: username,
nickname: None,
password: Some(param.new_password),
user: UserDto {
username: username,
password: Some(param.new_password),
..Default::default()
},
};
if let Ok(Ok(_r)) = app.user_manager.send(msg).await {
return Ok(HttpResponse::Ok().json(ApiResult::success(Some(true))));
Expand Down
49 changes: 26 additions & 23 deletions src/user/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ use serde::{Deserialize, Serialize};

use crate::common::appdata::AppShareData;

use super::{model::UserDo, UserManagerReq};
use super::{
model::{UserDo, UserDto},
UserManagerReq,
};

#[derive(Debug, Deserialize, Serialize)]
pub struct UserVo {
Expand Down Expand Up @@ -54,9 +57,12 @@ pub async fn add_user(
web::Form(param): web::Form<UserVo>,
) -> actix_web::Result<impl Responder> {
let msg = UserManagerReq::AddUser {
name: param.username,
nickname: param.nickname.unwrap(),
password: param.password.unwrap(),
user: UserDto {
username: param.username,
nickname: Some(param.nickname.unwrap()),
password: Some(param.password.unwrap()),
..Default::default()
},
};
app.user_manager.send(msg).await.ok();
Ok("{\"ok\":1}")
Expand All @@ -67,9 +73,12 @@ pub async fn update_user(
web::Form(param): web::Form<UserVo>,
) -> actix_web::Result<impl Responder> {
let msg = UserManagerReq::UpdateUser {
name: param.username,
nickname: param.nickname,
password: param.password,
user: UserDto {
username: param.username,
nickname: Some(param.nickname.unwrap()),
password: Some(param.password.unwrap()),
..Default::default()
},
};
app.user_manager.send(msg).await.ok();
Ok("{\"ok\":1}")
Expand Down Expand Up @@ -105,14 +114,11 @@ pub async fn get_user(
name: param.username,
};
match app.user_manager.send(msg).await.unwrap().unwrap() {
super::UserManagerResult::QueryUser(user) => {
let user: Option<UserVo> = user.map(|e| e.as_ref().to_owned().into());
Ok(Json(UserResult::<UserVo> {
success: true,
msg: None,
data: user,
}))
}
super::UserManagerResult::QueryUser(user) => Ok(Json(UserResult::<UserDto> {
success: true,
msg: None,
data: user,
})),
_ => Ok(Json(UserResult {
success: false,
msg: Some("result type is error".to_owned()),
Expand All @@ -132,14 +138,11 @@ pub async fn get_user_page_list(
is_rev: param.is_rev.unwrap_or_default(),
};
match app.user_manager.send(msg).await.unwrap().unwrap() {
super::UserManagerResult::UserPageResult(size, list) => {
let list: Vec<UserVo> = list.into_iter().map(|e| e.into()).collect();
Ok(Json(UserResult {
success: true,
msg: None,
data: Some(PageResult { size, list }),
}))
}
super::UserManagerResult::UserPageResult(size, list) => Ok(Json(UserResult {
success: true,
msg: None,
data: Some(PageResult { size, list }),
})),
_ => Ok(Json(UserResult {
success: false,
msg: Some("result type is error".to_owned()),
Expand Down
124 changes: 75 additions & 49 deletions src/user/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{collections::HashMap, sync::Arc, time::Duration};
use std::{sync::Arc, time::Duration};

use actix::prelude::*;
use bean_factory::{bean, Inject};
Expand All @@ -15,14 +15,36 @@ use crate::{
},
};

use self::model::UserDo;
use self::model::{UserDo, UserDto};

pub mod api;
pub mod model;

lazy_static::lazy_static! {
static ref USER_TABLE_NAME: Arc<String> = Arc::new("user".to_string());
static ref USER_ROLE_MANAGER: Arc<String> = Arc::new("0".to_string());
static ref USER_ROLE_DEVELOPER: Arc<String> = Arc::new("1".to_string());
static ref USER_ROLE_VISITOR: Arc<String> = Arc::new("2".to_string());
static ref ALL_ROLES: Vec<Arc<String>> = vec![USER_ROLE_MANAGER.clone(),USER_ROLE_DEVELOPER.clone(),USER_ROLE_VISITOR.clone()];
}

pub struct UserRoleHelper;

impl UserRoleHelper {
pub fn get_all_roles() -> Vec<Arc<String>> {
ALL_ROLES.clone()
}

pub fn get_role(role_value: &str) -> Arc<String> {
for item in ALL_ROLES.iter() {
if role_value == item.as_str() {
return item.clone();
}
}
Arc::new(role_value.to_owned())
}
}

#[bean(inject)]
pub struct UserManager {
//cache: MemCache<Arc<String>, Arc<UserDto>>,
Expand Down Expand Up @@ -59,11 +81,14 @@ impl UserManager {
};
if let TableManagerResult::PageListResult(count, _) = table_manager.send(req).await?? {
if count == 0 {
let user_manager_req = UserManagerReq::AddUser {
name: Arc::new("admin".to_owned()),
nickname: "admin".to_owned(),
password: "admin".to_owned(),
let user = UserDto {
username: Arc::new("admin".to_owned()),
nickname: Some("admin".to_owned()),
password: Some("admin".to_owned()),
roles: Some(vec![USER_ROLE_MANAGER.clone()]),
..Default::default()
};
let user_manager_req = UserManagerReq::AddUser { user };
self_addr.do_send(user_manager_req);
}
}
Expand Down Expand Up @@ -133,14 +158,10 @@ impl Actor for UserManager {
#[rtype(result = "anyhow::Result<UserManagerResult>")]
pub enum UserManagerReq {
AddUser {
name: Arc<String>,
nickname: String,
password: String,
user: UserDto,
},
UpdateUser {
name: Arc<String>,
nickname: Option<String>,
password: Option<String>,
user: UserDto,
},
CheckUser {
name: Arc<String>,
Expand All @@ -161,14 +182,14 @@ pub enum UserManagerInnerCtx {
UpdateUser { key: Arc<String>, value: UserDo },
CheckUserResult(Arc<String>, bool, UserDo),
QueryUser(Arc<String>, Option<UserDo>),
UserPageResult(usize, Vec<UserDo>),
UserPageResult(usize, Vec<UserDto>),
}

pub enum UserManagerResult {
None,
CheckUserResult(bool, UserDo),
QueryUser(Option<Arc<UserDo>>),
UserPageResult(usize, Vec<UserDo>),
CheckUserResult(bool, UserDto),
QueryUser(Option<UserDto>),
UserPageResult(usize, Vec<UserDto>),
}

impl Handler<UserManagerReq> for UserManager {
Expand All @@ -184,74 +205,82 @@ impl Handler<UserManagerReq> for UserManager {
let query_info_at_cache = false;
let fut = async move {
match msg {
UserManagerReq::AddUser {
name,
nickname,
password,
} => {
UserManagerReq::AddUser { user } => {
let now = (now_millis() / 1000) as u32;
let user = UserDo {
username: name.as_ref().to_owned(),
password,
nickname,
let user_do = UserDo {
username: user.username.as_ref().to_owned(),
password: user.password.unwrap_or_default(),
nickname: user.nickname.unwrap_or_default(),
gmt_create: now,
gmt_modified: now,
roles: vec![],
roles: user
.roles
.unwrap()
.into_iter()
.map(|e| e.as_ref().to_owned())
.collect(),
enable: true,
extend_info: HashMap::new(),
extend_info: user.extend_info.unwrap_or_default(),
};
let user_data = user.to_bytes();
let user_data = user_do.to_bytes();
let req = TableManagerReq::Set {
table_name: USER_TABLE_NAME.clone(),
key: name.as_bytes().to_owned(),
key: user.username.as_bytes().to_owned(),
value: user_data,
last_seq_id: None,
};
if let Some(raft_table_route) = raft_table_route {
raft_table_route.request(req).await.ok();
}
Ok(UserManagerInnerCtx::UpdateUser {
key: name,
value: user,
key: user.username,
value: user_do,
})
}
UserManagerReq::UpdateUser {
name,
nickname,
password,
} => {
UserManagerReq::UpdateUser { user } => {
let mut last_user = if let Some(raft_table_route) = &raft_table_route {
let query_req = TableManagerQueryReq::GetByArcKey {
table_name: USER_TABLE_NAME.clone(),
key: name.clone(),
key: user.username.clone(),
};
match raft_table_route.get_leader_data(query_req).await? {
TableManagerResult::Value(old_value) => UserDo::from_bytes(&old_value)?,
_ => return Err(anyhow::anyhow!("not found user {}", &name)),
_ => return Err(anyhow::anyhow!("not found user {}", &user.username)),
}
} else {
return Err(anyhow::anyhow!("raft_table_route is none "));
};
let now = (now_millis() / 1000) as u32;
last_user.gmt_modified = now;
if let Some(nickname) = nickname {
if let Some(nickname) = user.nickname {
last_user.nickname = nickname;
}
if let Some(password) = password {
if let Some(password) = user.password {
last_user.password = password;
}
if let Some(enable) = user.enable {
last_user.enable = enable;
}
if let Some(extend_info) = user.extend_info {
last_user.extend_info = extend_info;
}
if let Some(roles) = user.roles {
last_user.roles =
roles.into_iter().map(|e| e.as_ref().to_owned()).collect();
}
last_user.gmt_modified = now;
let user_data = last_user.to_bytes();
let req = TableManagerReq::Set {
table_name: USER_TABLE_NAME.clone(),
key: name.as_bytes().to_owned(),
key: user.username.as_bytes().to_owned(),
value: user_data,
last_seq_id: None,
};
if let Some(raft_table_route) = raft_table_route {
raft_table_route.request(req).await.ok();
}
Ok(UserManagerInnerCtx::UpdateUser {
key: name,
key: user.username,
value: last_user,
})
}
Expand All @@ -270,7 +299,7 @@ impl Handler<UserManagerReq> for UserManager {
};
Ok(UserManagerInnerCtx::CheckUserResult(
name,
last_user.password == password,
last_user.enable && last_user.password == password,
last_user,
))
}
Expand Down Expand Up @@ -313,7 +342,7 @@ impl Handler<UserManagerReq> for UserManager {
TableManagerResult::PageListResult(size, list) => {
let mut user_list = Vec::with_capacity(list.len());
for (_, v) in list {
user_list.push(UserDo::from_bytes(&v)?);
user_list.push(UserDo::from_bytes(&v)?.into());
}
Ok(UserManagerInnerCtx::UserPageResult(size, user_list))
}
Expand All @@ -336,13 +365,10 @@ impl Handler<UserManagerReq> for UserManager {
//if v {
// act.update_timeout(&key);
//}
Ok(UserManagerResult::CheckUserResult(v, user))
Ok(UserManagerResult::CheckUserResult(v, user.into()))
}
UserManagerInnerCtx::QueryUser(_key, user) => match user {
Some(user) => {
let user = Arc::new(user);
Ok(UserManagerResult::QueryUser(Some(user)))
}
Some(user) => Ok(UserManagerResult::QueryUser(Some(user.into()))),
None => Ok(UserManagerResult::QueryUser(None)),
},
UserManagerInnerCtx::UserPageResult(size, list) => {
Expand Down
Loading

0 comments on commit e83d687

Please sign in to comment.