From d778380d8b7fe4f1e5625c7897adb38521a80d9c Mon Sep 17 00:00:00 2001 From: Philippe Loctaux Date: Sun, 7 May 2023 18:39:02 +0200 Subject: [PATCH] admin/roles: view, archive and restore --- .../queries/roles/get_one_by_name.sql | 7 + .../queries/roles/set_archive_status.sql | 5 + crates/database/sqlx-data.json | 46 ++++++ crates/database/src/tables/roles.rs | 24 +++ crates/ezidam/src/page.rs | 5 + crates/ezidam/src/routes/admin.rs | 11 ++ crates/ezidam/src/routes/admin/roles.rs | 101 +++++++++++- .../templates/pages/admin/roles/new.html.tera | 2 +- .../pages/admin/roles/view.html.tera | 145 ++++++++++++++++++ crates/roles/src/database.rs | 19 +++ 10 files changed, 363 insertions(+), 2 deletions(-) create mode 100644 crates/database/queries/roles/get_one_by_name.sql create mode 100644 crates/database/queries/roles/set_archive_status.sql create mode 100644 crates/ezidam/templates/pages/admin/roles/view.html.tera diff --git a/crates/database/queries/roles/get_one_by_name.sql b/crates/database/queries/roles/get_one_by_name.sql new file mode 100644 index 0000000..d529b8e --- /dev/null +++ b/crates/database/queries/roles/get_one_by_name.sql @@ -0,0 +1,7 @@ +select name, + label, + created_at as "created_at: DateTime", + is_archived as "is_archived: bool" +from roles + +where name is (?) diff --git a/crates/database/queries/roles/set_archive_status.sql b/crates/database/queries/roles/set_archive_status.sql new file mode 100644 index 0000000..2cb867a --- /dev/null +++ b/crates/database/queries/roles/set_archive_status.sql @@ -0,0 +1,5 @@ +update roles + +set is_archived = ? + +where name is ? \ No newline at end of file diff --git a/crates/database/sqlx-data.json b/crates/database/sqlx-data.json index 66e82fb..e36b6f9 100644 --- a/crates/database/sqlx-data.json +++ b/crates/database/sqlx-data.json @@ -110,6 +110,16 @@ }, "query": "update apps\n\nset is_archived = 1\n\nwhere id is ?" }, + "2ee77458d93ae79d957e03e6ca50c1bf690f40b6cc6ec5f008eb0e928f376659": { + "describe": { + "columns": [], + "nullable": [], + "parameters": { + "Right": 2 + } + }, + "query": "update roles\n\nset is_archived = ?\n\nwhere name is ?" + }, "32d35bdd1f4cf64ce0ff7beb7a11591e0f35eab7211692bcde8230c68e4cedf3": { "describe": { "columns": [], @@ -864,6 +874,42 @@ }, "query": "select id,\n created_at as \"created_at: DateTime\",\n updated_at as \"updated_at: DateTime\",\n is_admin as \"is_admin: bool\",\n username,\n name,\n email,\n password,\n password_recover,\n paper_key,\n is_archived as \"is_archived: bool\",\n timezone,\n totp_secret,\n totp_backup\nfrom users\n\norder by created_at desc\n" }, + "9a3aef02e55fc436e9c09c1ee6d29477c2746765f6e7d5679058ec6525ee7253": { + "describe": { + "columns": [ + { + "name": "name", + "ordinal": 0, + "type_info": "Text" + }, + { + "name": "label", + "ordinal": 1, + "type_info": "Text" + }, + { + "name": "created_at: DateTime", + "ordinal": 2, + "type_info": "Text" + }, + { + "name": "is_archived: bool", + "ordinal": 3, + "type_info": "Int64" + } + ], + "nullable": [ + false, + false, + false, + false + ], + "parameters": { + "Right": 1 + } + }, + "query": "select name,\n label,\n created_at as \"created_at: DateTime\",\n is_archived as \"is_archived: bool\"\nfrom roles\n\nwhere name is (?)\n" + }, "9dc379b0f3a3c944a33ef01dc40489b29b2a61b9f73f6ca4b5df7e9fb9bccf90": { "describe": { "columns": [ diff --git a/crates/database/src/tables/roles.rs b/crates/database/src/tables/roles.rs index 162b9f4..d125570 100644 --- a/crates/database/src/tables/roles.rs +++ b/crates/database/src/tables/roles.rs @@ -31,4 +31,28 @@ impl Roles { .await .map_err(handle_error) } + + pub async fn get_one_by_name( + conn: impl SqliteExecutor<'_>, + name: &str, + ) -> Result, Error> { + sqlx::query_file_as!(Self, "queries/roles/get_one_by_name.sql", name) + .fetch_optional(conn) + .await + .map_err(handle_error) + } + + pub async fn set_archive_status( + conn: impl SqliteExecutor<'_>, + id: &str, + value: bool, + ) -> Result, Error> { + let query: SqliteQueryResult = + sqlx::query_file!("queries/roles/set_archive_status.sql", value, id) + .execute(conn) + .await + .map_err(handle_error)?; + + Ok((query.rows_affected() == 1).then_some(())) + } } diff --git a/crates/ezidam/src/page.rs b/crates/ezidam/src/page.rs index 0f83e7c..a54b1f0 100644 --- a/crates/ezidam/src/page.rs +++ b/crates/ezidam/src/page.rs @@ -34,6 +34,7 @@ pub enum Page { AdminUsersNew(AdminUsersNew), AdminRolesList(AdminRolesList), AdminRolesNew(AdminRolesNew), + AdminRolesView(AdminRolesView), } impl Page { @@ -64,6 +65,7 @@ impl Page { Page::AdminUsersNew(_) => "pages/admin/users/new", Page::AdminRolesList(_) => "pages/admin/roles/list", Page::AdminRolesNew(_) => "pages/admin/roles/new", + Page::AdminRolesView(_) => "pages/admin/roles/view", } } @@ -94,6 +96,7 @@ impl Page { Page::AdminUsersNew(_) => "New user", Page::AdminRolesList(_) => "Roles", Page::AdminRolesNew(_) => "New role", + Page::AdminRolesView(_) => "Role info", } } @@ -126,6 +129,7 @@ impl Page { Page::AdminUsersNew(_) => Some(AdminMenu::Users.into()), Page::AdminRolesList(_) => Some(AdminMenu::Roles.into()), Page::AdminRolesNew(_) => Some(AdminMenu::Roles.into()), + Page::AdminRolesView(_) => Some(AdminMenu::Roles.into()), } } @@ -156,6 +160,7 @@ impl Page { Page::AdminUsersNew(new) => Box::new(new), Page::AdminRolesList(list) => Box::new(list), Page::AdminRolesNew(new) => Box::new(new), + Page::AdminRolesView(view) => Box::new(view), } } } diff --git a/crates/ezidam/src/routes/admin.rs b/crates/ezidam/src/routes/admin.rs index 481cbb7..cf621f9 100644 --- a/crates/ezidam/src/routes/admin.rs +++ b/crates/ezidam/src/routes/admin.rs @@ -40,6 +40,8 @@ pub fn routes() -> Vec { admin_roles_list, admin_roles_new, admin_roles_new_form, + admin_roles_view, + admin_roles_archive, ] } @@ -143,4 +145,13 @@ pub mod content { pub struct AdminRolesNew { pub user: JwtClaims, } + + #[derive(Serialize)] + #[serde(crate = "rocket::serde")] + #[derive(Clone)] + pub struct AdminRolesView { + pub user: JwtClaims, + pub role: Role, + pub jwt_duration: i64, + } } diff --git a/crates/ezidam/src/routes/admin/roles.rs b/crates/ezidam/src/routes/admin/roles.rs index ebefb8a..fd7e60d 100644 --- a/crates/ezidam/src/routes/admin/roles.rs +++ b/crates/ezidam/src/routes/admin/roles.rs @@ -1,4 +1,5 @@ use crate::routes::prelude::*; +use crate::tokens::JWT_DURATION_MINUTES; use rocket::{get, post}; use roles::Role; use std::str::FromStr; @@ -71,9 +72,107 @@ pub async fn admin_roles_new_form( transaction.commit().await?; + let id = RocketRoleID(name); Ok(Flash::new( - Redirect::to(uri!(admin_roles_list)), + Redirect::to(uri!(admin_roles_view(id))), FlashKind::Success, "Role has been created.", )) } + +#[get("/admin/roles/")] +pub async fn admin_roles_view( + admin: JwtAdmin, + mut db: Connection, + id: RocketRoleID, + flash: Option>, +) -> Result