From d209df9e10544b7c1fc8ebfdb3a7910400ba0289 Mon Sep 17 00:00:00 2001 From: Stefan Melmuk Date: Fri, 2 Dec 2022 17:58:27 +0100 Subject: [PATCH 1/2] use a custom 404 page to customize the 404 page you can copy the handlebar template `src/static/templates/404.hbs` to the TEMPLATES_FOLDER (defaults to `data/templates/`) --- resources/404.svg | 93 +++++++++++++++++++++++++++++++++++ src/api/web.rs | 15 ++++-- src/config.rs | 2 + src/static/images/404.png | Bin 0 -> 5042 bytes src/static/templates/404.hbs | 62 +++++++++++++++++++++++ 5 files changed, 167 insertions(+), 5 deletions(-) create mode 100644 resources/404.svg create mode 100644 src/static/images/404.png create mode 100644 src/static/templates/404.hbs diff --git a/resources/404.svg b/resources/404.svg new file mode 100644 index 00000000..112db68d --- /dev/null +++ b/resources/404.svg @@ -0,0 +1,93 @@ + + + +404Return to the web vault? diff --git a/src/api/web.rs b/src/api/web.rs index e5485123..a7640cd9 100644 --- a/src/api/web.rs +++ b/src/api/web.rs @@ -1,11 +1,10 @@ use std::path::{Path, PathBuf}; -use rocket::serde::json::Json; -use rocket::{fs::NamedFile, http::ContentType, Catcher, Route}; +use rocket::{fs::NamedFile, http::ContentType, response::content::RawHtml as Html, serde::json::Json, Catcher, Route}; use serde_json::Value; use crate::{ - api::core::now, + api::{core::now, ApiResult}, error::Error, util::{Cached, SafeString}, CONFIG, @@ -30,8 +29,13 @@ pub fn catchers() -> Vec { } #[catch(404)] -async fn not_found() -> Cached> { - Cached::short(NamedFile::open(Path::new(&CONFIG.web_vault_folder()).join("404.html")).await.ok(), false) +fn not_found() -> ApiResult> { + // Return the page + let json = json!({ + "urlpath": CONFIG.domain_path() + }); + let text = CONFIG.render_template("404", &json)?; + Ok(Html(text)) } #[get("/")] @@ -91,6 +95,7 @@ fn alive(_conn: DbConn) -> Json { #[get("/vw_static/")] pub fn static_files(filename: String) -> Result<(ContentType, &'static [u8]), Error> { match filename.as_ref() { + "404.png" => Ok((ContentType::PNG, include_bytes!("../static/images/404.png"))), "mail-github.png" => Ok((ContentType::PNG, include_bytes!("../static/images/mail-github.png"))), "logo-gray.png" => Ok((ContentType::PNG, include_bytes!("../static/images/logo-gray.png"))), "error-x.svg" => Ok((ContentType::SVG, include_bytes!("../static/images/error-x.svg"))), diff --git a/src/config.rs b/src/config.rs index fbf0e412..eb776bb9 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1123,6 +1123,8 @@ where reg!("admin/organizations"); reg!("admin/diagnostics"); + reg!("404"); + // And then load user templates to overwrite the defaults // Use .hbs extension for the files // Templates get registered with their relative name diff --git a/src/static/images/404.png b/src/static/images/404.png new file mode 100644 index 0000000000000000000000000000000000000000..a76ddb041d98ce06a441c5d606d5057b3b7c86e0 GIT binary patch literal 5042 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 literal 0 HcmV?d00001 diff --git a/src/static/templates/404.hbs b/src/static/templates/404.hbs new file mode 100644 index 00000000..dc30b9e4 --- /dev/null +++ b/src/static/templates/404.hbs @@ -0,0 +1,62 @@ + + + + + + + + Page not found! + + + + + + + + +
+

Page not found!

+

Sorry, but the page you were looking for could not be found.

+

+ Return to the web vault?

+

You can return to the web-vault, or contact us.

+
+ + + + From 2d90c6ac249f24115536151fc0352556d9d35f16 Mon Sep 17 00:00:00 2001 From: BlackDex Date: Fri, 2 Dec 2022 17:39:19 +0100 Subject: [PATCH 2/2] Fix managers and groups link This PR should fix the managers and group link. Although i think there might be a cleaner sollution, there are a lot of other items to fix here which we should do in time. But for now, with theh group support already merged, this fix should at least help solving issue #2932. Fixes #2932 --- src/auth.rs | 12 +++++------- src/db/models/collection.rs | 35 +++++++++++++++++++++++++++++++---- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/auth.rs b/src/auth.rs index 8dea4165..f3e3af8b 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -266,7 +266,7 @@ use rocket::{ }; use crate::db::{ - models::{CollectionUser, Device, User, UserOrgStatus, UserOrgType, UserOrganization, UserStampException}, + models::{Collection, Device, User, UserOrgStatus, UserOrgType, UserOrganization, UserStampException}, DbConn, }; @@ -558,17 +558,15 @@ impl<'r> FromRequest<'r> for ManagerHeaders { _ => err_handler!("Error getting DB"), }; - if !headers.org_user.has_full_access() { - match CollectionUser::find_by_collection_and_user( + if !headers.org_user.has_full_access() + && !Collection::has_access_by_collection_and_user_uuid( &col_id, &headers.org_user.user_uuid, &mut conn, ) .await - { - Some(_) => (), - None => err_handler!("The current user isn't a manager for this collection"), - } + { + err_handler!("The current user isn't a manager for this collection") } } _ => err_handler!("Error getting the collection id"), diff --git a/src/db/models/collection.rs b/src/db/models/collection.rs index c4507e10..14eef617 100644 --- a/src/db/models/collection.rs +++ b/src/db/models/collection.rs @@ -167,15 +167,15 @@ impl Collection { users_collections::user_uuid.eq(user_uuid.clone()) ) )) - .left_join(users_organizations::table.on( + .inner_join(users_organizations::table.on( collections::org_uuid.eq(users_organizations::org_uuid).and( users_organizations::user_uuid.eq(user_uuid.clone()) ) )) - .left_join(groups_users::table.on( + .inner_join(groups_users::table.on( groups_users::users_organizations_uuid.eq(users_organizations::uuid) )) - .left_join(groups::table.on( + .inner_join(groups::table.on( groups::uuid.eq(groups_users::groups_uuid) )) .left_join(collections_groups::table.on( @@ -203,6 +203,17 @@ impl Collection { }} } + // Check if a user has access to a specific collection + // FIXME: This needs to be reviewed. The query used by `find_by_user_uuid` could be adjusted to filter when needed. + // For now this is a good solution without making to much changes. + pub async fn has_access_by_collection_and_user_uuid( + collection_uuid: &str, + user_uuid: &str, + conn: &mut DbConn, + ) -> bool { + Self::find_by_user_uuid(user_uuid.to_owned(), conn).await.into_iter().any(|c| c.uuid == collection_uuid) + } + pub async fn find_by_organization_and_user_uuid(org_uuid: &str, user_uuid: &str, conn: &mut DbConn) -> Vec { Self::find_by_user_uuid(user_uuid.to_owned(), conn) .await @@ -241,16 +252,32 @@ impl Collection { users_collections::user_uuid.eq(user_uuid.clone()) ) )) - .left_join(users_organizations::table.on( + .inner_join(users_organizations::table.on( collections::org_uuid.eq(users_organizations::org_uuid).and( users_organizations::user_uuid.eq(user_uuid) ) )) + .inner_join(groups_users::table.on( + groups_users::users_organizations_uuid.eq(users_organizations::uuid) + )) + .inner_join(groups::table.on( + groups::uuid.eq(groups_users::groups_uuid) + )) + .left_join(collections_groups::table.on( + collections_groups::groups_uuid.eq(groups_users::groups_uuid).and( + collections_groups::collections_uuid.eq(collections::uuid) + ) + )) .filter(collections::uuid.eq(uuid)) .filter( users_collections::collection_uuid.eq(uuid).or( // Directly accessed collection users_organizations::access_all.eq(true).or( // access_all in Organization users_organizations::atype.le(UserOrgType::Admin as i32) // Org admin or owner + )).or( + groups::access_all.eq(true) // access_all in groups + ).or( // access via groups + groups_users::users_organizations_uuid.eq(users_organizations::uuid).and( + collections_groups::collections_uuid.is_not_null() ) ) ).select(collections::all_columns)