/*
* This file is part of laurelin/api
* Copyright (C) 2023 Jonni Liljamo <jonni@liljamo.com>
*
* Licensed under GPL-3.0-only.
* See LICENSE for licensing information.
*/
use argon2::{Argon2, PasswordHash, PasswordVerifier};
use diesel::{ExpressionMethods, PgConnection, QueryDsl, RunQueryDsl};
use laurelin_shared::error::api::APIError;
use crate::{
models::{User, UserCredentials},
schema::users,
};
pub(crate) fn login(
conn: &mut PgConnection,
credentials: &UserCredentials,
) -> Result<User, APIError> {
let user = match users::table
.filter(users::email.eq(&credentials.email))
.first::<User>(conn)
{
Err(_) => {
// TODO: Handle and return other errors too...
// Might be misleading if not actually this specific error,
// but this is the most likely error.
return Err(APIError::UserNotFound);
}
Ok(user) => user,
};
// TODO: handle unwrap
let parsed_hash = PasswordHash::new(&user.password).unwrap();
let password_ok =
Argon2::default().verify_password(credentials.password.as_bytes(), &parsed_hash);
if password_ok.is_ok() {
Ok(user)
} else {
Err(APIError::UserInvalidCredentials)
}
}