From 3291163206f16d2d624b98e11125abf76da36c47 Mon Sep 17 00:00:00 2001 From: mo khan Date: Thu, 19 Jun 2025 17:33:31 -0600 Subject: refactor: extract a Authorizer Trait with a stub for a Cedar authorizer --- src/authorization.rs | 52 ++++++++++++++++++++++++++++++++++++++-------------- src/main.rs | 15 ++++++++------- 2 files changed, 46 insertions(+), 21 deletions(-) (limited to 'src') 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, - ) -> Result, 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, + ) -> Result, 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> { 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?; -- cgit v1.2.3