/* * This file is part of laurelin/api * Copyright (C) 2023 Jonni Liljamo * * 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 { let user = match users::table .filter(users::email.eq(&credentials.email)) .first::(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) } }