diff --git a/src/app_error.rs b/src/app_error.rs index 4d1f9d7..67681d4 100644 --- a/src/app_error.rs +++ b/src/app_error.rs @@ -8,18 +8,16 @@ use validator::ValidationErrors; #[derive(Debug)] pub enum AppError { InternalServerError(anyhow::Error), - ForbiddenError(String), - NotFoundError(String), - BadRequestError(String), - TooManyRequestsError(String), + Forbidden(String), + NotFound(String), + BadRequest(String), + TooManyRequests(String), } impl AppError { pub fn from_validation_errors(errs: ValidationErrors) -> Self { // TODO: customize validation errors formatting - Self::BadRequestError( - serde_json::to_string(&errs).unwrap_or("validation error".to_string()), - ) + Self::BadRequest(serde_json::to_string(&errs).unwrap_or("validation error".to_string())) } } @@ -30,21 +28,21 @@ impl IntoResponse for AppError { tracing::error!("Application error: {:?}", err); (StatusCode::INTERNAL_SERVER_ERROR, "Something went wrong").into_response() } - Self::ForbiddenError(client_message) => { + Self::Forbidden(client_message) => { tracing::info!("Forbidden: {}", client_message); (StatusCode::FORBIDDEN, client_message).into_response() } - Self::NotFoundError(client_message) => { + Self::NotFound(client_message) => { tracing::info!("Not found: {}", client_message); (StatusCode::NOT_FOUND, client_message).into_response() } - Self::TooManyRequestsError(client_message) => { + Self::TooManyRequests(client_message) => { // Debug level so that if this is from a runaway loop, it won't // overwhelm server logs tracing::debug!("Too many requests: {}", client_message); (StatusCode::TOO_MANY_REQUESTS, client_message).into_response() } - Self::BadRequestError(client_message) => { + Self::BadRequest(client_message) => { tracing::info!("Bad user input: {}", client_message); (StatusCode::BAD_REQUEST, client_message).into_response() } @@ -66,16 +64,16 @@ impl Display for AppError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { AppError::InternalServerError(inner) => inner.fmt(f), - AppError::ForbiddenError(client_message) => { + AppError::Forbidden(client_message) => { write!(f, "ForbiddenError: {}", client_message) } - AppError::NotFoundError(client_message) => { + AppError::NotFound(client_message) => { write!(f, "NotFoundError: {}", client_message) } - AppError::BadRequestError(client_message) => { + AppError::BadRequest(client_message) => { write!(f, "BadRequestError: {}", client_message) } - AppError::TooManyRequestsError(client_message) => { + AppError::TooManyRequests(client_message) => { write!(f, "TooManyRequestsError: {}", client_message) } } diff --git a/src/auth.rs b/src/auth.rs index 453a80e..92371c4 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -167,7 +167,7 @@ async fn callback( })?; if session_csrf_token != query.state { tracing::debug!("oauth csrf tokens did not match"); - return Err(AppError::ForbiddenError( + return Err(AppError::Forbidden( "OAuth CSRF tokens do not match.".to_string(), )); } diff --git a/src/channels_router.rs b/src/channels_router.rs index 0dc2975..6ba7f05 100644 --- a/src/channels_router.rs +++ b/src/channels_router.rs @@ -40,7 +40,7 @@ fn get_channel_by_params<'a>( .filter(Channel::with_team(team_id)) .first(conn) { - diesel::QueryResult::Err(diesel::result::Error::NotFound) => Err(AppError::NotFoundError( + diesel::QueryResult::Err(diesel::result::Error::NotFound) => Err(AppError::NotFound( "Channel with that team and ID not found.".to_string(), )), diesel::QueryResult::Err(err) => Err(err.into()), @@ -153,7 +153,7 @@ async fn post_new_channel( .await .unwrap()?, _ => { - return Err(AppError::BadRequestError( + return Err(AppError::BadRequest( "Channel type not recognized.".to_string(), )); } @@ -189,7 +189,7 @@ async fn channel_page( .unwrap()? { None => { - return Err(AppError::NotFoundError( + return Err(AppError::NotFound( "Channel with that team and ID not found".to_string(), )); } @@ -272,7 +272,7 @@ async fn update_channel( .context("Failed to load Channel while updating.")? }; if updated_rows != 1 { - return Err(AppError::NotFoundError( + return Err(AppError::NotFound( "Channel with that team and ID not found".to_string(), )); } @@ -308,7 +308,7 @@ async fn update_channel_email_recipient( guards::require_team_membership(¤t_user, &team_id, &db_conn).await?; if !is_permissible_email(&form_body.recipient) { - return Err(AppError::BadRequestError( + return Err(AppError::BadRequest( "Unable to validate email address format.".to_string(), )); } @@ -400,7 +400,7 @@ async fn verify_email( guards::require_team_membership(¤t_user, &team_id, &db_conn).await?; if form_body.code.len() != VERIFICATION_CODE_LEN { - return Err(AppError::BadRequestError(format!( + return Err(AppError::BadRequest(format!( "Verification code must be {} characters long.", VERIFICATION_CODE_LEN ))); @@ -414,15 +414,13 @@ async fn verify_email( let channel = get_channel_by_params(conn, &team_id, &channel_id)?; let config: EmailBackendConfig = channel.backend_config.try_into()?; if config.verified { - return Err(AppError::BadRequestError( + return Err(AppError::BadRequest( "Channel's email address is already verified.".to_string(), )); } const MAX_VERIFICATION_GUESSES: u32 = 100; if config.verification_code_guesses > MAX_VERIFICATION_GUESSES { - return Err(AppError::BadRequestError( - "Verification expired.".to_string(), - )); + return Err(AppError::BadRequest("Verification expired.".to_string())); } let new_config = if config.verification_code == verification_code { EmailBackendConfig { diff --git a/src/guards.rs b/src/guards.rs index 069d1f4..e57e80d 100644 --- a/src/guards.rs +++ b/src/guards.rs @@ -34,7 +34,7 @@ pub async fn require_team_membership( }; match maybe_team { Some((team, _)) => Ok(team), - None => Err(AppError::ForbiddenError( + None => Err(AppError::Forbidden( "not a member of requested team".to_string(), )), } @@ -50,6 +50,6 @@ pub async fn require_valid_csrf_token( if validate_csrf_token(db_conn, csrf_token, Some(current_user.id)).await? { Ok(()) } else { - Err(AppError::ForbiddenError("invalid CSRF token".to_string())) + Err(AppError::Forbidden("invalid CSRF token".to_string())) } } diff --git a/src/projects_router.rs b/src/projects_router.rs index b62b132..57a98be 100644 --- a/src/projects_router.rs +++ b/src/projects_router.rs @@ -124,7 +124,7 @@ async fn project_page( .filter(Project::with_team(&team_id)) .first(conn) { - diesel::QueryResult::Err(diesel::NotFound) => Err(AppError::NotFoundError( + diesel::QueryResult::Err(diesel::NotFound) => Err(AppError::NotFound( "Project with that team and ID not found.".to_string(), )), other => other @@ -213,7 +213,7 @@ async fn update_enabled_channels( .filter(Project::with_team(&team_id)) .first(conn) { - diesel::QueryResult::Err(diesel::NotFound) => Err(AppError::NotFoundError( + diesel::QueryResult::Err(diesel::NotFound) => Err(AppError::NotFound( "Project with that team and ID not found.".to_string(), )), other => other diff --git a/src/teams_router.rs b/src/teams_router.rs index 58acfb9..f2a3a40 100644 --- a/src/teams_router.rs +++ b/src/teams_router.rs @@ -139,7 +139,7 @@ async fn remove_api_key( "there should never be more than 1 API key with the same ID" ); if n_deleted == 0 { - Err(AppError::NotFoundError( + Err(AppError::NotFound( "no API key with that ID and team found".to_owned(), )) } else { diff --git a/src/v0_router.rs b/src/v0_router.rs index 3324161..04e0fd4 100644 --- a/src/v0_router.rs +++ b/src/v0_router.rs @@ -67,9 +67,8 @@ async fn say_get( query.validate().map_err(AppError::from_validation_errors)?; let api_key = { - let query_key = try_parse_as_uuid(&query.key).or(Err(AppError::ForbiddenError( - "key not accepted".to_string(), - )))?; + let query_key = try_parse_as_uuid(&query.key) + .or(Err(AppError::Forbidden("key not accepted".to_string())))?; db_conn .interact::<_, Result>(move |conn| { update(api_keys::table.filter(ApiKey::with_id(&query_key))) @@ -78,7 +77,7 @@ async fn say_get( .get_result(conn) .optional() .context("failed to get API key")? - .ok_or(AppError::ForbiddenError("key not accepted.".to_string())) + .ok_or(AppError::Forbidden("key not accepted.".to_string())) }) .await .unwrap()? @@ -146,7 +145,7 @@ async fn say_get( .unwrap()? .is_none() { - return Err(AppError::TooManyRequestsError( + return Err(AppError::TooManyRequests( "team rate limit exceeded".to_string(), )); }