mirror of
https://github.com/kanidm/kanidm.git
synced 2025-02-23 20:47:01 +01:00
Further test improvements (#1166)
This commit is contained in:
parent
df4043cf10
commit
692c0a3978
|
@ -97,3 +97,84 @@ pub(crate) fn qs_test(_args: &TokenStream, item: TokenStream, with_init: bool) -
|
||||||
|
|
||||||
result.into()
|
result.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn idm_test(_args: &TokenStream, item: TokenStream) -> TokenStream {
|
||||||
|
let input: syn::ItemFn = match syn::parse(item.clone()) {
|
||||||
|
Ok(it) => it,
|
||||||
|
Err(e) => return token_stream_with_error(item, e),
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(attr) = input.attrs.iter().find(|attr| attr.path.is_ident("test")) {
|
||||||
|
let msg = "second test attribute is supplied";
|
||||||
|
return token_stream_with_error(item, syn::Error::new_spanned(&attr, msg));
|
||||||
|
};
|
||||||
|
|
||||||
|
if input.sig.asyncness.is_none() {
|
||||||
|
let msg = "the `async` keyword is missing from the function declaration";
|
||||||
|
return token_stream_with_error(item, syn::Error::new_spanned(input.sig.fn_token, msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
// If type mismatch occurs, the current rustc points to the last statement.
|
||||||
|
let (last_stmt_start_span, _last_stmt_end_span) = {
|
||||||
|
let mut last_stmt = input
|
||||||
|
.block
|
||||||
|
.stmts
|
||||||
|
.last()
|
||||||
|
.map(ToTokens::into_token_stream)
|
||||||
|
.unwrap_or_default()
|
||||||
|
.into_iter();
|
||||||
|
// `Span` on stable Rust has a limitation that only points to the first
|
||||||
|
// token, not the whole tokens. We can work around this limitation by
|
||||||
|
// using the first/last span of the tokens like
|
||||||
|
// `syn::Error::new_spanned` does.
|
||||||
|
let start = last_stmt.next().map_or_else(Span::call_site, |t| t.span());
|
||||||
|
let end = last_stmt.last().map_or(start, |t| t.span());
|
||||||
|
(start, end)
|
||||||
|
};
|
||||||
|
|
||||||
|
let rt = quote_spanned! {last_stmt_start_span=>
|
||||||
|
tokio::runtime::Builder::new_current_thread()
|
||||||
|
};
|
||||||
|
|
||||||
|
let header = quote! {
|
||||||
|
#[::core::prelude::v1::test]
|
||||||
|
};
|
||||||
|
|
||||||
|
let test_fn = &input.sig.ident;
|
||||||
|
let test_driver = Ident::new(&format!("idm_{}", test_fn), input.sig.span());
|
||||||
|
|
||||||
|
// Effectively we are just injecting a real test function around this which we will
|
||||||
|
// call.
|
||||||
|
|
||||||
|
let result = quote! {
|
||||||
|
#input
|
||||||
|
|
||||||
|
#header
|
||||||
|
fn #test_driver() {
|
||||||
|
let body = async {
|
||||||
|
let (test_server, mut idms_delayed) = crate::testkit::setup_idm_test().await;
|
||||||
|
|
||||||
|
#test_fn(&test_server, &mut idms_delayed).await;
|
||||||
|
|
||||||
|
// Any needed teardown?
|
||||||
|
// Make sure there are no errors.
|
||||||
|
let mut idm_read_txn = test_server.proxy_read().await;
|
||||||
|
let verifications = idm_read_txn.qs_read.verify();
|
||||||
|
trace!("Verification result: {:?}", verifications);
|
||||||
|
assert!(verifications.len() == 0);
|
||||||
|
|
||||||
|
idms_delayed.check_is_empty_or_panic();
|
||||||
|
};
|
||||||
|
#[allow(clippy::expect_used, clippy::diverging_sub_expression)]
|
||||||
|
{
|
||||||
|
return #rt
|
||||||
|
.enable_all()
|
||||||
|
.build()
|
||||||
|
.expect("Failed building the Runtime")
|
||||||
|
.block_on(body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
result.into()
|
||||||
|
}
|
||||||
|
|
|
@ -26,3 +26,8 @@ pub fn qs_test(args: TokenStream, item: TokenStream) -> TokenStream {
|
||||||
pub fn qs_test_no_init(args: TokenStream, item: TokenStream) -> TokenStream {
|
pub fn qs_test_no_init(args: TokenStream, item: TokenStream) -> TokenStream {
|
||||||
entry::qs_test(&args, item, false)
|
entry::qs_test(&args, item, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[proc_macro_attribute]
|
||||||
|
pub fn idm_test(args: TokenStream, item: TokenStream) -> TokenStream {
|
||||||
|
entry::idm_test(&args, item)
|
||||||
|
}
|
||||||
|
|
|
@ -1,15 +1,11 @@
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
use async_std::task;
|
|
||||||
use criterion::{
|
use criterion::{
|
||||||
criterion_group, criterion_main, BenchmarkId, Criterion, SamplingMode, Throughput,
|
criterion_group, criterion_main, BenchmarkId, Criterion, SamplingMode, Throughput,
|
||||||
};
|
};
|
||||||
use kanidmd_lib;
|
use kanidmd_lib;
|
||||||
use kanidmd_lib::entry::{Entry, EntryInit, EntryNew};
|
use kanidmd_lib::entry::{Entry, EntryInit, EntryNew};
|
||||||
use kanidmd_lib::entry_init;
|
use kanidmd_lib::entry_init;
|
||||||
use kanidmd_lib::idm::server::{IdmServer, IdmServerDelayed};
|
|
||||||
use kanidmd_lib::macros::run_idm_test_no_logging;
|
|
||||||
use kanidmd_lib::server::QueryServer;
|
|
||||||
use kanidmd_lib::utils::duration_from_epoch_now;
|
use kanidmd_lib::utils::duration_from_epoch_now;
|
||||||
use kanidmd_lib::value::Value;
|
use kanidmd_lib::value::Value;
|
||||||
|
|
||||||
|
@ -28,14 +24,19 @@ pub fn scaling_user_create_single(c: &mut Criterion) {
|
||||||
println!("iters, size -> {:?}, {:?}", iters, size);
|
println!("iters, size -> {:?}, {:?}", iters, size);
|
||||||
|
|
||||||
for _i in 0..iters {
|
for _i in 0..iters {
|
||||||
run_idm_test_no_logging(
|
let mut rt = tokio::runtime::Builder::new_current_thread();
|
||||||
|_qs: &QueryServer, idms: &IdmServer, _idms_delayed: &IdmServerDelayed| {
|
elapsed = rt
|
||||||
let ct = duration_from_epoch_now();
|
.enable_all()
|
||||||
|
.build()
|
||||||
|
.expect("Failed building the Runtime")
|
||||||
|
.block_on(async {
|
||||||
|
let (idms, _idms_delayed) =
|
||||||
|
kanidmd_lib::testkit::setup_idm_test().await;
|
||||||
|
|
||||||
|
let ct = duration_from_epoch_now();
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
for counter in 0..size {
|
for counter in 0..size {
|
||||||
let idms_prox_write = task::block_on(idms.proxy_write_async(ct));
|
let mut idms_prox_write = idms.proxy_write(ct).await;
|
||||||
|
|
||||||
let name = format!("testperson_{}", counter);
|
let name = format!("testperson_{}", counter);
|
||||||
let e1 = entry_init!(
|
let e1 = entry_init!(
|
||||||
("class", Value::new_class("object")),
|
("class", Value::new_class("object")),
|
||||||
|
@ -51,9 +52,8 @@ pub fn scaling_user_create_single(c: &mut Criterion) {
|
||||||
|
|
||||||
idms_prox_write.commit().expect("Must not fail");
|
idms_prox_write.commit().expect("Must not fail");
|
||||||
}
|
}
|
||||||
elapsed = elapsed.checked_add(start.elapsed()).unwrap();
|
elapsed.checked_add(start.elapsed()).unwrap()
|
||||||
},
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
elapsed
|
elapsed
|
||||||
});
|
});
|
||||||
|
@ -92,20 +92,25 @@ pub fn scaling_user_create_batched(c: &mut Criterion) {
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
for _i in 0..iters {
|
for _i in 0..iters {
|
||||||
kanidmd_lib::macros::run_idm_test_no_logging(
|
let mut rt = tokio::runtime::Builder::new_current_thread();
|
||||||
|_qs: &QueryServer, idms: &IdmServer, _idms_delayed: &IdmServerDelayed| {
|
elapsed = rt
|
||||||
let ct = duration_from_epoch_now();
|
.enable_all()
|
||||||
|
.build()
|
||||||
|
.expect("Failed building the Runtime")
|
||||||
|
.block_on(async {
|
||||||
|
let (idms, _idms_delayed) =
|
||||||
|
kanidmd_lib::testkit::setup_idm_test().await;
|
||||||
|
|
||||||
|
let ct = duration_from_epoch_now();
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
|
|
||||||
let idms_prox_write = task::block_on(idms.proxy_write_async(ct));
|
let mut idms_prox_write = idms.proxy_write(ct).await;
|
||||||
let cr = idms_prox_write.qs_write.internal_create(data.clone());
|
let cr = idms_prox_write.qs_write.internal_create(data.clone());
|
||||||
assert!(cr.is_ok());
|
assert!(cr.is_ok());
|
||||||
|
|
||||||
idms_prox_write.commit().expect("Must not fail");
|
idms_prox_write.commit().expect("Must not fail");
|
||||||
elapsed = elapsed.checked_add(start.elapsed()).unwrap();
|
elapsed.checked_add(start.elapsed()).unwrap()
|
||||||
},
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
elapsed
|
elapsed
|
||||||
});
|
});
|
||||||
|
|
|
@ -1472,7 +1472,6 @@ impl<'a> IdmServerCredUpdateTransaction<'a> {
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use async_std::task;
|
|
||||||
use kanidm_proto::v1::{AuthAllowed, AuthIssueSession, AuthMech, CredentialDetailType};
|
use kanidm_proto::v1::{AuthAllowed, AuthIssueSession, AuthMech, CredentialDetailType};
|
||||||
use uuid::uuid;
|
use uuid::uuid;
|
||||||
use webauthn_authenticator_rs::softpasskey::SoftPasskey;
|
use webauthn_authenticator_rs::softpasskey::SoftPasskey;
|
||||||
|
@ -1494,13 +1493,13 @@ mod tests {
|
||||||
const TEST_CURRENT_TIME: u64 = 6000;
|
const TEST_CURRENT_TIME: u64 = 6000;
|
||||||
const TESTPERSON_UUID: Uuid = uuid!("cf231fea-1a8f-4410-a520-fd9b1a379c86");
|
const TESTPERSON_UUID: Uuid = uuid!("cf231fea-1a8f-4410-a520-fd9b1a379c86");
|
||||||
|
|
||||||
#[test]
|
#[idm_test]
|
||||||
fn test_idm_credential_update_session_init() {
|
async fn test_idm_credential_update_session_init(
|
||||||
run_idm_test!(|_qs: &QueryServer,
|
|
||||||
idms: &IdmServer,
|
idms: &IdmServer,
|
||||||
_idms_delayed: &mut IdmServerDelayed| {
|
_idms_delayed: &mut IdmServerDelayed,
|
||||||
|
) {
|
||||||
let ct = Duration::from_secs(TEST_CURRENT_TIME);
|
let ct = Duration::from_secs(TEST_CURRENT_TIME);
|
||||||
let mut idms_prox_write = task::block_on(idms.proxy_write(ct));
|
let mut idms_prox_write = idms.proxy_write(ct).await;
|
||||||
|
|
||||||
let testaccount_uuid = Uuid::new_v4();
|
let testaccount_uuid = Uuid::new_v4();
|
||||||
|
|
||||||
|
@ -1600,14 +1599,13 @@ mod tests {
|
||||||
|
|
||||||
trace!(?cur);
|
trace!(?cur);
|
||||||
assert!(cur.is_err());
|
assert!(cur.is_err());
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_test_session(
|
async fn setup_test_session(
|
||||||
idms: &IdmServer,
|
idms: &IdmServer,
|
||||||
ct: Duration,
|
ct: Duration,
|
||||||
) -> (CredentialUpdateSessionToken, CredentialUpdateSessionStatus) {
|
) -> (CredentialUpdateSessionToken, CredentialUpdateSessionStatus) {
|
||||||
let mut idms_prox_write = task::block_on(idms.proxy_write(ct));
|
let mut idms_prox_write = idms.proxy_write(ct).await;
|
||||||
|
|
||||||
let e2 = entry_init!(
|
let e2 = entry_init!(
|
||||||
("class", Value::new_class("object")),
|
("class", Value::new_class("object")),
|
||||||
|
@ -1638,11 +1636,11 @@ mod tests {
|
||||||
cur.expect("Failed to start update")
|
cur.expect("Failed to start update")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn renew_test_session(
|
async fn renew_test_session(
|
||||||
idms: &IdmServer,
|
idms: &IdmServer,
|
||||||
ct: Duration,
|
ct: Duration,
|
||||||
) -> (CredentialUpdateSessionToken, CredentialUpdateSessionStatus) {
|
) -> (CredentialUpdateSessionToken, CredentialUpdateSessionStatus) {
|
||||||
let mut idms_prox_write = task::block_on(idms.proxy_write(ct));
|
let mut idms_prox_write = idms.proxy_write(ct).await;
|
||||||
|
|
||||||
let testperson = idms_prox_write
|
let testperson = idms_prox_write
|
||||||
.qs_write
|
.qs_write
|
||||||
|
@ -1659,8 +1657,8 @@ mod tests {
|
||||||
cur.expect("Failed to start update")
|
cur.expect("Failed to start update")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn commit_session(idms: &IdmServer, ct: Duration, cust: CredentialUpdateSessionToken) {
|
async fn commit_session(idms: &IdmServer, ct: Duration, cust: CredentialUpdateSessionToken) {
|
||||||
let mut idms_prox_write = task::block_on(idms.proxy_write(ct));
|
let mut idms_prox_write = idms.proxy_write(ct).await;
|
||||||
|
|
||||||
idms_prox_write
|
idms_prox_write
|
||||||
.commit_credential_update(&cust, ct)
|
.commit_credential_update(&cust, ct)
|
||||||
|
@ -1669,7 +1667,7 @@ mod tests {
|
||||||
idms_prox_write.commit().expect("Failed to commit txn");
|
idms_prox_write.commit().expect("Failed to commit txn");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_testperson_password(
|
async fn check_testperson_password(
|
||||||
idms: &IdmServer,
|
idms: &IdmServer,
|
||||||
idms_delayed: &mut IdmServerDelayed,
|
idms_delayed: &mut IdmServerDelayed,
|
||||||
pw: &str,
|
pw: &str,
|
||||||
|
@ -1679,7 +1677,7 @@ mod tests {
|
||||||
|
|
||||||
let auth_init = AuthEvent::named_init("testperson");
|
let auth_init = AuthEvent::named_init("testperson");
|
||||||
|
|
||||||
let r1 = task::block_on(idms_auth.auth(&auth_init, ct));
|
let r1 = idms_auth.auth(&auth_init, ct).await;
|
||||||
let ar = r1.unwrap();
|
let ar = r1.unwrap();
|
||||||
let AuthResult {
|
let AuthResult {
|
||||||
sessionid,
|
sessionid,
|
||||||
|
@ -1694,7 +1692,7 @@ mod tests {
|
||||||
|
|
||||||
let auth_begin = AuthEvent::begin_mech(sessionid, AuthMech::Password);
|
let auth_begin = AuthEvent::begin_mech(sessionid, AuthMech::Password);
|
||||||
|
|
||||||
let r2 = task::block_on(idms_auth.auth(&auth_begin, ct));
|
let r2 = idms_auth.auth(&auth_begin, ct).await;
|
||||||
let ar = r2.unwrap();
|
let ar = r2.unwrap();
|
||||||
let AuthResult {
|
let AuthResult {
|
||||||
sessionid,
|
sessionid,
|
||||||
|
@ -1707,7 +1705,7 @@ mod tests {
|
||||||
let pw_step = AuthEvent::cred_step_password(sessionid, pw);
|
let pw_step = AuthEvent::cred_step_password(sessionid, pw);
|
||||||
|
|
||||||
// Expect success
|
// Expect success
|
||||||
let r2 = task::block_on(idms_auth.auth(&pw_step, ct));
|
let r2 = idms_auth.auth(&pw_step, ct).await;
|
||||||
debug!("r2 ==> {:?}", r2);
|
debug!("r2 ==> {:?}", r2);
|
||||||
idms_auth.commit().expect("Must not fail");
|
idms_auth.commit().expect("Must not fail");
|
||||||
|
|
||||||
|
@ -1727,7 +1725,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_testperson_password_totp(
|
async fn check_testperson_password_totp(
|
||||||
idms: &IdmServer,
|
idms: &IdmServer,
|
||||||
idms_delayed: &mut IdmServerDelayed,
|
idms_delayed: &mut IdmServerDelayed,
|
||||||
pw: &str,
|
pw: &str,
|
||||||
|
@ -1738,7 +1736,7 @@ mod tests {
|
||||||
|
|
||||||
let auth_init = AuthEvent::named_init("testperson");
|
let auth_init = AuthEvent::named_init("testperson");
|
||||||
|
|
||||||
let r1 = task::block_on(idms_auth.auth(&auth_init, ct));
|
let r1 = idms_auth.auth(&auth_init, ct).await;
|
||||||
let ar = r1.unwrap();
|
let ar = r1.unwrap();
|
||||||
let AuthResult {
|
let AuthResult {
|
||||||
sessionid,
|
sessionid,
|
||||||
|
@ -1753,7 +1751,7 @@ mod tests {
|
||||||
|
|
||||||
let auth_begin = AuthEvent::begin_mech(sessionid, AuthMech::PasswordMfa);
|
let auth_begin = AuthEvent::begin_mech(sessionid, AuthMech::PasswordMfa);
|
||||||
|
|
||||||
let r2 = task::block_on(idms_auth.auth(&auth_begin, ct));
|
let r2 = idms_auth.auth(&auth_begin, ct).await;
|
||||||
let ar = r2.unwrap();
|
let ar = r2.unwrap();
|
||||||
let AuthResult {
|
let AuthResult {
|
||||||
sessionid,
|
sessionid,
|
||||||
|
@ -1768,7 +1766,7 @@ mod tests {
|
||||||
.expect("Failed to perform totp step");
|
.expect("Failed to perform totp step");
|
||||||
|
|
||||||
let totp_step = AuthEvent::cred_step_totp(sessionid, totp);
|
let totp_step = AuthEvent::cred_step_totp(sessionid, totp);
|
||||||
let r2 = task::block_on(idms_auth.auth(&totp_step, ct));
|
let r2 = idms_auth.auth(&totp_step, ct).await;
|
||||||
let ar = r2.unwrap();
|
let ar = r2.unwrap();
|
||||||
let AuthResult {
|
let AuthResult {
|
||||||
sessionid,
|
sessionid,
|
||||||
|
@ -1781,7 +1779,7 @@ mod tests {
|
||||||
let pw_step = AuthEvent::cred_step_password(sessionid, pw);
|
let pw_step = AuthEvent::cred_step_password(sessionid, pw);
|
||||||
|
|
||||||
// Expect success
|
// Expect success
|
||||||
let r3 = task::block_on(idms_auth.auth(&pw_step, ct));
|
let r3 = idms_auth.auth(&pw_step, ct).await;
|
||||||
debug!("r3 ==> {:?}", r3);
|
debug!("r3 ==> {:?}", r3);
|
||||||
idms_auth.commit().expect("Must not fail");
|
idms_auth.commit().expect("Must not fail");
|
||||||
|
|
||||||
|
@ -1800,7 +1798,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_testperson_password_backup_code(
|
async fn check_testperson_password_backup_code(
|
||||||
idms: &IdmServer,
|
idms: &IdmServer,
|
||||||
idms_delayed: &mut IdmServerDelayed,
|
idms_delayed: &mut IdmServerDelayed,
|
||||||
pw: &str,
|
pw: &str,
|
||||||
|
@ -1811,7 +1809,7 @@ mod tests {
|
||||||
|
|
||||||
let auth_init = AuthEvent::named_init("testperson");
|
let auth_init = AuthEvent::named_init("testperson");
|
||||||
|
|
||||||
let r1 = task::block_on(idms_auth.auth(&auth_init, ct));
|
let r1 = idms_auth.auth(&auth_init, ct).await;
|
||||||
let ar = r1.unwrap();
|
let ar = r1.unwrap();
|
||||||
let AuthResult {
|
let AuthResult {
|
||||||
sessionid,
|
sessionid,
|
||||||
|
@ -1826,7 +1824,7 @@ mod tests {
|
||||||
|
|
||||||
let auth_begin = AuthEvent::begin_mech(sessionid, AuthMech::PasswordMfa);
|
let auth_begin = AuthEvent::begin_mech(sessionid, AuthMech::PasswordMfa);
|
||||||
|
|
||||||
let r2 = task::block_on(idms_auth.auth(&auth_begin, ct));
|
let r2 = idms_auth.auth(&auth_begin, ct).await;
|
||||||
let ar = r2.unwrap();
|
let ar = r2.unwrap();
|
||||||
let AuthResult {
|
let AuthResult {
|
||||||
sessionid,
|
sessionid,
|
||||||
|
@ -1837,7 +1835,7 @@ mod tests {
|
||||||
assert!(matches!(state, AuthState::Continue(_)));
|
assert!(matches!(state, AuthState::Continue(_)));
|
||||||
|
|
||||||
let code_step = AuthEvent::cred_step_backup_code(sessionid, code);
|
let code_step = AuthEvent::cred_step_backup_code(sessionid, code);
|
||||||
let r2 = task::block_on(idms_auth.auth(&code_step, ct));
|
let r2 = idms_auth.auth(&code_step, ct).await;
|
||||||
let ar = r2.unwrap();
|
let ar = r2.unwrap();
|
||||||
let AuthResult {
|
let AuthResult {
|
||||||
sessionid,
|
sessionid,
|
||||||
|
@ -1850,7 +1848,7 @@ mod tests {
|
||||||
let pw_step = AuthEvent::cred_step_password(sessionid, pw);
|
let pw_step = AuthEvent::cred_step_password(sessionid, pw);
|
||||||
|
|
||||||
// Expect success
|
// Expect success
|
||||||
let r3 = task::block_on(idms_auth.auth(&pw_step, ct));
|
let r3 = idms_auth.auth(&pw_step, ct).await;
|
||||||
debug!("r3 ==> {:?}", r3);
|
debug!("r3 ==> {:?}", r3);
|
||||||
idms_auth.commit().expect("Must not fail");
|
idms_auth.commit().expect("Must not fail");
|
||||||
|
|
||||||
|
@ -1863,7 +1861,7 @@ mod tests {
|
||||||
// There now should be a backup code invalidation present
|
// There now should be a backup code invalidation present
|
||||||
let da = idms_delayed.try_recv().expect("invalid");
|
let da = idms_delayed.try_recv().expect("invalid");
|
||||||
assert!(matches!(da, DelayedAction::BackupCodeRemoval(_)));
|
assert!(matches!(da, DelayedAction::BackupCodeRemoval(_)));
|
||||||
let r = task::block_on(idms.delayed_action(ct, da));
|
let r = idms.delayed_action(ct, da).await;
|
||||||
assert!(r.is_ok());
|
assert!(r.is_ok());
|
||||||
|
|
||||||
// Process the auth session
|
// Process the auth session
|
||||||
|
@ -1875,7 +1873,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_testperson_passkey(
|
async fn check_testperson_passkey(
|
||||||
idms: &IdmServer,
|
idms: &IdmServer,
|
||||||
idms_delayed: &mut IdmServerDelayed,
|
idms_delayed: &mut IdmServerDelayed,
|
||||||
wa: &mut WebauthnAuthenticator<SoftPasskey>,
|
wa: &mut WebauthnAuthenticator<SoftPasskey>,
|
||||||
|
@ -1886,7 +1884,7 @@ mod tests {
|
||||||
|
|
||||||
let auth_init = AuthEvent::named_init("testperson");
|
let auth_init = AuthEvent::named_init("testperson");
|
||||||
|
|
||||||
let r1 = task::block_on(idms_auth.auth(&auth_init, ct));
|
let r1 = idms_auth.auth(&auth_init, ct).await;
|
||||||
let ar = r1.unwrap();
|
let ar = r1.unwrap();
|
||||||
let AuthResult {
|
let AuthResult {
|
||||||
sessionid,
|
sessionid,
|
||||||
|
@ -1901,7 +1899,7 @@ mod tests {
|
||||||
|
|
||||||
let auth_begin = AuthEvent::begin_mech(sessionid, AuthMech::Passkey);
|
let auth_begin = AuthEvent::begin_mech(sessionid, AuthMech::Passkey);
|
||||||
|
|
||||||
let r2 = task::block_on(idms_auth.auth(&auth_begin, ct));
|
let r2 = idms_auth.auth(&auth_begin, ct).await;
|
||||||
let ar = r2.unwrap();
|
let ar = r2.unwrap();
|
||||||
let AuthResult {
|
let AuthResult {
|
||||||
sessionid,
|
sessionid,
|
||||||
|
@ -1927,7 +1925,7 @@ mod tests {
|
||||||
|
|
||||||
let passkey_step = AuthEvent::cred_step_passkey(sessionid, resp);
|
let passkey_step = AuthEvent::cred_step_passkey(sessionid, resp);
|
||||||
|
|
||||||
let r3 = task::block_on(idms_auth.auth(&passkey_step, ct));
|
let r3 = idms_auth.auth(&passkey_step, ct).await;
|
||||||
debug!("r3 ==> {:?}", r3);
|
debug!("r3 ==> {:?}", r3);
|
||||||
idms_auth.commit().expect("Must not fail");
|
idms_auth.commit().expect("Must not fail");
|
||||||
|
|
||||||
|
@ -1940,7 +1938,7 @@ mod tests {
|
||||||
// Process the webauthn update
|
// Process the webauthn update
|
||||||
let da = idms_delayed.try_recv().expect("invalid");
|
let da = idms_delayed.try_recv().expect("invalid");
|
||||||
assert!(matches!(da, DelayedAction::WebauthnCounterIncrement(_)));
|
assert!(matches!(da, DelayedAction::WebauthnCounterIncrement(_)));
|
||||||
let r = task::block_on(idms.delayed_action(ct, da));
|
let r = idms.delayed_action(ct, da).await;
|
||||||
assert!(r.is_ok());
|
assert!(r.is_ok());
|
||||||
|
|
||||||
// Process the auth session
|
// Process the auth session
|
||||||
|
@ -1953,13 +1951,13 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[idm_test]
|
||||||
fn test_idm_credential_update_session_cleanup() {
|
async fn test_idm_credential_update_session_cleanup(
|
||||||
run_idm_test!(|_qs: &QueryServer,
|
|
||||||
idms: &IdmServer,
|
idms: &IdmServer,
|
||||||
_idms_delayed: &mut IdmServerDelayed| {
|
_idms_delayed: &mut IdmServerDelayed,
|
||||||
|
) {
|
||||||
let ct = Duration::from_secs(TEST_CURRENT_TIME);
|
let ct = Duration::from_secs(TEST_CURRENT_TIME);
|
||||||
let (cust, _) = setup_test_session(idms, ct);
|
let (cust, _) = setup_test_session(idms, ct).await;
|
||||||
|
|
||||||
let cutxn = idms.cred_update_transaction();
|
let cutxn = idms.cred_update_transaction();
|
||||||
// The session exists
|
// The session exists
|
||||||
|
@ -1968,7 +1966,8 @@ mod tests {
|
||||||
drop(cutxn);
|
drop(cutxn);
|
||||||
|
|
||||||
// Making a new session is what triggers the clean of old sessions.
|
// Making a new session is what triggers the clean of old sessions.
|
||||||
let _ = renew_test_session(idms, ct + MAXIMUM_CRED_UPDATE_TTL + Duration::from_secs(1));
|
let (_cust, _) =
|
||||||
|
renew_test_session(idms, ct + MAXIMUM_CRED_UPDATE_TTL + Duration::from_secs(1)).await;
|
||||||
|
|
||||||
let cutxn = idms.cred_update_transaction();
|
let cutxn = idms.cred_update_transaction();
|
||||||
|
|
||||||
|
@ -1978,18 +1977,17 @@ mod tests {
|
||||||
.credential_update_status(&cust, ct)
|
.credential_update_status(&cust, ct)
|
||||||
.expect_err("Session is still valid!");
|
.expect_err("Session is still valid!");
|
||||||
assert!(matches!(c_status, OperationError::InvalidState));
|
assert!(matches!(c_status, OperationError::InvalidState));
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[idm_test]
|
||||||
fn test_idm_credential_update_onboarding_create_new_pw() {
|
async fn test_idm_credential_update_onboarding_create_new_pw(
|
||||||
run_idm_test!(
|
idms: &IdmServer,
|
||||||
|_qs: &QueryServer, idms: &IdmServer, idms_delayed: &mut IdmServerDelayed| {
|
idms_delayed: &mut IdmServerDelayed,
|
||||||
let test_pw =
|
) {
|
||||||
"fo3EitierohF9AelaNgiem0Ei6vup4equo1Oogeevaetehah8Tobeengae3Ci0ooh0uki";
|
let test_pw = "fo3EitierohF9AelaNgiem0Ei6vup4equo1Oogeevaetehah8Tobeengae3Ci0ooh0uki";
|
||||||
let ct = Duration::from_secs(TEST_CURRENT_TIME);
|
let ct = Duration::from_secs(TEST_CURRENT_TIME);
|
||||||
|
|
||||||
let (cust, _) = setup_test_session(idms, ct);
|
let (cust, _) = setup_test_session(idms, ct).await;
|
||||||
|
|
||||||
let cutxn = idms.cred_update_transaction();
|
let cutxn = idms.cred_update_transaction();
|
||||||
|
|
||||||
|
@ -2013,13 +2011,15 @@ mod tests {
|
||||||
assert!(c_status.can_commit);
|
assert!(c_status.can_commit);
|
||||||
|
|
||||||
drop(cutxn);
|
drop(cutxn);
|
||||||
commit_session(idms, ct, cust);
|
commit_session(idms, ct, cust).await;
|
||||||
|
|
||||||
// Check it works!
|
// Check it works!
|
||||||
assert!(check_testperson_password(idms, idms_delayed, test_pw, ct).is_some());
|
assert!(check_testperson_password(idms, idms_delayed, test_pw, ct)
|
||||||
|
.await
|
||||||
|
.is_some());
|
||||||
|
|
||||||
// Test deleting the pw
|
// Test deleting the pw
|
||||||
let (cust, _) = renew_test_session(idms, ct);
|
let (cust, _) = renew_test_session(idms, ct).await;
|
||||||
let cutxn = idms.cred_update_transaction();
|
let cutxn = idms.cred_update_transaction();
|
||||||
|
|
||||||
let c_status = cutxn
|
let c_status = cutxn
|
||||||
|
@ -2035,12 +2035,12 @@ mod tests {
|
||||||
assert!(c_status.primary.is_none());
|
assert!(c_status.primary.is_none());
|
||||||
|
|
||||||
drop(cutxn);
|
drop(cutxn);
|
||||||
commit_session(idms, ct, cust);
|
commit_session(idms, ct, cust).await;
|
||||||
|
|
||||||
// Must fail now!
|
// Must fail now!
|
||||||
assert!(check_testperson_password(idms, idms_delayed, test_pw, ct).is_none());
|
assert!(check_testperson_password(idms, idms_delayed, test_pw, ct)
|
||||||
}
|
.await
|
||||||
)
|
.is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test set of primary account password
|
// Test set of primary account password
|
||||||
|
@ -2048,15 +2048,15 @@ mod tests {
|
||||||
// - set correctly.
|
// - set correctly.
|
||||||
|
|
||||||
// - setup TOTP
|
// - setup TOTP
|
||||||
#[test]
|
#[idm_test]
|
||||||
fn test_idm_credential_update_onboarding_create_new_mfa_totp_basic() {
|
async fn test_idm_credential_update_onboarding_create_new_mfa_totp_basic(
|
||||||
run_idm_test!(
|
idms: &IdmServer,
|
||||||
|_qs: &QueryServer, idms: &IdmServer, idms_delayed: &mut IdmServerDelayed| {
|
idms_delayed: &mut IdmServerDelayed,
|
||||||
let test_pw =
|
) {
|
||||||
"fo3EitierohF9AelaNgiem0Ei6vup4equo1Oogeevaetehah8Tobeengae3Ci0ooh0uki";
|
let test_pw = "fo3EitierohF9AelaNgiem0Ei6vup4equo1Oogeevaetehah8Tobeengae3Ci0ooh0uki";
|
||||||
let ct = Duration::from_secs(TEST_CURRENT_TIME);
|
let ct = Duration::from_secs(TEST_CURRENT_TIME);
|
||||||
|
|
||||||
let (cust, _) = setup_test_session(idms, ct);
|
let (cust, _) = setup_test_session(idms, ct).await;
|
||||||
let cutxn = idms.cred_update_transaction();
|
let cutxn = idms.cred_update_transaction();
|
||||||
|
|
||||||
// Setup the PW
|
// Setup the PW
|
||||||
|
@ -2108,21 +2108,18 @@ mod tests {
|
||||||
// Should be okay now!
|
// Should be okay now!
|
||||||
|
|
||||||
drop(cutxn);
|
drop(cutxn);
|
||||||
commit_session(idms, ct, cust);
|
commit_session(idms, ct, cust).await;
|
||||||
|
|
||||||
// Check it works!
|
// Check it works!
|
||||||
assert!(check_testperson_password_totp(
|
assert!(
|
||||||
idms,
|
check_testperson_password_totp(idms, idms_delayed, test_pw, &totp_token, ct)
|
||||||
idms_delayed,
|
.await
|
||||||
test_pw,
|
.is_some()
|
||||||
&totp_token,
|
);
|
||||||
ct
|
|
||||||
)
|
|
||||||
.is_some());
|
|
||||||
// No need to test delete of the whole cred, we already did with pw above.
|
// No need to test delete of the whole cred, we already did with pw above.
|
||||||
|
|
||||||
// If we remove TOTP, show it reverts back.
|
// If we remove TOTP, show it reverts back.
|
||||||
let (cust, _) = renew_test_session(idms, ct);
|
let (cust, _) = renew_test_session(idms, ct).await;
|
||||||
let cutxn = idms.cred_update_transaction();
|
let cutxn = idms.cred_update_transaction();
|
||||||
|
|
||||||
let c_status = cutxn
|
let c_status = cutxn
|
||||||
|
@ -2136,24 +2133,24 @@ mod tests {
|
||||||
));
|
));
|
||||||
|
|
||||||
drop(cutxn);
|
drop(cutxn);
|
||||||
commit_session(idms, ct, cust);
|
commit_session(idms, ct, cust).await;
|
||||||
|
|
||||||
// Check it works with totp removed.
|
// Check it works with totp removed.
|
||||||
assert!(check_testperson_password(idms, idms_delayed, test_pw, ct).is_some());
|
assert!(check_testperson_password(idms, idms_delayed, test_pw, ct)
|
||||||
}
|
.await
|
||||||
)
|
.is_some());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check sha1 totp.
|
// Check sha1 totp.
|
||||||
#[test]
|
#[idm_test]
|
||||||
fn test_idm_credential_update_onboarding_create_new_mfa_totp_sha1() {
|
async fn test_idm_credential_update_onboarding_create_new_mfa_totp_sha1(
|
||||||
run_idm_test!(
|
idms: &IdmServer,
|
||||||
|_qs: &QueryServer, idms: &IdmServer, idms_delayed: &mut IdmServerDelayed| {
|
idms_delayed: &mut IdmServerDelayed,
|
||||||
let test_pw =
|
) {
|
||||||
"fo3EitierohF9AelaNgiem0Ei6vup4equo1Oogeevaetehah8Tobeengae3Ci0ooh0uki";
|
let test_pw = "fo3EitierohF9AelaNgiem0Ei6vup4equo1Oogeevaetehah8Tobeengae3Ci0ooh0uki";
|
||||||
let ct = Duration::from_secs(TEST_CURRENT_TIME);
|
let ct = Duration::from_secs(TEST_CURRENT_TIME);
|
||||||
|
|
||||||
let (cust, _) = setup_test_session(idms, ct);
|
let (cust, _) = setup_test_session(idms, ct).await;
|
||||||
let cutxn = idms.cred_update_transaction();
|
let cutxn = idms.cred_update_transaction();
|
||||||
|
|
||||||
// Setup the PW
|
// Setup the PW
|
||||||
|
@ -2208,31 +2205,26 @@ mod tests {
|
||||||
// Should be okay now!
|
// Should be okay now!
|
||||||
|
|
||||||
drop(cutxn);
|
drop(cutxn);
|
||||||
commit_session(idms, ct, cust);
|
commit_session(idms, ct, cust).await;
|
||||||
|
|
||||||
// Check it works!
|
// Check it works!
|
||||||
assert!(check_testperson_password_totp(
|
assert!(
|
||||||
idms,
|
check_testperson_password_totp(idms, idms_delayed, test_pw, &totp_token, ct)
|
||||||
idms_delayed,
|
.await
|
||||||
test_pw,
|
.is_some()
|
||||||
&totp_token,
|
);
|
||||||
ct
|
|
||||||
)
|
|
||||||
.is_some());
|
|
||||||
// No need to test delete, we already did with pw above.
|
// No need to test delete, we already did with pw above.
|
||||||
}
|
}
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[idm_test]
|
||||||
fn test_idm_credential_update_onboarding_create_new_mfa_totp_backup_codes() {
|
async fn test_idm_credential_update_onboarding_create_new_mfa_totp_backup_codes(
|
||||||
run_idm_test!(
|
idms: &IdmServer,
|
||||||
|_qs: &QueryServer, idms: &IdmServer, idms_delayed: &mut IdmServerDelayed| {
|
idms_delayed: &mut IdmServerDelayed,
|
||||||
let test_pw =
|
) {
|
||||||
"fo3EitierohF9AelaNgiem0Ei6vup4equo1Oogeevaetehah8Tobeengae3Ci0ooh0uki";
|
let test_pw = "fo3EitierohF9AelaNgiem0Ei6vup4equo1Oogeevaetehah8Tobeengae3Ci0ooh0uki";
|
||||||
let ct = Duration::from_secs(TEST_CURRENT_TIME);
|
let ct = Duration::from_secs(TEST_CURRENT_TIME);
|
||||||
|
|
||||||
let (cust, _) = setup_test_session(idms, ct);
|
let (cust, _) = setup_test_session(idms, ct).await;
|
||||||
let cutxn = idms.cred_update_transaction();
|
let cutxn = idms.cred_update_transaction();
|
||||||
|
|
||||||
// Setup the PW
|
// Setup the PW
|
||||||
|
@ -2293,7 +2285,7 @@ mod tests {
|
||||||
|
|
||||||
// Should be okay now!
|
// Should be okay now!
|
||||||
drop(cutxn);
|
drop(cutxn);
|
||||||
commit_session(idms, ct, cust);
|
commit_session(idms, ct, cust).await;
|
||||||
|
|
||||||
let backup_code = codes.iter().next().expect("No codes available");
|
let backup_code = codes.iter().next().expect("No codes available");
|
||||||
|
|
||||||
|
@ -2305,10 +2297,11 @@ mod tests {
|
||||||
backup_code,
|
backup_code,
|
||||||
ct
|
ct
|
||||||
)
|
)
|
||||||
|
.await
|
||||||
.is_some());
|
.is_some());
|
||||||
|
|
||||||
// Renew to start the next steps
|
// Renew to start the next steps
|
||||||
let (cust, _) = renew_test_session(idms, ct);
|
let (cust, _) = renew_test_session(idms, ct).await;
|
||||||
let cutxn = idms.cred_update_transaction();
|
let cutxn = idms.cred_update_transaction();
|
||||||
|
|
||||||
// Only 7 codes left.
|
// Only 7 codes left.
|
||||||
|
@ -2358,20 +2351,18 @@ mod tests {
|
||||||
));
|
));
|
||||||
|
|
||||||
drop(cutxn);
|
drop(cutxn);
|
||||||
commit_session(idms, ct, cust);
|
commit_session(idms, ct, cust).await;
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[idm_test]
|
||||||
fn test_idm_credential_update_onboarding_cancel_inprogress_totp() {
|
async fn test_idm_credential_update_onboarding_cancel_inprogress_totp(
|
||||||
run_idm_test!(
|
idms: &IdmServer,
|
||||||
|_qs: &QueryServer, idms: &IdmServer, idms_delayed: &mut IdmServerDelayed| {
|
idms_delayed: &mut IdmServerDelayed,
|
||||||
let test_pw =
|
) {
|
||||||
"fo3EitierohF9AelaNgiem0Ei6vup4equo1Oogeevaetehah8Tobeengae3Ci0ooh0uki";
|
let test_pw = "fo3EitierohF9AelaNgiem0Ei6vup4equo1Oogeevaetehah8Tobeengae3Ci0ooh0uki";
|
||||||
let ct = Duration::from_secs(TEST_CURRENT_TIME);
|
let ct = Duration::from_secs(TEST_CURRENT_TIME);
|
||||||
|
|
||||||
let (cust, _) = setup_test_session(idms, ct);
|
let (cust, _) = setup_test_session(idms, ct).await;
|
||||||
let cutxn = idms.cred_update_transaction();
|
let cutxn = idms.cred_update_transaction();
|
||||||
|
|
||||||
// Setup the PW
|
// Setup the PW
|
||||||
|
@ -2402,12 +2393,12 @@ mod tests {
|
||||||
assert!(c_status.can_commit);
|
assert!(c_status.can_commit);
|
||||||
|
|
||||||
drop(cutxn);
|
drop(cutxn);
|
||||||
commit_session(idms, ct, cust);
|
commit_session(idms, ct, cust).await;
|
||||||
|
|
||||||
// It's pw only, since we canceled TOTP
|
// It's pw only, since we canceled TOTP
|
||||||
assert!(check_testperson_password(idms, idms_delayed, test_pw, ct).is_some());
|
assert!(check_testperson_password(idms, idms_delayed, test_pw, ct)
|
||||||
}
|
.await
|
||||||
)
|
.is_some());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Primary cred must be pw or pwmfa
|
// Primary cred must be pw or pwmfa
|
||||||
|
@ -2416,13 +2407,14 @@ mod tests {
|
||||||
// - remove webauthn
|
// - remove webauthn
|
||||||
// - test mulitple webauthn token.
|
// - test mulitple webauthn token.
|
||||||
|
|
||||||
#[test]
|
#[idm_test]
|
||||||
fn test_idm_credential_update_onboarding_create_new_passkey() {
|
async fn test_idm_credential_update_onboarding_create_new_passkey(
|
||||||
run_idm_test!(
|
idms: &IdmServer,
|
||||||
|_qs: &QueryServer, idms: &IdmServer, idms_delayed: &mut IdmServerDelayed| {
|
idms_delayed: &mut IdmServerDelayed,
|
||||||
|
) {
|
||||||
let ct = Duration::from_secs(TEST_CURRENT_TIME);
|
let ct = Duration::from_secs(TEST_CURRENT_TIME);
|
||||||
|
|
||||||
let (cust, _) = setup_test_session(idms, ct);
|
let (cust, _) = setup_test_session(idms, ct).await;
|
||||||
let cutxn = idms.cred_update_transaction();
|
let cutxn = idms.cred_update_transaction();
|
||||||
let origin = cutxn.get_origin().clone();
|
let origin = cutxn.get_origin().clone();
|
||||||
|
|
||||||
|
@ -2468,16 +2460,17 @@ mod tests {
|
||||||
|
|
||||||
// Commit
|
// Commit
|
||||||
drop(cutxn);
|
drop(cutxn);
|
||||||
commit_session(idms, ct, cust);
|
commit_session(idms, ct, cust).await;
|
||||||
|
|
||||||
// Do an auth test
|
// Do an auth test
|
||||||
assert!(
|
assert!(
|
||||||
check_testperson_passkey(idms, idms_delayed, &mut wa, origin.clone(), ct)
|
check_testperson_passkey(idms, idms_delayed, &mut wa, origin.clone(), ct)
|
||||||
|
.await
|
||||||
.is_some()
|
.is_some()
|
||||||
);
|
);
|
||||||
|
|
||||||
// Now test removing the token
|
// Now test removing the token
|
||||||
let (cust, _) = renew_test_session(idms, ct);
|
let (cust, _) = renew_test_session(idms, ct).await;
|
||||||
let cutxn = idms.cred_update_transaction();
|
let cutxn = idms.cred_update_transaction();
|
||||||
|
|
||||||
trace!(?c_status);
|
trace!(?c_status);
|
||||||
|
@ -2493,15 +2486,15 @@ mod tests {
|
||||||
assert!(c_status.passkeys.is_empty());
|
assert!(c_status.passkeys.is_empty());
|
||||||
|
|
||||||
drop(cutxn);
|
drop(cutxn);
|
||||||
commit_session(idms, ct, cust);
|
commit_session(idms, ct, cust).await;
|
||||||
|
|
||||||
// Must fail now!
|
// Must fail now!
|
||||||
assert!(
|
assert!(
|
||||||
check_testperson_passkey(idms, idms_delayed, &mut wa, origin, ct).is_none()
|
check_testperson_passkey(idms, idms_delayed, &mut wa, origin, ct)
|
||||||
|
.await
|
||||||
|
.is_none()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// W_ policy, assert can't remove MFA if it's enforced.
|
// W_ policy, assert can't remove MFA if it's enforced.
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use core::task::{Context, Poll};
|
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -11,8 +10,6 @@ use concread::cowcell::{CowCellReadTxn, CowCellWriteTxn};
|
||||||
use concread::hashmap::HashMap;
|
use concread::hashmap::HashMap;
|
||||||
use concread::CowCell;
|
use concread::CowCell;
|
||||||
use fernet::Fernet;
|
use fernet::Fernet;
|
||||||
// #[cfg(any(test,bench))]
|
|
||||||
use futures::task as futures_task;
|
|
||||||
use hashbrown::HashSet;
|
use hashbrown::HashSet;
|
||||||
use kanidm_proto::v1::{
|
use kanidm_proto::v1::{
|
||||||
ApiToken, BackupCodesView, CredentialStatus, PasswordFeedback, RadiusAuthToken, UatPurpose,
|
ApiToken, BackupCodesView, CredentialStatus, PasswordFeedback, RadiusAuthToken, UatPurpose,
|
||||||
|
@ -343,8 +340,12 @@ impl IdmServer {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IdmServerDelayed {
|
impl IdmServerDelayed {
|
||||||
// #[cfg(any(test,bench))]
|
// I think we can just make this async in the future?
|
||||||
|
#[cfg(test)]
|
||||||
pub(crate) fn check_is_empty_or_panic(&mut self) {
|
pub(crate) fn check_is_empty_or_panic(&mut self) {
|
||||||
|
use core::task::{Context, Poll};
|
||||||
|
use futures::task as futures_task;
|
||||||
|
|
||||||
let waker = futures_task::noop_waker();
|
let waker = futures_task::noop_waker();
|
||||||
let mut cx = Context::from_waker(&waker);
|
let mut cx = Context::from_waker(&waker);
|
||||||
match self.async_rx.poll_recv(&mut cx) {
|
match self.async_rx.poll_recv(&mut cx) {
|
||||||
|
@ -365,6 +366,9 @@ impl IdmServerDelayed {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub(crate) fn try_recv(&mut self) -> Result<DelayedAction, OperationError> {
|
pub(crate) fn try_recv(&mut self) -> Result<DelayedAction, OperationError> {
|
||||||
|
use core::task::{Context, Poll};
|
||||||
|
use futures::task as futures_task;
|
||||||
|
|
||||||
let waker = futures_task::noop_waker();
|
let waker = futures_task::noop_waker();
|
||||||
let mut cx = Context::from_waker(&waker);
|
let mut cx = Context::from_waker(&waker);
|
||||||
match self.async_rx.poll_recv(&mut cx) {
|
match self.async_rx.poll_recv(&mut cx) {
|
||||||
|
|
|
@ -375,24 +375,22 @@ mod tests {
|
||||||
use kanidm_proto::v1::ApiToken;
|
use kanidm_proto::v1::ApiToken;
|
||||||
|
|
||||||
use super::{DestroyApiTokenEvent, GenerateApiTokenEvent};
|
use super::{DestroyApiTokenEvent, GenerateApiTokenEvent};
|
||||||
// use crate::prelude::*;
|
|
||||||
use crate::event::CreateEvent;
|
use crate::event::CreateEvent;
|
||||||
use crate::idm::server::IdmServerTransaction;
|
use crate::idm::server::IdmServerTransaction;
|
||||||
|
use crate::prelude::*;
|
||||||
use async_std::task;
|
|
||||||
|
|
||||||
const TEST_CURRENT_TIME: u64 = 6000;
|
const TEST_CURRENT_TIME: u64 = 6000;
|
||||||
|
|
||||||
#[test]
|
#[idm_test]
|
||||||
fn test_idm_service_account_api_token() {
|
async fn test_idm_service_account_api_token(
|
||||||
run_idm_test!(|_qs: &QueryServer,
|
|
||||||
idms: &IdmServer,
|
idms: &IdmServer,
|
||||||
_idms_delayed: &mut IdmServerDelayed| {
|
_idms_delayed: &mut IdmServerDelayed,
|
||||||
|
) {
|
||||||
let ct = Duration::from_secs(TEST_CURRENT_TIME);
|
let ct = Duration::from_secs(TEST_CURRENT_TIME);
|
||||||
let past_grc = Duration::from_secs(TEST_CURRENT_TIME + 1) + GRACE_WINDOW;
|
let past_grc = Duration::from_secs(TEST_CURRENT_TIME + 1) + GRACE_WINDOW;
|
||||||
let exp = Duration::from_secs(TEST_CURRENT_TIME + 6000);
|
let exp = Duration::from_secs(TEST_CURRENT_TIME + 6000);
|
||||||
let post_exp = Duration::from_secs(TEST_CURRENT_TIME + 6010);
|
let post_exp = Duration::from_secs(TEST_CURRENT_TIME + 6010);
|
||||||
let mut idms_prox_write = task::block_on(idms.proxy_write(ct));
|
let mut idms_prox_write = idms.proxy_write(ct).await;
|
||||||
|
|
||||||
let testaccount_uuid = Uuid::new_v4();
|
let testaccount_uuid = Uuid::new_v4();
|
||||||
|
|
||||||
|
@ -443,10 +441,8 @@ mod tests {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Delete session
|
// Delete session
|
||||||
let dte = DestroyApiTokenEvent::new_internal(
|
let dte =
|
||||||
apitoken_inner.account_id,
|
DestroyApiTokenEvent::new_internal(apitoken_inner.account_id, apitoken_inner.token_id);
|
||||||
apitoken_inner.token_id,
|
|
||||||
);
|
|
||||||
assert!(idms_prox_write
|
assert!(idms_prox_write
|
||||||
.service_account_destroy_api_token(&dte)
|
.service_account_destroy_api_token(&dte)
|
||||||
.is_ok());
|
.is_ok());
|
||||||
|
@ -467,6 +463,5 @@ mod tests {
|
||||||
);
|
);
|
||||||
|
|
||||||
assert!(idms_prox_write.commit().is_ok());
|
assert!(idms_prox_write.commit().is_ok());
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,8 +52,7 @@ mod repl;
|
||||||
pub mod schema;
|
pub mod schema;
|
||||||
pub mod server;
|
pub mod server;
|
||||||
pub mod status;
|
pub mod status;
|
||||||
#[cfg(test)]
|
pub mod testkit;
|
||||||
mod testkit;
|
|
||||||
|
|
||||||
/// A prelude of imports that should be imported by all other Kanidm modules to
|
/// A prelude of imports that should be imported by all other Kanidm modules to
|
||||||
/// help make imports cleaner.
|
/// help make imports cleaner.
|
||||||
|
@ -79,6 +78,7 @@ pub mod prelude {
|
||||||
FilterInvalid, FC,
|
FilterInvalid, FC,
|
||||||
};
|
};
|
||||||
pub use crate::identity::{AccessScope, IdentType, Identity, IdentityId};
|
pub use crate::identity::{AccessScope, IdentType, Identity, IdentityId};
|
||||||
|
pub use crate::idm::server::{IdmServer, IdmServerDelayed};
|
||||||
pub use crate::modify::{m_pres, m_purge, m_remove, Modify, ModifyInvalid, ModifyList};
|
pub use crate::modify::{m_pres, m_purge, m_remove, Modify, ModifyInvalid, ModifyList};
|
||||||
pub use crate::server::{
|
pub use crate::server::{
|
||||||
QueryServer, QueryServerReadTransaction, QueryServerTransaction,
|
QueryServer, QueryServerReadTransaction, QueryServerTransaction,
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#[cfg(test)]
|
||||||
macro_rules! setup_test {
|
macro_rules! setup_test {
|
||||||
() => {{
|
() => {{
|
||||||
let _ = sketching::test_init();
|
let _ = sketching::test_init();
|
||||||
|
@ -71,6 +72,7 @@ macro_rules! entry_str_to_account {
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
macro_rules! run_idm_test_inner {
|
macro_rules! run_idm_test_inner {
|
||||||
($test_fn:expr) => {{
|
($test_fn:expr) => {{
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
|
@ -112,18 +114,6 @@ macro_rules! run_idm_test {
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_idm_test_no_logging<F>(mut test_fn: F)
|
|
||||||
where
|
|
||||||
F: FnMut(
|
|
||||||
&crate::server::QueryServer,
|
|
||||||
&crate::idm::server::IdmServer,
|
|
||||||
&crate::idm::server::IdmServerDelayed,
|
|
||||||
),
|
|
||||||
{
|
|
||||||
sketching::test_init();
|
|
||||||
run_idm_test_inner!(test_fn);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test helpers for all plugins.
|
// Test helpers for all plugins.
|
||||||
// #[macro_export]
|
// #[macro_export]
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -1603,6 +1603,7 @@ impl Schema {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(any(test))]
|
||||||
pub(crate) fn write_blocking(&self) -> SchemaWriteTransaction<'_> {
|
pub(crate) fn write_blocking(&self) -> SchemaWriteTransaction<'_> {
|
||||||
self.write()
|
self.write()
|
||||||
}
|
}
|
||||||
|
|
|
@ -820,7 +820,7 @@ impl<'a> QueryServerReadTransaction<'a> {
|
||||||
// Verify the data content of the server is as expected. This will probably
|
// Verify the data content of the server is as expected. This will probably
|
||||||
// call various functions for validation, including possibly plugin
|
// call various functions for validation, including possibly plugin
|
||||||
// verifications.
|
// verifications.
|
||||||
fn verify(&mut self) -> Vec<Result<(), ConsistencyError>> {
|
pub(crate) fn verify(&mut self) -> Vec<Result<(), ConsistencyError>> {
|
||||||
// If we fail after backend, we need to return NOW because we can't
|
// If we fail after backend, we need to return NOW because we can't
|
||||||
// assert any other faith in the DB states.
|
// assert any other faith in the DB states.
|
||||||
// * backend
|
// * backend
|
||||||
|
|
|
@ -19,3 +19,13 @@ pub async fn setup_test() -> QueryServer {
|
||||||
// Init is called via the proc macro
|
// Init is called via the proc macro
|
||||||
qs
|
qs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn setup_idm_test() -> (IdmServer, IdmServerDelayed) {
|
||||||
|
let qs = setup_test().await;
|
||||||
|
|
||||||
|
qs.initialise_helper(duration_from_epoch_now())
|
||||||
|
.await
|
||||||
|
.expect("init failed!");
|
||||||
|
|
||||||
|
IdmServer::new(qs, "https://idm.example.com").expect("Failed to setup idms")
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue