From 7a97b99bd69d6a1305174be0dd79d873e6d180f3 Mon Sep 17 00:00:00 2001 From: Jef Roosens Date: Sat, 21 Aug 2021 15:58:51 +0200 Subject: [PATCH] Added some basic error handling --- src/rb/auth.rs | 13 +++++-------- src/rb/errors.rs | 32 +++++++++++++++++++++++++++++++- src/rb/lib.rs | 2 ++ 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/src/rb/auth.rs b/src/rb/auth.rs index 645cd08..4fed292 100644 --- a/src/rb/auth.rs +++ b/src/rb/auth.rs @@ -1,4 +1,4 @@ -use crate::errors::AuthError; +use crate::errors::RBError; use crate::models::User; use crate::schema::users::dsl as users; use argon2::verify_encoded; @@ -15,19 +15,16 @@ const JWT_EXP_SECONDS: i64 = 900; /// Amount of bytes the refresh tokens should consist of const REFRESH_TOKEN_N_BYTES: u32 = 64; -pub fn verify_user(conn: &PgConnection, username: &str, password: &str) -> Result { +pub fn verify_user(conn: &PgConnection, username: &str, password: &str) -> crate::Result { // TODO handle non-"NotFound" Diesel errors accordingely - let user = match users::users + let user = users::users .filter(users::username.eq(username)) .first::(conn) - { - Err(_) => return Err(AuthError::UnknownUser), - Ok(user) => user, - }; + .map_err(|_| RBError::UnknownUser)?; match verify_encoded(user.password.as_str(), password.as_bytes()) { Ok(true) => Ok(user), - _ => Err(AuthError::InvalidPassword), + _ => Err(RBError::InvalidPassword), } } diff --git a/src/rb/errors.rs b/src/rb/errors.rs index fc12ba9..b9f387c 100644 --- a/src/rb/errors.rs +++ b/src/rb/errors.rs @@ -1,4 +1,34 @@ -pub enum AuthError { +use rocket::request::Request; +use rocket::response::{self, Response, Responder}; +use rocket::http::Status; +use std::io; + +pub enum RBError { + /// When the login requests an unknown user UnknownUser, + /// Invalid login password. InvalidPassword, + /// When a non-admin user tries to use an admin endpoint + Unauthorized, + /// When an expired JWT token is used for auth. + JWTTokenExpired } + +impl<'r> Responder<'r, 'static> for RBError { + fn respond_to(self, _: &'r Request<'_>) -> response::Result<'static> { + let (status, message): (Status, &str) = match self { + UnknownUser => (Status::NotFound, "Unknown user"), + InvalidPassword => (Status::Unauthorized, "Invalid password"), + Unauthorized => (Status::Unauthorized, "Unauthorized"), + JWTTokenExpired => (Status::Unauthorized, "Token expired"), + }; + + let res = Response::new(); + res.set_status(status); + res.set_sized_body(message.len(), io::Cursor::new(message)); + + Ok(res) + } +} + +pub type Result = std::result::Result; diff --git a/src/rb/lib.rs b/src/rb/lib.rs index 3d7d0f4..13c8330 100644 --- a/src/rb/lib.rs +++ b/src/rb/lib.rs @@ -5,3 +5,5 @@ pub mod auth; pub mod errors; mod models; pub(crate) mod schema; + +pub use errors::Result;