forked from projectmoon/tenebrous-dicebot
Add user accounts, registration command, secure command valiation.
This commit is contained in:
parent
a84d4fd869
commit
c1ec7366e4
|
@ -33,3 +33,20 @@ impl Command for ResyncCommand {
|
|||
Execution::success(message)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RegisterCommand(pub String);
|
||||
|
||||
#[async_trait]
|
||||
impl Command for RegisterCommand {
|
||||
fn name(&self) -> &'static str {
|
||||
"register user account"
|
||||
}
|
||||
|
||||
fn is_secure(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
async fn execute(&self, ctx: &Context<'_>) -> ExecutionResult {
|
||||
Execution::success("User account registered".to_string())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,9 @@ pub enum CommandError {
|
|||
#[error("invalid command: {0}")]
|
||||
InvalidCommand(String),
|
||||
|
||||
#[error("command can only be executed from encrypted direct message")]
|
||||
InsecureExecution,
|
||||
|
||||
#[error("ignored command")]
|
||||
IgnoredCommand,
|
||||
}
|
||||
|
@ -99,13 +102,33 @@ pub trait Command: Send + Sync {
|
|||
fn is_secure(&self) -> bool;
|
||||
}
|
||||
|
||||
/// Determine if we are allowed to execute this command. Currently the
|
||||
/// rules are that secure commands must be executed in secure rooms
|
||||
/// (encrypted + direct), and anything else can be executed where
|
||||
/// ever. Later, we can add stuff like admin/regular user power
|
||||
/// separation, etc.
|
||||
fn execution_allowed(cmd: &(impl Command + ?Sized), ctx: &Context<'_>) -> Result<(), CommandError> {
|
||||
if cmd.is_secure() {
|
||||
if ctx.is_secure() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(CommandError::InsecureExecution)
|
||||
}
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
/// Attempt to execute a command, and return the content that should
|
||||
/// go back to Matrix, if the command was executed (successfully or
|
||||
/// not). If a command is determined to be ignored, this function will
|
||||
/// return None, signifying that we should not send a response.
|
||||
pub async fn execute_command(ctx: &Context<'_>) -> ExecutionResult {
|
||||
let cmd = parser::parse_command(&ctx.message_body)?;
|
||||
cmd.execute(ctx).await
|
||||
|
||||
match execution_allowed(cmd.as_ref(), ctx) {
|
||||
Ok(_) => cmd.execute(ctx).await,
|
||||
Err(e) => Err(ExecutionError(e.into())),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -9,7 +9,7 @@ use crate::commands::{
|
|||
basic_rolling::RollCommand,
|
||||
cofd::PoolRollCommand,
|
||||
cthulhu::{CthAdvanceRoll, CthRoll},
|
||||
management::ResyncCommand,
|
||||
management::{RegisterCommand, ResyncCommand},
|
||||
misc::HelpCommand,
|
||||
variables::{
|
||||
DeleteVariableCommand, GetAllVariablesCommand, GetVariableCommand, SetVariableCommand,
|
||||
|
@ -47,6 +47,10 @@ fn parse_roll(input: &str) -> Result<Box<dyn Command>, BotError> {
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_register_command(input: &str) -> Result<Box<dyn Command>, BotError> {
|
||||
Ok(Box::new(RegisterCommand(input.to_owned())))
|
||||
}
|
||||
|
||||
fn parse_get_variable_command(input: &str) -> Result<Box<dyn Command>, BotError> {
|
||||
Ok(Box::new(GetVariableCommand(input.to_owned())))
|
||||
}
|
||||
|
@ -141,6 +145,7 @@ pub fn parse_command(input: &str) -> Result<Box<dyn Command>, BotError> {
|
|||
"cthadv" | "ctharoll" => parse_cth_advancement_roll(&cmd_input),
|
||||
"chance" => chance_die(),
|
||||
"help" => help(&cmd_input),
|
||||
"register" => parse_register_command(&cmd_input),
|
||||
_ => Err(CommandParsingError::UnrecognizedCommand(cmd).into()),
|
||||
},
|
||||
//All other errors passed up.
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
use barrel::backend::Sqlite;
|
||||
use barrel::{types, types::Type, Migration};
|
||||
|
||||
fn primary_uuid() -> Type {
|
||||
types::text().unique(true).primary(true).nullable(false)
|
||||
}
|
||||
|
||||
pub fn migration() -> String {
|
||||
let mut m = Migration::new();
|
||||
|
||||
//Table of room ID, event ID, event timestamp
|
||||
m.create_table("accounts", move |t| {
|
||||
t.add_column("user_id", primary_uuid());
|
||||
t.add_column("password", types::text().nullable(false));
|
||||
});
|
||||
|
||||
m.make::<Sqlite>()
|
||||
}
|
Loading…
Reference in New Issue