#[cfg(test)] mod tests { use crate::support::factory_bot::*; use authzd::CheckService; use envoy_types::ext_authz::v3::pb::Authorization; use envoy_types::pb::envoy::service::auth::v3::attribute_context::HttpRequest; use std::sync::Arc; fn subject() -> CheckService { CheckService::new(Arc::new(build_cedar_authorizer( cedar_policy::Entities::empty(), ))) } #[tokio::test] async fn test_no_headers() { let request = tonic::Request::new(build_request(|_http| {})); let response = subject().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!( tonic::Code::from_i32(status.code), tonic::Code::Unauthenticated ); } #[tokio::test] async fn test_static_assets() { let routes = vec![ ("GET", "/app.js", tonic::Code::Ok), ("GET", "/application.js", tonic::Code::Ok), ("GET", "/favicon.ico", tonic::Code::Ok), ("GET", "/favicon.png", tonic::Code::Ok), ("GET", "/image.jpg", tonic::Code::Ok), ("GET", "/assets/image.jpg", tonic::Code::Ok), ("GET", "/assets/style.css", tonic::Code::Ok), ("GET", "/assets/application.js", tonic::Code::Ok), ("GET", "/htmx.js", tonic::Code::Ok), ("GET", "/index.html", tonic::Code::Ok), ("GET", "/logo.png", tonic::Code::Ok), ("GET", "/pico.min.css", tonic::Code::Ok), ("GET", "/vue.global.js", tonic::Code::Ok), ]; for (method, path, expected_status_code) in &routes { let request = tonic::Request::new(build_request(|item: &mut HttpRequest| { item.method = method.to_string(); item.path = path.to_string(); item.host = "localhost:3000".to_string(); item.headers = build_headers(vec![ (String::from(":path"), item.path.to_string()), (String::from(":method"), item.method.to_string()), (String::from(":authority"), item.host.to_string()), ]); })); let response = subject().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!(tonic::Code::from_i32(status.code), *expected_status_code); } } #[tokio::test] async fn test_public_sparkle_endpoints() { let hosts = vec![ "localhost:10000", "sparkle.runway.gitlab.net", "sparkle.staging.runway.gitlab.net", ]; let routes = vec![ ("GET", "/", tonic::Code::Ok), ("GET", "/callback", tonic::Code::Ok), ("GET", "/dashboard/nav", tonic::Code::Ok), ("GET", "/health", tonic::Code::Ok), ("GET", "/signout", tonic::Code::Ok), ("GET", "/sparkles", tonic::Code::Ok), ("POST", "/sparkles/restore", tonic::Code::Ok), ("GET", "/dashboard", tonic::Code::Unauthenticated), ("POST", "/sparkles", tonic::Code::Unauthenticated), ]; for host in hosts { for (method, path, expected_status_code) in &routes { let request = tonic::Request::new(build_request(|item: &mut HttpRequest| { item.method = method.to_string(); item.path = path.to_string(); item.host = host.to_string(); item.headers = build_headers(vec![ (String::from(":path"), path.to_string()), (String::from(":method"), method.to_string()), (String::from(":authority"), host.to_string()), ]); })); let response = subject().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!( tonic::Code::from_i32(status.code), *expected_status_code, "{} {}", method, path ); } } } }