Added string length validation (#4)
continuous-integration/woodpecker the build failed Details

+ Added a length check to string fields on add_item and add_location
+ Only doing length validation for now
+ Clippy + Fmt
main
Joey Hines 2021-12-22 19:00:40 -07:00
parent 99a78599c7
commit caf7212cca
No known key found for this signature in database
GPG Key ID: 80F567B5C968F91B
8 changed files with 37 additions and 15 deletions

View File

@ -1,5 +1,7 @@
use crate::commands::{Command, RequestType}; use crate::commands::{Command, RequestType};
use crate::config::GeoffreyAPIConfig;
use crate::context::Context; use crate::context::Context;
use crate::helper::validate_string_parameter;
use crate::Result; use crate::Result;
use geoffrey_db::helper::{find_location_by_name_type, load_location}; use geoffrey_db::helper::{find_location_by_name_type, load_location};
use geoffrey_models::models::item::ItemListing; use geoffrey_models::models::item::ItemListing;
@ -28,14 +30,6 @@ impl Command for AddItem {
CommandLevel::REGISTERED CommandLevel::REGISTERED
} }
fn validate_parameters(req: &Self::Req) -> Result<()> {
if req.quantity == 0 {
Err(GeoffreyAPIError::ParameterInvalid("quantity".to_string()))
} else {
Ok(())
}
}
fn run_command(ctx: Arc<Context>, req: &Self::Req, user: Option<Player>) -> Result<Self::Resp> { fn run_command(ctx: Arc<Context>, req: &Self::Req, user: Option<Player>) -> Result<Self::Resp> {
let user = user.unwrap(); let user = user.unwrap();
@ -56,4 +50,14 @@ impl Command for AddItem {
Err(GeoffreyAPIError::EntryNotFound) Err(GeoffreyAPIError::EntryNotFound)
} }
} }
fn validate_parameters(req: &Self::Req, cfg: &GeoffreyAPIConfig) -> Result<()> {
if req.quantity == 0 {
return Err(GeoffreyAPIError::ParameterInvalid("quantity".to_string()));
}
validate_string_parameter("item_name", &req.item_name, cfg.max_str_len)?;
Ok(())
}
} }

View File

@ -1,5 +1,7 @@
use crate::commands::{Command, RequestType}; use crate::commands::{Command, RequestType};
use crate::config::GeoffreyAPIConfig;
use crate::context::Context; use crate::context::Context;
use crate::helper::validate_string_parameter;
use crate::Result; use crate::Result;
use geoffrey_db::helper::load_location; use geoffrey_db::helper::load_location;
use geoffrey_models::models::locations::{Location, LocationDb}; use geoffrey_models::models::locations::{Location, LocationDb};
@ -41,4 +43,8 @@ impl Command for AddLocation {
load_location(&ctx.db, &location).map_err(|err| err.into()) load_location(&ctx.db, &location).map_err(|err| err.into())
} }
fn validate_parameters(req: &Self::Req, cfg: &GeoffreyAPIConfig) -> Result<()> {
validate_string_parameter("name", &req.name, cfg.max_str_len)
}
} }

View File

