diff options
| author | mo khan <mo@mokhan.ca> | 2025-06-19 17:33:31 -0600 |
|---|---|---|
| committer | mo khan <mo@mokhan.ca> | 2025-06-19 17:33:31 -0600 |
| commit | 3291163206f16d2d624b98e11125abf76da36c47 (patch) | |
| tree | 46feb38f684f89c516269893051a627c4db17d9d | |
| parent | 5fc7a6f0d477b7dcb9489f7b6841b01d7964fdbe (diff) | |
refactor: extract a Authorizer Trait with a stub for a Cedar authorizer
| -rw-r--r-- | src/authorization.rs | 52 | ||||
| -rw-r--r-- | src/main.rs | 15 |
2 files changed, 46 insertions, 21 deletions
diff --git a/src/authorization.rs b/src/authorization.rs index 279f62cc..d86e8938 100644 --- a/src/authorization.rs +++ b/src/authorization.rs @@ -2,34 +2,58 @@ use envoy_types::ext_authz::v3::CheckResponseExt; use envoy_types::ext_authz::v3::pb::{CheckRequest, CheckResponse}; use tonic::{Request, Response, Status}; -#[derive(Debug, Default)] -pub struct CheckService; +trait Authorizer { + fn authorize(&self, request: CheckRequest) -> bool; +} -#[tonic::async_trait] -impl envoy_types::ext_authz::v3::pb::Authorization for CheckService { - async fn check( - &self, - request: Request<CheckRequest>, - ) -> Result<Response<CheckResponse>, Status> { - let request = request.into_inner(); +struct CedarAuthorizer {} +impl CedarAuthorizer { + fn new() -> CedarAuthorizer { + return CedarAuthorizer {}; + } +} + +impl Authorizer for CedarAuthorizer { + fn authorize(&self, request: CheckRequest) -> bool { let client_headers = request .attributes .as_ref() .and_then(|attr| attr.request.as_ref()) .and_then(|req| req.http.as_ref()) .map(|http| &http.headers) - .ok_or_else(|| Status::invalid_argument("client headers not populated by envoy"))?; - - let mut request_status = Status::unauthenticated("not authorized"); + .ok_or_else(|| Status::invalid_argument("client headers not populated by envoy")) + .unwrap(); if let Some(authorization) = client_headers.get("authorization") { if authorization == "Bearer valid-token" { - request_status = Status::ok("request is valid"); + return true; } } - Ok(Response::new(CheckResponse::with_status(request_status))) + return false; + } +} + +#[derive(Debug, Default)] +pub struct CheckService; + +#[tonic::async_trait] +impl envoy_types::ext_authz::v3::pb::Authorization for CheckService { + async fn check( + &self, + request: Request<CheckRequest>, + ) -> Result<Response<CheckResponse>, Status> { + let request = request.into_inner(); + + let authorizer = CedarAuthorizer::new(); + if authorizer.authorize(request) { + return Ok(Response::new(CheckResponse::with_status(Status::ok("OK")))); + } + + return Ok(Response::new(CheckResponse::with_status( + Status::unauthenticated("Unauthorized"), + ))); } } diff --git a/src/main.rs b/src/main.rs index 917cace5..57f98b9a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,17 +7,18 @@ use authorization::CheckService; #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> { let addr = "[::1]:50051".parse()?; - let authorization_service = AuthorizationServer::new(CheckService::default()); + let (_health_reporter, health_service) = tonic_health::server::health_reporter(); - let reflection_service = tonic_reflection::server::Builder::configure() - .register_encoded_file_descriptor_set(tonic_health::pb::FILE_DESCRIPTOR_SET) - .build_v1() - .unwrap(); Server::builder() - .add_service(authorization_service) + .add_service(AuthorizationServer::new(CheckService::default())) .add_service(health_service) - .add_service(reflection_service) + .add_service( + tonic_reflection::server::Builder::configure() + .register_encoded_file_descriptor_set(tonic_health::pb::FILE_DESCRIPTOR_SET) + .build_v1() + .unwrap(), + ) .serve(addr) .await?; |
