Skip to content

Commit

Permalink
add permissions for coaching_relationships by organization
Browse files Browse the repository at this point in the history
  • Loading branch information
calebbourg committed Dec 3, 2024
1 parent a4837cc commit c2d7d19
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 41 deletions.
4 changes: 2 additions & 2 deletions migration/src/refactor_platform_rs.sql
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
-- SQL dump generated using DBML (dbml-lang.org)
-- SQL dump generated using DBML (dbml.dbdiagram.io)
-- Database: PostgreSQL
-- Generated at: 2024-10-31T16:04:10.825Z
-- Generated at: 2024-12-03T17:35:25.615Z


CREATE TYPE "status" AS ENUM (
Expand Down
40 changes: 30 additions & 10 deletions web/src/protect/coaching_relationships.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,34 @@
use axum::extract::Request;
use entity_api::user::AuthSession;
use crate::{extractors::authenticated_user::AuthenticatedUser, AppState};
use axum::{
extract::{Path, Request, State},
http::StatusCode,
middleware::Next,
response::IntoResponse,
};

struct AuthorizationError {}
use entity::Id;
use entity_api::organization;
use std::collections::HashSet;

pub(crate) async fn protect(
auth_session: AuthSession,
/// Checks that the organization record referenced by `organization_id`
/// exists and that the authenticated user is associated with i.t
/// Intended to be given to axum::middleware::from_fn_with_state in the router
pub(crate) async fn index(
State(app_state): State<AppState>,
AuthenticatedUser(user): AuthenticatedUser,
Path(organization_id): Path<Id>,
request: Request,
) -> Result<Request, AuthorizationError> {
// here we have access to the current user (actor) making the request
// as well as the request itself (from which we can determine which resource is being acted upon).
// We can use both pieces of information to determine if the actor is allowed to operate on the resource.
Ok(request)
next: Next,
) -> impl IntoResponse {
let user_organization_ids = organization::find_by_user(app_state.db_conn_ref(), user.id)
.await
.unwrap_or(vec![])
.into_iter()
.map(|org| org.id)
.collect::<HashSet<Id>>();
if user_organization_ids.contains(&organization_id) {
next.run(request).await
} else {
(StatusCode::UNAUTHORIZED, "UNAUTHORIZED").into_response()
}
}
21 changes: 0 additions & 21 deletions web/src/protect/mod.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1 @@
pub(crate) mod coaching_relationships;

#[macro_export]
macro_rules! protected_resource {
($protect:expr, $alternative:expr) => {{
use axum::{
extract::Request,
middleware::{from_fn, Next},
response::IntoResponse,
};
use entity_api::user::AuthSession;

from_fn(
|auth_session: AuthSession, req: Request, next: Next| async move {
match $protect(auth_session, req).await {
Ok(req) => next.run(req).await,
Err(_) => $alternative.into_response(),
}
},
)
}};
}
14 changes: 6 additions & 8 deletions web/src/router.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{protected_resource, AppState};
use crate::{protect, AppState};
use axum::{
http::StatusCode,
middleware::from_fn_with_state,
routing::{delete, get, post, put},
Router,
};
Expand All @@ -14,8 +14,6 @@ use crate::controller::{
user_session_controller,
};

use crate::protect::coaching_relationships;

use utoipa::{
openapi::security::{ApiKey, ApiKeyValue, SecurityScheme},
Modify, OpenApi,
Expand Down Expand Up @@ -178,15 +176,15 @@ fn organization_coaching_relationship_routes(app_state: AppState) -> Router {
"/organizations/:organization_id/coaching_relationships",
get(organization::coaching_relationship_controller::index),
)
.route_layer(from_fn_with_state(
app_state.clone(),
protect::coaching_relationships::index,
))
.route(
"/organizations/:organization_id/coaching_relationships/:relationship_id",
get(organization::coaching_relationship_controller::read),
)
.route_layer(login_required!(Backend, login_url = "/login"))
.route_layer(protected_resource!(
coaching_relationships::protect,
StatusCode::UNAUTHORIZED
))
.with_state(app_state)
}

Expand Down

0 comments on commit c2d7d19

Please sign in to comment.