@ -9,6 +9,7 @@ use crate::commands::register::Register;
use crate::commands::remove_item::RemoveItem; use crate::commands::remove_item::RemoveItem;
use crate::commands::selling::Selling; use crate::commands::selling::Selling;
use crate::commands::set_portal::SetPortal; use crate::commands::set_portal::SetPortal;
use crate::config::GeoffreyAPIConfig;
use crate::context::Context; use crate::context::Context;
use crate::helper::{get_player_from_req, get_token_from_req}; use crate::helper::{get_player_from_req, get_token_from_req};
use crate::Result; use crate::Result;
@ -54,7 +55,7 @@ pub trait Command {
fn command_level() -> CommandLevel; fn command_level() -> CommandLevel;
fn run_command(ctx: Arc<Context>, req: &Self::Req, user: Option<Player>) -> Result<Self::Resp>; fn run_command(ctx: Arc<Context>, req: &Self::Req, user: Option<Player>) -> Result<Self::Resp>;
fn validate_parameters(_: &Self::Req) -> Result<()> { fn validate_parameters(_: &Self::Req, _: &GeoffreyAPIConfig) -> Result<()> {
Ok(()) Ok(())
} }
@ -97,7 +98,7 @@ pub fn handle_command<T: Command>(
match T::user_is_authorized(&token, &user) { match T::user_is_authorized(&token, &user) {
Ok(_) => { Ok(_) => {
T::validate_parameters(&req.params)?; T::validate_parameters(&req.params, &ctx.cfg)?;
T::run_command(ctx, &req.params, user) T::run_command(ctx, &req.params, user)
} }
Err(e) => Err(e), Err(e) => Err(e),

View File

@ -6,6 +6,7 @@ use std::path::{Path, PathBuf};
pub struct GeoffreyAPIConfig { pub struct GeoffreyAPIConfig {
pub db_path: PathBuf, pub db_path: PathBuf,
pub host: String, pub host: String,
pub max_str_len: usize,
} }
impl GeoffreyAPIConfig { impl GeoffreyAPIConfig {

View File

@ -2,6 +2,7 @@ use crate::Result;
use geoffrey_db::database::Database; use geoffrey_db::database::Database;
use geoffrey_models::models::parameters::{CommandRequest, GeoffreyParam}; use geoffrey_models::models::parameters::{CommandRequest, GeoffreyParam};
use geoffrey_models::models::player::Player; use geoffrey_models::models::player::Player;
use geoffrey_models::models::response::api_error::GeoffreyAPIError;
use geoffrey_models::models::token::Token; use geoffrey_models::models::token::Token;
pub fn get_player_from_req<T: GeoffreyParam>( pub fn get_player_from_req<T: GeoffreyParam>(
@ -25,3 +26,11 @@ pub fn get_token_from_req<T: GeoffreyParam>(
.filter(|_, token: &Token| token.secret == req.token)? .filter(|_, token: &Token| token.secret == req.token)?
.next()) .next())
} }
pub fn validate_string_parameter(param_name: &str, s: &str, max_len: usize) -> Result<()> {
if s.len() < max_len {
Ok(())
} else {
Err(GeoffreyAPIError::ParameterInvalid(param_name.to_string()))
}
}

View File

@ -6,11 +6,11 @@ use serenity::model::interactions::application_command::{
use crate::bot::arg_parse::option_to_string; use crate::bot::arg_parse::option_to_string;
use crate::bot::commands::{BotCommand, CommandError}; use crate::bot::commands::{BotCommand, CommandError};
use crate::bot::lang::ACCOUNT_LINK_INVALID;
use geoffrey_models::models::parameters::register_params::RegisterParameters; use geoffrey_models::models::parameters::register_params::RegisterParameters;
use geoffrey_models::models::player::{Player, UserID}; use geoffrey_models::models::player::{Player, UserID};
use serenity::builder::CreateApplicationCommand;
use geoffrey_models::models::response::api_error::GeoffreyAPIError; use geoffrey_models::models::response::api_error::GeoffreyAPIError;
use crate::bot::lang::ACCOUNT_LINK_INVALID; use serenity::builder::CreateApplicationCommand;
pub struct RegisterCommand; pub struct RegisterCommand;
@ -32,7 +32,7 @@ impl BotCommand for RegisterCommand {
CommandError::GeoffreyApi(GeoffreyAPIError::AccountLinkInvalid) => { CommandError::GeoffreyApi(GeoffreyAPIError::AccountLinkInvalid) => {
Some(ACCOUNT_LINK_INVALID.to_string()) Some(ACCOUNT_LINK_INVALID.to_string())
} }
_ => None _ => None,
} }
} }

View File

@ -4,4 +4,5 @@ pub const PLAYER_DOES_NOT_HAVE_MATCHING_SHOP: &str =
"You don't have a shop by that name, try again champ."; "You don't have a shop by that name, try again champ.";
pub const PLAYER_ALREADY_SELLS_ITEM: &str = "You already sell that ding dong"; pub const PLAYER_ALREADY_SELLS_ITEM: &str = "You already sell that ding dong";
pub const NO_LOCATION_FOUND: &str = "No location found by that name goober"; pub const NO_LOCATION_FOUND: &str = "No location found by that name goober";
pub const ACCOUNT_LINK_INVALID: &str = "Your link code is invalid. You may need a new one. Or to git gud."; pub const ACCOUNT_LINK_INVALID: &str =
"Your link code is invalid. You may need a new one. Or to git gud.";

View File

@ -90,7 +90,7 @@ impl Display for Position {
write!( write!(
f, f,
"({} x={}, y={}, z={}) ", "({} x={}, y={}, z={}) ",
self.dimension ,self.x, self.y, self.z self.dimension, self.x, self.y, self.z
) )
} }
} }