summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/authorization.rs104
-rw-r--r--src/lib.rs3
-rw-r--r--src/main.rs35
3 files changed, 111 insertions, 31 deletions
diff --git a/src/authorization.rs b/src/authorization.rs
new file mode 100644
index 00000000..22cd695c
--- /dev/null
+++ b/src/authorization.rs
@@ -0,0 +1,104 @@
+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 PolicyServer;
+
+#[tonic::async_trait]
+impl envoy_types::ext_authz::v3::pb::Authorization for PolicyServer {
+ async fn check(
+ &self,
+ request: Request<CheckRequest>,
+ ) -> Result<Response<CheckResponse>, Status> {
+ let request = request.into_inner();
+
+ 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");
+
+ if let Some(authorization) = client_headers.get("authorization") {
+ if authorization == "Bearer valid-token" {
+ request_status = Status::ok("request is valid");
+ }
+ }
+
+ Ok(Response::new(CheckResponse::with_status(request_status)))
+ }
+}
+
+#[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<String, String>) -> Request<CheckRequest> {
+ 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<String, String> {
+ 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 = PolicyServer::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 = PolicyServer::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/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;
diff --git a/src/main.rs b/src/main.rs
index 05d57719..25e2c88f 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,35 +1,8 @@
-use envoy_types::ext_authz::v3::pb::{
- Authorization, AuthorizationServer, CheckRequest, CheckResponse,
-};
-use envoy_types::ext_authz::v3::{CheckRequestExt, CheckResponseExt};
-use tonic::{Request, Response, Status, transport::Server};
+use envoy_types::ext_authz::v3::pb::AuthorizationServer;
+use tonic::transport::Server;
-#[derive(Debug, Default)]
-struct PolicyServer;
-
-#[tonic::async_trait]
-impl Authorization for PolicyServer {
- async fn check(
- &self,
- request: Request<CheckRequest>,
- ) -> Result<Response<CheckResponse>, Status> {
- let request = request.into_inner();
-
- let client_headers = request
- .get_client_headers()
- .ok_or_else(|| Status::invalid_argument("client headers not populated by envoy"))?;
-
- let mut request_status = Status::unauthenticated("not authorized");
-
- if let Some(authorization) = client_headers.get("authorization") {
- if authorization == "Bearer valid-token" {
- request_status = Status::ok("request is valid");
- }
- }
-
- Ok(Response::new(CheckResponse::with_status(request_status)))
- }
-}
+pub mod authorization;
+use authorization::PolicyServer;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {