mirror of
https://github.com/openobserve/openobserve.git
synced 2026-11-04 16:09:05 +00:00
fix: root user password reset (#8348)
This commit is contained in:
@@ -170,15 +170,16 @@ pub async fn cli() -> Result<bool, anyhow::Error> {
|
||||
// init infra, create data dir & tables
|
||||
let cfg = config::get_config();
|
||||
infra::init().await.expect("infra init failed");
|
||||
db::org_users::cache().await?;
|
||||
match name.as_str() {
|
||||
"reset" => {
|
||||
let component = command.get_one::<String>("component").unwrap();
|
||||
match component.as_str() {
|
||||
"root" => {
|
||||
let _ = users::update_user(
|
||||
let ret = users::update_user(
|
||||
meta::organization::DEFAULT_ORG,
|
||||
cfg.auth.root_user_email.as_str(),
|
||||
false,
|
||||
meta::user::UserUpdateMode::CliUpdate,
|
||||
cfg.auth.root_user_email.as_str(),
|
||||
meta::user::UpdateUser {
|
||||
change_password: true,
|
||||
@@ -198,6 +199,12 @@ pub async fn cli() -> Result<bool, anyhow::Error> {
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
if !ret.status().is_success() {
|
||||
return Err(anyhow::anyhow!(
|
||||
"reset root user failed, error: {:?}",
|
||||
ret.body()
|
||||
));
|
||||
}
|
||||
}
|
||||
"user" => {
|
||||
db::user::reset().await?;
|
||||
|
||||
@@ -127,6 +127,23 @@ pub struct UpdateUser {
|
||||
pub token: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, ToSchema)]
|
||||
pub enum UserUpdateMode {
|
||||
OtherUpdate,
|
||||
SelfUpdate,
|
||||
CliUpdate,
|
||||
}
|
||||
|
||||
impl UserUpdateMode {
|
||||
pub fn is_self_update(&self) -> bool {
|
||||
self == &UserUpdateMode::SelfUpdate
|
||||
}
|
||||
|
||||
pub fn is_cli_update(&self) -> bool {
|
||||
self == &UserUpdateMode::CliUpdate
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_default_user_org() -> UserOrg {
|
||||
UserOrg {
|
||||
name: "".to_string(),
|
||||
|
||||
@@ -29,7 +29,7 @@ use crate::{
|
||||
self,
|
||||
http::HttpResponse as MetaHttpResponse,
|
||||
service_account::{APIToken, ServiceAccountRequest, UpdateServiceAccountRequest},
|
||||
user::{UpdateUser, UserRequest},
|
||||
user::{UpdateUser, UserRequest, UserUpdateMode},
|
||||
},
|
||||
utils::auth::UserEmail,
|
||||
},
|
||||
@@ -226,7 +226,14 @@ pub async fn update(
|
||||
};
|
||||
let initiator_id = &user_email.user_id;
|
||||
|
||||
users::update_user(&org_id, &email_id, false, initiator_id, user).await
|
||||
users::update_user(
|
||||
&org_id,
|
||||
&email_id,
|
||||
UserUpdateMode::OtherUpdate,
|
||||
initiator_id,
|
||||
user,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
/// RemoveServiceAccount
|
||||
|
||||
@@ -45,7 +45,7 @@ use crate::{
|
||||
self,
|
||||
user::{
|
||||
AuthTokens, PostUserRequest, RolesResponse, SignInResponse, SignInUser, UpdateUser,
|
||||
UserOrgRole, UserRequest, UserRoleRequest, get_roles,
|
||||
UserOrgRole, UserRequest, UserRoleRequest, UserUpdateMode, get_roles,
|
||||
},
|
||||
},
|
||||
utils::auth::{UserEmail, generate_presigned_url, is_valid_email},
|
||||
@@ -245,8 +245,12 @@ pub async fn update(
|
||||
});
|
||||
}
|
||||
let initiator_id = &user_email.user_id;
|
||||
let self_update = user_email.user_id.eq(&email_id);
|
||||
users::update_user(&org_id, &email_id, self_update, initiator_id, user).await
|
||||
let update_mode = if user_email.user_id.eq(&email_id) {
|
||||
UserUpdateMode::SelfUpdate
|
||||
} else {
|
||||
UserUpdateMode::OtherUpdate
|
||||
};
|
||||
users::update_user(&org_id, &email_id, update_mode, initiator_id, user).await
|
||||
}
|
||||
|
||||
/// AddUserToOrganization
|
||||
|
||||
+31
-15
@@ -44,7 +44,8 @@ use crate::{
|
||||
http::HttpResponse as MetaHttpResponse,
|
||||
organization::{DEFAULT_ORG, OrgRoleMapping},
|
||||
user::{
|
||||
UpdateUser, UserList, UserOrgRole, UserRequest, UserResponse, get_default_user_org,
|
||||
UpdateUser, UserList, UserOrgRole, UserRequest, UserResponse, UserUpdateMode,
|
||||
get_default_user_org,
|
||||
},
|
||||
},
|
||||
utils::auth::{get_hash, get_role, is_root_user, is_valid_email},
|
||||
@@ -246,9 +247,9 @@ pub async fn create_new_user(mut db_user: DBUser) -> Result<(), anyhow::Error> {
|
||||
pub async fn update_user(
|
||||
org_id: &str,
|
||||
email: &str,
|
||||
self_update: bool,
|
||||
update_mode: UserUpdateMode,
|
||||
initiator_id: &str,
|
||||
user: UpdateUser,
|
||||
mut user: UpdateUser,
|
||||
) -> Result<HttpResponse, Error> {
|
||||
let mut allow_password_update = false;
|
||||
if !is_valid_email(email) {
|
||||
@@ -258,9 +259,16 @@ pub async fn update_user(
|
||||
)));
|
||||
}
|
||||
let is_email_root = is_root_user(email);
|
||||
#[cfg(not(feature = "enterprise"))]
|
||||
if is_email_root {
|
||||
user.role = Some(crate::common::meta::user::UserRoleRequest {
|
||||
role: UserRole::Root.to_string(),
|
||||
custom: None,
|
||||
});
|
||||
}
|
||||
|
||||
// Only root user can update root user
|
||||
if is_email_root && !self_update {
|
||||
if is_email_root && !update_mode.is_self_update() && !update_mode.is_cli_update() {
|
||||
return Ok(HttpResponse::BadRequest().json(MetaHttpResponse::message(
|
||||
http::StatusCode::BAD_REQUEST,
|
||||
"Root user cannot be updated",
|
||||
@@ -307,7 +315,7 @@ pub async fn update_user(
|
||||
"Updates not allowed with external users, please update with source system",
|
||||
)));
|
||||
}
|
||||
if !self_update {
|
||||
if !update_mode.is_self_update() {
|
||||
if is_root_user(initiator_id) {
|
||||
allow_password_update = true
|
||||
} else {
|
||||
@@ -325,14 +333,20 @@ pub async fn update_user(
|
||||
}
|
||||
}
|
||||
}
|
||||
if !self_update && local_user.role.eq(&UserRole::Root) {
|
||||
if local_user.role.eq(&UserRole::Root)
|
||||
&& !update_mode.is_self_update()
|
||||
&& !update_mode.is_cli_update()
|
||||
{
|
||||
return Ok(HttpResponse::BadRequest().json(MetaHttpResponse::message(
|
||||
http::StatusCode::BAD_REQUEST,
|
||||
"Only root user can update its details",
|
||||
)));
|
||||
}
|
||||
new_user = local_user.clone();
|
||||
if self_update && user.old_password.is_some() && user.new_password.is_some() {
|
||||
if update_mode.is_self_update()
|
||||
&& user.old_password.is_some()
|
||||
&& user.new_password.is_some()
|
||||
{
|
||||
if local_user.password.eq(&get_hash(
|
||||
&user.clone().old_password.unwrap(),
|
||||
&local_user.salt,
|
||||
@@ -350,10 +364,12 @@ pub async fn update_user(
|
||||
message,
|
||||
)));
|
||||
}
|
||||
} else if self_update && user.new_password.is_some() && user.old_password.is_none()
|
||||
} else if update_mode.is_self_update()
|
||||
&& user.new_password.is_some()
|
||||
&& user.old_password.is_none()
|
||||
{
|
||||
message = "Please provide existing password";
|
||||
} else if !self_update
|
||||
} else if !update_mode.is_self_update()
|
||||
&& allow_password_update
|
||||
&& user.new_password.is_some()
|
||||
&& !local_user.is_external
|
||||
@@ -378,7 +394,7 @@ pub async fn update_user(
|
||||
}
|
||||
if user.role.is_some()
|
||||
&& !local_user.is_external
|
||||
&& (!self_update
|
||||
&& (!update_mode.is_self_update()
|
||||
|| (local_user.role.eq(&UserRole::Admin)
|
||||
// Editor can update other's roles, but viewer can update only self
|
||||
|| local_user.role.eq(&UserRole::Editor)
|
||||
@@ -393,7 +409,7 @@ pub async fn update_user(
|
||||
new_role = Some(new_user.role.clone());
|
||||
if local_user.role.eq(&UserRole::Root) && new_user.role.ne(&UserRole::Root) {
|
||||
message = "Root user role cannot be changed";
|
||||
} else if self_update && local_user.role < new_user.role {
|
||||
} else if update_mode.is_self_update() && local_user.role < new_user.role {
|
||||
message = "Self role cannot be upgraded";
|
||||
} else if local_user.role.ne(&new_user.role) {
|
||||
#[cfg(feature = "enterprise")]
|
||||
@@ -1380,7 +1396,7 @@ mod tests {
|
||||
let resp = update_user(
|
||||
"dummy",
|
||||
"user2@example.com",
|
||||
true,
|
||||
UserUpdateMode::SelfUpdate,
|
||||
"user2@example.com",
|
||||
UpdateUser {
|
||||
token: Some("new_token".to_string()),
|
||||
@@ -1402,7 +1418,7 @@ mod tests {
|
||||
let resp = update_user(
|
||||
"dummy",
|
||||
"user2@example.com",
|
||||
false,
|
||||
UserUpdateMode::OtherUpdate,
|
||||
"admin@zo.dev",
|
||||
UpdateUser {
|
||||
token: Some("new_token".to_string()),
|
||||
@@ -1635,7 +1651,7 @@ mod tests {
|
||||
let resp = update_user(
|
||||
"dummy",
|
||||
"invalid-email",
|
||||
false,
|
||||
UserUpdateMode::OtherUpdate,
|
||||
"admin@zo.dev",
|
||||
UpdateUser {
|
||||
token: None,
|
||||
@@ -1655,7 +1671,7 @@ mod tests {
|
||||
let resp = update_user(
|
||||
"dummy",
|
||||
"nonexistent@example.com",
|
||||
false,
|
||||
UserUpdateMode::OtherUpdate,
|
||||
"admin@zo.dev",
|
||||
UpdateUser {
|
||||
token: None,
|
||||
|
||||
Reference in New Issue
Block a user