diff --git a/backend/migrations/20240926235210_role_tables.down.sql b/backend/migrations/20240926235210_role_tables.down.sql new file mode 100644 index 0000000..d2f607c --- /dev/null +++ b/backend/migrations/20240926235210_role_tables.down.sql @@ -0,0 +1 @@ +-- Add down migration script here diff --git a/backend/migrations/20240926235210_role_tables.up.sql b/backend/migrations/20240926235210_role_tables.up.sql new file mode 100644 index 0000000..e3015f9 --- /dev/null +++ b/backend/migrations/20240926235210_role_tables.up.sql @@ -0,0 +1,23 @@ +-- Add up migration script here + +CREATE TABLE IF NOT EXISTS roles ( + "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, + "created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + "name" TEXT NOT NULL, + "description" TEXT +); + +CREATE TABLE IF NOT EXISTS user_roles ( + "user_id" integer NOT NULL, + "role_id" integer NOT NULL, + "created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP +); + +create TABLE IF NOT EXISTS role_permissions ( + "role_id" integer NOT NULL, + "item" text NOT NULL, + "created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP +); diff --git a/backend/src/main.rs b/backend/src/main.rs index da9f61b..babaf7e 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -83,16 +83,16 @@ async fn main() { // build our application with some routes let app = Router::new() //Routes that require authentication - .route("/logout", get(logout)) .route("/profile", get(profile)) .route("/useradmin", get(useradmin)) - .route_layer(middleware::from_fn_with_state(app_state.clone(), check_auth)) + .route_layer(middleware::from_fn_with_state(app_state.db_pool.clone(), check_auth)) //Routes that don't require authentication .nest_service("/assets", ServeDir::new("templates/assets") .fallback(get_service(ServeDir::new("templates/assets")))) .route("/", get(index)) .route("/login", get(login)) + .route("/logout", get(logout)) .route("/google_auth", get(google_auth)) .route("/google_auth_return", get(google_auth_return)) .route_layer(middleware::from_fn_with_state(app_state.db_pool.clone(), inject_user_data)) diff --git a/backend/src/middlewares.rs b/backend/src/middlewares.rs index 83f1302..13ec81f 100644 --- a/backend/src/middlewares.rs +++ b/backend/src/middlewares.rs @@ -65,15 +65,52 @@ pub async fn inject_user_data( Ok(next.run(request).await) } -pub async fn check_auth(request: Request, next: Next) -> Result { +pub async fn check_auth(State(app_state): State, request: Request, next: Next) -> Result { + if request .extensions() .get::>() .ok_or("check_auth: extensions have no UserData")? .is_some() { + let path = &*request.uri().to_string(); + println!("{}", path); + println!("{}",&*request.extensions().get::>().unwrap().as_ref().unwrap().email); + + let query: Result<(i64,), _> = match path { + "/profile" => + sqlx::query_as(r#"select u.id from users u where email =?"#) + .bind(request.extensions().get::>().unwrap().as_ref().unwrap().email.as_str()) + .fetch_one(&app_state) + .await, + _ => sqlx::query_as(r#"select u.id from role_permissions r join user_roles ur on ur.role_id = r.role_id join users u on u.id = ur.user_id where item = ? and email =?"#) + .bind(&*request.uri().to_string()) + .bind(request.extensions().get::>().unwrap().as_ref().unwrap().email.as_str()) + .fetch_one(&app_state) + .await, + }; + + // user is logged in + // check if user has the proper role + // if not, display banner and return to home page + let user_id = if let Ok(query) = query { + query.0 + } else { + // user does not have the proper role + 0 + }; + + println!("{}", user_id); + if user_id == 0 { + // user does not have the proper role + // display banner and return to home page + return Ok(Redirect::to("/").into_response()); + } + Ok(next.run(request).await) } else { + // user is not logged in + // redirect to login page with return_url let login_url = "/login?return_url=".to_owned() + &*request.uri().to_string(); Ok(Redirect::to(login_url.as_str()).into_response()) } diff --git a/backend/src/oauth.rs b/backend/src/oauth.rs index 3b9b471..10cb8af 100644 --- a/backend/src/oauth.rs +++ b/backend/src/oauth.rs @@ -154,7 +154,6 @@ pub async fn google_auth_return( .map_err(|_| "OAuth: reqwest received invalid userinfo")?; let mut body: serde_json::Value = serde_json::from_str(body.as_str()).map_err(|_| "OAuth: Serde failed to parse userinfo")?; - println!("body: {}", body); let email = body["email"] .take() .as_str()