Skip to content

Commit

Permalink
basic scaffolding for custom authorization functions
Browse files Browse the repository at this point in the history
  • Loading branch information
calebbourg committed Nov 19, 2024
1 parent e1c8a77 commit 2d30304
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 3 deletions.
6 changes: 4 additions & 2 deletions web/src/controller/organization_controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,16 @@ use log::debug;
)]
pub async fn index(
CompareApiVersion(_v): CompareApiVersion,
AuthenticatedUser(_user): AuthenticatedUser,
AuthenticatedUser(user): AuthenticatedUser,
// TODO: create a new Extractor to authorize the user to access
// the data requested
State(app_state): State<AppState>,
Query(params): Query<HashMap<String, String>>,
Query(mut params): Query<HashMap<String, String>>,
) -> Result<impl IntoResponse, Error> {
debug!("GET all Organizations");

params.insert("user_id".to_string(), user.id.to_string());

let organizations = OrganizationApi::find_by(app_state.db_conn_ref(), params).await?;

debug!("Found Organizations: {:?}", organizations);
Expand Down
1 change: 1 addition & 0 deletions web/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use tower_http::cors::CorsLayer;
mod controller;
mod error;
pub(crate) mod extractors;
pub(crate) mod protect;
mod router;

pub async fn init_server(app_state: AppState) -> Result<()> {
Expand Down
14 changes: 14 additions & 0 deletions web/src/protect/coaching_relationships.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use axum::extract::Request;
use entity_api::user::AuthSession;

struct AuthorizationError {}

pub(crate) async fn protect(
auth_session: AuthSession,
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)
}
22 changes: 22 additions & 0 deletions web/src/protect/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
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(),
}
},
)
}};
}
9 changes: 8 additions & 1 deletion web/src/router.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::AppState;
use crate::{protected_resource, AppState};
use axum::{
http::StatusCode,
routing::{delete, get, post, put},
Router,
};
Expand All @@ -13,6 +14,8 @@ use crate::controller::{
user_session_controller,
};

use crate::protect::coaching_relationships;

use utoipa::{
openapi::security::{ApiKey, ApiKeyValue, SecurityScheme},
Modify, OpenApi,
Expand Down Expand Up @@ -180,6 +183,10 @@ fn organization_coaching_relationship_routes(app_state: AppState) -> Router {
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 2d30304

Please sign in to comment.