Added some basic error handling

pull/36/head
Jef Roosens 2021-08-21 15:58:51 +02:00
parent 6782fecc0d
commit 7a97b99bd6
Signed by: Jef Roosens
GPG Key ID: 955C0660072F691F
3 changed files with 38 additions and 9 deletions

View File

@ -1,4 +1,4 @@
use crate::errors::AuthError; use crate::errors::RBError;
use crate::models::User; use crate::models::User;
use crate::schema::users::dsl as users; use crate::schema::users::dsl as users;
use argon2::verify_encoded; use argon2::verify_encoded;
@ -15,19 +15,16 @@ const JWT_EXP_SECONDS: i64 = 900;
/// Amount of bytes the refresh tokens should consist of /// Amount of bytes the refresh tokens should consist of
const REFRESH_TOKEN_N_BYTES: u32 = 64; const REFRESH_TOKEN_N_BYTES: u32 = 64;
pub fn verify_user(conn: &PgConnection, username: &str, password: &str) -> Result<User, AuthError> { pub fn verify_user(conn: &PgConnection, username: &str, password: &str) -> crate::Result<User> {
// TODO handle non-"NotFound" Diesel errors accordingely // TODO handle non-"NotFound" Diesel errors accordingely
let user = match users::users let user = users::users
.filter(users::username.eq(username)) .filter(users::username.eq(username))
.first::<User>(conn) .first::<User>(conn)
{ .map_err(|_| RBError::UnknownUser)?;
Err(_) => return Err(AuthError::UnknownUser),
Ok(user) => user,
};
match verify_encoded(user.password.as_str(), password.as_bytes()) { match verify_encoded(user.password.as_str(), password.as_bytes()) {
Ok(true) => Ok(user), Ok(true) => Ok(user),
_ => Err(AuthError::InvalidPassword), _ => Err(RBError::InvalidPassword),
} }
} }

View File

@ -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, UnknownUser,
/// Invalid login password.
InvalidPassword, 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<T> = std::result::Result<T, RBError>;

View File

@ -5,3 +5,5 @@ pub mod auth;
pub mod errors; pub mod errors;
mod models; mod models;
pub(crate) mod schema; pub(crate) mod schema;
pub use errors::Result;