diff --git a/backend/migrations/20241018235116_calendar_roles.down.sql b/backend/migrations/20241018235116_calendar_roles.down.sql new file mode 100644 index 0000000..5910f34 --- /dev/null +++ b/backend/migrations/20241018235116_calendar_roles.down.sql @@ -0,0 +1,9 @@ +-- Add down migration script here +-- Delete role records +DELETE FROM "main"."roles" WHERE "id" = '5'; + +-- Delete permission records +DELETE FROM "main"."role_permissions" WHERE "id" = '8'; + +-- Delete user role records +DELETE FROM "main"."user_roles" WHERE "role_id" = '5'; diff --git a/backend/migrations/20241018235116_calendar_roles.up.sql b/backend/migrations/20241018235116_calendar_roles.up.sql new file mode 100644 index 0000000..4f7c40b --- /dev/null +++ b/backend/migrations/20241018235116_calendar_roles.up.sql @@ -0,0 +1,9 @@ +-- Add up migration script here +-- Add roles for calendar +INSERT INTO "main"."roles" ("id", "created_at", "created_by", "updated_at", "updated_by", "name", "description") VALUES ('5', '0', '0', '0', '0', 'calendar', 'Users with access to the calendar'); + +-- Add permissions for calendar +INSERT INTO "main"."role_permissions" ("id", "created_at", "created_by", "updated_at", "updated_by", "role_id", "item") VALUES ('8', '0', '0', '0', '0', '5', '/cottagecalendar'); + +-- Add user roles for calendar +INSERT INTO "main"."user_roles" ("id", "created_at", "created_by", "updated_at", "updated_by", "user_id", "role_id") VALUES ('1', '0', '0', '0', '0', '1', '5'); diff --git a/backend/src/main.rs b/backend/src/main.rs index 07906a9..32b9f93 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -15,7 +15,7 @@ mod user; use error_handling::AppError; use middlewares::inject_user_data; use google_oauth::{login, logout, google_auth_return}; -use routes::{dashboard, index, about, contact, profile, user_profile, useradmin}; +use routes::{dashboard, index, about, cottagecalendar, contact, profile, user_profile, useradmin}; use user::{add_user_role, delete_user_role, UserData}; #[derive(Clone)] @@ -47,6 +47,7 @@ async fn main() { // build our application with some routes let app = Router::new() .route("/dashboard", get(dashboard)) + .route("/cottagecalendar", get(cottagecalendar)) .route("/profile", get(profile)) .route("/useradmin", get(useradmin)) .route("/users/:user_id", get(user_profile)) diff --git a/backend/src/routes.rs b/backend/src/routes.rs index 45c09e0..2b9dcd0 100644 --- a/backend/src/routes.rs +++ b/backend/src/routes.rs @@ -1,9 +1,17 @@ use askama_axum::{Response, Template}; -use axum::{extract::{Path, State}, response::{Html, IntoResponse, Redirect}, Extension}; +use axum::{ + extract::{Path, State}, + response::{Html, IntoResponse, Redirect}, + Extension, +}; use http::StatusCode; use sqlx::SqlitePool; -use crate::{middlewares::is_authorized, user::{get_other_roles_display, get_user_roles_display}, UserData}; +use crate::{ + middlewares::is_authorized, + user::{get_other_roles_display, get_user_roles_display}, + UserData, +}; #[derive(Template)] #[template(path = "profile.html")] @@ -20,7 +28,7 @@ struct UserProfileTemplate { name: String, user: UserData, user_roles: Vec, - non_user_roles: Vec + non_user_roles: Vec, } struct HtmlTemplate(T); @@ -64,10 +72,10 @@ pub async fn index( let name = user_name.unwrap_or_default(); if is_authorized("/dashboard", user_data, db_pool).await { - Redirect::to("/dashboard").into_response() + Redirect::to("/dashboard").into_response() } else { let template = IndexTemplate { logged_in, name }; - HtmlTemplate(template).into_response() + HtmlTemplate(template).into_response() } } @@ -80,7 +88,7 @@ pub async fn dashboard( let name = user_name.unwrap_or_default(); if is_authorized("/dashboard", user_data, db_pool).await { - let template = DashboardTemplate { logged_in, name}; + let template = DashboardTemplate { logged_in, name }; HtmlTemplate(template).into_response() } else { Redirect::to("/").into_response() @@ -96,15 +104,19 @@ pub async fn profile( let user_name = user_data.as_ref().map(|s| s.name.clone()); let logged_in = user_name.is_some(); let name = user_name.unwrap_or_default(); - + if logged_in { // Extract the user data. let user = user_data.as_ref().unwrap().clone(); if is_authorized("/profile", user_data, db_pool).await { // Create the profile template. - let template = ProfileTemplate { logged_in, name, user: user.clone() }; - return HtmlTemplate(template).into_response() + let template = ProfileTemplate { + logged_in, + name, + user: user.clone(), + }; + return HtmlTemplate(template).into_response(); } else { Redirect::to("/").into_response() } @@ -113,7 +125,7 @@ pub async fn profile( } } - pub async fn user_profile( +pub async fn user_profile( Path(user_id): Path, State(db_pool): State, Extension(user_data): Extension>, @@ -122,16 +134,12 @@ pub async fn profile( let user_name = user_data.as_ref().map(|s| s.name.clone()); let logged_in = user_data.is_some(); let name = user_name.unwrap_or_default(); - + // Extract the user data. - let user = sqlx::query_as!( - UserData, - "SELECT * FROM users WHERE id = ?", - user_id - ) - .fetch_one(&db_pool) - .await - .unwrap(); + let user = sqlx::query_as!(UserData, "SELECT * FROM users WHERE id = ?", user_id) + .fetch_one(&db_pool) + .await + .unwrap(); if is_authorized("/users", user_data, db_pool.clone()).await { // Get user roles @@ -141,8 +149,14 @@ pub async fn profile( let non_user_roles = get_other_roles_display(user_id, &db_pool.clone()).await; // Create the profile template. - let template = UserProfileTemplate { logged_in, name, user: user, user_roles , non_user_roles}; - return HtmlTemplate(template).into_response() + let template = UserProfileTemplate { + logged_in, + name, + user: user, + user_roles, + non_user_roles, + }; + return HtmlTemplate(template).into_response(); } else { Redirect::to("/").into_response() } @@ -153,25 +167,28 @@ pub async fn profile( struct UserAdminTemplate { logged_in: bool, name: String, - users: Vec + users: Vec, } pub async fn useradmin( Extension(user_data): Extension>, State(db_pool): State, ) -> impl IntoResponse { - let user_name = user_data.as_ref().map(|s| s.name.clone()); let logged_in = user_name.is_some(); let name = user_name.unwrap_or_default(); let users = sqlx::query_as::<_, UserData>("SELECT * FROM users") - .fetch_all(&db_pool) - .await - .unwrap(); + .fetch_all(&db_pool) + .await + .unwrap(); if is_authorized("/useradmin", user_data, db_pool).await { - let template = UserAdminTemplate { logged_in, name, users }; + let template = UserAdminTemplate { + logged_in, + name, + users, + }; HtmlTemplate(template).into_response() } else { Redirect::to("/").into_response() @@ -185,9 +202,7 @@ struct AboutTemplate { name: String, } -pub async fn about( - Extension(user_data): Extension>, -) -> impl IntoResponse { +pub async fn about(Extension(user_data): Extension>) -> impl IntoResponse { let user_name = user_data.map(|s| s.name); let logged_in = user_name.is_some(); let name = user_name.unwrap_or_default(); @@ -196,7 +211,6 @@ pub async fn about( HtmlTemplate(template) } - #[derive(Template)] #[template(path = "contactus.html")] struct ContactTemplate { @@ -204,13 +218,34 @@ struct ContactTemplate { name: String, } -pub async fn contact( - Extension(user_data): Extension>, -) -> impl IntoResponse { +pub async fn contact(Extension(user_data): Extension>) -> impl IntoResponse { let user_name = user_data.map(|s| s.name); let logged_in = user_name.is_some(); let name = user_name.unwrap_or_default(); let template = ContactTemplate { logged_in, name }; HtmlTemplate(template) -} \ No newline at end of file +} + +#[derive(Template)] +#[template(path = "cottagecalendar.html")] +struct CottageCalendarTemplate { + logged_in: bool, + name: String, +} + +pub async fn cottagecalendar( + Extension(user_data): Extension>, + State(db_pool): State, +) -> impl IntoResponse { + let user_name = user_data.as_ref().map(|s| s.name.clone()); + let logged_in = user_name.is_some(); + let name = user_name.unwrap_or_default(); + + if is_authorized("/cottagecalendar", user_data, db_pool).await { + let template = CottageCalendarTemplate { logged_in, name }; + HtmlTemplate(template).into_response() + } else { + Redirect::to("/").into_response() + } +} diff --git a/backend/templates/authorized.html b/backend/templates/authorized.html index 4cd345d..c154e87 100644 --- a/backend/templates/authorized.html +++ b/backend/templates/authorized.html @@ -8,6 +8,7 @@
diff --git a/backend/templates/cottagecalendar.html b/backend/templates/cottagecalendar.html new file mode 100644 index 0000000..110d7b5 --- /dev/null +++ b/backend/templates/cottagecalendar.html @@ -0,0 +1,8 @@ +{% extends "authorized.html" %} +{% block center %} +

Cottage Calendar

+
+ + +
+{% endblock center %} \ No newline at end of file diff --git a/backend/templates/dashboard.html b/backend/templates/dashboard.html index f58d888..7f9e9ea 100644 --- a/backend/templates/dashboard.html +++ b/backend/templates/dashboard.html @@ -5,17 +5,18 @@

Web links

TLC Creations

Fonts

Family tree

{% endblock center %} \ No newline at end of file