feat: set functions for user
This commit is contained in:
parent
c830704fa4
commit
736b69d2c3
@ -8,6 +8,7 @@ use crate::{
|
||||
};
|
||||
use actix_web::HttpResponse;
|
||||
use rinja::Template;
|
||||
use serde::Deserialize;
|
||||
use sqlx::PgPool;
|
||||
use zxcvbn::{zxcvbn, Score};
|
||||
|
||||
@ -26,9 +27,9 @@ pub mod post_edit;
|
||||
pub mod post_login;
|
||||
pub mod post_new;
|
||||
pub mod post_register;
|
||||
pub mod post_resend_registration;
|
||||
pub mod post_reset;
|
||||
pub mod post_toggle;
|
||||
pub mod post_resend_registration;
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "user/new_or_edit.html")]
|
||||
@ -45,6 +46,21 @@ pub struct NewOrEditUserTemplate {
|
||||
area_id: Option<i32>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[cfg_attr(test, derive(serde::Serialize))]
|
||||
struct NewOrEditUserForm {
|
||||
email: String,
|
||||
name: String,
|
||||
role: u8,
|
||||
#[serde(rename(deserialize = "is-posten"))]
|
||||
is_posten: Option<bool>,
|
||||
#[serde(rename(deserialize = "is-wachhabender"))]
|
||||
is_wachhabender: Option<bool>,
|
||||
#[serde(rename(deserialize = "is-fuehrungsassistent"))]
|
||||
is_fuehrungsassistent: Option<bool>,
|
||||
area: Option<i32>,
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "user/change_password.html")]
|
||||
struct ResetPasswordTemplate<'a> {
|
||||
|
@ -1,30 +1,19 @@
|
||||
use actix_web::{http::header::LOCATION, web, HttpResponse, Responder};
|
||||
use garde::Validate;
|
||||
use serde::Deserialize;
|
||||
use sqlx::PgPool;
|
||||
|
||||
use crate::{
|
||||
endpoints::IdPath,
|
||||
models::{Area, Role, User, UserChangeset},
|
||||
endpoints::{user::NewOrEditUserForm, IdPath},
|
||||
models::{Area, Function, Role, User, UserChangeset},
|
||||
utils::ApplicationError,
|
||||
};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[cfg_attr(test, derive(serde::Serialize))]
|
||||
pub struct EditUserForm {
|
||||
email: String,
|
||||
name: String,
|
||||
role: u8,
|
||||
function: u8,
|
||||
area: Option<i32>,
|
||||
}
|
||||
|
||||
#[actix_web::post("/users/edit/{id}")]
|
||||
pub async fn post_edit(
|
||||
user: web::ReqData<User>,
|
||||
pool: web::Data<PgPool>,
|
||||
path: web::Path<IdPath>,
|
||||
form: web::Form<EditUserForm>,
|
||||
form: web::Form<NewOrEditUserForm>,
|
||||
) -> Result<impl Responder, ApplicationError> {
|
||||
if user.role != Role::AreaManager && user.role != Role::Admin {
|
||||
return Err(ApplicationError::Unauthorized);
|
||||
@ -47,11 +36,25 @@ pub async fn post_edit(
|
||||
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.clone(),
|
||||
role: form.role.try_into()?,
|
||||
function: form.function.try_into()?,
|
||||
functions,
|
||||
area_id,
|
||||
};
|
||||
|
||||
@ -69,8 +72,7 @@ pub async fn post_edit(
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{models::*, utils::test_helper::*};
|
||||
use crate::{endpoints::user::NewOrEditUserForm, models::*, utils::test_helper::*};
|
||||
use brass_macros::db_test;
|
||||
use fake::{
|
||||
faker::{internet::en::SafeEmail, name::en::Name},
|
||||
@ -94,11 +96,13 @@ mod tests {
|
||||
let new_name: String = Name().fake();
|
||||
let new_mail: String = SafeEmail().fake();
|
||||
|
||||
let form = EditUserForm {
|
||||
let form = NewOrEditUserForm {
|
||||
name: new_name.clone(),
|
||||
email: new_mail.clone(),
|
||||
role: Role::AreaManager as u8,
|
||||
function: Function::Fuehrungsassistent as u8,
|
||||
is_posten: None,
|
||||
is_wachhabender: None,
|
||||
is_fuehrungsassistent: Some(true),
|
||||
area: Some(2),
|
||||
};
|
||||
|
||||
@ -127,11 +131,13 @@ mod tests {
|
||||
user_area: 1,
|
||||
};
|
||||
|
||||
let form = EditUserForm {
|
||||
let form = NewOrEditUserForm {
|
||||
name: "".to_string(),
|
||||
email: "".to_string(),
|
||||
role: Role::AreaManager as u8,
|
||||
function: Function::Fuehrungsassistent as u8,
|
||||
is_posten: None,
|
||||
is_wachhabender: None,
|
||||
is_fuehrungsassistent: Some(true),
|
||||
area: Some(1),
|
||||
};
|
||||
|
||||
|
@ -1,28 +1,19 @@
|
||||
use actix_web::{http::header::LOCATION, web, HttpResponse, Responder};
|
||||
use garde::Validate;
|
||||
use serde::Deserialize;
|
||||
use sqlx::PgPool;
|
||||
|
||||
use crate::{
|
||||
endpoints::user::NewOrEditUserForm,
|
||||
mail::Mailer,
|
||||
models::{Function, Registration, Role, User, UserChangeset},
|
||||
utils::ApplicationError,
|
||||
};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct NewUserForm {
|
||||
email: String,
|
||||
name: String,
|
||||
role: u8,
|
||||
function: u8,
|
||||
area: Option<i32>,
|
||||
}
|
||||
|
||||
#[actix_web::post("/users/new")]
|
||||
pub async fn post_new(
|
||||
user: web::ReqData<User>,
|
||||
pool: web::Data<PgPool>,
|
||||
form: web::Form<NewUserForm>,
|
||||
form: web::Form<NewOrEditUserForm>,
|
||||
mailer: web::Data<Mailer>,
|
||||
) -> Result<impl Responder, ApplicationError> {
|
||||
if user.role != Role::AreaManager && user.role != Role::Admin {
|
||||
@ -36,29 +27,39 @@ pub async fn post_new(
|
||||
}
|
||||
|
||||
let role = Role::try_from(form.role)?;
|
||||
let function = Function::try_from(form.function)?;
|
||||
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.clone(),
|
||||
role,
|
||||
function,
|
||||
area_id
|
||||
functions,
|
||||
area_id,
|
||||
};
|
||||
|
||||
if let Err(e) = changeset.validate() {
|
||||
return Ok(HttpResponse::BadRequest().body(e.to_string()));
|
||||
};
|
||||
|
||||
let id = User::create(
|
||||
pool.get_ref(),
|
||||
changeset
|
||||
)
|
||||
.await?;
|
||||
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?;
|
||||
mailer
|
||||
.send_registration_mail(&new_user, ®istration.token)
|
||||
.await?;
|
||||
|
||||
Ok(HttpResponse::Found()
|
||||
.insert_header((LOCATION, "/users"))
|
||||
|
@ -30,7 +30,7 @@ impl User {
|
||||
changeset.name,
|
||||
changeset.email,
|
||||
changeset.role as Role,
|
||||
changeset.function as Function,
|
||||
changeset.functions.as_slice() as &[Function],
|
||||
changeset.area_id
|
||||
)
|
||||
.fetch_one(pool)
|
||||
@ -285,7 +285,7 @@ impl User {
|
||||
changeset.name,
|
||||
changeset.email,
|
||||
changeset.role as Role,
|
||||
changeset.function as Function,
|
||||
changeset.functions.as_slice() as &[Function],
|
||||
changeset.area_id,
|
||||
id
|
||||
)
|
||||
|
@ -5,7 +5,7 @@ use garde::Validate;
|
||||
|
||||
use super::{Function, Role};
|
||||
|
||||
#[derive(Validate)]
|
||||
#[derive(Debug, Validate)]
|
||||
#[cfg_attr(test, derive(Dummy))]
|
||||
#[garde(allow_unvalidated)]
|
||||
pub struct UserChangeset {
|
||||
@ -16,8 +16,8 @@ pub struct UserChangeset {
|
||||
pub email: String,
|
||||
#[cfg_attr(test, dummy(expr = "Role::Staff"))]
|
||||
pub role: Role,
|
||||
#[cfg_attr(test, dummy(expr = "Function::Posten"))]
|
||||
pub function: Function,
|
||||
#[cfg_attr(test, dummy(expr = "vec![Function::Posten]"))]
|
||||
pub functions: Vec<Function>,
|
||||
/// check before: must exist and user can create other user for this area
|
||||
#[cfg_attr(test, dummy(expr = "1"))]
|
||||
pub area_id: i32,
|
||||
|
@ -64,12 +64,28 @@
|
||||
<label class="label">Funktion</label>
|
||||
</div>
|
||||
<div class="field-body">
|
||||
<div class="field is-narrow">
|
||||
<div class="field is-grouped">
|
||||
<div class="control">
|
||||
<div class="select is-fullwidth">
|
||||
<select name="function">
|
||||
</select>
|
||||
</div>
|
||||
<label class="checkbox">
|
||||
<input id="is-posten" type="checkbox" name="is-posten" value="true" {{
|
||||
is_posten.unwrap_or(false)|ref|cond_show("checked") }} />
|
||||
Posten
|
||||
</label>
|
||||
</div>
|
||||
<div class="control">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" name="is-wachhabender" value="true" {{
|
||||
is_wachhabender.unwrap_or(false)|ref|cond_show("checked") }}
|
||||
_="on change if me.checked then set checked of previous <input/> to true" />
|
||||
Wachhabender
|
||||
</label>
|
||||
</div>
|
||||
<div class="control">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" name="is-fuehrungsassistent" value="true" {{
|
||||
is_fuehrungsassistent.unwrap_or(false)|ref|cond_show("checked") }} />
|
||||
Führungsassistent
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -87,8 +103,8 @@
|
||||
<select name="area">
|
||||
{% for area in areas.as_ref().unwrap() %}
|
||||
<option value="{{ area.id }}" {{ area_id|is_some_and_eq(area.id)|ref|cond_show("selected") }}>{{
|
||||
area.name }}</option>
|
||||
{% endfor %}
|
||||
area.name }}</input>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user