forked from projectmoon/tenebrous-dicebot
Add an account deletion command.
This commit is contained in:
parent
921c4cd644
commit
76214bc790
|
@ -1,7 +1,7 @@
|
|||
use super::{Command, Execution, ExecutionResult};
|
||||
use crate::context::Context;
|
||||
use crate::db::Users;
|
||||
use crate::error::BotError::{AuthenticationError, PasswordCreationError};
|
||||
use crate::error::BotError::{AccountDoesNotExist, AuthenticationError, PasswordCreationError};
|
||||
use crate::logic::{hash_password, record_room_information};
|
||||
use crate::models::User;
|
||||
use async_trait::async_trait;
|
||||
|
@ -82,3 +82,28 @@ impl Command for CheckCommand {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct UnregisterCommand;
|
||||
|
||||
#[async_trait]
|
||||
impl Command for UnregisterCommand {
|
||||
fn name(&self) -> &'static str {
|
||||
"unregister user account"
|
||||
}
|
||||
|
||||
fn is_secure(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
async fn execute(&self, ctx: &Context<'_>) -> ExecutionResult {
|
||||
let user = ctx.db.get_user(&ctx.username).await?;
|
||||
|
||||
match user {
|
||||
Some(_) => {
|
||||
ctx.db.delete_user(&ctx.username).await?;
|
||||
Execution::success("Your user account has been removed.".to_string())
|
||||
}
|
||||
None => Err(AccountDoesNotExist.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ use crate::commands::{
|
|||
basic_rolling::RollCommand,
|
||||
cofd::PoolRollCommand,
|
||||
cthulhu::{CthAdvanceRoll, CthRoll},
|
||||
management::{CheckCommand, RegisterCommand, ResyncCommand},
|
||||
management::{CheckCommand, RegisterCommand, ResyncCommand, UnregisterCommand},
|
||||
misc::HelpCommand,
|
||||
variables::{
|
||||
DeleteVariableCommand, GetAllVariablesCommand, GetVariableCommand, SetVariableCommand,
|
||||
|
@ -55,6 +55,10 @@ fn parse_check_command(input: &str) -> Result<Box<dyn Command>, BotError> {
|
|||
Ok(Box::new(CheckCommand(input.to_owned())))
|
||||
}
|
||||
|
||||
fn parse_unregister_command() -> Result<Box<dyn Command>, BotError> {
|
||||
Ok(Box::new(UnregisterCommand))
|
||||
}
|
||||
|
||||
fn parse_get_variable_command(input: &str) -> Result<Box<dyn Command>, BotError> {
|
||||
Ok(Box::new(GetVariableCommand(input.to_owned())))
|
||||
}
|
||||
|
@ -151,6 +155,7 @@ pub fn parse_command(input: &str) -> Result<Box<dyn Command>, BotError> {
|
|||
"help" => help(&cmd_input),
|
||||
"register" => parse_register_command(&cmd_input),
|
||||
"check" => parse_check_command(&cmd_input),
|
||||
"unregister" => parse_unregister_command(),
|
||||
_ => Err(CommandParsingError::UnrecognizedCommand(cmd).into()),
|
||||
},
|
||||
//All other errors passed up.
|
||||
|
|
|
@ -22,6 +22,8 @@ pub(crate) trait Users {
|
|||
|
||||
async fn get_user(&self, username: &str) -> Result<Option<User>, DataError>;
|
||||
|
||||
async fn delete_user(&self, username: &str) -> Result<(), DataError>;
|
||||
|
||||
async fn authenticate_user(
|
||||
&self,
|
||||
username: &str,
|
||||
|
|
|
@ -20,6 +20,15 @@ impl Users for Database {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
async fn delete_user(&self, username: &str) -> Result<(), DataError> {
|
||||
sqlx::query(r#"DELETE FROM accounts WHERE user_id = ?"#)
|
||||
.bind(&username)
|
||||
.execute(&self.conn)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_user(&self, username: &str) -> Result<Option<User>, DataError> {
|
||||
let user_row = sqlx::query!(
|
||||
r#"SELECT user_id, password FROM accounts
|
||||
|
@ -119,6 +128,31 @@ mod tests {
|
|||
assert_eq!(user.password, "123"); //From second upsert
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||
async fn can_delete_user() {
|
||||
let db = create_db().await;
|
||||
|
||||
let insert_result = db
|
||||
.upsert_user(&User {
|
||||
username: "myuser".to_string(),
|
||||
password: "abc".to_string(),
|
||||
})
|
||||
.await;
|
||||
|
||||
assert!(insert_result.is_ok());
|
||||
|
||||
db.delete_user("myuser")
|
||||
.await
|
||||
.expect("User deletion query failed");
|
||||
|
||||
let user = db
|
||||
.get_user("myuser")
|
||||
.await
|
||||
.expect("User retrieval query failed");
|
||||
|
||||
assert!(user.is_none());
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
|
||||
async fn username_not_in_db_returns_none() {
|
||||
let db = create_db().await;
|
||||
|
|
|
@ -84,6 +84,9 @@ pub enum BotError {
|
|||
|
||||
#[error("account does not exist, or password incorrect")]
|
||||
AuthenticationError,
|
||||
|
||||
#[error("user account does not exist, try registering")]
|
||||
AccountDoesNotExist,
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
|
|
Loading…
Reference in New Issue