mirror of
https://github.com/openobserve/openobserve.git
synced 2026-11-05 08:09:22 +00:00
root user fixes (#97)
Co-authored-by: Hengfei Yang <hengfei.yang@gmail.com>
This commit is contained in:
co-authored by
Hengfei Yang
parent
c557300450
commit
3605db9b05
+21
-1
@@ -14,7 +14,10 @@
|
||||
|
||||
use argon2::{password_hash::SaltString, Algorithm, Argon2, Params, PasswordHasher, Version};
|
||||
|
||||
use crate::infra::config::PASSWORD_HASH;
|
||||
use crate::{
|
||||
infra::config::{PASSWORD_HASH, USERS},
|
||||
meta::user::UserRole,
|
||||
};
|
||||
|
||||
pub fn get_hash(pass: &str, salt: &str) -> String {
|
||||
let key = format!("{}{}", pass, salt);
|
||||
@@ -38,3 +41,20 @@ pub fn get_hash(pass: &str, salt: &str) -> String {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn is_root_user(user_id: &str) -> bool {
|
||||
match USERS.get(user_id) {
|
||||
Some(user) => user.role.eq(&UserRole::Root),
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test_utils {
|
||||
use super::*;
|
||||
#[actix_web::test]
|
||||
async fn test_is_root_user() {
|
||||
let res = is_root_user("dummy").await;
|
||||
assert_eq!(res, false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
use crate::{
|
||||
common::auth::get_hash,
|
||||
infra::config::{CONFIG, USERS},
|
||||
infra::config::{CONFIG, ROOT_USER},
|
||||
};
|
||||
use http_auth_basic::Credentials;
|
||||
use tonic::{Request, Status};
|
||||
@@ -38,10 +38,10 @@ pub fn check_auth(req: Request<()>) -> Result<Request<()>, Status> {
|
||||
Err(_) => return Err(Status::unauthenticated("No valid auth token")),
|
||||
};
|
||||
|
||||
let user = USERS.get(&CONFIG.auth.root_user_email).unwrap();
|
||||
let user = ROOT_USER.get("root").unwrap();
|
||||
let in_pass = get_hash(&credentials.password, &user.salt);
|
||||
|
||||
if credentials.user_id.eq(&CONFIG.auth.root_user_email)
|
||||
if credentials.user_id.eq(&user.email)
|
||||
&& (user.password.eq(&credentials.password) || user.password.eq(&in_pass))
|
||||
{
|
||||
Ok(req)
|
||||
|
||||
@@ -19,8 +19,7 @@ use actix_web::{
|
||||
};
|
||||
use actix_web_httpauth::extractors::basic::BasicAuth;
|
||||
|
||||
use crate::common::auth::get_hash;
|
||||
use crate::infra::config::CONFIG;
|
||||
use crate::common::auth::{get_hash, is_root_user};
|
||||
use crate::meta::user::UserRole;
|
||||
use crate::service::users;
|
||||
|
||||
@@ -93,22 +92,3 @@ pub async fn validate_credentials(
|
||||
Err(ErrorForbidden("Not allowed"))
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn is_root_user(user_id: &str) -> bool {
|
||||
user_id.eq(&CONFIG.auth.root_user_email)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test_utils {
|
||||
use super::*;
|
||||
#[actix_web::test]
|
||||
async fn test_validate_credentials() {
|
||||
let res = validate_credentials(
|
||||
&CONFIG.auth.root_user_email,
|
||||
&CONFIG.auth.root_user_password,
|
||||
"index",
|
||||
)
|
||||
.await;
|
||||
assert_eq!(res.is_ok(), true)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@ use actix_web_httpauth::extractors::basic::BasicAuth;
|
||||
use serde::Serialize;
|
||||
use std::io::Error;
|
||||
|
||||
use crate::handler::http::auth::is_root_user;
|
||||
use crate::infra::config::{CONFIG, USERS};
|
||||
use crate::common::auth::is_root_user;
|
||||
use crate::infra::config::USERS;
|
||||
use crate::meta::organization::PasscodeResponse;
|
||||
use crate::service::organization::get_passcode;
|
||||
use crate::service::organization::{self, update_passcode};
|
||||
@@ -81,7 +81,7 @@ pub async fn organizarions_by_username(
|
||||
};
|
||||
|
||||
for user in USERS.iter() {
|
||||
if !user.key().ends_with(&CONFIG.auth.root_user_email) {
|
||||
if !user.key().ends_with(&user_name) {
|
||||
let org = Organization {
|
||||
identifier: user.key().split('/').collect::<Vec<&str>>()[0].to_string(),
|
||||
label: user.key().split('/').collect::<Vec<&str>>()[0].to_string(),
|
||||
@@ -134,7 +134,7 @@ pub async fn organizations(credentials: BasicAuth) -> Result<HttpResponse, Error
|
||||
});
|
||||
|
||||
for user in USERS.iter() {
|
||||
if !user.key().ends_with(&CONFIG.auth.root_user_email) {
|
||||
if !user.key().ends_with(&user_id) {
|
||||
id += 1;
|
||||
let org = OrganizationDetails {
|
||||
id,
|
||||
|
||||
@@ -19,8 +19,8 @@ use rand::distributions::{Alphanumeric, DistString};
|
||||
use serde_json::Value;
|
||||
use std::io::Error;
|
||||
|
||||
use crate::common::auth::is_root_user;
|
||||
use crate::handler::http::auth::validate_credentials;
|
||||
use crate::infra::config::CONFIG;
|
||||
use crate::meta;
|
||||
use crate::meta::user::SignInUser;
|
||||
use crate::meta::user::UpdateUser;
|
||||
@@ -147,7 +147,7 @@ pub async fn authentication(
|
||||
{
|
||||
Ok(v) => {
|
||||
if v {
|
||||
if user.name == CONFIG.auth.root_user_email {
|
||||
if is_root_user(&user.name).await {
|
||||
ret.insert("role", Value::String(UserRole::Admin.to_string()));
|
||||
} else if let Some(user) = users::get_user(Some(&org_id), &user.name).await {
|
||||
ret.insert("role", Value::String(user.role.to_string()));
|
||||
|
||||
@@ -52,6 +52,7 @@ lazy_static! {
|
||||
pub static ref STREAM_SCHEMAS: DashMap<String, Vec<Schema>> = DashMap::new();
|
||||
pub static ref QUERY_FUNCTIONS: DashMap<String, Transform> = DashMap::new();
|
||||
pub static ref USERS: DashMap<String, User> = DashMap::new();
|
||||
pub static ref ROOT_USER: DashMap<String, User> = DashMap::new();
|
||||
pub static ref PASSWORD_HASH: DashMap<String, String> = DashMap::new();
|
||||
#[derive(Debug)]
|
||||
pub static ref METRIC_CLUSTER_MAP: DashMap<String, Vec<String>> = DashMap::new();
|
||||
|
||||
@@ -20,7 +20,7 @@ use tonic::{codec::CompressionEncoding, metadata::MetadataValue, transport::Chan
|
||||
|
||||
use crate::handler::grpc::cluster_rpc;
|
||||
use crate::infra::cluster;
|
||||
use crate::infra::config::{CONFIG, USERS};
|
||||
use crate::infra::config::{CONFIG, ROOT_USER};
|
||||
use crate::meta::common::FileKey;
|
||||
|
||||
lazy_static! {
|
||||
@@ -61,8 +61,8 @@ async fn send_to_node(
|
||||
if cluster::ge_node_by_uuid(&node.uuid).is_none() {
|
||||
return Ok(());
|
||||
}
|
||||
let user = USERS.get(&CONFIG.auth.root_user_email).unwrap();
|
||||
let credentials = Credentials::new(&CONFIG.auth.root_user_password, &user.password);
|
||||
let user = ROOT_USER.get("root").unwrap();
|
||||
let credentials = Credentials::new(&user.email, &user.password);
|
||||
let credentials = credentials.as_http_header();
|
||||
let token: MetadataValue<_> = credentials.parse()?;
|
||||
let channel = Channel::from_shared(node.grpc_addr)
|
||||
|
||||
@@ -16,7 +16,7 @@ use std::sync::Arc;
|
||||
use tracing::info_span;
|
||||
|
||||
use crate::common::json;
|
||||
use crate::infra::config::USERS;
|
||||
use crate::infra::config::{ROOT_USER, USERS};
|
||||
use crate::infra::db::Event;
|
||||
use crate::meta::user::User;
|
||||
|
||||
@@ -95,6 +95,9 @@ pub async fn cache() -> Result<(), anyhow::Error> {
|
||||
for (item_key, item_value) in ret {
|
||||
let item_key = item_key.strip_prefix(key).unwrap();
|
||||
let json_val: User = json::from_slice(&item_value).unwrap();
|
||||
if !item_key.contains('/') {
|
||||
ROOT_USER.insert("root".to_string(), json_val.clone());
|
||||
}
|
||||
USERS.insert(item_key.to_string(), json_val);
|
||||
}
|
||||
log::info!("[TRACE] Users Cached");
|
||||
|
||||
@@ -25,7 +25,7 @@ use uuid::Uuid;
|
||||
|
||||
use crate::handler::grpc::cluster_rpc;
|
||||
use crate::infra::cluster;
|
||||
use crate::infra::config::{CONFIG, USERS};
|
||||
use crate::infra::config::{CONFIG, ROOT_USER};
|
||||
use crate::infra::db::etcd;
|
||||
use crate::meta;
|
||||
use crate::meta::search::Response;
|
||||
@@ -290,8 +290,8 @@ async fn search_in_cluster(req: cluster_rpc::SearchRequest) -> Result<Response,
|
||||
let span4 = info_span!("service:search:cluster:do_search").entered();
|
||||
|
||||
// make grpc auth token
|
||||
let user = USERS.get(&CONFIG.auth.root_user_email).unwrap();
|
||||
let credentials = Credentials::new(&CONFIG.auth.root_user_email, &user.password);
|
||||
let user = ROOT_USER.get("root").unwrap();
|
||||
let credentials = Credentials::new(&user.email, &user.password);
|
||||
let credentials = credentials.as_http_header();
|
||||
|
||||
// make cluster request
|
||||
|
||||
@@ -22,13 +22,10 @@ use uuid::Uuid;
|
||||
use super::db;
|
||||
use crate::{common::auth::get_hash, meta::http::HttpResponse as MetaHttpResponse};
|
||||
use crate::{
|
||||
handler::http::auth::is_root_user,
|
||||
common::auth::is_root_user,
|
||||
meta::user::{User, UserList, UserResponse, UserRole},
|
||||
};
|
||||
use crate::{
|
||||
infra::config::{CONFIG, USERS},
|
||||
meta::user::UpdateUser,
|
||||
};
|
||||
use crate::{infra::config::USERS, meta::user::UpdateUser};
|
||||
|
||||
pub async fn post_user(org_id: &str, mut user: User) -> Result<HttpResponse, Error> {
|
||||
let salt = Uuid::new_v4().to_string();
|
||||
@@ -152,7 +149,7 @@ pub async fn update_user(
|
||||
|
||||
pub async fn get_user(org_id: Option<&str>, name: &str) -> Option<User> {
|
||||
let mut local_org = "";
|
||||
let user_key = if name.eq(&CONFIG.auth.root_user_email) {
|
||||
let user_key = if is_root_user(name).await {
|
||||
name.to_owned()
|
||||
} else {
|
||||
match org_id {
|
||||
|
||||
Reference in New Issue
Block a user