summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormo khan <mo@mokhan.ca>2025-06-27 10:40:44 -0600
committermo khan <mo@mokhan.ca>2025-06-27 10:40:44 -0600
commitafd9729146a7e90bd97bf36f9d2081e29de9da35 (patch)
tree0251e024592fd10c2d6eb1d1580c69371c4586da
parent9f4bf84825c5a725b0ea36d4474d4fa2cec916fd (diff)
feat: scan directory for all policy files
-rw-r--r--src/authorization/cedar_authorizer.rs34
-rw-r--r--tests/authorization/cedar_authorizer_test.rs21
-rw-r--r--tests/authorization/check_service_test.rs11
-rw-r--r--tests/integration_tests.rs12
4 files changed, 60 insertions, 18 deletions
diff --git a/src/authorization/cedar_authorizer.rs b/src/authorization/cedar_authorizer.rs
index 568bafbc..4ec3b34d 100644
--- a/src/authorization/cedar_authorizer.rs
+++ b/src/authorization/cedar_authorizer.rs
@@ -5,6 +5,8 @@ use cedar_policy::{
};
use envoy_types::ext_authz::v3::pb::CheckRequest;
use std::collections::HashMap;
+use std::fs;
+use std::path::Path;
use std::str::FromStr;
#[derive(Debug)]
@@ -20,10 +22,40 @@ impl CedarAuthorizer {
authorizer: CedarAuth::new(),
}
}
+
+ pub fn new_from(dir_path: &str) -> CedarAuthorizer {
+ Self::new(Self::load_from(dir_path).unwrap_or_else(|_| PolicySet::default()))
+ }
+
+ fn load_from(dir_path: &str) -> Result<PolicySet, Box<dyn std::error::Error>> {
+ let path = Path::new(dir_path);
+ if !path.exists() || !path.is_dir() {
+ return Ok(PolicySet::default());
+ }
+
+ let mut policies = PolicySet::new();
+
+ for entry in fs::read_dir(path)? {
+ let file_path = entry?.path();
+
+ if let Some(extension) = file_path.extension() {
+ if extension == "cedar" {
+ let content = fs::read_to_string(&file_path)?;
+ let file_policies = PolicySet::from_str(&content)?;
+
+ for policy in file_policies.policies() {
+ policies.add(policy.clone())?;
+ }
+ }
+ }
+ }
+
+ Ok(policies)
+ }
}
impl Default for CedarAuthorizer {
fn default() -> Self {
- Self::new(PolicySet::default())
+ Self::new_from("/etc/authzd")
}
}
diff --git a/tests/authorization/cedar_authorizer_test.rs b/tests/authorization/cedar_authorizer_test.rs
index d6742995..3073417d 100644
--- a/tests/authorization/cedar_authorizer_test.rs
+++ b/tests/authorization/cedar_authorizer_test.rs
@@ -6,9 +6,14 @@ mod tests {
use envoy_types::pb::envoy::service::auth::v3::attribute_context::HttpRequest;
use std::collections::HashMap;
+ fn authorizer() -> CedarAuthorizer {
+ CedarAuthorizer::new_from(
+ "/home/mokhax/src/gitlab.com/gitlab-org/software-supply-chain-security/authorization/authzd/etc/authzd",
+ )
+ }
+
#[test]
fn test_cedar_authorizer_allows_valid_token() {
- let authorizer = CedarAuthorizer::default();
let request = create_request(|item: &mut HttpRequest| {
item.headers = build_with(|item: &mut HashMap<String, String>| {
item.insert(
@@ -18,12 +23,11 @@ mod tests {
});
});
- assert!(authorizer.authorize(request));
+ assert!(authorizer().authorize(request));
}
#[test]
fn test_cedar_authorizer_denies_invalid_token() {
- let authorizer = CedarAuthorizer::default();
let request = create_request(|item: &mut HttpRequest| {
item.headers = build_with(|item: &mut HashMap<String, String>| {
item.insert(
@@ -33,40 +37,37 @@ mod tests {
});
});
- assert!(!authorizer.authorize(request));
+ assert!(!authorizer().authorize(request));
}
#[test]
fn test_cedar_authorizer_denies_missing_header() {
- let authorizer = CedarAuthorizer::default();
let request = create_request(|item: &mut HttpRequest| {
item.headers = HashMap::new();
});
- assert!(!authorizer.authorize(request));
+ assert!(!authorizer().authorize(request));
}
#[test]
fn test_cedar_authorizer_allows_static_assets() {
- let authorizer = CedarAuthorizer::default();
let request = create_request(|item: &mut HttpRequest| {
item.headers = build_with(|item: &mut HashMap<String, String>| {
item.insert(String::from(":path"), String::from("/public/style.css"));
});
});
- assert!(authorizer.authorize(request));
+ assert!(authorizer().authorize(request));
}
#[test]
fn test_cedar_authorizer_allows_js_assets() {
- let authorizer = CedarAuthorizer::default();
let mut headers = HashMap::new();
headers.insert(":path".to_string(), "/app.js".to_string());
let request = create_request(|item: &mut HttpRequest| {
item.headers = headers;
});
- assert!(authorizer.authorize(request));
+ assert!(authorizer().authorize(request));
}
}
diff --git a/tests/authorization/check_service_test.rs b/tests/authorization/check_service_test.rs
index a739b16a..c101850c 100644
--- a/tests/authorization/check_service_test.rs
+++ b/tests/authorization/check_service_test.rs
@@ -8,10 +8,16 @@ mod tests {
use std::collections::HashMap;
use std::sync::Arc;
+ fn authorizer() -> Arc<dyn authzd::Authorizer + Send + Sync> {
+ Arc::new(CedarAuthorizer::new_from(
+ "/home/mokhax/src/gitlab.com/gitlab-org/software-supply-chain-security/authorization/authzd/etc/authzd",
+ ))
+ }
+
#[tokio::test]
async fn test_check_allows_valid_bearer_token() {
let token = create_token();
- let server = CheckService::new(Arc::new(CedarAuthorizer::default()));
+ let server = CheckService::new(authorizer());
let mut headers = HashMap::new();
headers.insert("authorization".to_string(), format!("Bearer {}", token));
@@ -30,8 +36,7 @@ mod tests {
#[tokio::test]
async fn test_check_denies_invalid_bearer_token() {
- let authorizer = Arc::new(CedarAuthorizer::default());
- let server = CheckService::new(authorizer);
+ let server = CheckService::new(authorizer());
let request = tonic::Request::new(create_request(|item: &mut HttpRequest| {
item.headers = HashMap::new();
}));
diff --git a/tests/integration_tests.rs b/tests/integration_tests.rs
index a265c2be..8bf433d1 100644
--- a/tests/integration_tests.rs
+++ b/tests/integration_tests.rs
@@ -7,10 +7,15 @@ use std::sync::Arc;
mod authorization;
mod common;
+fn authorizer() -> Arc<dyn authzd::Authorizer + Send + Sync> {
+ Arc::new(CedarAuthorizer::new_from(
+ "/home/mokhax/src/gitlab.com/gitlab-org/software-supply-chain-security/authorization/authzd/etc/authzd",
+ ))
+}
+
#[tokio::test]
async fn test_success_response() {
- let authorizer = Arc::new(CedarAuthorizer::default());
- let server = CheckService::new(authorizer);
+ let server = CheckService::new(authorizer());
let request = tonic::Request::new(factory_bot::create_request(|item: &mut HttpRequest| {
item.headers = factory_bot::build_headers(vec![(
"authorization".to_string(),
@@ -30,8 +35,7 @@ async fn test_success_response() {
#[tokio::test]
async fn test_multiple() {
- let authorizer = Arc::new(CedarAuthorizer::default());
- let server = CheckService::new(authorizer);
+ let server = CheckService::new(authorizer());
let test_cases = vec![
("Bearer valid-token", true),