diff --git a/migrations/20241224112057_routing_permission.down.sql b/migrations/20241224112057_routing_permission.down.sql new file mode 100644 index 0000000..1a41b63 --- /dev/null +++ b/migrations/20241224112057_routing_permission.down.sql @@ -0,0 +1,2 @@ +-- Add down migration script here +DROP TABLE IF EXISTS "routing_permission"; \ No newline at end of file diff --git a/migrations/20241224112057_routing_permission.up.sql b/migrations/20241224112057_routing_permission.up.sql new file mode 100644 index 0000000..882fd7c --- /dev/null +++ b/migrations/20241224112057_routing_permission.up.sql @@ -0,0 +1,6 @@ +-- Add up migration script here +CREATE TABLE IF NOT EXISTS "routing_permission"( + routing_id BIGSERIAL NOT NULL REFERENCES "routing"(id), + permission_id BIGSERIAL NOT NULL REFERENCES "permission"(id), + PRIMARY KEY (routing_id, permission_id) +); \ No newline at end of file diff --git a/src/database.rs b/src/database.rs index 77160b7..83d7671 100644 --- a/src/database.rs +++ b/src/database.rs @@ -8,6 +8,7 @@ pub mod post_interaction; pub mod role; pub mod role_permission; pub mod routing; +pub mod routing_permission; pub mod user; pub mod user_contact; diff --git a/src/database/routing_permission.rs b/src/database/routing_permission.rs new file mode 100644 index 0000000..3d6de10 --- /dev/null +++ b/src/database/routing_permission.rs @@ -0,0 +1,106 @@ +use sqlx::{Pool, Postgres}; + +use crate::feature::routing_permission::RoutingPermission; + +pub async fn create( + routing_id: &i64, + permission_id: &i64, + database_connection: &Pool, +) -> Result { + sqlx::query_as!( + RoutingPermission, + r#" + INSERT INTO "routing_permission"(routing_id, permission_id) + VALUES ($1, $2) + RETURNING * + "#, + routing_id, + permission_id + ) + .fetch_one(database_connection) + .await +} + +pub async fn read( + routing_id: &i64, + permission_id: &i64, + database_connection: &Pool, +) -> Result { + sqlx::query_as!( + RoutingPermission, + r#" + SELECT * FROM "routing_permission" WHERE "routing_id" = $1 AND "permission_id" = $2 + "#, + routing_id, + permission_id, + ) + .fetch_one(database_connection) + .await +} + +pub async fn update( + routing_id: &i64, + permission_id: &i64, + database_connection: &Pool, +) -> Result { + sqlx::query_as!( + RoutingPermission, + r#" + UPDATE "routing_permission" SET "permission_id" = $2 WHERE "routing_id" = $1 + RETURNING * + "#, + routing_id, + permission_id, + ) + .fetch_one(database_connection) + .await +} + +pub async fn delete( + routing_id: &i64, + permission_id: &i64, + database_connection: &Pool, +) -> Result { + sqlx::query_as!( + RoutingPermission, + r#" + DELETE FROM "routing_permission" WHERE "routing_id" = $1 AND "permission_id" = $2 + RETURNING * + "#, + routing_id, + permission_id, + ) + .fetch_one(database_connection) + .await +} + +pub async fn read_all_for_routing( + routing_id: &i64, + database_connection: &Pool, +) -> Result, sqlx::Error> { + sqlx::query_as!( + RoutingPermission, + r#" + SELECT * FROM "routing_permission" WHERE "routing_id" = $1 + "#, + routing_id + ) + .fetch_all(database_connection) + .await +} + +pub async fn delete_all_for_routing( + routing_id: &i64, + database_connection: &Pool, +) -> Result, sqlx::Error> { + sqlx::query_as!( + RoutingPermission, + r#" + DELETE FROM "routing_permission" WHERE "routing_id" = $1 + RETURNING * + "#, + routing_id, + ) + .fetch_all(database_connection) + .await +} diff --git a/src/feature.rs b/src/feature.rs index 1039cde..83428c8 100644 --- a/src/feature.rs +++ b/src/feature.rs @@ -8,5 +8,6 @@ pub mod post_interaction; pub mod role; pub mod role_permission; pub mod routing; +pub mod routing_permission; pub mod user; pub mod user_contact; diff --git a/src/feature/routing_permission.rs b/src/feature/routing_permission.rs new file mode 100644 index 0000000..a19afee --- /dev/null +++ b/src/feature/routing_permission.rs @@ -0,0 +1,57 @@ +use serde::{Deserialize, Serialize}; +use sqlx::{Pool, Postgres}; + +use crate::database::routing_permission; + +#[derive(Debug, Serialize, Deserialize)] +pub struct RoutingPermission { + pub routing_id: i64, + pub permission_id: i64, +} + +impl RoutingPermission { + pub async fn create( + routing_id: &i64, + permission_id: &i64, + database_connection: &Pool, + ) -> Result { + routing_permission::create(routing_id, permission_id, database_connection).await + } + + pub async fn read( + routing_id: &i64, + permission_id: &i64, + database_connection: &Pool, + ) -> Result { + routing_permission::read(routing_id, permission_id, database_connection).await + } + + pub async fn update( + routing_id: &i64, + permission_id: &i64, + database_connection: &Pool, + ) -> Result { + routing_permission::update(routing_id, permission_id, database_connection).await + } + pub async fn delete( + routing_id: &i64, + permission_id: &i64, + database_connection: &Pool, + ) -> Result { + routing_permission::delete(routing_id, permission_id, database_connection).await + } + + pub async fn read_all_for_routing( + routing_id: &i64, + database_connection: &Pool, + ) -> Result, sqlx::Error> { + routing_permission::read_all_for_routing(routing_id, database_connection).await + } + + pub async fn delete_all_for_routing( + routing_id: &i64, + database_connection: &Pool, + ) -> Result, sqlx::Error> { + routing_permission::delete_all_for_routing(routing_id, database_connection).await + } +} diff --git a/src/routing.rs b/src/routing.rs index 6eff30b..e60f829 100644 --- a/src/routing.rs +++ b/src/routing.rs @@ -8,6 +8,7 @@ pub mod post_interaction; pub mod role; pub mod role_permission; pub mod routing; +pub mod routing_permission; pub mod user; pub mod user_contact; @@ -63,6 +64,10 @@ pub async fn route(State(app_state): State) -> Router { "/routings", routing::route(axum::extract::State(app_state.clone())), ) + .nest( + "/routing_permissions", + routing_permission::route(axum::extract::State(app_state.clone())), + ) .layer(CorsLayer::permissive()) .with_state(app_state) } diff --git a/src/routing/routing_permission.rs b/src/routing/routing_permission.rs new file mode 100644 index 0000000..017a9ab --- /dev/null +++ b/src/routing/routing_permission.rs @@ -0,0 +1,144 @@ +use axum::{ + extract::{Path, State}, + http::StatusCode, + response::IntoResponse, + routing::{delete, get, patch, post}, + Json, Router, +}; +use serde::{Deserialize, Serialize}; + +use crate::{feature::routing_permission::RoutingPermission, AppState}; + +#[derive(Debug, Serialize, Deserialize)] +struct CreateRoutingPermission { + pub routing_id: i64, + pub permission_id: i64, +} + +#[derive(Debug, Serialize, Deserialize)] +struct UpdateRoutingPermission { + pub routing_id: i64, + pub permission_id: i64, +} + +pub fn route(State(app_state): State) -> Router { + Router::new() + .route("/", post(create)) + .route( + "/routings/:routing_id/permissions/:permission_id", + get(read), + ) + .route("/", patch(update)) + .route( + "/routings/:routing_id/permissions/:permission_id", + delete(delete_), + ) + .route("/routings/:routing_id", get(read_all_for_routing)) + .route("/routings/:routing_id", delete(delete_all_for_routing)) + .with_state(app_state) +} + +async fn create( + State(app_state): State, + Json(create_role_permission): Json, +) -> impl IntoResponse { + match RoutingPermission::create( + &create_role_permission.routing_id, + &create_role_permission.permission_id, + &app_state.database_connection, + ) + .await + { + Ok(role_permission) => ( + StatusCode::CREATED, + Json(serde_json::json!(role_permission)), + ), + Err(err_val) => ( + StatusCode::BAD_REQUEST, + Json(serde_json::json!(err_val.to_string())), + ), + } +} + +async fn read( + State(app_state): State, + Path((routing_id, permission_id)): Path<(i64, i64)>, +) -> impl IntoResponse { + match RoutingPermission::read(&routing_id, &permission_id, &app_state.database_connection).await + { + Ok(role_permission) => (StatusCode::OK, Json(serde_json::json!(role_permission))), + Err(err_val) => ( + StatusCode::BAD_REQUEST, + Json(serde_json::json!(err_val.to_string())), + ), + } +} + +async fn update( + State(app_state): State, + Json(update_role): Json, +) -> impl IntoResponse { + match RoutingPermission::update( + &update_role.routing_id, + &update_role.permission_id, + &app_state.database_connection, + ) + .await + { + Ok(role_permission) => ( + StatusCode::ACCEPTED, + Json(serde_json::json!(role_permission)), + ), + Err(err_val) => ( + StatusCode::BAD_REQUEST, + Json(serde_json::json!(err_val.to_string())), + ), + } +} + +async fn delete_( + State(app_state): State, + Path((routing_id, permission_id)): Path<(i64, i64)>, +) -> impl IntoResponse { + match RoutingPermission::delete(&routing_id, &permission_id, &app_state.database_connection) + .await + { + Ok(role_permission) => ( + StatusCode::NO_CONTENT, + Json(serde_json::json!(role_permission)), + ), + Err(err_val) => ( + StatusCode::BAD_REQUEST, + Json(serde_json::json!(err_val.to_string())), + ), + } +} + +async fn read_all_for_routing( + State(app_state): State, + Path(routing_id): Path, +) -> impl IntoResponse { + match RoutingPermission::read_all_for_routing(&routing_id, &app_state.database_connection).await + { + Ok(role_permissions) => (StatusCode::OK, Json(serde_json::json!(role_permissions))), + Err(err_val) => ( + StatusCode::BAD_REQUEST, + Json(serde_json::json!(err_val.to_string())), + ), + } +} + +async fn delete_all_for_routing( + State(app_state): State, + Path(routing_id): Path, +) -> impl IntoResponse { + match RoutingPermission::delete_all_for_routing(&routing_id, &app_state.database_connection) + .await + { + Ok(role_permissions) => (StatusCode::OK, Json(serde_json::json!(role_permissions))), + Err(err_val) => ( + StatusCode::BAD_REQUEST, + Json(serde_json::json!(err_val.to_string())), + ), + } +}