brass/web/src/endpoints/user/post_new.rs

76 lines
2.3 KiB
Rust

use actix_web::{http::header::LOCATION, web, HttpResponse, Responder};
use sqlx::PgPool;
use crate::{endpoints::user::NewOrEditUserForm, mail::Mailer, utils::ApplicationError};
use brass_db::{
models::{Function, Registration, Role, User, UserChangeset},
validation::{AsyncValidate, DbContext},
};
#[actix_web::post("/users/new")]
pub async fn post_new(
user: web::ReqData<User>,
pool: web::Data<PgPool>,
form: web::Form<NewOrEditUserForm>,
mailer: web::Data<Mailer>,
) -> Result<impl Responder, ApplicationError> {
if user.role != Role::AreaManager && user.role != Role::Admin {
return Err(ApplicationError::Unauthorized);
}
let mut area_id = user.area_id;
if user.role == Role::Admin && form.area.is_some() {
area_id = form.area.unwrap();
}
let role = Role::try_from(form.role)?;
if role == Role::Admin && user.role != Role::Admin {
return Err(ApplicationError::Unauthorized);
}
let mut functions = Vec::with_capacity(3);
if form.is_posten.unwrap_or(false) {
functions.push(Function::Posten);
}
if form.is_wachhabender.unwrap_or(false) {
functions.push(Function::Wachhabender);
}
if form.is_fuehrungsassistent.unwrap_or(false) {
functions.push(Function::Fuehrungsassistent);
}
let changeset = UserChangeset {
name: form.name.clone(),
email: form.email.to_lowercase(),
role,
functions,
area_id,
};
if let Some(_) = User::exists(pool.get_ref(), &changeset.email).await? {
return Ok(HttpResponse::UnprocessableEntity()
.body("email: an user already exists with the same email"));
}
let context = DbContext::new(pool.get_ref());
if let Err(e) = changeset.validate_with_context(&context).await {
return Ok(HttpResponse::UnprocessableEntity().body(e.to_string()));
};
let id = User::create(pool.get_ref(), changeset).await?;
let registration = Registration::insert_new_for_user(pool.get_ref(), id).await?;
let new_user = User::read_by_id(pool.get_ref(), id).await?.unwrap();
mailer
.send_registration_mail(&new_user, &registration.token)
.await?;
Ok(HttpResponse::Found()
.insert_header((LOCATION, "/users"))
.finish())
}