feat: delete user

This commit is contained in:
Zack Fu Zi Xiang 2024-09-01 00:51:05 +08:00
parent 3b79ac5cca
commit 06a5a22032
No known key found for this signature in database
6 changed files with 92 additions and 1 deletions

View File

@ -0,0 +1,14 @@
{
"db_name": "PostgreSQL",
"query": "\n DELETE FROM auth.users WHERE id = $1\n ",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Uuid"
]
},
"nullable": []
},
"hash": "e6acbe78f0e8f776901c560088222939e80ec2e75747503f0493d081ba43e4bd"
}

View File

@ -738,6 +738,19 @@ impl Client {
AppResponse::<()>::from_response(resp).await?.into_error()
}
/// Deletes the user account and all associated data.
#[instrument(level = "info", skip_all, err)]
pub async fn delete_user(&self) -> Result<(), AppResponseError> {
let url = format!("{}/api/user", self.base_url);
let resp = self
.http_client_with_auth(Method::DELETE, &url)
.await?
.send()
.await?;
log_request_id(&resp);
AppResponse::<()>::from_response(resp).await?.into_error()
}
pub async fn get_snapshot_list(
&self,
workspace_id: &str,

View File

@ -240,3 +240,24 @@ pub async fn select_name_from_uuid(pool: &PgPool, user_uuid: &Uuid) -> Result<St
.await?;
Ok(email)
}
#[inline]
pub async fn delete_user(pool: &PgPool, user_uuid: &Uuid) -> Result<(), AppError> {
let res = sqlx::query!(
r#"
DELETE FROM auth.users WHERE id = $1
"#,
user_uuid
)
.execute(pool)
.await?;
if res.rows_affected() != 1 {
return Err(AppError::RecordNotFound(format!(
"User with UUID {} not found",
user_uuid
)));
}
Ok(())
}

View File

@ -1,4 +1,4 @@
use crate::biz::user::user_info::{get_profile, get_user_workspace_info, update_user};
use crate::biz::user::user_info::{delete_user, get_profile, get_user_workspace_info, update_user};
use crate::biz::user::user_verify::verify_token;
use crate::state::AppState;
use actix_web::web::{Data, Json};
@ -16,6 +16,7 @@ pub fn user_scope() -> Scope {
.service(web::resource("/update").route(web::post().to(update_user_handler)))
.service(web::resource("/profile").route(web::get().to(get_user_profile_handler)))
.service(web::resource("/workspace").route(web::get().to(get_user_workspace_info_handler)))
.service(web::resource("").route(web::delete().to(delete_user_handler)))
}
#[tracing::instrument(skip(state, path), err)]
@ -61,3 +62,12 @@ async fn update_user_handler(
update_user(&state.pg_pool, auth.uuid()?, params).await?;
Ok(AppResponse::Ok().into())
}
#[tracing::instrument(skip(state), err)]
async fn delete_user_handler(
auth: Authorization,
state: Data<AppState>,
) -> Result<JsonAppResponse<()>> {
delete_user(&state.pg_pool, auth.uuid()?).await?;
Ok(AppResponse::Ok().into())
}

View File

@ -74,3 +74,7 @@ pub async fn update_user(
let metadata = params.metadata.map(|m| json!(m.into_inner()));
Ok(database::user::update_user(pg_pool, &user_uuid, params.name, params.email, metadata).await?)
}
pub async fn delete_user(pg_pool: &PgPool, user_uuid: Uuid) -> Result<(), AppResponseError> {
Ok(database::user::delete_user(pg_pool, &user_uuid).await?)
}

View File

@ -1,6 +1,35 @@
use client_api_test::*;
use gotrue::params::{AdminDeleteUserParams, AdminUserParams};
#[tokio::test]
async fn user_delete_self() {
let (client, user) = generate_unique_registered_user_client().await;
let admin_client = admin_user_client().await;
{
// user found before deletion
let search_result = admin_client
.admin_list_users(Some(&user.email))
.await
.unwrap();
let _target_user = search_result
.into_iter()
.find(|u| u.email == user.email)
.unwrap();
}
client.delete_user().await.unwrap();
{
// user cannot be found after deletion
let search_result = admin_client
.admin_list_users(Some(&user.email))
.await
.unwrap();
let target_user = search_result.into_iter().find(|u| u.email == user.email);
assert!(target_user.is_none(), "User should be deleted: {:?}", user);
}
}
#[tokio::test]
async fn admin_delete_create_same_user_hard() {
let (client, user) = generate_unique_registered_user_client().await;