From f08ef97f4894fde8feff08bb91bed1e1c1105b83 Mon Sep 17 00:00:00 2001 From: mo khan Date: Thu, 19 Jun 2025 11:40:27 -0600 Subject: test: add tests --- src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/lib.rs (limited to 'src/lib.rs') diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 00000000..cb28e34b --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,3 @@ +pub mod authorization; + +pub use authorization::PolicyServer; -- cgit v1.2.3 From 5fc7a6f0d477b7dcb9489f7b6841b01d7964fdbe Mon Sep 17 00:00:00 2001 From: mo khan Date: Thu, 19 Jun 2025 17:18:07 -0600 Subject: refactor: rename PolicyServer to CheckService --- .gitignore | 4 +--- src/authorization.rs | 8 ++++---- src/lib.rs | 2 +- src/main.rs | 9 +++------ tests/integration_tests.rs | 6 +++--- 5 files changed, 12 insertions(+), 17 deletions(-) (limited to 'src/lib.rs') diff --git a/.gitignore b/.gitignore index 6bfb8923..eb5a316c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1 @@ -tmp -*.pdf -/target +target diff --git a/src/authorization.rs b/src/authorization.rs index 22cd695c..279f62cc 100644 --- a/src/authorization.rs +++ b/src/authorization.rs @@ -3,10 +3,10 @@ use envoy_types::ext_authz::v3::pb::{CheckRequest, CheckResponse}; use tonic::{Request, Response, Status}; #[derive(Debug, Default)] -pub struct PolicyServer; +pub struct CheckService; #[tonic::async_trait] -impl envoy_types::ext_authz::v3::pb::Authorization for PolicyServer { +impl envoy_types::ext_authz::v3::pb::Authorization for CheckService { async fn check( &self, request: Request, @@ -75,7 +75,7 @@ mod tests { #[tokio::test] async fn test_check_allows_valid_bearer_token() { let token = String::from("valid-token"); - let server = PolicyServer::default(); + let server = CheckService::default(); let headers = create_headers_with_auth(&format!("Bearer {}", token)); let request = create_test_request_with_headers(headers); @@ -90,7 +90,7 @@ mod tests { #[tokio::test] async fn test_check_denies_invalid_bearer_token() { - let server = PolicyServer::default(); + let server = CheckService::default(); let request = create_test_request_with_headers(HashMap::new()); let response = server.check(request).await; diff --git a/src/lib.rs b/src/lib.rs index cb28e34b..b3791974 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,3 @@ pub mod authorization; -pub use authorization::PolicyServer; +pub use authorization::CheckService; diff --git a/src/main.rs b/src/main.rs index 25e2c88f..917cace5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,16 +2,13 @@ use envoy_types::ext_authz::v3::pb::AuthorizationServer; use tonic::transport::Server; pub mod authorization; -use authorization::PolicyServer; +use authorization::CheckService; #[tokio::main] async fn main() -> Result<(), Box> { let addr = "[::1]:50051".parse()?; - let authorization_service = AuthorizationServer::new(PolicyServer::default()); - let (health_reporter, health_service) = tonic_health::server::health_reporter(); - health_reporter - .set_serving::>() - .await; + 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) diff --git a/tests/integration_tests.rs b/tests/integration_tests.rs index 28cdf959..a3603c11 100644 --- a/tests/integration_tests.rs +++ b/tests/integration_tests.rs @@ -1,11 +1,11 @@ -use authzd::PolicyServer; +use authzd::CheckService; use envoy_types::ext_authz::v3::pb::Authorization; mod common; #[tokio::test] async fn test_success_response() { - let server = PolicyServer::default(); + let server = CheckService::default(); let headers = common::create_headers_with_auth("Bearer valid-token"); let request = common::create_test_request_with_headers(headers); @@ -22,7 +22,7 @@ async fn test_success_response() { #[tokio::test] async fn test_multiple() { - let server = PolicyServer::default(); + let server = CheckService::default(); let test_cases = vec![ ("Bearer valid-token", true), -- cgit v1.2.3 From 2e26e151c273cbcc063eba2d08d28dc2ba5a33ec Mon Sep 17 00:00:00 2001 From: mo khan Date: Thu, 19 Jun 2025 17:45:39 -0600 Subject: refactor: split types into separate files --- src/authorization.rs | 127 ---------------------------------- src/authorization/authorizer.rs | 5 ++ src/authorization/cedar_authorizer.rs | 103 +++++++++++++++++++++++++++ src/authorization/check_service.rs | 97 ++++++++++++++++++++++++++ src/authorization/mod.rs | 7 ++ src/lib.rs | 2 +- 6 files changed, 213 insertions(+), 128 deletions(-) delete mode 100644 src/authorization.rs create mode 100644 src/authorization/authorizer.rs create mode 100644 src/authorization/cedar_authorizer.rs create mode 100644 src/authorization/check_service.rs create mode 100644 src/authorization/mod.rs (limited to 'src/lib.rs') diff --git a/src/authorization.rs b/src/authorization.rs deleted file mode 100644 index 35062d84..00000000 --- a/src/authorization.rs +++ /dev/null @@ -1,127 +0,0 @@ -use envoy_types::ext_authz::v3::CheckResponseExt; -use envoy_types::ext_authz::v3::pb::{CheckRequest, CheckResponse}; -use tonic::{Request, Response, Status}; - -trait Authorizer { - fn authorize(&self, request: CheckRequest) -> bool; -} - -struct CedarAuthorizer {} - -impl CedarAuthorizer { - fn new() -> CedarAuthorizer { - return CedarAuthorizer {}; - } -} - -impl Authorizer for CedarAuthorizer { - fn authorize(&self, request: CheckRequest) -> bool { - let headers = request - .attributes - .as_ref() - .and_then(|attr| attr.request.as_ref()) - .and_then(|req| req.http.as_ref()) - .map(|http| &http.headers) - .unwrap(); - - if let Some(authorization) = headers.get("authorization") { - if authorization == "Bearer valid-token" { - return true; - } - } - - 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"), - ))); - } -} - -#[cfg(test)] -mod tests { - use super::*; - use envoy_types::ext_authz::v3::pb::{Authorization, CheckRequest}; - use std::collections::HashMap; - use tonic::Request; - - fn create_test_request_with_headers(headers: HashMap) -> Request { - use envoy_types::pb::envoy::service::auth::v3::{AttributeContext, attribute_context}; - - let http_request = attribute_context::HttpRequest { - headers, - ..Default::default() - }; - - let request_context = attribute_context::Request { - http: Some(http_request), - ..Default::default() - }; - - let attributes = AttributeContext { - request: Some(request_context), - ..Default::default() - }; - - let check_request = CheckRequest { - attributes: Some(attributes), - ..Default::default() - }; - - Request::new(check_request) - } - - fn create_headers_with_auth(auth_value: &str) -> HashMap { - let mut headers = HashMap::new(); - headers.insert("authorization".to_string(), auth_value.to_string()); - headers - } - - #[tokio::test] - async fn test_check_allows_valid_bearer_token() { - let token = String::from("valid-token"); - let server = CheckService::default(); - let headers = create_headers_with_auth(&format!("Bearer {}", token)); - let request = create_test_request_with_headers(headers); - - let response = server.check(request).await; - - assert!(response.is_ok()); - let check_response = response.unwrap().into_inner(); - assert!(check_response.status.is_some()); - let status = check_response.status.unwrap(); - assert_eq!(status.code, tonic::Code::Ok.into()); - } - - #[tokio::test] - async fn test_check_denies_invalid_bearer_token() { - let server = CheckService::default(); - let request = create_test_request_with_headers(HashMap::new()); - - let response = server.check(request).await; - - assert!(response.is_ok()); - let check_response = response.unwrap().into_inner(); - assert!(check_response.status.is_some()); - let status = check_response.status.unwrap(); - assert_eq!(status.code, tonic::Code::Unauthenticated.into()); - } -} diff --git a/src/authorization/authorizer.rs b/src/authorization/authorizer.rs new file mode 100644 index 00000000..0f700ba7 --- /dev/null +++ b/src/authorization/authorizer.rs @@ -0,0 +1,5 @@ +use envoy_types::ext_authz::v3::pb::CheckRequest; + +pub trait Authorizer { + fn authorize(&self, request: CheckRequest) -> bool; +} diff --git a/src/authorization/cedar_authorizer.rs b/src/authorization/cedar_authorizer.rs new file mode 100644 index 00000000..2efbda28 --- /dev/null +++ b/src/authorization/cedar_authorizer.rs @@ -0,0 +1,103 @@ +use super::authorizer::Authorizer; +use envoy_types::ext_authz::v3::pb::CheckRequest; + +pub struct CedarAuthorizer {} + +impl CedarAuthorizer { + pub fn new() -> CedarAuthorizer { + CedarAuthorizer {} + } +} + +impl Default for CedarAuthorizer { + fn default() -> Self { + Self::new() + } +} + +impl Authorizer for CedarAuthorizer { + fn authorize(&self, request: CheckRequest) -> bool { + let headers = request + .attributes + .as_ref() + .and_then(|attr| attr.request.as_ref()) + .and_then(|req| req.http.as_ref()) + .map(|http| &http.headers) + .unwrap(); + + if let Some(authorization) = headers.get("authorization") { + if authorization == "Bearer valid-token" { + return true; + } + } + + false + } +} + +#[cfg(test)] +mod tests { + use super::*; + use envoy_types::pb::envoy::service::auth::v3::{AttributeContext, attribute_context}; + use std::collections::HashMap; + + fn create_test_request_with_headers(headers: HashMap) -> CheckRequest { + let http_request = attribute_context::HttpRequest { + headers, + ..Default::default() + }; + + let request_context = attribute_context::Request { + http: Some(http_request), + ..Default::default() + }; + + let attributes = AttributeContext { + request: Some(request_context), + ..Default::default() + }; + + CheckRequest { + attributes: Some(attributes), + ..Default::default() + } + } + + #[test] + fn test_cedar_authorizer_allows_valid_token() { + let authorizer = CedarAuthorizer::new(); + let mut headers = HashMap::new(); + headers.insert( + "authorization".to_string(), + "Bearer valid-token".to_string(), + ); + let request = create_test_request_with_headers(headers); + + let result = authorizer.authorize(request); + assert!(result); + } + + #[test] + fn test_cedar_authorizer_denies_invalid_token() { + let authorizer = CedarAuthorizer::new(); + let mut headers = HashMap::new(); + headers.insert( + "authorization".to_string(), + "Bearer invalid-token".to_string(), + ); + let request = create_test_request_with_headers(headers); + + let result = authorizer.authorize(request); + assert!(!result); + } + + #[test] + fn test_cedar_authorizer_denies_missing_header() { + let authorizer = CedarAuthorizer::new(); + let headers = HashMap::new(); + let request = create_test_request_with_headers(headers); + + let result = authorizer.authorize(request); + assert!(!result); + } +} diff --git a/src/authorization/check_service.rs b/src/authorization/check_service.rs new file mode 100644 index 00000000..7ca39fcd --- /dev/null +++ b/src/authorization/check_service.rs @@ -0,0 +1,97 @@ +use envoy_types::ext_authz::v3::CheckResponseExt; +use envoy_types::ext_authz::v3::pb::{CheckRequest, CheckResponse}; +use tonic::{Request, Response, Status}; + +use super::authorizer::Authorizer; +use super::cedar_authorizer::CedarAuthorizer; + +#[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) { + Ok(Response::new(CheckResponse::with_status(Status::ok("OK")))) + } else { + Ok(Response::new(CheckResponse::with_status( + Status::unauthenticated("Unauthorized"), + ))) + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use envoy_types::ext_authz::v3::pb::{Authorization, CheckRequest}; + use envoy_types::pb::envoy::service::auth::v3::{AttributeContext, attribute_context}; + use std::collections::HashMap; + use tonic::Request; + + fn create_test_request_with_headers(headers: HashMap) -> Request { + let http_request = attribute_context::HttpRequest { + headers, + ..Default::default() + }; + + let request_context = attribute_context::Request { + http: Some(http_request), + ..Default::default() + }; + + let attributes = AttributeContext { + request: Some(request_context), + ..Default::default() + }; + + let check_request = CheckRequest { + attributes: Some(attributes), + ..Default::default() + }; + + Request::new(check_request) + } + + fn create_headers_with_auth(auth_value: &str) -> HashMap { + let mut headers = HashMap::new(); + headers.insert("authorization".to_string(), auth_value.to_string()); + headers + } + + #[tokio::test] + async fn test_check_allows_valid_bearer_token() { + let token = String::from("valid-token"); + let server = CheckService::default(); + let headers = create_headers_with_auth(&format!("Bearer {}", token)); + let request = create_test_request_with_headers(headers); + + let response = server.check(request).await; + + assert!(response.is_ok()); + let check_response = response.unwrap().into_inner(); + assert!(check_response.status.is_some()); + let status = check_response.status.unwrap(); + assert_eq!(status.code, tonic::Code::Ok.into()); + } + + #[tokio::test] + async fn test_check_denies_invalid_bearer_token() { + let server = CheckService::default(); + let request = create_test_request_with_headers(HashMap::new()); + + let response = server.check(request).await; + + assert!(response.is_ok()); + let check_response = response.unwrap().into_inner(); + assert!(check_response.status.is_some()); + let status = check_response.status.unwrap(); + assert_eq!(status.code, tonic::Code::Unauthenticated.into()); + } +} diff --git a/src/authorization/mod.rs b/src/authorization/mod.rs new file mode 100644 index 00000000..7d3856a5 --- /dev/null +++ b/src/authorization/mod.rs @@ -0,0 +1,7 @@ +pub mod authorizer; +pub mod cedar_authorizer; +pub mod check_service; + +pub use authorizer::Authorizer; +pub use cedar_authorizer::CedarAuthorizer; +pub use check_service::CheckService; diff --git a/src/lib.rs b/src/lib.rs index b3791974..c24db79b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,3 @@ pub mod authorization; -pub use authorization::CheckService; +pub use authorization::{Authorizer, CedarAuthorizer, CheckService}; -- cgit v1.2.3 From d4e3bb8f30c4b9edeb392881bd7b4a6baf79d415 Mon Sep 17 00:00:00 2001 From: mo khan Date: Tue, 24 Jun 2025 16:41:03 -0600 Subject: refactor: copy duplicate test helper method --- src/authorization/check_service.rs | 59 ++++++++++++++++---------------------- src/lib.rs | 1 - src/main.rs | 13 ++++----- 3 files changed, 30 insertions(+), 43 deletions(-) (limited to 'src/lib.rs') diff --git a/src/authorization/check_service.rs b/src/authorization/check_service.rs index a4d0ec7b..c0a05e21 100644 --- a/src/authorization/check_service.rs +++ b/src/authorization/check_service.rs @@ -36,51 +36,38 @@ impl envoy_types::ext_authz::v3::pb::Authorization for CheckService { #[cfg(test)] mod tests { - use super::*; use super::super::cedar_authorizer::CedarAuthorizer; + use super::*; use envoy_types::ext_authz::v3::pb::{Authorization, CheckRequest}; - use envoy_types::pb::envoy::service::auth::v3::{AttributeContext, attribute_context}; + use envoy_types::pb::envoy::service::auth::v3::AttributeContext; + use envoy_types::pb::envoy::service::auth::v3::attribute_context::{HttpRequest, Request}; use std::collections::HashMap; use std::sync::Arc; - use tonic::Request; - - fn create_test_request_with_headers(headers: HashMap) -> Request { - let http_request = attribute_context::HttpRequest { - headers, - ..Default::default() - }; - - let request_context = attribute_context::Request { - http: Some(http_request), - ..Default::default() - }; - - let attributes = AttributeContext { - request: Some(request_context), - ..Default::default() - }; - - let check_request = CheckRequest { - attributes: Some(attributes), - ..Default::default() - }; - Request::new(check_request) + pub fn create_request(f: impl std::ops::FnOnce(&mut HttpRequest)) -> CheckRequest { + please::build_with(|item: &mut CheckRequest| { + item.attributes = Some(please::build_with(|item: &mut AttributeContext| { + item.request = Some(please::build_with(|item: &mut Request| { + item.http = Some(please::build_with(|item: &mut HttpRequest| f(item))); + })); + })); + }) } - fn create_headers_with_auth(auth_value: &str) -> HashMap { - let mut headers = HashMap::new(); - headers.insert("authorization".to_string(), auth_value.to_string()); - headers + pub fn create_token() -> String { + return String::from("valid-token"); } #[tokio::test] async fn test_check_allows_valid_bearer_token() { - let token = String::from("valid-token"); - let authorizer = Arc::new(CedarAuthorizer::new()); - let server = CheckService::new(authorizer); - let headers = create_headers_with_auth(&format!("Bearer {}", token)); - let request = create_test_request_with_headers(headers); + let token = create_token(); + let server = CheckService::new(Arc::new(CedarAuthorizer::new())); + + let mut headers = HashMap::new(); + headers.insert("authorization".to_string(), format!("Bearer {}", token)); + let request = tonic::Request::new(create_request(|item: &mut HttpRequest| { + item.headers = headers; + })); let response = server.check(request).await; @@ -95,7 +82,9 @@ mod tests { async fn test_check_denies_invalid_bearer_token() { let authorizer = Arc::new(CedarAuthorizer::new()); let server = CheckService::new(authorizer); - let request = create_test_request_with_headers(HashMap::new()); + let request = tonic::Request::new(create_request(|item: &mut HttpRequest| { + item.headers = HashMap::new(); + })); let response = server.check(request).await; diff --git a/src/lib.rs b/src/lib.rs index c24db79b..210699b5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,2 @@ pub mod authorization; - pub use authorization::{Authorizer, CedarAuthorizer, CheckService}; diff --git a/src/main.rs b/src/main.rs index 8eb7b5ef..8fa32b33 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,18 +1,17 @@ -use envoy_types::ext_authz::v3::pb::AuthorizationServer; -use std::sync::Arc; -use tonic::transport::Server; - pub mod authorization; -use authorization::{CedarAuthorizer, CheckService}; #[tokio::main] async fn main() -> Result<(), Box> { + use envoy_types::ext_authz::v3::pb::AuthorizationServer; + use std::sync::Arc; + use tonic::transport::Server; + let addr = "[::1]:50051".parse()?; let (_health_reporter, health_service) = tonic_health::server::health_reporter(); - let authorizer = Arc::new(CedarAuthorizer::new()); - let check_service = CheckService::new(authorizer); + let authorizer = Arc::new(authorization::CedarAuthorizer::new()); + let check_service = authorization::CheckService::new(authorizer); Server::builder() .add_service(AuthorizationServer::new(check_service)) -- cgit v1.2.3 From 84420606035fd62bbdcacb6231b9181f197d068f Mon Sep 17 00:00:00 2001 From: mo khan Date: Fri, 27 Jun 2025 13:24:40 -0600 Subject: refactor: extract create_server function to test it directly --- src/authorization/cedar_authorizer.rs | 2 +- src/lib.rs | 20 ++++++++++++++++++++ src/main.rs | 21 ++------------------- tests/main_test.rs | 8 +++++++- 4 files changed, 30 insertions(+), 21 deletions(-) (limited to 'src/lib.rs') diff --git a/src/authorization/cedar_authorizer.rs b/src/authorization/cedar_authorizer.rs index c2c594fe..658de7a6 100644 --- a/src/authorization/cedar_authorizer.rs +++ b/src/authorization/cedar_authorizer.rs @@ -53,7 +53,7 @@ impl CedarAuthorizer { } impl Default for CedarAuthorizer { fn default() -> Self { - Self::new_from(fs::canonicalize("/etc/authzd").unwrap().as_path()) + Self::new_from(std::path::Path::new("/etc/authzd")) } } diff --git a/src/lib.rs b/src/lib.rs index 210699b5..a82c2ace 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,2 +1,22 @@ pub mod authorization; pub use authorization::{Authorizer, CedarAuthorizer, CheckService}; + +use envoy_types::ext_authz::v3::pb::AuthorizationServer; +use std::sync::Arc; +use tonic::transport::Server; + +pub fn create_server() -> Result> { + let (_health_reporter, health_service) = tonic_health::server::health_reporter(); + let authorizer = Arc::new(authorization::CedarAuthorizer::default()); + let check_service = authorization::CheckService::new(authorizer); + let server = Server::builder() + .add_service(AuthorizationServer::new(check_service)) + .add_service(health_service) + .add_service( + tonic_reflection::server::Builder::configure() + .register_encoded_file_descriptor_set(tonic_health::pb::FILE_DESCRIPTOR_SET) + .build_v1() + .unwrap(), + ); + Ok(server) +} diff --git a/src/main.rs b/src/main.rs index 1a3ff00c..13d313d7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,31 +1,14 @@ -pub mod authorization; +use authzd::create_server; #[tokio::main] async fn main() -> Result<(), Box> { - use envoy_types::ext_authz::v3::pb::AuthorizationServer; - use std::sync::Arc; - use tonic::transport::Server; - tracing_subscriber::fmt().json().init(); let addr = std::env::var("BIND_ADDR") .unwrap_or_else(|_| "[::1]:50051".to_string()) .parse()?; - let (_health_reporter, health_service) = tonic_health::server::health_reporter(); - - let authorizer = Arc::new(authorization::CedarAuthorizer::default()); - let check_service = authorization::CheckService::new(authorizer); - - let server = Server::builder() - .add_service(AuthorizationServer::new(check_service)) - .add_service(health_service) - .add_service( - tonic_reflection::server::Builder::configure() - .register_encoded_file_descriptor_set(tonic_health::pb::FILE_DESCRIPTOR_SET) - .build_v1() - .unwrap(), - ); + let server = create_server()?; log::info!("Listening on... {addr}"); server.serve(addr).await?; diff --git a/tests/main_test.rs b/tests/main_test.rs index 5c6016f6..69c6eda1 100644 --- a/tests/main_test.rs +++ b/tests/main_test.rs @@ -1,2 +1,8 @@ #[cfg(test)] -mod tests {} +mod tests { + #[test] + fn test_create_server() { + let result = authzd::create_server(); + assert!(result.is_ok()); + } +} -- cgit v1.2.3 From cce3e0f170dfacb6b626a8777255c3183c5c5eb3 Mon Sep 17 00:00:00 2001 From: mo khan Date: Fri, 27 Jun 2025 16:45:17 -0600 Subject: refactor: extract authorization::Server type --- src/authorization/cedar_authorizer.rs | 1 + src/authorization/mod.rs | 2 ++ src/authorization/server.rs | 41 +++++++++++++++++++++++++++++++++++ src/lib.rs | 22 +------------------ src/main.rs | 5 +---- tests/authorization/server_test.rs | 2 +- 6 files changed, 47 insertions(+), 26 deletions(-) create mode 100644 src/authorization/server.rs (limited to 'src/lib.rs') diff --git a/src/authorization/cedar_authorizer.rs b/src/authorization/cedar_authorizer.rs index 658de7a6..a877cf87 100644 --- a/src/authorization/cedar_authorizer.rs +++ b/src/authorization/cedar_authorizer.rs @@ -51,6 +51,7 @@ impl CedarAuthorizer { Ok(policies) } } + impl Default for CedarAuthorizer { fn default() -> Self { Self::new_from(std::path::Path::new("/etc/authzd")) diff --git a/src/authorization/mod.rs b/src/authorization/mod.rs index 7d3856a5..d664815b 100644 --- a/src/authorization/mod.rs +++ b/src/authorization/mod.rs @@ -1,7 +1,9 @@ pub mod authorizer; pub mod cedar_authorizer; pub mod check_service; +pub mod server; pub use authorizer::Authorizer; pub use cedar_authorizer::CedarAuthorizer; pub use check_service::CheckService; +pub use server::Server; diff --git a/src/authorization/server.rs b/src/authorization/server.rs new file mode 100644 index 00000000..f11d0465 --- /dev/null +++ b/src/authorization/server.rs @@ -0,0 +1,41 @@ +use super::cedar_authorizer::CedarAuthorizer; +use super::check_service::CheckService; +use envoy_types::ext_authz::v3::pb::AuthorizationServer; +use std::sync::Arc; + +pub fn create_router() -> Result> { + let (_health_reporter, health_service) = tonic_health::server::health_reporter(); + let authorizer = Arc::new(CedarAuthorizer::default()); + let check_service = CheckService::new(authorizer); + let server = tonic::transport::Server::builder() + .add_service(AuthorizationServer::new(check_service)) + .add_service(health_service) + .add_service( + tonic_reflection::server::Builder::configure() + .register_encoded_file_descriptor_set(tonic_health::pb::FILE_DESCRIPTOR_SET) + .build_v1() + .unwrap(), + ); + Ok(server) +} + +pub struct Server { + router: tonic::transport::server::Router, +} + +impl Server { + pub fn new() -> Result> { + let router = create_router()?; + Ok(Server { router: router }) + } + + pub async fn serve(self, addr: std::net::SocketAddr) -> Result<(), tonic::transport::Error> { + self.router.serve(addr).await + } +} + +impl Default for Server { + fn default() -> Self { + Self::new().unwrap() + } +} diff --git a/src/lib.rs b/src/lib.rs index a82c2ace..3bd8fbd1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,22 +1,2 @@ pub mod authorization; -pub use authorization::{Authorizer, CedarAuthorizer, CheckService}; - -use envoy_types::ext_authz::v3::pb::AuthorizationServer; -use std::sync::Arc; -use tonic::transport::Server; - -pub fn create_server() -> Result> { - let (_health_reporter, health_service) = tonic_health::server::health_reporter(); - let authorizer = Arc::new(authorization::CedarAuthorizer::default()); - let check_service = authorization::CheckService::new(authorizer); - let server = Server::builder() - .add_service(AuthorizationServer::new(check_service)) - .add_service(health_service) - .add_service( - tonic_reflection::server::Builder::configure() - .register_encoded_file_descriptor_set(tonic_health::pb::FILE_DESCRIPTOR_SET) - .build_v1() - .unwrap(), - ); - Ok(server) -} +pub use authorization::{Authorizer, CedarAuthorizer, CheckService, Server}; diff --git a/src/main.rs b/src/main.rs index 13d313d7..8638e14b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,3 @@ -use authzd::create_server; - #[tokio::main] async fn main() -> Result<(), Box> { tracing_subscriber::fmt().json().init(); @@ -8,9 +6,8 @@ async fn main() -> Result<(), Box> { .unwrap_or_else(|_| "[::1]:50051".to_string()) .parse()?; - let server = create_server()?; - log::info!("Listening on... {addr}"); + let server = authzd::authorization::Server::new()?; server.serve(addr).await?; Ok(()) diff --git a/tests/authorization/server_test.rs b/tests/authorization/server_test.rs index 55645dd4..fe8c8a73 100644 --- a/tests/authorization/server_test.rs +++ b/tests/authorization/server_test.rs @@ -15,7 +15,7 @@ mod tests { async fn start_server() -> (SocketAddr, tokio::task::JoinHandle<()>) { let addr = available_port().await; - let server = authzd::create_server().expect("Failed to create server"); + let server = authzd::authorization::Server::default(); let handle = tokio::spawn(async move { server.serve(addr).await.expect("Failed to start server"); -- cgit v1.2.3