diff options
Diffstat (limited to 'atuin-server')
| -rw-r--r-- | atuin-server/src/database.rs | 21 | ||||
| -rw-r--r-- | atuin-server/src/handlers/user.rs | 19 | ||||
| -rw-r--r-- | atuin-server/src/router.rs | 1 |
3 files changed, 40 insertions, 1 deletions
diff --git a/atuin-server/src/database.rs b/atuin-server/src/database.rs index 7f3e5dac..e7057f6b 100644 --- a/atuin-server/src/database.rs +++ b/atuin-server/src/database.rs @@ -27,6 +27,7 @@ pub trait Database { async fn get_user(&self, username: &str) -> Result<User>; async fn get_user_session(&self, u: &User) -> Result<Session>; async fn add_user(&self, user: &NewUser) -> Result<i64>; + async fn delete_user(&self, u: &User) -> Result<()>; async fn count_history(&self, user: &User) -> Result<i64>; async fn count_history_cached(&self, user: &User) -> Result<i64>; @@ -337,6 +338,26 @@ impl Database for Postgres { } #[instrument(skip_all)] + async fn delete_user(&self, u: &User) -> Result<()> { + sqlx::query("delete from sessions where user_id = $1") + .bind(u.id) + .execute(&self.pool) + .await?; + + sqlx::query("delete from users where id = $1") + .bind(u.id) + .execute(&self.pool) + .await?; + + sqlx::query("delete from history where user_id = $1") + .bind(u.id) + .execute(&self.pool) + .await?; + + Ok(()) + } + + #[instrument(skip_all)] async fn add_user(&self, user: &NewUser) -> Result<i64> { let email: &str = &user.email; let username: &str = &user.username; diff --git a/atuin-server/src/handlers/user.rs b/atuin-server/src/handlers/user.rs index 89aa0601..ec2131e1 100644 --- a/atuin-server/src/handlers/user.rs +++ b/atuin-server/src/handlers/user.rs @@ -18,7 +18,7 @@ use uuid::Uuid; use super::{ErrorResponse, ErrorResponseStatus, RespExt}; use crate::{ database::Database, - models::{NewSession, NewUser}, + models::{NewSession, NewUser, User}, router::AppState, }; @@ -138,6 +138,23 @@ pub async fn register<DB: Database>( } } +#[instrument(skip_all, fields(user.id = user.id))] +pub async fn delete<DB: Database>( + user: User, + state: State<AppState<DB>>, +) -> Result<Json<DeleteUserResponse>, ErrorResponseStatus<'static>> { + debug!("request to delete user {}", user.id); + + let db = &state.0.database; + if let Err(e) = db.delete_user(&user).await { + error!("failed to delete user: {}", e); + + return Err(ErrorResponse::reply("failed to delete user") + .with_status(StatusCode::INTERNAL_SERVER_ERROR)); + }; + Ok(Json(DeleteUserResponse {})) +} + #[instrument(skip_all, fields(user.username = login.username.as_str()))] pub async fn login<DB: Database>( state: State<AppState<DB>>, diff --git a/atuin-server/src/router.rs b/atuin-server/src/router.rs index 58aac3bd..20b11f45 100644 --- a/atuin-server/src/router.rs +++ b/atuin-server/src/router.rs @@ -72,6 +72,7 @@ pub fn router<DB: Database + Clone + Send + Sync + 'static>( .route("/history", post(handlers::history::add)) .route("/history", delete(handlers::history::delete)) .route("/user/:username", get(handlers::user::get)) + .route("/account", delete(handlers::user::delete)) .route("/register", post(handlers::user::register)) .route("/login", post(handlers::user::login)); |
