admin based on title
This commit is contained in:
@@ -105,12 +105,17 @@ impl<'r> FromRequest<'r> for CurrentUser {
|
|||||||
let db = try_outcome!(request.guard::<Db>().await);
|
let db = try_outcome!(request.guard::<Db>().await);
|
||||||
if let Some(u) = User::get_by_token(&db, &rconn, token).await {
|
if let Some(u) = User::get_by_token(&db, &rconn, token).await {
|
||||||
let namehash = rh.hash_with_salt(&u.name);
|
let namehash = rh.hash_with_salt(&u.name);
|
||||||
|
let user_base = CurrentUser::from_hash(&rconn, namehash).await;
|
||||||
Some(CurrentUser {
|
Some(CurrentUser {
|
||||||
id: Some(u.id),
|
id: Some(u.id),
|
||||||
is_admin: u.is_admin
|
is_admin: u.is_admin
|
||||||
|| is_elected_admin(&rconn, &namehash).await.unwrap(),
|
|| is_elected_admin(&rconn, &user_base.custom_title)
|
||||||
is_candidate: is_elected_candidate(&rconn, &namehash).await.unwrap(),
|
.await
|
||||||
..CurrentUser::from_hash(&rconn, namehash).await
|
.unwrap(),
|
||||||
|
is_candidate: is_elected_candidate(&rconn, &user_base.custom_title)
|
||||||
|
.await
|
||||||
|
.unwrap(),
|
||||||
|
..user_base
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|||||||
@@ -177,6 +177,8 @@ pub async fn get_list(
|
|||||||
"count": ps_data.len(),
|
"count": ps_data.len(),
|
||||||
"custom_title": user.custom_title,
|
"custom_title": user.custom_title,
|
||||||
"title_secret": user.title_secret,
|
"title_secret": user.title_secret,
|
||||||
|
"is_admin": user.is_admin,
|
||||||
|
"is_candidate": user.is_candidate,
|
||||||
"auto_block_rank": user.auto_block_rank,
|
"auto_block_rank": user.auto_block_rank,
|
||||||
"announcement": get_announcement(&rconn).await?,
|
"announcement": get_announcement(&rconn).await?,
|
||||||
"code": 0
|
"code": 0
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use crate::api::{CurrentUser, JsonApi};
|
use crate::api::{CurrentUser, JsonApi};
|
||||||
use crate::random_hasher::RandomHasher;
|
use crate::random_hasher::RandomHasher;
|
||||||
use crate::rds_conn::RdsConn;
|
use crate::rds_conn::RdsConn;
|
||||||
use crate::rds_models::Systemlog;
|
use crate::rds_models::{get_admin_list, get_candidate_list, Systemlog};
|
||||||
use rocket::serde::json::{json, Value};
|
use rocket::serde::json::{json, Value};
|
||||||
use rocket::State;
|
use rocket::State;
|
||||||
|
|
||||||
@@ -14,6 +14,8 @@ pub async fn get_systemlog(user: CurrentUser, rh: &State<RandomHasher>, rconn: R
|
|||||||
"salt": look!(rh.salt),
|
"salt": look!(rh.salt),
|
||||||
"start_time": rh.start_time.timestamp(),
|
"start_time": rh.start_time.timestamp(),
|
||||||
"custom_title": user.custom_title,
|
"custom_title": user.custom_title,
|
||||||
|
"admin_list": get_admin_list(&rconn).await?,
|
||||||
|
"candidate_list": get_candidate_list(&rconn).await?,
|
||||||
"data": logs.into_iter().map(|log|
|
"data": logs.into_iter().map(|log|
|
||||||
json!({
|
json!({
|
||||||
"type": log.action_type,
|
"type": log.action_type,
|
||||||
|
|||||||
@@ -233,9 +233,17 @@ impl CustomTitle {
|
|||||||
Err(PolicyError::TitleUsed)?
|
Err(PolicyError::TitleUsed)?
|
||||||
} else {
|
} else {
|
||||||
let ori_secret: Option<String> = rconn.get(KEY_TITLE_SECRET!(title)).await?;
|
let ori_secret: Option<String> = rconn.get(KEY_TITLE_SECRET!(title)).await?;
|
||||||
|
if ori_secret.is_none() {
|
||||||
|
clear_title_from_admins(&rconn, title).await?;
|
||||||
|
}
|
||||||
ori_secret
|
ori_secret
|
||||||
.map_or(Some(()), |s| (s.eq(&secret).then_some(())))
|
.map_or(Some(()), |s| (s.eq(&secret).then_some(())))
|
||||||
.ok_or(PolicyError::TitleProtected)?;
|
.ok_or(PolicyError::TitleProtected)?;
|
||||||
|
|
||||||
|
let old_title: Option<String> = rconn.hget(KEY_CUSTOM_TITLE, namehash).await?;
|
||||||
|
if let Some(t) = old_title {
|
||||||
|
clear_title_from_admins(&rconn, &t).await?;
|
||||||
|
}
|
||||||
rconn.hset(KEY_CUSTOM_TITLE, namehash, title).await?;
|
rconn.hset(KEY_CUSTOM_TITLE, namehash, title).await?;
|
||||||
rconn.hset(KEY_CUSTOM_TITLE, title, namehash).await?;
|
rconn.hset(KEY_CUSTOM_TITLE, title, namehash).await?;
|
||||||
Ok(Self::gen_and_set_secret(&rconn, title).await?)
|
Ok(Self::gen_and_set_secret(&rconn, title).await?)
|
||||||
@@ -332,12 +340,33 @@ pub async fn get_announcement(rconn: &RdsConn) -> RedisResult<Option<String>> {
|
|||||||
rconn.clone().get(KEY_ANNOUNCEMENT).await
|
rconn.clone().get(KEY_ANNOUNCEMENT).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn is_elected_candidate(rconn: &RdsConn, namehash: &str) -> RedisResult<bool> {
|
pub async fn is_elected_candidate(rconn: &RdsConn, title: &str) -> RedisResult<bool> {
|
||||||
rconn.clone().sismember(KEY_CANDIDATE, namehash).await
|
if title.is_empty() {
|
||||||
|
return Ok(false);
|
||||||
|
}
|
||||||
|
rconn.clone().sismember(KEY_CANDIDATE, title).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn is_elected_admin(rconn: &RdsConn, namehash: &str) -> RedisResult<bool> {
|
pub async fn is_elected_admin(rconn: &RdsConn, title: &str) -> RedisResult<bool> {
|
||||||
rconn.clone().sismember(KEY_ADMIN, namehash).await
|
if title.is_empty() {
|
||||||
|
return Ok(false);
|
||||||
|
}
|
||||||
|
rconn.clone().sismember(KEY_ADMIN, title).await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_admin_list(rconn: &RdsConn) -> RedisResult<Vec<String>> {
|
||||||
|
rconn.clone().smembers(KEY_ADMIN).await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_candidate_list(rconn: &RdsConn) -> RedisResult<Vec<String>> {
|
||||||
|
rconn.clone().smembers(KEY_CANDIDATE).await
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn clear_title_from_admins(rconn: &RdsConn, title: &str) -> RedisResult<()> {
|
||||||
|
let mut rconn = rconn.clone();
|
||||||
|
rconn.srem(KEY_CANDIDATE, title).await?;
|
||||||
|
rconn.srem(KEY_ADMIN, title).await?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) use init;
|
pub(crate) use init;
|
||||||
|
|||||||
Reference in New Issue
Block a user