From 871f954fe2c61c4ed0664b6bbc29edd30ef89dec Mon Sep 17 00:00:00 2001 From: Hengfei Yang Date: Tue, 1 Apr 2025 12:27:11 +0800 Subject: [PATCH] feat: add new ENV to set token for root user (#6438) --- src/cli/basic/cli.rs | 6 ++++- src/common/meta/user.rs | 2 ++ src/common/utils/auth.rs | 1 + src/common/utils/auth_tests.rs | 1 + src/config/src/config.rs | 2 ++ src/handler/http/auth/validator.rs | 2 ++ .../http/request/service_accounts/mod.rs | 1 + src/job/mod.rs | 5 ++++ src/service/organization.rs | 2 ++ src/service/users.rs | 24 +++++++++++++------ 10 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/cli/basic/cli.rs b/src/cli/basic/cli.rs index 192492a36d..3aa435ac77 100644 --- a/src/cli/basic/cli.rs +++ b/src/cli/basic/cli.rs @@ -252,7 +252,11 @@ pub async fn cli() -> Result { role: Some(meta::user::UserRole::Root), first_name: Some("root".to_owned()), last_name: Some("".to_owned()), - token: None, + token: if cfg.auth.root_user_token.is_empty() { + None + } else { + Some(cfg.auth.root_user_token.clone()) + }, }, ) .await?; diff --git a/src/common/meta/user.rs b/src/common/meta/user.rs index 95773b4712..774b817c2a 100644 --- a/src/common/meta/user.rs +++ b/src/common/meta/user.rs @@ -32,6 +32,8 @@ pub struct UserRequest { /// Is the user created via ldap flow. #[serde(default)] pub is_external: bool, + #[serde(skip_serializing)] + pub token: Option, } impl UserRequest { diff --git a/src/common/utils/auth.rs b/src/common/utils/auth.rs index 8b4f03555b..4a7c13e8ae 100644 --- a/src/common/utils/auth.rs +++ b/src/common/utils/auth.rs @@ -1012,6 +1012,7 @@ mod tests { first_name: "root".to_owned(), last_name: "".to_owned(), is_external: false, + token: None, }, ) .await; diff --git a/src/common/utils/auth_tests.rs b/src/common/utils/auth_tests.rs index 6ec024356d..ef0d3b464d 100644 --- a/src/common/utils/auth_tests.rs +++ b/src/common/utils/auth_tests.rs @@ -2961,6 +2961,7 @@ mod tests { auth: config::Auth { root_user_email: String::default(), root_user_password: String::default(), + root_user_token: String::default(), cookie_max_age: i64::default(), cookie_same_site_lax: bool::default(), cookie_secure_only: bool::default(), diff --git a/src/config/src/config.rs b/src/config/src/config.rs index 53fa14db11..897a9ef148 100644 --- a/src/config/src/config.rs +++ b/src/config/src/config.rs @@ -550,6 +550,8 @@ pub struct Auth { pub root_user_email: String, #[env_config(name = "ZO_ROOT_USER_PASSWORD")] pub root_user_password: String, + #[env_config(name = "ZO_ROOT_USER_TOKEN")] + pub root_user_token: String, #[env_config(name = "ZO_COOKIE_MAX_AGE", default = 2592000)] // seconds, 30 days pub cookie_max_age: i64, #[env_config(name = "ZO_COOKIE_SAME_SITE_LAX", default = true)] diff --git a/src/handler/http/auth/validator.rs b/src/handler/http/auth/validator.rs index e03e0a8889..15fc1c9608 100644 --- a/src/handler/http/auth/validator.rs +++ b/src/handler/http/auth/validator.rs @@ -1038,6 +1038,7 @@ mod tests { first_name: "root".to_owned(), last_name: "".to_owned(), is_external: false, + token: None, }, ) .await @@ -1051,6 +1052,7 @@ mod tests { first_name: "root".to_owned(), last_name: "".to_owned(), is_external: true, + token: None, }, init_user, ) diff --git a/src/handler/http/request/service_accounts/mod.rs b/src/handler/http/request/service_accounts/mod.rs index 02d027227a..d1cc6d43a2 100644 --- a/src/handler/http/request/service_accounts/mod.rs +++ b/src/handler/http/request/service_accounts/mod.rs @@ -120,6 +120,7 @@ pub async fn save( password: generate_random_string(16), role: meta::user::UserRole::ServiceAccount, is_external: false, + token: None, }; users::post_user(&org_id, user, &initiator_id).await diff --git a/src/job/mod.rs b/src/job/mod.rs index 69f55757c3..dd20eeb877 100644 --- a/src/job/mod.rs +++ b/src/job/mod.rs @@ -71,6 +71,11 @@ pub async fn init() -> Result<(), anyhow::Error> { first_name: "root".to_owned(), last_name: "".to_owned(), is_external: false, + token: if cfg.auth.root_user_token.is_empty() { + None + } else { + Some(cfg.auth.root_user_token.clone()) + }, }, ) .await; diff --git a/src/service/organization.rs b/src/service/organization.rs index 1c8c90a443..645b914ce2 100644 --- a/src/service/organization.rs +++ b/src/service/organization.rs @@ -266,6 +266,7 @@ mod tests { first_name: "root".to_owned(), last_name: "".to_owned(), is_external: false, + token: None, }, ) .await @@ -280,6 +281,7 @@ mod tests { first_name: "admin".to_owned(), last_name: "".to_owned(), is_external: false, + token: None, }, init_user, ) diff --git a/src/service/users.rs b/src/service/users.rs index ce45352081..725218efa7 100644 --- a/src/service/users.rs +++ b/src/service/users.rs @@ -803,20 +803,29 @@ pub async fn root_user_exists() -> bool { } } -pub(crate) async fn create_root_user(org_id: &str, usr_req: UserRequest) -> Result<(), Error> { +pub(crate) async fn create_root_user(org_id: &str, user_req: UserRequest) -> Result<(), Error> { let cfg = get_config(); let salt = ider::uuid(); - let password = get_hash(&usr_req.password, &salt); - let password_ext = get_hash(&usr_req.password, &cfg.auth.ext_auth_salt); - let token = generate_random_string(16); - let rum_token = format!("rum{}", generate_random_string(16)); - let user = usr_req.to_new_dbuser( + let password = get_hash(&user_req.password, &salt); + let password_ext = get_hash(&user_req.password, &cfg.auth.ext_auth_salt); + let token = user_req + .token + .clone() + .unwrap_or_else(|| generate_random_string(16)); + let rum_token = format!( + "rum{}", + user_req + .token + .clone() + .unwrap_or_else(|| generate_random_string(16)) + ); + let user = user_req.to_new_dbuser( password, salt, org_id.replace(' ', "_"), token, rum_token, - usr_req.is_external, + user_req.is_external, password_ext, ); db::user::set(&user).await.unwrap(); @@ -880,6 +889,7 @@ mod tests { first_name: "user".to_owned(), last_name: "".to_owned(), is_external: false, + token: None, }, "admin@zo.dev", )