diff --git a/src/routes/api.rs b/src/routes/api.rs index d19b5a9..0ebcabd 100644 --- a/src/routes/api.rs +++ b/src/routes/api.rs @@ -5,6 +5,7 @@ use crate::models::proto::{cofd::*, Proto}; use crate::models::users::User; use rocket_contrib::templates::Template; use serde::Serialize; +use std::borrow::Cow; use std::collections::HashMap; pub(crate) fn routes() -> Vec { @@ -18,6 +19,30 @@ pub(crate) fn routes() -> Vec { ] } +/// Load the character belonging to the given user, as long as they're +/// the owner of that character. Returns an error if user is not +/// logged in, the owner of the character is not found, or the logged +/// in user does not have the permission to access this character. +async fn load_character( + conn: &TenebrousDbConn, + logged_in_user: Option<&User>, + owner: String, + character_id: i32, +) -> Result { + let logged_in_user = logged_in_user.ok_or(Error::NotLoggedIn)?; + let owner = conn.load_user(owner).await?.ok_or(Error::NotFound)?; + let character: Character = conn + .load_character(character_id) + .await? + .ok_or(Error::NotFound)?; + + if logged_in_user != &owner { + return Err(Error::NoPermission); + } + + Ok(character) +} + /// Protobuf-based REST endpoints for editing a character. mod cofd { use super::*; @@ -49,29 +74,19 @@ mod cofd { conn: TenebrousDbConn, logged_in_user: Option<&User>, ) -> Result<&'a str, Error> { - let logged_in_user = logged_in_user.ok_or(Error::NotLoggedIn)?; - let owner = conn.load_user(owner).await?.ok_or(Error::NotFound)?; - let mut character: Character = conn - .load_character(character_id) - .await? - .ok_or(Error::NotFound)?; - - if logged_in_user != &owner { - return Err(Error::NoPermission); - } - + let mut character = load_character(&conn, logged_in_user, owner, character_id).await?; let mut sheet: CofdSheet = character.try_deserialize()?; match attr_update.name.to_lowercase().as_ref() { - "strength" => Ok(sheet.strength += attr_update.value), - "dexterity" => Ok(sheet.dexterity += attr_update.value), - "stamina" => Ok(sheet.stamina += attr_update.value), - "intelligence" => Ok(sheet.intelligence += attr_update.value), - "wits" => Ok(sheet.wits += attr_update.value), - "resolve" => Ok(sheet.resolve += attr_update.value), - "presence" => Ok(sheet.presence += attr_update.value), - "manipulation" => Ok(sheet.manipulation += attr_update.value), - "composure" => Ok(sheet.composure += attr_update.value), + "strength" => Ok(sheet.strength = attr_update.value), + "dexterity" => Ok(sheet.dexterity = attr_update.value), + "stamina" => Ok(sheet.stamina = attr_update.value), + "intelligence" => Ok(sheet.intelligence = attr_update.value), + "wits" => Ok(sheet.wits = attr_update.value), + "resolve" => Ok(sheet.resolve = attr_update.value), + "presence" => Ok(sheet.presence = attr_update.value), + "manipulation" => Ok(sheet.manipulation = attr_update.value), + "composure" => Ok(sheet.composure = attr_update.value), _ => Err(Error::InvalidInput), }?;