kanidm/server/testkit/tests/scim_test.rs

256 lines
7.4 KiB
Rust
Raw Permalink Normal View History

use compact_jwt::{traits::JwsVerifiable, JwsCompact, JwsEs256Verifier, JwsVerifier};
2022-10-29 11:07:54 +02:00
use kanidm_client::KanidmClient;
use kanidm_proto::internal::ScimSyncToken;
use kanidm_proto::scim_v1::ScimEntryGetQuery;
2024-09-12 04:53:43 +02:00
use kanidmd_lib::prelude::{Attribute, BUILTIN_GROUP_IDM_ADMINS_V1};
use kanidmd_testkit::{ADMIN_TEST_PASSWORD, ADMIN_TEST_USER};
Converting from tide to axum (#1797) * Starting to chase down testing * commenting out unused/inactive endpoints, adding more tests * clippyism * making clippy happy v2 * testing when things are not right * moar checkpoint * splitting up testkit things a bit * moving https -> tide * mad lad be crabbin * spawning like a frog * something something different spawning * woot it works ish * more server things * adding version header to requests * adding kopid_middleware * well that was supposed to be an hour... four later * more nonsense * carrying on with the conversion * first pass through the conversion is DONE! * less pub more better * session storage works better, fixed some paths * axum-csp version thing * try a typedheader * better openssl config things * updating lockfile * http2 * actually sending JSON when we say we will! * just about to do something dumb * flargl * more yak shaving * So many clippy-isms, fixing up a query handler bleep bloop * So many clippy-isms, fixing up a query handler bleep bloop * fmt * all tests pass including basic web logins and nav * so much clippyism * stripping out old comments * fmt * commenty things * stripping out tide * updates * de-tiding things * fmt * adding optional header matching ,thanks @cuberoot74088 * oauth2 stuff to match #1807 but in axum * CLIPPY IS FINALLY SATED * moving scim from /v1/scim to /scim * one day clippy will make sense * cleanups * removing sketching middleware * cleanup, strip a broken test endpoint (routemap), more clippy * docs fmt * pulling axum-csp from the wrong cargo.toml * docs fmt * fmt fixes
2023-07-05 14:26:39 +02:00
use reqwest::header::HeaderValue;
use std::str::FromStr;
use url::Url;
2022-10-29 11:07:54 +02:00
#[kanidmd_testkit::test]
async fn test_sync_account_lifecycle(rsclient: KanidmClient) {
let a_res = rsclient
.auth_simple_password(ADMIN_TEST_USER, ADMIN_TEST_PASSWORD)
2022-10-29 11:07:54 +02:00
.await;
assert!(a_res.is_ok());
let a_list = rsclient.idm_sync_account_list().await.unwrap();
assert!(a_list.is_empty());
rsclient
.idm_sync_account_create("ipa_sync_account", Some("Demo of a sync account"))
.await
.unwrap();
let a_list = rsclient.idm_sync_account_list().await.unwrap();
assert!(!a_list.is_empty());
let a = rsclient
.idm_sync_account_get("ipa_sync_account")
.await
.unwrap();
let sync_entry = a.expect("No sync account was created?!");
2022-10-29 11:07:54 +02:00
// Shouldn't have a cred portal.
assert!(!sync_entry.attrs.contains_key("sync_credential_portal"));
let url = Url::parse("https://sink.ipa.example.com/reset").unwrap();
// Set our credential portal.
rsclient
.idm_sync_account_set_credential_portal("ipa_sync_account", Some(&url))
.await
.unwrap();
let a = rsclient
.idm_sync_account_get("ipa_sync_account")
.await
.unwrap();
let sync_entry = a.expect("No sync account present?");
// Should have a cred portal.
2022-10-29 11:07:54 +02:00
let url_a = sync_entry
.attrs
.get("sync_credential_portal")
.and_then(|x| x.first());
2022-10-29 11:07:54 +02:00
assert_eq!(
url_a.map(|s| s.as_str()),
Some("https://sink.ipa.example.com/reset")
);
2022-10-29 11:07:54 +02:00
// Also check we can get it direct
let url_b = rsclient
.idm_sync_account_get_credential_portal("ipa_sync_account")
.await
.unwrap();
2022-10-29 11:07:54 +02:00
assert_eq!(url_b, Some(url));
2022-10-29 11:07:54 +02:00
// Get a token
let token = rsclient
.idm_sync_account_generate_token("ipa_sync_account", "token_label")
.await
.expect("Failed to generate token");
2022-10-29 11:07:54 +02:00
let token_unverified = JwsCompact::from_str(&token).expect("Failed to parse apitoken");
let key_id = token_unverified
.kid()
.expect("token does not have a key id");
assert!(token_unverified.get_jwk_pubkey().is_none());
let jwk = rsclient
.get_public_jwk(key_id)
.await
.expect("Unable to get jwk");
let jws_verifier = JwsEs256Verifier::try_from(&jwk).expect("Unable to build verifier");
let token = jws_verifier
.verify(&token_unverified)
.map(|jws| jws.from_json::<ScimSyncToken>().expect("Invalid json"))
.expect("Unable verify token");
println!("{:?}", token);
rsclient
.idm_sync_account_destroy_token("ipa_sync_account")
.await
.expect("Failed to destroy token");
2022-10-29 11:07:54 +02:00
}
Converting from tide to axum (#1797) * Starting to chase down testing * commenting out unused/inactive endpoints, adding more tests * clippyism * making clippy happy v2 * testing when things are not right * moar checkpoint * splitting up testkit things a bit * moving https -> tide * mad lad be crabbin * spawning like a frog * something something different spawning * woot it works ish * more server things * adding version header to requests * adding kopid_middleware * well that was supposed to be an hour... four later * more nonsense * carrying on with the conversion * first pass through the conversion is DONE! * less pub more better * session storage works better, fixed some paths * axum-csp version thing * try a typedheader * better openssl config things * updating lockfile * http2 * actually sending JSON when we say we will! * just about to do something dumb * flargl * more yak shaving * So many clippy-isms, fixing up a query handler bleep bloop * So many clippy-isms, fixing up a query handler bleep bloop * fmt * all tests pass including basic web logins and nav * so much clippyism * stripping out old comments * fmt * commenty things * stripping out tide * updates * de-tiding things * fmt * adding optional header matching ,thanks @cuberoot74088 * oauth2 stuff to match #1807 but in axum * CLIPPY IS FINALLY SATED * moving scim from /v1/scim to /scim * one day clippy will make sense * cleanups * removing sketching middleware * cleanup, strip a broken test endpoint (routemap), more clippy * docs fmt * pulling axum-csp from the wrong cargo.toml * docs fmt * fmt fixes
2023-07-05 14:26:39 +02:00
#[kanidmd_testkit::test]
async fn test_scim_sync_get(rsclient: KanidmClient) {
// We need to do manual reqwests here.
let mut headers = reqwest::header::HeaderMap::new();
headers.insert(
reqwest::header::AUTHORIZATION,
HeaderValue::from_str(&format!("Bearer {:?}", rsclient.get_token().await)).unwrap(),
);
let client = reqwest::Client::builder()
.danger_accept_invalid_certs(true)
.default_headers(headers)
.build()
.unwrap();
Converting from tide to axum (#1797) * Starting to chase down testing * commenting out unused/inactive endpoints, adding more tests * clippyism * making clippy happy v2 * testing when things are not right * moar checkpoint * splitting up testkit things a bit * moving https -> tide * mad lad be crabbin * spawning like a frog * something something different spawning * woot it works ish * more server things * adding version header to requests * adding kopid_middleware * well that was supposed to be an hour... four later * more nonsense * carrying on with the conversion * first pass through the conversion is DONE! * less pub more better * session storage works better, fixed some paths * axum-csp version thing * try a typedheader * better openssl config things * updating lockfile * http2 * actually sending JSON when we say we will! * just about to do something dumb * flargl * more yak shaving * So many clippy-isms, fixing up a query handler bleep bloop * So many clippy-isms, fixing up a query handler bleep bloop * fmt * all tests pass including basic web logins and nav * so much clippyism * stripping out old comments * fmt * commenty things * stripping out tide * updates * de-tiding things * fmt * adding optional header matching ,thanks @cuberoot74088 * oauth2 stuff to match #1807 but in axum * CLIPPY IS FINALLY SATED * moving scim from /v1/scim to /scim * one day clippy will make sense * cleanups * removing sketching middleware * cleanup, strip a broken test endpoint (routemap), more clippy * docs fmt * pulling axum-csp from the wrong cargo.toml * docs fmt * fmt fixes
2023-07-05 14:26:39 +02:00
// here we test the /ui/ endpoint which should have the headers
let response = match client.get(rsclient.make_url("/scim/v1/Sync")).send().await {
Converting from tide to axum (#1797) * Starting to chase down testing * commenting out unused/inactive endpoints, adding more tests * clippyism * making clippy happy v2 * testing when things are not right * moar checkpoint * splitting up testkit things a bit * moving https -> tide * mad lad be crabbin * spawning like a frog * something something different spawning * woot it works ish * more server things * adding version header to requests * adding kopid_middleware * well that was supposed to be an hour... four later * more nonsense * carrying on with the conversion * first pass through the conversion is DONE! * less pub more better * session storage works better, fixed some paths * axum-csp version thing * try a typedheader * better openssl config things * updating lockfile * http2 * actually sending JSON when we say we will! * just about to do something dumb * flargl * more yak shaving * So many clippy-isms, fixing up a query handler bleep bloop * So many clippy-isms, fixing up a query handler bleep bloop * fmt * all tests pass including basic web logins and nav * so much clippyism * stripping out old comments * fmt * commenty things * stripping out tide * updates * de-tiding things * fmt * adding optional header matching ,thanks @cuberoot74088 * oauth2 stuff to match #1807 but in axum * CLIPPY IS FINALLY SATED * moving scim from /v1/scim to /scim * one day clippy will make sense * cleanups * removing sketching middleware * cleanup, strip a broken test endpoint (routemap), more clippy * docs fmt * pulling axum-csp from the wrong cargo.toml * docs fmt * fmt fixes
2023-07-05 14:26:39 +02:00
Ok(value) => value,
Err(error) => {
panic!(
"Failed to query {:?} : {:#?}",
rsclient.make_url("/scim/v1/Sync"),
error
);
Converting from tide to axum (#1797) * Starting to chase down testing * commenting out unused/inactive endpoints, adding more tests * clippyism * making clippy happy v2 * testing when things are not right * moar checkpoint * splitting up testkit things a bit * moving https -> tide * mad lad be crabbin * spawning like a frog * something something different spawning * woot it works ish * more server things * adding version header to requests * adding kopid_middleware * well that was supposed to be an hour... four later * more nonsense * carrying on with the conversion * first pass through the conversion is DONE! * less pub more better * session storage works better, fixed some paths * axum-csp version thing * try a typedheader * better openssl config things * updating lockfile * http2 * actually sending JSON when we say we will! * just about to do something dumb * flargl * more yak shaving * So many clippy-isms, fixing up a query handler bleep bloop * So many clippy-isms, fixing up a query handler bleep bloop * fmt * all tests pass including basic web logins and nav * so much clippyism * stripping out old comments * fmt * commenty things * stripping out tide * updates * de-tiding things * fmt * adding optional header matching ,thanks @cuberoot74088 * oauth2 stuff to match #1807 but in axum * CLIPPY IS FINALLY SATED * moving scim from /v1/scim to /scim * one day clippy will make sense * cleanups * removing sketching middleware * cleanup, strip a broken test endpoint (routemap), more clippy * docs fmt * pulling axum-csp from the wrong cargo.toml * docs fmt * fmt fixes
2023-07-05 14:26:39 +02:00
}
};
eprintln!("response: {:#?}", response);
assert!(response.status().is_client_error());
// check that the CSP headers are coming back
eprintln!(
"csp headers: {:#?}",
response
.headers()
.get(http::header::CONTENT_SECURITY_POLICY)
);
assert_ne!(
response
.headers()
.get(http::header::CONTENT_SECURITY_POLICY),
None
);
// test that the proper content type comes back
let url = rsclient.make_url("/scim/v1/Sink");
let response = match client.get(url.clone()).send().await {
Ok(value) => value,
Err(error) => {
panic!("Failed to query {:?} : {:#?}", url, error);
}
};
assert!(response.status().is_success());
let content_type = response.headers().get(http::header::CONTENT_TYPE).unwrap();
assert!(content_type.to_str().unwrap().contains("text/html"));
assert!(response.text().await.unwrap().contains("Sink"));
Converting from tide to axum (#1797) * Starting to chase down testing * commenting out unused/inactive endpoints, adding more tests * clippyism * making clippy happy v2 * testing when things are not right * moar checkpoint * splitting up testkit things a bit * moving https -> tide * mad lad be crabbin * spawning like a frog * something something different spawning * woot it works ish * more server things * adding version header to requests * adding kopid_middleware * well that was supposed to be an hour... four later * more nonsense * carrying on with the conversion * first pass through the conversion is DONE! * less pub more better * session storage works better, fixed some paths * axum-csp version thing * try a typedheader * better openssl config things * updating lockfile * http2 * actually sending JSON when we say we will! * just about to do something dumb * flargl * more yak shaving * So many clippy-isms, fixing up a query handler bleep bloop * So many clippy-isms, fixing up a query handler bleep bloop * fmt * all tests pass including basic web logins and nav * so much clippyism * stripping out old comments * fmt * commenty things * stripping out tide * updates * de-tiding things * fmt * adding optional header matching ,thanks @cuberoot74088 * oauth2 stuff to match #1807 but in axum * CLIPPY IS FINALLY SATED * moving scim from /v1/scim to /scim * one day clippy will make sense * cleanups * removing sketching middleware * cleanup, strip a broken test endpoint (routemap), more clippy * docs fmt * pulling axum-csp from the wrong cargo.toml * docs fmt * fmt fixes
2023-07-05 14:26:39 +02:00
}
2024-09-12 04:53:43 +02:00
#[kanidmd_testkit::test]
async fn test_scim_sync_entry_get(rsclient: KanidmClient) {
let res = rsclient
.auth_simple_password("admin", ADMIN_TEST_PASSWORD)
.await;
assert!(res.is_ok());
// All admin to create persons.
rsclient
.idm_group_add_members(BUILTIN_GROUP_IDM_ADMINS_V1.name, &["admin"])
.await
.unwrap();
rsclient
.idm_person_account_create("demo_account", "Deeeeemo")
.await
.unwrap();
// This will be as raw json, not the strongly typed version the server sees
// internally.
let scim_entry = rsclient
.scim_v1_entry_get("demo_account", None)
.await
.unwrap();
tracing::info!("{:#?}", scim_entry);
assert!(scim_entry.attrs.contains_key(&Attribute::Class));
assert!(scim_entry.attrs.contains_key(&Attribute::Name));
assert_eq!(
scim_entry
.attrs
.get(&Attribute::Name)
.and_then(|v| v.as_str())
.unwrap(),
"demo_account".to_string()
);
// Limit the attributes we want.
let query = ScimEntryGetQuery {
attributes: Some(vec![Attribute::Name]),
..Default::default()
};
let scim_entry = rsclient
.scim_v1_entry_get("demo_account", Some(query))
.await
.unwrap();
tracing::info!("{:#?}", scim_entry);
// Should not be present now.
assert!(!scim_entry.attrs.contains_key(&Attribute::Class));
assert!(scim_entry.attrs.contains_key(&Attribute::Name));
// ==========================================
// Same, but via the Person API
let scim_entry = rsclient
.scim_v1_person_get("demo_account", None)
.await
.unwrap();
2024-09-12 04:53:43 +02:00
tracing::info!("{:#?}", scim_entry);
assert!(scim_entry.attrs.contains_key(&Attribute::Class));
assert!(scim_entry.attrs.contains_key(&Attribute::Name));
assert_eq!(
scim_entry
.attrs
.get(&Attribute::Name)
.and_then(|v| v.as_str())
.unwrap(),
"demo_account".to_string()
);
// Limit the attributes we want.
let query = ScimEntryGetQuery {
attributes: Some(vec![Attribute::Name]),
..Default::default()
};
let scim_entry = rsclient
.scim_v1_person_get("demo_account", Some(query))
.await
.unwrap();
tracing::info!("{:#?}", scim_entry);
// Should not be present now.
assert!(!scim_entry.attrs.contains_key(&Attribute::Class));
assert!(scim_entry.attrs.contains_key(&Attribute::Name));
2024-09-12 04:53:43 +02:00
}