88 lines
2.5 KiB
Rust
88 lines
2.5 KiB
Rust
use crate::error::ApiError;
|
|
use argon2::{
|
|
password_hash::{rand_core::OsRng, PasswordHasher, SaltString},
|
|
Argon2, PasswordHash, PasswordVerifier,
|
|
};
|
|
use sea_orm::{
|
|
ActiveModelTrait,
|
|
ActiveValue::{NotSet, Set},
|
|
ColumnTrait, DbErr, EntityTrait, ModelTrait, QueryFilter, TransactionTrait,
|
|
};
|
|
use uuid::Uuid;
|
|
|
|
use crate::{entity, Database};
|
|
|
|
impl Database {
|
|
pub async fn create_user(
|
|
&self,
|
|
name: String,
|
|
username: String,
|
|
password: String,
|
|
) -> Result<entity::user::Model, ApiError> {
|
|
let argon2 = Argon2::default();
|
|
|
|
let salt = SaltString::generate(&mut OsRng);
|
|
let hash = argon2
|
|
.hash_password(password.as_bytes(), &salt)
|
|
.map_err(|err| ApiError::Argon2Error(err.to_string()))?
|
|
.to_string();
|
|
|
|
let user = self
|
|
.conn
|
|
.transaction::<_, entity::user::Model, DbErr>(|txn| {
|
|
Box::pin(async move {
|
|
let user = entity::user::ActiveModel {
|
|
id: NotSet,
|
|
name: Set(name),
|
|
username: Set(username),
|
|
};
|
|
|
|
let user: entity::user::Model = user.insert(txn).await?;
|
|
|
|
let local_auth = entity::local_auth::ActiveModel {
|
|
id: Set(user.id),
|
|
hash: Set(hash),
|
|
password_change_required: NotSet,
|
|
};
|
|
|
|
local_auth.insert(txn).await?;
|
|
Ok(user)
|
|
})
|
|
})
|
|
.await?;
|
|
Ok(user)
|
|
}
|
|
|
|
pub async fn verify_local_user(
|
|
&self,
|
|
username: &str,
|
|
password: &str,
|
|
) -> Result<Uuid, ApiError> {
|
|
let user = entity::user::Entity::find()
|
|
.filter(entity::user::Column::Username.eq(username))
|
|
.one(&self.conn)
|
|
.await?
|
|
.ok_or(ApiError::Unauthorized)?;
|
|
|
|
let local_auth = user
|
|
.find_related(entity::local_auth::Entity)
|
|
.one(&self.conn)
|
|
.await?
|
|
.ok_or(ApiError::Unauthorized)?;
|
|
|
|
let argon2 = Argon2::default();
|
|
|
|
let password_hash = PasswordHash::new(&local_auth.hash)
|
|
.map_err(|err| ApiError::Argon2Error(err.to_string()))?;
|
|
|
|
if let Err(_) = argon2.verify_password(password.as_bytes(), &password_hash) {
|
|
return Err(ApiError::Unauthorized);
|
|
}
|
|
|
|
Ok(user.id)
|
|
}
|
|
|
|
pub async fn verify_ldap_user() {}
|
|
|
|
pub async fn change_user_password() {}
|
|
}
|