diff options
| -rw-r--r-- | src/authorization/authorizer.rs | 5 | ||||
| -rw-r--r-- | src/authorization/cedar_authorizer.rs | 103 | ||||
| -rw-r--r-- | src/authorization/check_service.rs (renamed from src/authorization.rs) | 46 | ||||
| -rw-r--r-- | src/authorization/mod.rs | 7 | ||||
| -rw-r--r-- | src/lib.rs | 2 |
5 files changed, 124 insertions, 39 deletions
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<String, String>) -> 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.rs b/src/authorization/check_service.rs index 35062d84..7ca39fcd 100644 --- a/src/authorization.rs +++ b/src/authorization/check_service.rs @@ -2,37 +2,8 @@ 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; - } -} +use super::authorizer::Authorizer; +use super::cedar_authorizer::CedarAuthorizer; #[derive(Debug, Default)] pub struct CheckService; @@ -47,12 +18,12 @@ impl envoy_types::ext_authz::v3::pb::Authorization for CheckService { let authorizer = CedarAuthorizer::new(); if authorizer.authorize(request) { - return Ok(Response::new(CheckResponse::with_status(Status::ok("OK")))); + Ok(Response::new(CheckResponse::with_status(Status::ok("OK")))) + } else { + Ok(Response::new(CheckResponse::with_status( + Status::unauthenticated("Unauthorized"), + ))) } - - return Ok(Response::new(CheckResponse::with_status( - Status::unauthenticated("Unauthorized"), - ))); } } @@ -60,12 +31,11 @@ impl envoy_types::ext_authz::v3::pb::Authorization for CheckService { 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<String, String>) -> Request<CheckRequest> { - use envoy_types::pb::envoy::service::auth::v3::{AttributeContext, attribute_context}; - let http_request = attribute_context::HttpRequest { headers, ..Default::default() 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; @@ -1,3 +1,3 @@ pub mod authorization; -pub use authorization::CheckService; +pub use authorization::{Authorizer, CedarAuthorizer, CheckService}; |
