Skip to content

Commit

Permalink
feat(webserver): Add GraphQL endpoint updateUserRole (#1449)
Browse files Browse the repository at this point in the history
* feat(webserver): Add GraphQL endpoint updateUserRole

* Add unit test
  • Loading branch information
boxbeam authored Feb 13, 2024
1 parent 22a99e4 commit 80cb148
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 0 deletions.
18 changes: 18 additions & 0 deletions ee/tabby-db/src/users.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,24 @@ impl DbConn {
Ok(())
}
}

pub async fn update_user_role(&self, id: i32, is_admin: bool) -> Result<()> {
let not_admin = !is_admin;
let changed = query!(
"UPDATE users SET is_admin = ? WHERE id = ? AND is_admin = ?",
is_admin,
id,
not_admin
)
.execute(&self.pool)
.await?
.rows_affected();
if changed != 1 {
Err(anyhow!("user admin status was not changed"))
} else {
Ok(())
}
}
}

fn generate_auth_token() -> String {
Expand Down
1 change: 1 addition & 0 deletions ee/tabby-webserver/src/schema/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,7 @@ pub trait AuthenticationService: Send + Sync {

async fn delete_oauth_credential(&self, provider: OAuthProvider) -> Result<()>;
async fn update_user_active(&self, id: &ID, active: bool) -> Result<()>;
async fn update_user_role(&self, id: &ID, is_admin: bool) -> Result<()>;
}

#[cfg(test)]
Expand Down
6 changes: 6 additions & 0 deletions ee/tabby-webserver/src/schema/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,12 @@ impl Mutation {
Ok(true)
}

async fn update_user_role(ctx: &Context, id: ID, is_admin: bool) -> Result<bool> {
check_admin(ctx)?;
ctx.locator.auth().update_user_role(&id, is_admin).await?;
Ok(true)
}

async fn register(
ctx: &Context,
email: String,
Expand Down
34 changes: 34 additions & 0 deletions ee/tabby-webserver/src/service/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,14 @@ impl AuthenticationService for AuthenticationServiceImpl {
Ok(!admin.is_empty())
}

async fn update_user_role(&self, id: &ID, is_admin: bool) -> Result<()> {
let id = id.as_rowid()?;
if id == 1 {
return Err(anyhow!("The owner's admin status may not be changed"));
}
self.db.update_user_role(id, is_admin).await
}

async fn get_user_by_email(&self, email: &str) -> Result<User> {
let user = self.db.get_user_by_email(email).await?;
if let Some(user) = user {
Expand Down Expand Up @@ -803,6 +811,32 @@ mod tests {
.is_err());
}

#[tokio::test]
async fn test_update_role() {
let service = test_authentication_service().await;
let admin_id = service
.db
.create_user("[email protected]".into(), "".into(), true)
.await
.unwrap();

let user_id = service
.db
.create_user("[email protected]".into(), "".into(), false)
.await
.unwrap();

assert!(service
.update_user_role(&user_id.as_id(), true)
.await
.is_ok());

assert!(service
.update_user_role(&admin_id.as_id(), false)
.await
.is_err());
}

#[tokio::test]
async fn test_pagination() {
let service = test_authentication_service().await;
Expand Down

0 comments on commit 80cb148

Please sign in to comment.