#![allow(unused_imports)]
#![allow(dead_code)]
use cedarling::{
AuthorizationConfig, AuthorizeMultiIssuerRequest, BootstrapConfig, Cedarling, DataStoreConfig,
EntityData, HttpClientConfig, InitCedarlingError, JwtConfig, LogConfig, LogLevel,
LogTypeConfig, PolicyStoreConfig, TokenInput,
};
use serde_json::json;
use std::collections::HashSet;
use std::fs::File;
#[cfg(not(any(target_arch = "wasm32", target_os = "windows")))]
use jsonwebtoken::Algorithm;
#[cfg(not(any(target_arch = "wasm32", target_os = "windows")))]
use test_utils::token_claims::generate_token_using_claims_and_keypair;
#[cfg(not(any(target_arch = "wasm32", target_os = "windows")))]
use test_utils::{MockServer, gen_mock_server};
const POLICY_STORE_RAW: &str =
include_str!("../../test_files/policy-store-multi-issuer-basic.yaml");
#[cfg(not(any(target_arch = "wasm32", target_os = "windows")))]
#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mock1 = gen_mock_server();
let mock2 = gen_mock_server();
let cedarling = init_cedarling_multi_issuer(&mock1.base_idp_url, &mock2.base_idp_url).await?;
let request = prepare_cedarling_request_for_multi_issuer_jwt_validation(&mock1, &mock2);
let validation_result = cedarling
.authorize_multi_issuer(request.clone())
.await
.expect("authorization validation should succeed");
assert!(
validation_result.decision,
"authorization validation should return Allow decision"
);
let guard = pprof::ProfilerGuardBuilder::default()
.frequency(1000)
.blocklist(&["libc", "libgcc", "pthread", "vdso"])
.build()
.unwrap();
for _ in 0..1000 {
call_authorize_multi_issuer(&cedarling, &request).await;
}
if let Ok(report) = guard.report().build() {
println!("report: {:?}", &report);
let file = File::create(format!(
"{}/../{}",
env!("CARGO_MANIFEST_DIR"),
"cedarling_profiling_multi_issuer_flamegraph.svg",
))
.unwrap();
let mut options = pprof::flamegraph::Options::default();
options.image_width = Some(3000);
report.flamegraph_with_options(file, &mut options).unwrap();
}
Ok(())
}
#[cfg(not(any(target_arch = "wasm32", target_os = "windows")))]
async fn init_cedarling_multi_issuer(
base_idp_url1: &str,
base_idp_url2: &str,
) -> Result<Cedarling, InitCedarlingError> {
let mut policy_store = serde_yaml_ng::from_str::<serde_yaml_ng::Value>(POLICY_STORE_RAW)
.expect("a valid YAML policy store");
policy_store["policy_stores"]["multi_issuer_basic_store"]["trusted_issuers"]["AcmeIssuer"]["openid_configuration_endpoint"] =
format!("{base_idp_url1}/.well-known/openid-configuration").into();
policy_store["policy_stores"]["multi_issuer_basic_store"]["trusted_issuers"]["DolphinIssuer"]
["openid_configuration_endpoint"] =
format!("{base_idp_url2}/.well-known/openid-configuration").into();
let bootstrap_config = BootstrapConfig {
application_name: "test_app".to_string(),
log_config: LogConfig {
log_type: LogTypeConfig::Off,
log_level: LogLevel::INFO,
},
policy_store_config: PolicyStoreConfig {
source: cedarling::PolicyStoreSource::Yaml(
serde_yaml_ng::to_string(&policy_store).expect("serialize policy store to YAML"),
),
..Default::default()
},
jwt_config: JwtConfig {
jwks: None,
jwt_sig_validation: true,
jwt_status_validation: false,
signature_algorithms_supported: HashSet::from([Algorithm::HS256]),
..Default::default()
},
authorization_config: AuthorizationConfig::default(),
lock_config: None,
max_base64_size: None,
max_default_entities: None,
data_store_config: DataStoreConfig::default(),
http_client_config: HttpClientConfig::default(),
};
Cedarling::new(&bootstrap_config).await
}
#[cfg(not(any(target_arch = "wasm32", target_os = "windows")))]
fn prepare_cedarling_request_for_multi_issuer_jwt_validation(
mock1: &MockServer,
mock2: &MockServer,
) -> AuthorizeMultiIssuerRequest {
let acme_multi_token = generate_token_using_claims_and_keypair(
&json!({
"iss": mock1.base_idp_url,
"sub": "acme_user_multi",
"jti": "acme_multi_123",
"client_id": "acme_multi_client_123",
"aud": "acme_multi_audience",
"scope": ["read:wiki", "write:profile"],
"exp": 2_000_000_000,
"iat": 1_516_239_022
}),
&mock1.keys,
);
let dolphin_multi_token = generate_token_using_claims_and_keypair(
&json!({
"iss": mock2.base_idp_url,
"sub": "dolphin_user_multi",
"jti": "dolphin_multi_456",
"client_id": "dolphin_multi_client_456",
"aud": "dolphin_multi_audience",
"location": ["miami"],
"exp": 2_000_000_000,
"iat": 1_516_239_022
}),
&mock2.keys,
);
AuthorizeMultiIssuerRequest::new_with_fields(
vec![
TokenInput::new("Acme::Access_Token".to_string(), acme_multi_token),
TokenInput::new("Dolphin::Access_Token".to_string(), dolphin_multi_token),
],
EntityData::from_json(
&json!({
"cedar_entity_mapping": {
"entity_type": "Acme::Resource",
"id": "WikiPages"
},
"name": "Wiki Pages"
})
.to_string(),
)
.expect("Failed to create resource entity"),
"Acme::Action::\"ReadProfile\"".to_string(),
None,
)
}
#[cfg(not(any(target_arch = "wasm32", target_os = "windows")))]
async fn call_authorize_multi_issuer(cedarling: &Cedarling, request: &AuthorizeMultiIssuerRequest) {
let _result = cedarling.authorize_multi_issuer(request.clone()).await;
}
#[cfg(any(target_arch = "wasm32", target_os = "windows"))]
#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
unimplemented!("Profiling is not supported on wasm32 or windows.")
}