feat: delete user
This commit is contained in:
parent
3b79ac5cca
commit
06a5a22032
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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?)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue