DEVELOPMENT ENVIRONMENT

~liljamo/deck-builder

ref: 3a729b27a2d7c122eecda8127e364a399c07fa6c deck-builder/api/src/actions/user/create.rs -rw-r--r-- 1.3 KiB
3a729b27Jonni Liljamo feat(api): reimpl user registration 1 year, 7 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/*
 * 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::{
    password_hash::{rand_core::OsRng, SaltString},
    Argon2, PasswordHasher,
};
use diesel::{PgConnection, RunQueryDsl};
use laurelin_shared::error::api::APIError;

use crate::{
    models::{InsertableUser, User},
    schema::users,
};

pub(crate) fn create(conn: &mut PgConnection, user: &InsertableUser) -> Result<User, APIError> {
    let salt = SaltString::generate(&mut OsRng);
    let password_hash_result = Argon2::default().hash_password(user.password.as_bytes(), &salt);

    let password_hash = match password_hash_result {
        Err(_) => return Err(APIError::UserPasswordHashFailed),
        Ok(password_hash) => password_hash.to_string(),
    };

    let new_user = InsertableUser {
        username: user.username.clone(),
        email: user.email.clone(),
        password: password_hash,
    };

    let user: Result<User, diesel::result::Error> = diesel::insert_into(users::table)
        .values(&new_user)
        .get_result::<User>(conn);

    match user {
        Err(_) => {
            // TODO: we certainly could handle Diesel errors here...
            return Err(APIError::UserCreationFailed);
        }
        Ok(u) => return Ok(u),
    }
}