feat: edit user with query builder

This commit is contained in:
Max Hohlfeld 2024-03-06 00:02:40 +01:00
parent e107687f71
commit 39a28038ca
12 changed files with 171 additions and 9 deletions

View File

@ -16,4 +16,5 @@ pub fn init(cfg: &mut ServiceConfig) {
cfg.service(user::get_new::get_new);
cfg.service(user::post_new::post_new);
cfg.service(user::get_edit::get_edit);
cfg.service(user::post_edit::post_edit);
}

View File

@ -11,6 +11,7 @@ use crate::{endpoints::IdPath, models::{Area, Role, User}};
pub struct EditUserTemplate {
user: User,
areas: Option<Vec<Area>>,
id: i32,
email: String,
name: String,
role: u8,
@ -23,12 +24,16 @@ pub async fn get_edit(user: Identity, pool: web::Data<PgPool>, path: web::Path<I
let current_user = User::read_by_id(pool.get_ref(), user.id().unwrap().parse().unwrap()).await.unwrap();
let mut areas = None;
if current_user.role != Role::AreaManager && current_user.role != Role::Admin {
return HttpResponse::Unauthorized().finish();
}
if current_user.role == Role::Admin {
areas = Some(Area::read_all(pool.get_ref()).await.unwrap());
}
if let Ok(user_in_db) = User::read_by_id(pool.get_ref(), path.id).await {
let template = EditUserTemplate { user: current_user, areas, email: user_in_db.email, name: user_in_db.name, role: user_in_db.role as u8, function: user_in_db.function as u8, area_id: user_in_db.area_id };
let template = EditUserTemplate { user: current_user, id: user_in_db.id, areas, email: user_in_db.email, name: user_in_db.name, role: user_in_db.role as u8, function: user_in_db.function as u8, area_id: user_in_db.area_id };
return template.to_response();
}

View File

@ -2,4 +2,4 @@ pub mod get_overview;
pub mod get_new;
pub mod post_new;
pub mod get_edit;
pub mod put_edit;
pub mod post_edit;

View File

@ -0,0 +1,90 @@
use actix_identity::Identity;
use actix_web::{http::header::LOCATION, web, HttpResponse, Responder};
use serde::Deserialize;
use sqlx::PgPool;
use crate::{
endpoints::IdPath,
models::{Function, Role, User},
};
#[derive(Deserialize)]
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: Identity,
pool: web::Data<PgPool>,
path: web::Path<IdPath>,
form: web::Form<EditUserForm>,
) -> impl Responder {
let current_user = User::read_by_id(pool.get_ref(), user.id().unwrap().parse().unwrap())
.await
.unwrap();
if current_user.role != Role::AreaManager && current_user.role != Role::Admin {
return HttpResponse::Unauthorized().finish();
}
if let Ok(user_in_db) = User::read_by_id(pool.get_ref(), path.id).await {
let mut changed = false;
let email = if user_in_db.email != form.email {
changed = true;
Some(form.email.as_str())
} else {
None
};
let name = if user_in_db.name != form.name {
changed = true;
Some(form.name.as_str())
} else {
None
};
let role = if user_in_db.role as u8 != form.role {
if let Ok(r) = Role::try_from(form.role) {
changed = true;
Some(r)
} else {
None
}
} else {
None
};
let function = if user_in_db.function as u8 != form.function {
if let Ok(f) = Function::try_from(form.function) {
changed = true;
Some(f)
} else {
None
}
} else {
None
};
let area = if current_user.role == Role::Admin && form.area.is_some() && user_in_db.area_id != form.area.unwrap() {
changed = true;
Some(form.area.unwrap())
} else {
None
};
if changed {
match User::update(pool.get_ref(), path.id, email, name, role, function, area).await {
Ok(_) => return HttpResponse::Found().insert_header((LOCATION, "/users")).finish(),
Err(err) => println!("{}", err)
}
}
}
return HttpResponse::BadRequest().body("Fehler beim Bearbeiten des Nutzers");
}

View File

@ -18,6 +18,11 @@ pub struct NewUserForm {
#[actix_web::post("/users/new")]
pub async fn post_new(user: Identity, pool: web::Data<PgPool>, form: web::Form<NewUserForm>) -> impl Responder {
let current_user = User::read_by_id(pool.get_ref(), user.id().unwrap().parse().unwrap()).await.unwrap();
if current_user.role != Role::AreaManager && current_user.role != Role::Admin {
return HttpResponse::Unauthorized().finish();
}
let mut area_id = current_user.area_id;
if current_user.role == Role::Admin {

View File

@ -11,6 +11,7 @@ use crate::auth::redirect;
mod auth;
mod calendar;
mod models;
mod endpoints;
#[actix_web::main]
async fn main() -> anyhow::Result<()> {

View File

@ -1,6 +1,6 @@
use std::fmt::Display;
#[derive(sqlx::Type, Debug, Clone)]
#[derive(sqlx::Type, Debug, Clone, Copy)]
#[sqlx(type_name = "function", rename_all = "lowercase")]
pub enum Function {
Posten = 1,

View File

@ -1,4 +1,4 @@
#[derive(sqlx::Type, Debug, Clone, PartialEq)]
#[derive(sqlx::Type, Debug, Clone, Copy, PartialEq)]
#[sqlx(type_name = "role", rename_all = "lowercase")]
pub enum Role {
Staff = 1,

View File

@ -1,5 +1,5 @@
use chrono::{DateTime, Utc};
use sqlx::PgPool;
use sqlx::{Execute, PgPool};
use super::{Area, Function, Role};
@ -268,9 +268,53 @@ impl User {
Ok(result)
}
// pub async fn update(pool: &PgPool, id: i32, updated_user: User) -> Option<User> {
// todo!()
// }
pub async fn update(
pool: &PgPool,
id: i32,
email: Option<&str>,
name: Option<&str>,
role: Option<Role>,
function: Option<Function>,
area_id: Option<i32>,
) -> anyhow::Result<()> {
let mut query_builder = sqlx::QueryBuilder::new("UPDATE user_ SET ");
let mut separated = query_builder.separated(", ");
if let Some(email) = email {
separated.push("email = ");
separated.push_bind_unseparated(email);
}
if let Some(name) = name {
separated.push("name = ");
separated.push_bind_unseparated(name);
}
if let Some(role) = role {
separated.push("role = ");
separated.push_bind_unseparated(role as Role);
}
if let Some(function) = function {
separated.push("function = ");
separated.push_bind_unseparated(function as Function);
}
if let Some(area_id) = area_id {
separated.push("areaId = ");
separated.push_bind_unseparated(area_id);
}
query_builder.push(" WHERE id = ");
query_builder.push_bind(id);
query_builder.push(";");
query_builder.build()
.execute(pool)
.await?;
Ok(())
}
// pub async fn delete(pool: &PgPool, id: i32) -> anyhow::Result<bool> {
// todo!()

View File

@ -3,7 +3,7 @@
{% block content %}
<section class="section">
<div class="container">
<form method="post" action="/users/new">
<form method="post" action="/users/edit/{{ id }}">
<h1 class="title">Nutzer {{ name }} bearbeiten</h1>
<div class="field is-horizontal">

View File

@ -30,6 +30,8 @@
{% if user.role == Role::Admin %}
<th>Bereich</th>
{% endif %}
<th>Letzter Login</th>
<th>gesperrt</th>
<th></th>
</tr>
</thead>
@ -67,6 +69,20 @@
{{ u.area.as_ref().unwrap().name }}
</td>
{% endif %}
<td>
{% if u.last_login.is_some() %}
{{ u.last_login.as_ref().unwrap() }}
{% else %}
nie
{% endif %}
</td>
<td>
{% if u.locked %}
ja
{% else %}
nein
{% endif %}
</td>
<td>
<div class="buttons is-right">
<a class="button is-link" href="/users/edit/{{ u.id }}">Bearbeiten</a>