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, pool: web::Data, form: web::Form, mailer: web::Data, ) -> Result { 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, ®istration.token) .await?; Ok(HttpResponse::Found() .insert_header((LOCATION, "/users")) .finish()) }