Skip to content

Commit 5e89972

Browse files
chore: allow user to be created without role (#1428)
this is helpful when an admin wants to create a user and assign group to it
1 parent 7d5600b commit 5e89972

File tree

4 files changed

+37
-46
lines changed

4 files changed

+37
-46
lines changed

src/handlers/http/modal/query/querier_rbac.rs

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -51,33 +51,26 @@ pub async fn post_user(
5151
let user_roles: HashSet<String> = if let Some(body) = body {
5252
serde_json::from_value(body.into_inner())?
5353
} else {
54-
return Err(RBACError::RoleValidationError);
54+
HashSet::new()
5555
};
5656

57-
if user_roles.is_empty() {
58-
return Err(RBACError::RoleValidationError);
59-
} else {
60-
let mut non_existant_roles = Vec::new();
61-
user_roles
62-
.iter()
63-
.map(|r| {
64-
if !roles().contains_key(r) {
65-
non_existant_roles.push(r.clone());
66-
}
67-
})
68-
.for_each(drop);
69-
if !non_existant_roles.is_empty() {
70-
return Err(RBACError::RolesDoNotExist(non_existant_roles));
57+
let mut non_existent_roles = Vec::new();
58+
for role in &user_roles {
59+
if !roles().contains_key(role) {
60+
non_existent_roles.push(role.clone());
7161
}
7262
}
63+
if !non_existent_roles.is_empty() {
64+
return Err(RBACError::RolesDoNotExist(non_existent_roles));
65+
}
7366
let _guard = UPDATE_LOCK.lock().await;
7467
if Users.contains(&username)
7568
|| metadata
7669
.users
7770
.iter()
7871
.any(|user| matches!(&user.ty, UserType::Native(basic) if basic.username == username))
7972
{
80-
return Err(RBACError::UserExists);
73+
return Err(RBACError::UserExists(username));
8174
}
8275

8376
let (user, password) = user::User::new_basic(username.clone());
@@ -89,12 +82,13 @@ pub async fn post_user(
8982
Users.put_user(user.clone());
9083

9184
sync_user_creation_with_ingestors(user, &Some(user_roles)).await?;
92-
93-
add_roles_to_user(
94-
web::Path::<String>::from(username.clone()),
95-
web::Json(created_role),
96-
)
97-
.await?;
85+
if !created_role.is_empty() {
86+
add_roles_to_user(
87+
web::Path::<String>::from(username.clone()),
88+
web::Json(created_role),
89+
)
90+
.await?;
91+
}
9892

9993
Ok(password)
10094
}

src/handlers/http/modal/query_server.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ impl QueryServer {
194194
)
195195
.service(
196196
web::resource("/{username}")
197-
// PUT /user/{username} => Create a new user
197+
// POST /user/{username} => Create a new user
198198
.route(
199199
web::post()
200200
.to(querier_rbac::post_user)

src/handlers/http/modal/server.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,7 @@ impl Server {
641641
)
642642
.service(
643643
web::resource("/{username}")
644-
// PUT /user/{username} => Create a new user
644+
// POST /user/{username} => Create a new user
645645
.route(
646646
web::post()
647647
.to(http::rbac::post_user)

src/handlers/http/rbac.rs

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -108,30 +108,26 @@ pub async fn post_user(
108108
let user_roles: HashSet<String> = if let Some(body) = body {
109109
serde_json::from_value(body.into_inner())?
110110
} else {
111-
return Err(RBACError::RoleValidationError);
111+
HashSet::new()
112112
};
113113

114-
if user_roles.is_empty() {
115-
return Err(RBACError::RoleValidationError);
116-
} else {
117-
let mut non_existent_roles = Vec::new();
118-
for role in &user_roles {
119-
if !roles().contains_key(role) {
120-
non_existent_roles.push(role.clone());
121-
}
122-
}
123-
if !non_existent_roles.is_empty() {
124-
return Err(RBACError::RolesDoNotExist(non_existent_roles));
114+
let mut non_existent_roles = Vec::new();
115+
for role in &user_roles {
116+
if !roles().contains_key(role) {
117+
non_existent_roles.push(role.clone());
125118
}
126119
}
120+
if !non_existent_roles.is_empty() {
121+
return Err(RBACError::RolesDoNotExist(non_existent_roles));
122+
}
127123
let _guard = UPDATE_LOCK.lock().await;
128124
if Users.contains(&username) && Users.contains(&username)
129125
|| metadata.users.iter().any(|user| match &user.ty {
130126
UserType::Native(basic) => basic.username == username,
131127
UserType::OAuth(_) => false, // OAuth users should be created differently
132128
})
133129
{
134-
return Err(RBACError::UserExists);
130+
return Err(RBACError::UserExists(username));
135131
}
136132

137133
let (user, password) = user::User::new_basic(username.clone());
@@ -141,12 +137,13 @@ pub async fn post_user(
141137
put_metadata(&metadata).await?;
142138
let created_role = user_roles.clone();
143139
Users.put_user(user.clone());
144-
145-
add_roles_to_user(
146-
web::Path::<String>::from(username.clone()),
147-
web::Json(created_role),
148-
)
149-
.await?;
140+
if !created_role.is_empty() {
141+
add_roles_to_user(
142+
web::Path::<String>::from(username.clone()),
143+
web::Json(created_role),
144+
)
145+
.await?;
146+
}
150147

151148
Ok(password)
152149
}
@@ -383,8 +380,8 @@ pub struct InvalidUserGroupError {
383380

384381
#[derive(Debug, thiserror::Error)]
385382
pub enum RBACError {
386-
#[error("User exists already")]
387-
UserExists,
383+
#[error("User {0} already exists")]
384+
UserExists(String),
388385
#[error("User does not exist")]
389386
UserDoesNotExist,
390387
#[error("{0}")]
@@ -422,7 +419,7 @@ pub enum RBACError {
422419
impl actix_web::ResponseError for RBACError {
423420
fn status_code(&self) -> http::StatusCode {
424421
match self {
425-
Self::UserExists => StatusCode::BAD_REQUEST,
422+
Self::UserExists(_) => StatusCode::BAD_REQUEST,
426423
Self::UserDoesNotExist => StatusCode::NOT_FOUND,
427424
Self::SerdeError(_) => StatusCode::BAD_REQUEST,
428425
Self::ValidationError(_) => StatusCode::BAD_REQUEST,

0 commit comments

Comments
 (0)