2019-07-29 09:09:09 +02:00
|
|
|
#![deny(warnings)]
|
2023-10-04 09:24:12 +02:00
|
|
|
use std::path::Path;
|
2020-04-10 07:50:45 +02:00
|
|
|
use std::time::SystemTime;
|
2019-09-09 12:32:49 +02:00
|
|
|
|
2023-10-14 04:39:14 +02:00
|
|
|
use kanidm_proto::constants::KSESSIONID;
|
2024-02-27 10:25:02 +01:00
|
|
|
use kanidm_proto::internal::{
|
|
|
|
ApiToken, CURegState, Filter, ImageValue, Modify, ModifyList, UatPurpose, UserAuthToken,
|
|
|
|
};
|
2022-09-25 03:21:30 +02:00
|
|
|
use kanidm_proto::v1::{
|
2024-02-27 10:25:02 +01:00
|
|
|
AuthCredential, AuthIssueSession, AuthMech, AuthRequest, AuthResponse, AuthState, AuthStep,
|
|
|
|
Entry,
|
2022-09-25 03:21:30 +02:00
|
|
|
};
|
2022-10-05 01:48:48 +02:00
|
|
|
use kanidmd_lib::credential::totp::Totp;
|
2023-09-16 04:11:06 +02:00
|
|
|
use kanidmd_lib::prelude::{
|
|
|
|
Attribute, BUILTIN_GROUP_IDM_ADMINS_V1, BUILTIN_GROUP_SYSTEM_ADMINS_V1,
|
|
|
|
};
|
2023-10-04 09:24:12 +02:00
|
|
|
use tracing::{debug, trace};
|
2018-10-03 13:21:21 +02:00
|
|
|
|
2022-09-25 03:21:30 +02:00
|
|
|
use std::str::FromStr;
|
2018-10-03 13:21:21 +02:00
|
|
|
|
2023-11-24 03:53:22 +01:00
|
|
|
use compact_jwt::{JwsCompact, JwsEs256Verifier, JwsVerifier};
|
2022-10-01 08:08:51 +02:00
|
|
|
use webauthn_authenticator_rs::softpasskey::SoftPasskey;
|
|
|
|
use webauthn_authenticator_rs::WebauthnAuthenticator;
|
|
|
|
|
2023-08-24 01:54:33 +02:00
|
|
|
use kanidm_client::{ClientError, KanidmClient};
|
2023-10-11 07:44:29 +02:00
|
|
|
use kanidmd_testkit::{ADMIN_TEST_PASSWORD, ADMIN_TEST_USER};
|
2020-12-02 02:12:07 +01:00
|
|
|
|
2020-05-03 08:44:01 +02:00
|
|
|
const UNIX_TEST_PASSWORD: &str = "unix test user password";
|
2019-07-12 07:28:46 +02:00
|
|
|
|
2022-10-24 01:50:31 +02:00
|
|
|
#[kanidmd_testkit::test]
|
|
|
|
async fn test_server_create(rsclient: KanidmClient) {
|
2022-04-29 05:03:21 +02:00
|
|
|
let e: Entry = serde_json::from_str(
|
|
|
|
r#"{
|
2018-11-27 11:48:21 +01:00
|
|
|
"attrs": {
|
2022-09-02 06:21:20 +02:00
|
|
|
"class": ["account", "service_account"],
|
|
|
|
"name": ["testaccount"],
|
|
|
|
"displayname": ["testaccount"]
|
2018-11-27 11:48:21 +01:00
|
|
|
}
|
|
|
|
}"#,
|
2022-04-29 05:03:21 +02:00
|
|
|
)
|
|
|
|
.unwrap();
|
2018-11-27 11:48:21 +01:00
|
|
|
|
2022-04-29 05:03:21 +02:00
|
|
|
// Not logged in - should fail!
|
|
|
|
let res = rsclient.create(vec![e.clone()]).await;
|
|
|
|
assert!(res.is_err());
|
2018-11-26 07:13:22 +01:00
|
|
|
|
2022-04-29 05:03:21 +02:00
|
|
|
let a_res = rsclient
|
|
|
|
.auth_simple_password("admin", ADMIN_TEST_PASSWORD)
|
|
|
|
.await;
|
|
|
|
assert!(a_res.is_ok());
|
2018-11-26 07:13:22 +01:00
|
|
|
|
2022-04-29 05:03:21 +02:00
|
|
|
let res = rsclient.create(vec![e]).await;
|
|
|
|
assert!(res.is_ok());
|
2018-10-03 13:21:21 +02:00
|
|
|
}
|
|
|
|
|
2022-10-24 01:50:31 +02:00
|
|
|
#[kanidmd_testkit::test]
|
|
|
|
async fn test_server_whoami_anonymous(rsclient: KanidmClient) {
|
2022-04-29 05:03:21 +02:00
|
|
|
// First show we are un-authenticated.
|
|
|
|
let pre_res = rsclient.whoami().await;
|
|
|
|
// This means it was okay whoami, but no uat attached.
|
|
|
|
assert!(pre_res.unwrap().is_none());
|
|
|
|
|
|
|
|
// Now login as anonymous
|
|
|
|
let res = rsclient.auth_anonymous().await;
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
|
|
|
// Now do a whoami.
|
2022-09-25 03:21:30 +02:00
|
|
|
let e = rsclient
|
|
|
|
.whoami()
|
|
|
|
.await
|
|
|
|
.expect("Unable to call whoami")
|
|
|
|
.expect("No entry matching self returned");
|
|
|
|
debug!(?e);
|
|
|
|
assert!(e.attrs.get("spn") == Some(&vec!["anonymous@localhost".to_string()]));
|
2022-04-29 05:03:21 +02:00
|
|
|
|
|
|
|
// Do a check of the auth/valid endpoint, tells us if our token
|
|
|
|
// is okay.
|
|
|
|
let res = rsclient.auth_valid().await;
|
|
|
|
assert!(res.is_ok());
|
2019-09-04 03:06:37 +02:00
|
|
|
}
|
|
|
|
|
2022-10-24 01:50:31 +02:00
|
|
|
#[kanidmd_testkit::test]
|
|
|
|
async fn test_server_whoami_admin_simple_password(rsclient: KanidmClient) {
|
2022-04-29 05:03:21 +02:00
|
|
|
// First show we are un-authenticated.
|
|
|
|
let pre_res = rsclient.whoami().await;
|
|
|
|
// This means it was okay whoami, but no uat attached.
|
|
|
|
assert!(pre_res.unwrap().is_none());
|
|
|
|
|
|
|
|
let res = rsclient
|
|
|
|
.auth_simple_password("admin", ADMIN_TEST_PASSWORD)
|
|
|
|
.await;
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
|
|
|
// Now do a whoami.
|
2022-09-25 03:21:30 +02:00
|
|
|
let e = rsclient
|
|
|
|
.whoami()
|
|
|
|
.await
|
|
|
|
.expect("Unable to call whoami")
|
|
|
|
.expect("No entry matching self returned");
|
|
|
|
debug!(?e);
|
|
|
|
assert!(e.attrs.get("spn") == Some(&vec!["admin@localhost".to_string()]));
|
2019-07-12 07:28:46 +02:00
|
|
|
}
|
|
|
|
|
2022-10-24 01:50:31 +02:00
|
|
|
#[kanidmd_testkit::test]
|
|
|
|
async fn test_server_search(rsclient: KanidmClient) {
|
2022-04-29 05:03:21 +02:00
|
|
|
// First show we are un-authenticated.
|
|
|
|
let pre_res = rsclient.whoami().await;
|
|
|
|
// This means it was okay whoami, but no uat attached.
|
2023-08-14 12:47:49 +02:00
|
|
|
println!("Response: {:?}", pre_res);
|
2022-04-29 05:03:21 +02:00
|
|
|
assert!(pre_res.unwrap().is_none());
|
|
|
|
|
|
|
|
let res = rsclient
|
|
|
|
.auth_simple_password("admin", ADMIN_TEST_PASSWORD)
|
|
|
|
.await;
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
|
|
|
let rset = rsclient
|
2023-09-12 03:47:24 +02:00
|
|
|
.search(Filter::Eq(Attribute::Name.to_string(), "admin".to_string()))
|
2022-04-29 05:03:21 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
println!("{:?}", rset);
|
|
|
|
let e = rset.first().unwrap();
|
|
|
|
// Check it's admin.
|
|
|
|
println!("{:?}", e);
|
2023-09-12 03:47:24 +02:00
|
|
|
let name = e.attrs.get(Attribute::Name.as_ref()).unwrap();
|
2022-04-29 05:03:21 +02:00
|
|
|
assert!(name == &vec!["admin".to_string()]);
|
2018-09-29 09:54:16 +02:00
|
|
|
}
|
2019-09-15 20:05:26 +02:00
|
|
|
|
2019-10-05 02:40:43 +02:00
|
|
|
// test the rest group endpoint.
|
2022-10-24 01:50:31 +02:00
|
|
|
#[kanidmd_testkit::test]
|
|
|
|
async fn test_server_rest_group_read(rsclient: KanidmClient) {
|
2022-04-29 05:03:21 +02:00
|
|
|
let res = rsclient
|
|
|
|
.auth_simple_password("admin", ADMIN_TEST_PASSWORD)
|
|
|
|
.await;
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
|
|
|
// List the groups
|
|
|
|
let g_list = rsclient.idm_group_list().await.unwrap();
|
|
|
|
assert!(!g_list.is_empty());
|
|
|
|
|
2023-09-16 04:11:06 +02:00
|
|
|
let g = rsclient
|
|
|
|
.idm_group_get(BUILTIN_GROUP_IDM_ADMINS_V1.name)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
2022-04-29 05:03:21 +02:00
|
|
|
assert!(g.is_some());
|
|
|
|
println!("{:?}", g);
|
2019-10-05 02:40:43 +02:00
|
|
|
}
|
|
|
|
|
2022-10-24 01:50:31 +02:00
|
|
|
#[kanidmd_testkit::test]
|
|
|
|
async fn test_server_rest_group_lifecycle(rsclient: KanidmClient) {
|
2022-04-29 05:03:21 +02:00
|
|
|
let res = rsclient
|
|
|
|
.auth_simple_password("admin", ADMIN_TEST_PASSWORD)
|
|
|
|
.await;
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
|
|
|
// List the groups
|
|
|
|
let g_list = rsclient.idm_group_list().await.unwrap();
|
|
|
|
assert!(!g_list.is_empty());
|
|
|
|
|
|
|
|
// Create a new group
|
2023-12-18 00:10:13 +01:00
|
|
|
rsclient
|
|
|
|
.idm_group_create("demo_group", Some(BUILTIN_GROUP_IDM_ADMINS_V1.name))
|
|
|
|
.await
|
|
|
|
.unwrap();
|
2022-04-29 05:03:21 +02:00
|
|
|
|
|
|
|
// List again, ensure one more.
|
|
|
|
let g_list_2 = rsclient.idm_group_list().await.unwrap();
|
|
|
|
assert!(g_list_2.len() > g_list.len());
|
|
|
|
|
|
|
|
// Test modifications to the group
|
|
|
|
|
|
|
|
// Add a member.
|
|
|
|
rsclient
|
|
|
|
.idm_group_add_members("demo_group", &["admin"])
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
let members = rsclient.idm_group_get_members("demo_group").await.unwrap();
|
2022-07-30 14:10:24 +02:00
|
|
|
assert!(members == Some(vec!["admin@localhost".to_string()]));
|
2019-11-02 02:15:15 +01:00
|
|
|
|
2022-04-29 05:03:21 +02:00
|
|
|
// Set the list of members
|
|
|
|
rsclient
|
|
|
|
.idm_group_set_members("demo_group", &["admin", "demo_group"])
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
let members = rsclient.idm_group_get_members("demo_group").await.unwrap();
|
|
|
|
assert!(
|
|
|
|
members
|
|
|
|
== Some(vec![
|
2022-07-30 14:10:24 +02:00
|
|
|
"admin@localhost".to_string(),
|
|
|
|
"demo_group@localhost".to_string()
|
2022-04-29 05:03:21 +02:00
|
|
|
])
|
|
|
|
);
|
|
|
|
|
|
|
|
// Remove a member from the group
|
|
|
|
rsclient
|
|
|
|
.idm_group_remove_members("demo_group", &["demo_group"])
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
let members = rsclient.idm_group_get_members("demo_group").await.unwrap();
|
2022-07-30 14:10:24 +02:00
|
|
|
assert!(members == Some(vec!["admin@localhost".to_string()]));
|
2019-10-05 02:40:43 +02:00
|
|
|
|
2022-04-29 05:03:21 +02:00
|
|
|
// purge members
|
|
|
|
rsclient
|
|
|
|
.idm_group_purge_members("demo_group")
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
let members = rsclient.idm_group_get_members("demo_group").await.unwrap();
|
2023-01-28 04:52:44 +01:00
|
|
|
assert!(members.is_none());
|
2022-04-29 05:03:21 +02:00
|
|
|
|
|
|
|
// Delete the group
|
|
|
|
rsclient.idm_group_delete("demo_group").await.unwrap();
|
|
|
|
let g_list_3 = rsclient.idm_group_list().await.unwrap();
|
|
|
|
assert!(g_list_3.len() == g_list.len());
|
|
|
|
|
|
|
|
// Check we can get an exact group
|
2023-09-16 04:11:06 +02:00
|
|
|
let g = rsclient
|
|
|
|
.idm_group_get(BUILTIN_GROUP_IDM_ADMINS_V1.name)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
2022-04-29 05:03:21 +02:00
|
|
|
assert!(g.is_some());
|
|
|
|
println!("{:?}", g);
|
|
|
|
|
|
|
|
// They should have members
|
2023-09-16 04:11:06 +02:00
|
|
|
let members = rsclient
|
|
|
|
.idm_group_get_members(BUILTIN_GROUP_IDM_ADMINS_V1.name)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
2022-04-29 05:03:21 +02:00
|
|
|
println!("{:?}", members);
|
2023-12-18 00:10:13 +01:00
|
|
|
assert!(
|
|
|
|
members
|
|
|
|
== Some(vec![
|
|
|
|
"admin@localhost".to_string(),
|
|
|
|
"idm_admin@localhost".to_string()
|
|
|
|
])
|
|
|
|
);
|
2022-04-29 05:03:21 +02:00
|
|
|
}
|
2019-10-05 02:40:43 +02:00
|
|
|
|
2022-10-24 01:50:31 +02:00
|
|
|
#[kanidmd_testkit::test]
|
|
|
|
async fn test_server_rest_account_read(rsclient: KanidmClient) {
|
2022-04-29 05:03:21 +02:00
|
|
|
let res = rsclient
|
|
|
|
.auth_simple_password("admin", ADMIN_TEST_PASSWORD)
|
|
|
|
.await;
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
|
|
|
// List the accounts
|
2022-09-02 06:21:20 +02:00
|
|
|
let a_list = rsclient.idm_service_account_list().await.unwrap();
|
2022-04-29 05:03:21 +02:00
|
|
|
assert!(!a_list.is_empty());
|
|
|
|
|
2022-09-02 06:21:20 +02:00
|
|
|
let a = rsclient.idm_service_account_get("admin").await.unwrap();
|
2022-04-29 05:03:21 +02:00
|
|
|
assert!(a.is_some());
|
|
|
|
println!("{:?}", a);
|
2019-10-05 02:40:43 +02:00
|
|
|
}
|
|
|
|
|
2022-10-24 01:50:31 +02:00
|
|
|
#[kanidmd_testkit::test]
|
|
|
|
async fn test_server_rest_schema_read(rsclient: KanidmClient) {
|
2022-04-29 05:03:21 +02:00
|
|
|
let res = rsclient
|
|
|
|
.auth_simple_password("admin", ADMIN_TEST_PASSWORD)
|
|
|
|
.await;
|
|
|
|
assert!(res.is_ok());
|
2019-10-05 02:40:43 +02:00
|
|
|
|
2022-04-29 05:03:21 +02:00
|
|
|
// List the schema
|
|
|
|
let s_list = rsclient.idm_schema_list().await.unwrap();
|
|
|
|
assert!(!s_list.is_empty());
|
2019-10-05 02:40:43 +02:00
|
|
|
|
2022-04-29 05:03:21 +02:00
|
|
|
let a_list = rsclient.idm_schema_attributetype_list().await.unwrap();
|
|
|
|
assert!(!a_list.is_empty());
|
2019-10-05 02:40:43 +02:00
|
|
|
|
2022-04-29 05:03:21 +02:00
|
|
|
let c_list = rsclient.idm_schema_classtype_list().await.unwrap();
|
|
|
|
assert!(!c_list.is_empty());
|
2019-10-05 02:40:43 +02:00
|
|
|
|
2022-04-29 05:03:21 +02:00
|
|
|
// Get an attr/class
|
2023-09-16 04:11:06 +02:00
|
|
|
let a = rsclient
|
|
|
|
.idm_schema_attributetype_get(Attribute::Name.as_ref())
|
|
|
|
.await
|
|
|
|
.unwrap();
|
2022-04-29 05:03:21 +02:00
|
|
|
assert!(a.is_some());
|
|
|
|
println!("{:?}", a);
|
2019-10-05 02:40:43 +02:00
|
|
|
|
2023-09-16 04:11:06 +02:00
|
|
|
let c = rsclient
|
|
|
|
.idm_schema_classtype_get(Attribute::Account.as_ref())
|
|
|
|
.await
|
|
|
|
.unwrap();
|
2022-04-29 05:03:21 +02:00
|
|
|
assert!(c.is_some());
|
|
|
|
println!("{:?}", c);
|
2019-10-05 02:40:43 +02:00
|
|
|
}
|
|
|
|
|
2019-10-31 01:48:15 +01:00
|
|
|
// Test resetting a radius cred, and then checking/viewing it.
|
2022-10-24 01:50:31 +02:00
|
|
|
#[kanidmd_testkit::test]
|
|
|
|
async fn test_server_radius_credential_lifecycle(rsclient: KanidmClient) {
|
2022-04-29 05:03:21 +02:00
|
|
|
let res = rsclient
|
|
|
|
.auth_simple_password("admin", ADMIN_TEST_PASSWORD)
|
|
|
|
.await;
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
2022-09-02 06:21:20 +02:00
|
|
|
// All admin to create persons.
|
2022-04-29 05:03:21 +02:00
|
|
|
rsclient
|
2023-09-16 04:11:06 +02:00
|
|
|
.idm_group_add_members(BUILTIN_GROUP_IDM_ADMINS_V1.name, &["admin"])
|
2022-04-29 05:03:21 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
2019-10-31 01:48:15 +01:00
|
|
|
|
2022-09-02 06:21:20 +02:00
|
|
|
// self management of credentials is only for persons.
|
2022-04-29 05:03:21 +02:00
|
|
|
rsclient
|
2022-09-02 06:21:20 +02:00
|
|
|
.idm_person_account_create("demo_account", "Deeeeemo")
|
2022-04-29 05:03:21 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Should have no radius secret
|
|
|
|
let n_sec = rsclient
|
|
|
|
.idm_account_radius_credential_get("demo_account")
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
assert!(n_sec.is_none());
|
|
|
|
|
|
|
|
// Set one
|
|
|
|
let sec1 = rsclient
|
|
|
|
.idm_account_radius_credential_regenerate("demo_account")
|
|
|
|
.await
|
|
|
|
.unwrap();
|
2019-11-02 02:15:15 +01:00
|
|
|
|
2022-04-29 05:03:21 +02:00
|
|
|
// Should be able to get it.
|
|
|
|
let r_sec = rsclient
|
|
|
|
.idm_account_radius_credential_get("demo_account")
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
assert!(sec1 == r_sec.unwrap());
|
|
|
|
|
|
|
|
// test getting the token - we can do this as self or the radius server
|
|
|
|
let r_tok = rsclient
|
|
|
|
.idm_account_radius_token_get("demo_account")
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
assert!(sec1 == r_tok.secret);
|
|
|
|
assert!(r_tok.name == "demo_account");
|
|
|
|
|
|
|
|
// Reset it
|
|
|
|
let sec2 = rsclient
|
|
|
|
.idm_account_radius_credential_regenerate("demo_account")
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Should be different
|
|
|
|
println!("s1 {} != s2 {}", sec1, sec2);
|
|
|
|
assert!(sec1 != sec2);
|
|
|
|
|
|
|
|
// Delete it
|
|
|
|
let res = rsclient
|
|
|
|
.idm_account_radius_credential_delete("demo_account")
|
|
|
|
.await;
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
|
|
|
// No secret
|
|
|
|
let n_sec = rsclient
|
|
|
|
.idm_account_radius_credential_get("demo_account")
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
assert!(n_sec.is_none());
|
2019-11-16 05:40:45 +01:00
|
|
|
}
|
|
|
|
|
2022-10-24 01:50:31 +02:00
|
|
|
#[kanidmd_testkit::test]
|
|
|
|
async fn test_server_rest_person_account_lifecycle(rsclient: KanidmClient) {
|
2022-04-29 05:03:21 +02:00
|
|
|
let res = rsclient
|
|
|
|
.auth_simple_password("admin", ADMIN_TEST_PASSWORD)
|
|
|
|
.await;
|
|
|
|
assert!(res.is_ok());
|
|
|
|
// To enable the admin to actually make some of these changes, we have
|
|
|
|
// to make them a people admin. NOT recommended in production!
|
|
|
|
rsclient
|
2023-09-16 04:11:06 +02:00
|
|
|
.idm_group_add_members(BUILTIN_GROUP_IDM_ADMINS_V1.name, &["admin"])
|
2022-04-29 05:03:21 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
2019-11-29 01:48:22 +01:00
|
|
|
|
2022-04-29 05:03:21 +02:00
|
|
|
// Create a new account
|
|
|
|
rsclient
|
2022-09-02 06:21:20 +02:00
|
|
|
.idm_person_account_create("demo_account", "Deeeeemo")
|
2022-04-29 05:03:21 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
2019-11-29 01:48:22 +01:00
|
|
|
|
2022-04-29 05:03:21 +02:00
|
|
|
// View the account
|
2022-09-02 06:21:20 +02:00
|
|
|
rsclient
|
|
|
|
.idm_person_account_get("demo_account")
|
|
|
|
.await
|
|
|
|
.unwrap();
|
2022-04-29 05:03:21 +02:00
|
|
|
|
|
|
|
// change the name?
|
|
|
|
rsclient
|
2022-09-02 06:21:20 +02:00
|
|
|
.idm_person_account_set_attr("demo_account", "displayname", &["Demo Account"])
|
2022-04-29 05:03:21 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Test adding some mail addrs
|
|
|
|
rsclient
|
2023-09-16 04:11:06 +02:00
|
|
|
.idm_person_account_add_attr(
|
|
|
|
"demo_account",
|
|
|
|
Attribute::Mail.as_ref(),
|
|
|
|
&["demo@idm.example.com"],
|
|
|
|
)
|
2022-04-29 05:03:21 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
let r = rsclient
|
2023-09-16 04:11:06 +02:00
|
|
|
.idm_person_account_get_attr("demo_account", Attribute::Mail.as_ref())
|
2022-04-29 05:03:21 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
assert!(r == Some(vec!["demo@idm.example.com".to_string()]));
|
|
|
|
|
|
|
|
// Delete the account
|
2022-09-02 06:21:20 +02:00
|
|
|
rsclient
|
|
|
|
.idm_person_account_delete("demo_account")
|
|
|
|
.await
|
|
|
|
.unwrap();
|
2019-11-29 01:48:22 +01:00
|
|
|
}
|
|
|
|
|
2022-10-24 01:50:31 +02:00
|
|
|
#[kanidmd_testkit::test]
|
|
|
|
async fn test_server_rest_sshkey_lifecycle(rsclient: KanidmClient) {
|
2022-04-29 05:03:21 +02:00
|
|
|
let res = rsclient
|
|
|
|
.auth_simple_password("admin", ADMIN_TEST_PASSWORD)
|
|
|
|
.await;
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
|
|
|
// Get the keys, should be empty vec.
|
|
|
|
let sk1 = rsclient.idm_account_get_ssh_pubkeys("admin").await.unwrap();
|
|
|
|
assert!(sk1.is_empty());
|
|
|
|
|
|
|
|
// idm_account_get_ssh_pubkeys
|
|
|
|
// idm_account_post_ssh_pubkey
|
|
|
|
// idm_account_get_ssh_pubkey
|
|
|
|
// idm_account_delete_ssh_pubkey
|
|
|
|
|
|
|
|
// Post an invalid key (should error)
|
|
|
|
let r1 = rsclient
|
2022-09-02 06:21:20 +02:00
|
|
|
.idm_service_account_post_ssh_pubkey("admin", "inv", "invalid key")
|
2022-04-29 05:03:21 +02:00
|
|
|
.await;
|
|
|
|
assert!(r1.is_err());
|
|
|
|
|
|
|
|
// Post a valid key
|
|
|
|
let r2 = rsclient
|
2022-09-02 06:21:20 +02:00
|
|
|
.idm_service_account_post_ssh_pubkey("admin", "k1", "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAeGW1P6Pc2rPq0XqbRaDKBcXZUPRklo0L1EyR30CwoP william@amethyst").await;
|
2022-04-29 05:03:21 +02:00
|
|
|
println!("{:?}", r2);
|
|
|
|
assert!(r2.is_ok());
|
|
|
|
|
|
|
|
// Get, should have the key
|
|
|
|
let sk2 = rsclient.idm_account_get_ssh_pubkeys("admin").await.unwrap();
|
|
|
|
assert!(sk2.len() == 1);
|
|
|
|
|
|
|
|
// Post a valid key
|
|
|
|
let r3 = rsclient
|
2022-09-02 06:21:20 +02:00
|
|
|
.idm_service_account_post_ssh_pubkey("admin", "k2", "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBx4TpJYQjd0YI5lQIHqblIsCIK5NKVFURYS/eM3o6/Z william@amethyst").await;
|
2022-04-29 05:03:21 +02:00
|
|
|
assert!(r3.is_ok());
|
|
|
|
|
|
|
|
// Get, should have both keys.
|
|
|
|
let sk3 = rsclient.idm_account_get_ssh_pubkeys("admin").await.unwrap();
|
|
|
|
assert!(sk3.len() == 2);
|
|
|
|
|
|
|
|
// Delete a key (by tag)
|
2022-09-02 06:21:20 +02:00
|
|
|
let r4 = rsclient
|
|
|
|
.idm_service_account_delete_ssh_pubkey("admin", "k1")
|
|
|
|
.await;
|
2022-04-29 05:03:21 +02:00
|
|
|
assert!(r4.is_ok());
|
|
|
|
|
|
|
|
// Get, should have remaining key.
|
|
|
|
let sk4 = rsclient.idm_account_get_ssh_pubkeys("admin").await.unwrap();
|
|
|
|
assert!(sk4.len() == 1);
|
|
|
|
|
|
|
|
// get by tag
|
|
|
|
let skn = rsclient.idm_account_get_ssh_pubkey("admin", "k2").await;
|
|
|
|
assert!(skn.is_ok());
|
|
|
|
assert!(skn.unwrap() == Some("ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBx4TpJYQjd0YI5lQIHqblIsCIK5NKVFURYS/eM3o6/Z william@amethyst".to_string()));
|
2023-05-29 08:11:00 +02:00
|
|
|
|
|
|
|
// Add a key and delete with a space in the name.
|
|
|
|
let r5 = rsclient
|
|
|
|
.idm_service_account_post_ssh_pubkey("admin", "Yk 5 Nfc", "sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBENubZikrb8hu+HeVRdZ0pp/VAk2qv4JDbuJhvD0yNdWDL2e3cBbERiDeNPkWx58Q4rVnxkbV1fa8E2waRtT91wAAAAEc3NoOg== william@maxixe").await;
|
|
|
|
assert!(r5.is_ok());
|
|
|
|
|
|
|
|
let r6 = rsclient
|
|
|
|
.idm_service_account_delete_ssh_pubkey("admin", "Yk 5 Nfc")
|
|
|
|
.await;
|
|
|
|
assert!(r6.is_ok());
|
|
|
|
|
|
|
|
let sk5 = rsclient.idm_account_get_ssh_pubkeys("admin").await.unwrap();
|
|
|
|
assert!(sk5.len() == 1);
|
2020-02-13 00:43:01 +01:00
|
|
|
}
|
|
|
|
|
2022-10-24 01:50:31 +02:00
|
|
|
#[kanidmd_testkit::test]
|
|
|
|
async fn test_server_rest_domain_lifecycle(rsclient: KanidmClient) {
|
2022-04-29 05:03:21 +02:00
|
|
|
let res = rsclient
|
|
|
|
.auth_simple_password("admin", ADMIN_TEST_PASSWORD)
|
|
|
|
.await;
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
|
|
|
let _dlocal = rsclient.idm_domain_get().await.unwrap();
|
|
|
|
|
|
|
|
// Change the ssid
|
|
|
|
rsclient.idm_domain_set_ssid("new_ssid").await.unwrap();
|
|
|
|
// check get and get the ssid and domain info
|
|
|
|
let nssid = rsclient.idm_domain_get_ssid().await.unwrap();
|
|
|
|
assert!(nssid == "new_ssid");
|
2022-07-07 05:03:08 +02:00
|
|
|
|
|
|
|
// Change the domain display name
|
|
|
|
rsclient
|
|
|
|
.idm_domain_set_display_name("Super Cool Crabz")
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
let dlocal = rsclient.idm_domain_get().await.unwrap();
|
|
|
|
assert!(
|
|
|
|
dlocal
|
|
|
|
.attrs
|
2023-09-16 04:11:06 +02:00
|
|
|
.get(Attribute::DomainDisplayName.as_ref())
|
2024-02-21 01:52:10 +01:00
|
|
|
.and_then(|v| v.first())
|
2022-07-07 05:03:08 +02:00
|
|
|
== Some(&"Super Cool Crabz".to_string())
|
|
|
|
);
|
2020-02-29 05:02:14 +01:00
|
|
|
}
|
|
|
|
|
2022-10-24 01:50:31 +02:00
|
|
|
#[kanidmd_testkit::test]
|
|
|
|
async fn test_server_rest_posix_lifecycle(rsclient: KanidmClient) {
|
2022-04-29 05:03:21 +02:00
|
|
|
let res = rsclient
|
|
|
|
.auth_simple_password("admin", ADMIN_TEST_PASSWORD)
|
|
|
|
.await;
|
|
|
|
assert!(res.is_ok());
|
|
|
|
// Not recommended in production!
|
|
|
|
rsclient
|
2023-09-16 04:11:06 +02:00
|
|
|
.idm_group_add_members(BUILTIN_GROUP_IDM_ADMINS_V1.name, &["admin"])
|
2022-04-29 05:03:21 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
2020-03-24 23:21:49 +01:00
|
|
|
|
2022-04-29 05:03:21 +02:00
|
|
|
// Create a new account
|
|
|
|
rsclient
|
2022-09-02 06:21:20 +02:00
|
|
|
.idm_person_account_create("posix_account", "Posix Demo Account")
|
2022-04-29 05:03:21 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
2020-03-24 23:21:49 +01:00
|
|
|
|
2022-04-29 05:03:21 +02:00
|
|
|
// Extend the account with posix attrs.
|
|
|
|
rsclient
|
2022-09-02 06:21:20 +02:00
|
|
|
.idm_person_account_unix_extend("posix_account", None, None)
|
2022-04-29 05:03:21 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
2020-03-24 23:21:49 +01:00
|
|
|
|
2022-04-29 05:03:21 +02:00
|
|
|
// Create a group
|
2020-03-24 23:21:49 +01:00
|
|
|
|
2022-04-29 05:03:21 +02:00
|
|
|
// Extend the group with posix attrs
|
2023-12-18 00:10:13 +01:00
|
|
|
rsclient
|
|
|
|
.idm_group_create("posix_group", Some(BUILTIN_GROUP_IDM_ADMINS_V1.name))
|
|
|
|
.await
|
|
|
|
.unwrap();
|
2022-04-29 05:03:21 +02:00
|
|
|
rsclient
|
|
|
|
.idm_group_add_members("posix_group", &["posix_account"])
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
rsclient
|
|
|
|
.idm_group_unix_extend("posix_group", None)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
2023-07-19 01:44:51 +02:00
|
|
|
// here we check that we can successfully change the gid without breaking anything
|
|
|
|
|
|
|
|
let res = rsclient
|
|
|
|
.idm_group_unix_extend("posix_group", Some(123123))
|
|
|
|
.await;
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
|
|
|
let res = rsclient.idm_group_unix_extend("posix_group", None).await;
|
|
|
|
assert!(res.is_ok());
|
2020-03-24 23:21:49 +01:00
|
|
|
|
2022-04-29 05:03:21 +02:00
|
|
|
// Open a new connection as anonymous
|
|
|
|
let res = rsclient.auth_anonymous().await;
|
|
|
|
assert!(res.is_ok());
|
2020-03-24 23:21:49 +01:00
|
|
|
|
2022-04-29 05:03:21 +02:00
|
|
|
// Get the account by name
|
|
|
|
let r = rsclient
|
|
|
|
.idm_account_unix_token_get("posix_account")
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
// Get the account by gidnumber
|
|
|
|
let r1 = rsclient
|
|
|
|
.idm_account_unix_token_get(r.gidnumber.to_string().as_str())
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
// get the account by spn
|
|
|
|
let r2 = rsclient
|
|
|
|
.idm_account_unix_token_get(r.spn.as_str())
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
// get the account by uuid
|
|
|
|
let r3 = rsclient
|
2023-07-28 02:48:56 +02:00
|
|
|
.idm_account_unix_token_get(&r.uuid.hyphenated().to_string())
|
2022-04-29 05:03:21 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
2020-03-24 23:21:49 +01:00
|
|
|
|
2022-04-29 05:03:21 +02:00
|
|
|
println!("{:?}", r);
|
|
|
|
assert!(r.name == "posix_account");
|
|
|
|
assert!(r1.name == "posix_account");
|
|
|
|
assert!(r2.name == "posix_account");
|
|
|
|
assert!(r3.name == "posix_account");
|
2020-03-24 23:21:49 +01:00
|
|
|
|
2023-01-10 04:50:53 +01:00
|
|
|
// get the group by name
|
2022-04-29 05:03:21 +02:00
|
|
|
let r = rsclient
|
|
|
|
.idm_group_unix_token_get("posix_group")
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
// Get the group by gidnumber
|
|
|
|
let r1 = rsclient
|
|
|
|
.idm_group_unix_token_get(r.gidnumber.to_string().as_str())
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
// get the group spn
|
|
|
|
let r2 = rsclient
|
|
|
|
.idm_group_unix_token_get(r.spn.as_str())
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
// get the group by uuid
|
|
|
|
let r3 = rsclient
|
2023-07-28 02:48:56 +02:00
|
|
|
.idm_group_unix_token_get(&r.uuid.hyphenated().to_string())
|
2022-04-29 05:03:21 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
println!("{:?}", r);
|
|
|
|
assert!(r.name == "posix_group");
|
|
|
|
assert!(r1.name == "posix_group");
|
|
|
|
assert!(r2.name == "posix_group");
|
|
|
|
assert!(r3.name == "posix_group");
|
2020-03-24 23:21:49 +01:00
|
|
|
}
|
|
|
|
|
2022-10-24 01:50:31 +02:00
|
|
|
#[kanidmd_testkit::test]
|
|
|
|
async fn test_server_rest_posix_auth_lifecycle(rsclient: KanidmClient) {
|
2022-04-29 05:03:21 +02:00
|
|
|
let res = rsclient
|
|
|
|
.auth_simple_password("admin", ADMIN_TEST_PASSWORD)
|
|
|
|
.await;
|
|
|
|
assert!(res.is_ok());
|
|
|
|
// Get an anon connection
|
|
|
|
let anon_rsclient = rsclient.new_session().unwrap();
|
|
|
|
assert!(anon_rsclient.auth_anonymous().await.is_ok());
|
|
|
|
|
|
|
|
// Not recommended in production!
|
|
|
|
rsclient
|
2023-09-16 04:11:06 +02:00
|
|
|
.idm_group_add_members(BUILTIN_GROUP_IDM_ADMINS_V1.name, &["admin"])
|
2022-04-29 05:03:21 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Setup a unix user
|
|
|
|
rsclient
|
2022-09-02 06:21:20 +02:00
|
|
|
.idm_person_account_create("posix_account", "Posix Demo Account")
|
2022-04-29 05:03:21 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Extend the account with posix attrs.
|
|
|
|
rsclient
|
2022-09-02 06:21:20 +02:00
|
|
|
.idm_person_account_unix_extend("posix_account", None, None)
|
2022-04-29 05:03:21 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// add their password (unix self)
|
|
|
|
rsclient
|
2022-09-02 06:21:20 +02:00
|
|
|
.idm_person_account_unix_cred_put("posix_account", UNIX_TEST_PASSWORD)
|
2022-04-29 05:03:21 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
2023-08-14 00:51:44 +02:00
|
|
|
// test sending a faulty JSON blob to the person unix update endpoint
|
|
|
|
let bad_json: serde_json::Value = serde_json::json!({
|
|
|
|
"shell" : "test_value",
|
|
|
|
"gidnumber" : "5" // this should be a u32, but it's not!
|
|
|
|
});
|
|
|
|
let res = rsclient
|
|
|
|
.perform_post_request::<serde_json::Value, String>(
|
|
|
|
format!("/v1/person/{}/_unix", "posix_account").as_str(),
|
|
|
|
bad_json,
|
|
|
|
)
|
|
|
|
.await;
|
2023-08-15 07:42:15 +02:00
|
|
|
tracing::trace!("{:?}", &res);
|
2023-08-14 00:51:44 +02:00
|
|
|
assert!(res.is_err());
|
|
|
|
|
|
|
|
// test sending a faulty JSON blob to the person unix update endpoint
|
|
|
|
let bad_json: serde_json::Value = serde_json::json!({
|
|
|
|
"crab" : "cakes", // this is an invalid field.
|
|
|
|
"gidnumber" : 5
|
|
|
|
});
|
|
|
|
let res = rsclient
|
|
|
|
.perform_post_request::<serde_json::Value, String>(
|
|
|
|
format!("/v1/person/{}/_unix", "posix_account").as_str(),
|
|
|
|
bad_json,
|
|
|
|
)
|
|
|
|
.await;
|
2023-08-15 07:42:15 +02:00
|
|
|
tracing::trace!("{:?}", &res);
|
2023-08-14 00:51:44 +02:00
|
|
|
assert!(res.is_err());
|
|
|
|
|
2022-04-29 05:03:21 +02:00
|
|
|
// attempt to verify (good, anon-conn)
|
|
|
|
let r1 = anon_rsclient
|
|
|
|
.idm_account_unix_cred_verify("posix_account", UNIX_TEST_PASSWORD)
|
|
|
|
.await;
|
|
|
|
match r1 {
|
|
|
|
Ok(Some(_tok)) => {}
|
|
|
|
_ => assert!(false),
|
|
|
|
};
|
|
|
|
|
|
|
|
// attempt to verify (bad, anon-conn)
|
|
|
|
let r2 = anon_rsclient
|
|
|
|
.idm_account_unix_cred_verify("posix_account", "ntaotnhuohtsuoehtsu")
|
|
|
|
.await;
|
|
|
|
match r2 {
|
|
|
|
Ok(None) => {}
|
|
|
|
_ => assert!(false),
|
|
|
|
};
|
|
|
|
|
|
|
|
// lock? (admin-conn)
|
|
|
|
// attempt to verify (good pw, should fail, anon-conn)
|
|
|
|
// status? (self-conn)
|
|
|
|
|
|
|
|
// clear password? (unix self)
|
|
|
|
rsclient
|
2022-09-02 06:21:20 +02:00
|
|
|
.idm_person_account_unix_cred_delete("posix_account")
|
2022-04-29 05:03:21 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// attempt to verify (good pw, should fail, anon-conn)
|
|
|
|
let r3 = anon_rsclient
|
|
|
|
.idm_account_unix_cred_verify("posix_account", UNIX_TEST_PASSWORD)
|
|
|
|
.await;
|
|
|
|
match r3 {
|
|
|
|
Ok(None) => {}
|
|
|
|
_ => assert!(false),
|
|
|
|
};
|
2020-03-26 23:27:07 +01:00
|
|
|
}
|
|
|
|
|
2022-10-24 01:50:31 +02:00
|
|
|
#[kanidmd_testkit::test]
|
|
|
|
async fn test_server_rest_recycle_lifecycle(rsclient: KanidmClient) {
|
2022-04-29 05:03:21 +02:00
|
|
|
let res = rsclient
|
|
|
|
.auth_simple_password("admin", ADMIN_TEST_PASSWORD)
|
|
|
|
.await;
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
|
|
|
// Not recommended in production!
|
|
|
|
rsclient
|
2023-09-16 04:11:06 +02:00
|
|
|
.idm_group_add_members(BUILTIN_GROUP_IDM_ADMINS_V1.name, &["admin"])
|
2022-04-29 05:03:21 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Setup a unix user
|
|
|
|
rsclient
|
2022-09-02 06:21:20 +02:00
|
|
|
.idm_person_account_create("recycle_account", "Recycle Demo Account")
|
2022-04-29 05:03:21 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// delete them
|
|
|
|
rsclient
|
2022-09-02 06:21:20 +02:00
|
|
|
.idm_person_account_delete("recycle_account")
|
2022-04-29 05:03:21 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// not there
|
2022-09-02 06:21:20 +02:00
|
|
|
let acc = rsclient
|
|
|
|
.idm_person_account_get("recycle_account")
|
|
|
|
.await
|
|
|
|
.unwrap();
|
2022-04-29 05:03:21 +02:00
|
|
|
assert!(acc.is_none());
|
|
|
|
|
|
|
|
// list the recycle bin
|
|
|
|
let r_list = rsclient.recycle_bin_list().await.unwrap();
|
|
|
|
|
|
|
|
assert!(r_list.len() == 1);
|
|
|
|
// get the user in recycle bin
|
|
|
|
let r_user = rsclient.recycle_bin_get("recycle_account").await.unwrap();
|
|
|
|
assert!(r_user.is_some());
|
|
|
|
|
|
|
|
// revive
|
|
|
|
rsclient
|
|
|
|
.recycle_bin_revive("recycle_account")
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// they are there!
|
2022-09-02 06:21:20 +02:00
|
|
|
let acc = rsclient
|
|
|
|
.idm_person_account_get("recycle_account")
|
|
|
|
.await
|
|
|
|
.unwrap();
|
2022-04-29 05:03:21 +02:00
|
|
|
assert!(acc.is_some());
|
2021-07-22 04:04:56 +02:00
|
|
|
}
|
|
|
|
|
2022-10-24 01:50:31 +02:00
|
|
|
#[kanidmd_testkit::test]
|
2023-12-18 00:10:13 +01:00
|
|
|
async fn test_server_rest_oauth2_basic_lifecycle(rsclient: KanidmClient) {
|
2022-04-29 05:03:21 +02:00
|
|
|
let res = rsclient
|
|
|
|
.auth_simple_password("admin", ADMIN_TEST_PASSWORD)
|
|
|
|
.await;
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
|
|
|
rsclient
|
2023-12-18 00:10:13 +01:00
|
|
|
.idm_group_add_members(BUILTIN_GROUP_IDM_ADMINS_V1.name, &["admin"])
|
2022-04-29 05:03:21 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// List, there are non.
|
|
|
|
let initial_configs = rsclient
|
|
|
|
.idm_oauth2_rs_list()
|
|
|
|
.await
|
|
|
|
.expect("Failed to retrieve oauth2 configs");
|
|
|
|
|
|
|
|
assert!(initial_configs.is_empty());
|
|
|
|
|
|
|
|
// Create a new oauth2 config
|
|
|
|
rsclient
|
|
|
|
.idm_oauth2_rs_basic_create(
|
|
|
|
"test_integration",
|
|
|
|
"Test Integration",
|
|
|
|
"https://demo.example.com",
|
|
|
|
)
|
|
|
|
.await
|
|
|
|
.expect("Failed to create oauth2 config");
|
|
|
|
|
|
|
|
// List, there is what we created.
|
|
|
|
let initial_configs = rsclient
|
|
|
|
.idm_oauth2_rs_list()
|
|
|
|
.await
|
|
|
|
.expect("Failed to retrieve oauth2 configs");
|
|
|
|
|
|
|
|
assert!(initial_configs.len() == 1);
|
|
|
|
|
|
|
|
// Get the value. Assert we have oauth2_rs_basic_secret,
|
|
|
|
// but can NOT see the token_secret.
|
|
|
|
let oauth2_config = rsclient
|
|
|
|
.idm_oauth2_rs_get("test_integration")
|
|
|
|
.await
|
|
|
|
.ok()
|
|
|
|
.flatten()
|
|
|
|
.expect("Failed to retrieve test_integration config");
|
|
|
|
|
|
|
|
eprintln!("{:?}", oauth2_config);
|
|
|
|
|
|
|
|
// What can we see?
|
2023-09-16 04:11:06 +02:00
|
|
|
assert!(oauth2_config
|
|
|
|
.attrs
|
|
|
|
.contains_key(Attribute::OAuth2RsBasicSecret.as_ref()));
|
2022-04-29 05:03:21 +02:00
|
|
|
// This is present, but redacted.
|
2023-09-16 04:11:06 +02:00
|
|
|
assert!(oauth2_config
|
|
|
|
.attrs
|
|
|
|
.contains_key(Attribute::OAuth2RsTokenKey.as_ref()));
|
2022-04-29 05:03:21 +02:00
|
|
|
|
|
|
|
// Mod delete the secret/key and check them again.
|
|
|
|
// Check we can patch the oauth2_rs_name / oauth2_rs_origin
|
|
|
|
rsclient
|
|
|
|
.idm_oauth2_rs_update(
|
|
|
|
"test_integration",
|
|
|
|
None,
|
|
|
|
Some("Test Integration"),
|
|
|
|
Some("https://new_demo.example.com"),
|
2022-11-21 02:59:47 +01:00
|
|
|
None,
|
2022-04-29 05:03:21 +02:00
|
|
|
true,
|
|
|
|
true,
|
|
|
|
true,
|
|
|
|
)
|
|
|
|
.await
|
|
|
|
.expect("Failed to update config");
|
|
|
|
|
|
|
|
let oauth2_config_updated = rsclient
|
|
|
|
.idm_oauth2_rs_get("test_integration")
|
|
|
|
.await
|
|
|
|
.ok()
|
|
|
|
.flatten()
|
|
|
|
.expect("Failed to retrieve test_integration config");
|
|
|
|
|
|
|
|
assert!(oauth2_config_updated != oauth2_config);
|
|
|
|
|
|
|
|
// Check that we can add scope maps and delete them.
|
|
|
|
rsclient
|
2023-09-16 04:11:06 +02:00
|
|
|
.idm_oauth2_rs_update_scope_map(
|
|
|
|
"test_integration",
|
|
|
|
BUILTIN_GROUP_SYSTEM_ADMINS_V1.name,
|
|
|
|
vec!["a", "b"],
|
|
|
|
)
|
2022-04-29 05:03:21 +02:00
|
|
|
.await
|
|
|
|
.expect("Failed to create scope map");
|
|
|
|
|
|
|
|
let oauth2_config_updated2 = rsclient
|
|
|
|
.idm_oauth2_rs_get("test_integration")
|
|
|
|
.await
|
|
|
|
.ok()
|
|
|
|
.flatten()
|
|
|
|
.expect("Failed to retrieve test_integration config");
|
|
|
|
|
|
|
|
assert!(oauth2_config_updated != oauth2_config_updated2);
|
|
|
|
|
2022-10-09 09:11:55 +02:00
|
|
|
// Check we can update a scope map
|
|
|
|
rsclient
|
2023-09-16 04:11:06 +02:00
|
|
|
.idm_oauth2_rs_update_scope_map(
|
|
|
|
"test_integration",
|
|
|
|
BUILTIN_GROUP_SYSTEM_ADMINS_V1.name,
|
|
|
|
vec!["a", "b", "c"],
|
|
|
|
)
|
2022-10-09 09:11:55 +02:00
|
|
|
.await
|
|
|
|
.expect("Failed to create scope map");
|
|
|
|
|
|
|
|
let oauth2_config_updated3 = rsclient
|
|
|
|
.idm_oauth2_rs_get("test_integration")
|
|
|
|
.await
|
|
|
|
.ok()
|
|
|
|
.flatten()
|
|
|
|
.expect("Failed to retrieve test_integration config");
|
|
|
|
|
|
|
|
assert!(oauth2_config_updated2 != oauth2_config_updated3);
|
|
|
|
|
2023-10-04 09:24:12 +02:00
|
|
|
// Check we can upload an image
|
|
|
|
let image_path = Path::new("../../server/lib/src/valueset/image/test_images/ok.png");
|
|
|
|
assert!(image_path.exists());
|
|
|
|
let image_contents = std::fs::read(image_path).unwrap();
|
|
|
|
let image = ImageValue::new(
|
|
|
|
"test".to_string(),
|
|
|
|
kanidm_proto::internal::ImageType::Png,
|
|
|
|
image_contents,
|
|
|
|
);
|
|
|
|
|
|
|
|
let res = rsclient
|
|
|
|
.idm_oauth2_rs_update_image("test_integration", image)
|
|
|
|
.await;
|
|
|
|
trace!("update image result: {:?}", &res);
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
|
|
|
//test getting the image
|
|
|
|
let client = reqwest::Client::new();
|
|
|
|
|
|
|
|
let response = client
|
|
|
|
.get(rsclient.make_url("/ui/images/oauth2/test_integration"))
|
|
|
|
.bearer_auth(rsclient.get_token().await.unwrap());
|
|
|
|
|
|
|
|
let response = response
|
|
|
|
.send()
|
|
|
|
.await
|
|
|
|
.map_err(|err| rsclient.handle_response_error(err))
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
assert!(response.status().is_success());
|
|
|
|
|
|
|
|
// check we can upload a *replacement* image
|
|
|
|
|
|
|
|
let image_path = Path::new("../../server/lib/src/valueset/image/test_images/ok.jpg");
|
|
|
|
trace!("image path {:?}", &image_path.canonicalize());
|
|
|
|
assert!(image_path.exists());
|
|
|
|
let jpg_file_contents = std::fs::read(image_path).unwrap();
|
|
|
|
let image = ImageValue::new(
|
|
|
|
"test".to_string(),
|
|
|
|
kanidm_proto::internal::ImageType::Jpg,
|
|
|
|
jpg_file_contents.clone(),
|
|
|
|
);
|
|
|
|
let res = rsclient
|
|
|
|
.idm_oauth2_rs_update_image("test_integration", image)
|
|
|
|
.await;
|
|
|
|
trace!("idm_oauth2_rs_update_image result: {:?}", &res);
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
|
|
|
// check it fails when we upload a jpg and say it's a webp
|
|
|
|
let image = ImageValue::new(
|
|
|
|
"test".to_string(),
|
|
|
|
kanidm_proto::internal::ImageType::Webp,
|
|
|
|
jpg_file_contents,
|
|
|
|
);
|
|
|
|
let res = rsclient
|
|
|
|
.idm_oauth2_rs_update_image("test_integration", image)
|
|
|
|
.await;
|
|
|
|
trace!("idm_oauth2_rs_update_image result: {:?}", &res);
|
|
|
|
assert!(res.is_err());
|
|
|
|
|
|
|
|
// check we can remove an image
|
|
|
|
|
|
|
|
let res = rsclient
|
|
|
|
.idm_oauth2_rs_delete_image("test_integration")
|
|
|
|
.await;
|
|
|
|
trace!("idm_oauth2_rs_delete_image result: {:?}", &res);
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
2022-10-09 09:11:55 +02:00
|
|
|
// Check we can delete a scope map.
|
|
|
|
|
2022-04-29 05:03:21 +02:00
|
|
|
rsclient
|
2023-09-16 04:11:06 +02:00
|
|
|
.idm_oauth2_rs_delete_scope_map("test_integration", BUILTIN_GROUP_SYSTEM_ADMINS_V1.name)
|
2022-04-29 05:03:21 +02:00
|
|
|
.await
|
|
|
|
.expect("Failed to delete scope map");
|
|
|
|
|
2022-10-09 09:11:55 +02:00
|
|
|
let oauth2_config_updated4 = rsclient
|
2022-04-29 05:03:21 +02:00
|
|
|
.idm_oauth2_rs_get("test_integration")
|
|
|
|
.await
|
|
|
|
.ok()
|
|
|
|
.flatten()
|
|
|
|
.expect("Failed to retrieve test_integration config");
|
|
|
|
|
|
|
|
eprintln!("{:?}", oauth2_config_updated);
|
2022-10-09 09:11:55 +02:00
|
|
|
eprintln!("{:?}", oauth2_config_updated4);
|
2022-04-29 05:03:21 +02:00
|
|
|
|
2022-10-09 09:11:55 +02:00
|
|
|
assert!(oauth2_config_updated == oauth2_config_updated4);
|
2022-04-29 05:03:21 +02:00
|
|
|
|
|
|
|
// Delete the config
|
|
|
|
rsclient
|
|
|
|
.idm_oauth2_rs_delete("test_integration")
|
|
|
|
.await
|
|
|
|
.expect("Failed to delete test_integration");
|
|
|
|
|
|
|
|
// List, there are none.
|
|
|
|
let final_configs = rsclient
|
|
|
|
.idm_oauth2_rs_list()
|
|
|
|
.await
|
|
|
|
.expect("Failed to retrieve oauth2 configs");
|
|
|
|
|
|
|
|
assert!(final_configs.is_empty());
|
2021-06-29 06:23:39 +02:00
|
|
|
}
|
|
|
|
|
2022-10-24 01:50:31 +02:00
|
|
|
#[kanidmd_testkit::test]
|
|
|
|
async fn test_server_credential_update_session_pw(rsclient: KanidmClient) {
|
2022-04-29 05:03:21 +02:00
|
|
|
let res = rsclient
|
|
|
|
.auth_simple_password("admin", ADMIN_TEST_PASSWORD)
|
|
|
|
.await;
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
|
|
|
// Not recommended in production!
|
|
|
|
rsclient
|
2023-09-16 04:11:06 +02:00
|
|
|
.idm_group_add_members(BUILTIN_GROUP_IDM_ADMINS_V1.name, &["admin"])
|
2022-04-29 05:03:21 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Create an account
|
|
|
|
rsclient
|
2022-09-02 06:21:20 +02:00
|
|
|
.idm_person_account_create("demo_account", "Demo Account")
|
2022-04-29 05:03:21 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Create an intent token for them
|
|
|
|
let intent_token = rsclient
|
2023-06-24 04:24:13 +02:00
|
|
|
.idm_person_account_credential_update_intent("demo_account", Some(0))
|
2022-04-29 05:03:21 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
2020-10-10 02:31:51 +02:00
|
|
|
|
2022-04-29 05:03:21 +02:00
|
|
|
// Logout, we don't need any auth now.
|
|
|
|
let _ = rsclient.logout();
|
|
|
|
// Exchange the intent token
|
2022-06-05 08:30:08 +02:00
|
|
|
let (session_token, _status) = rsclient
|
2022-04-29 05:03:21 +02:00
|
|
|
.idm_account_credential_update_exchange(intent_token)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
2019-10-31 01:48:15 +01:00
|
|
|
|
2022-04-29 05:03:21 +02:00
|
|
|
let _status = rsclient
|
|
|
|
.idm_account_credential_update_status(&session_token)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
2021-06-25 04:39:05 +02:00
|
|
|
|
2022-04-29 05:03:21 +02:00
|
|
|
// Setup and update the password
|
|
|
|
let _status = rsclient
|
|
|
|
.idm_account_credential_update_set_password(&session_token, "eicieY7ahchaoCh0eeTa")
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Commit it
|
|
|
|
rsclient
|
|
|
|
.idm_account_credential_update_commit(&session_token)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Assert it now works.
|
|
|
|
let _ = rsclient.logout();
|
|
|
|
let res = rsclient
|
|
|
|
.auth_simple_password("demo_account", "eicieY7ahchaoCh0eeTa")
|
|
|
|
.await;
|
|
|
|
assert!(res.is_ok());
|
2023-12-18 00:10:13 +01:00
|
|
|
|
|
|
|
// Get privs
|
|
|
|
let res = rsclient
|
|
|
|
.reauth_simple_password("eicieY7ahchaoCh0eeTa")
|
|
|
|
.await;
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
|
|
|
// Build a self mod.
|
|
|
|
let f = Filter::SelfUuid;
|
|
|
|
let m = ModifyList::new_list(vec![
|
|
|
|
Modify::Purged(Attribute::DisplayName.to_string()),
|
|
|
|
Modify::Present(Attribute::DisplayName.to_string(), "test".to_string()),
|
|
|
|
]);
|
|
|
|
|
|
|
|
let res = rsclient.modify(f, m).await;
|
|
|
|
println!("{:?}", res);
|
|
|
|
assert!(res.is_ok());
|
2022-04-29 05:03:21 +02:00
|
|
|
}
|
2022-05-06 01:52:58 +02:00
|
|
|
|
2022-10-24 01:50:31 +02:00
|
|
|
#[kanidmd_testkit::test]
|
|
|
|
async fn test_server_credential_update_session_totp_pw(rsclient: KanidmClient) {
|
2022-05-06 01:52:58 +02:00
|
|
|
let res = rsclient
|
|
|
|
.auth_simple_password("admin", ADMIN_TEST_PASSWORD)
|
|
|
|
.await;
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
|
|
|
// Not recommended in production!
|
|
|
|
rsclient
|
2023-09-16 04:11:06 +02:00
|
|
|
.idm_group_add_members(BUILTIN_GROUP_IDM_ADMINS_V1.name, &["admin"])
|
2022-05-06 01:52:58 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
2022-09-02 06:21:20 +02:00
|
|
|
// Create a person
|
|
|
|
// - person so they can self-modify credentials later in the test
|
2022-05-06 01:52:58 +02:00
|
|
|
rsclient
|
2022-09-02 06:21:20 +02:00
|
|
|
.idm_person_account_create("demo_account", "Demo Account")
|
2022-05-06 01:52:58 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
let intent_token = rsclient
|
2023-06-24 04:24:13 +02:00
|
|
|
.idm_person_account_credential_update_intent("demo_account", Some(999999))
|
2022-05-06 01:52:58 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Logout, we don't need any auth now, the intent tokens care for it.
|
|
|
|
let _ = rsclient.logout();
|
|
|
|
// Exchange the intent token
|
2022-06-05 08:30:08 +02:00
|
|
|
let (session_token, _statu) = rsclient
|
2022-05-06 01:52:58 +02:00
|
|
|
.idm_account_credential_update_exchange(intent_token)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
let _status = rsclient
|
|
|
|
.idm_account_credential_update_status(&session_token)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Set the password
|
|
|
|
let _status = rsclient
|
|
|
|
.idm_account_credential_update_set_password(&session_token, "sohdi3iuHo6mai7noh0a")
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Set the totp.
|
|
|
|
let status = rsclient
|
|
|
|
.idm_account_credential_update_init_totp(&session_token)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Extract the totp from the status, and set it back
|
|
|
|
let totp: Totp = match status.mfaregstate {
|
2023-01-19 08:14:38 +01:00
|
|
|
CURegState::TotpCheck(totp_secret) => totp_secret.try_into().unwrap(),
|
2022-05-06 01:52:58 +02:00
|
|
|
_ => unreachable!(),
|
|
|
|
};
|
|
|
|
|
|
|
|
let totp_chal = totp
|
|
|
|
.do_totp_duration_from_epoch(
|
|
|
|
&SystemTime::now()
|
|
|
|
.duration_since(SystemTime::UNIX_EPOCH)
|
|
|
|
.unwrap(),
|
|
|
|
)
|
|
|
|
.expect("Failed to do totp?");
|
|
|
|
|
|
|
|
let _status = rsclient
|
2023-01-17 05:14:11 +01:00
|
|
|
.idm_account_credential_update_check_totp(&session_token, totp_chal, "totp")
|
2022-05-06 01:52:58 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Commit it
|
|
|
|
rsclient
|
|
|
|
.idm_account_credential_update_commit(&session_token)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
let totp_chal = totp
|
|
|
|
.do_totp_duration_from_epoch(
|
|
|
|
&SystemTime::now()
|
|
|
|
.duration_since(SystemTime::UNIX_EPOCH)
|
|
|
|
.unwrap(),
|
|
|
|
)
|
|
|
|
.expect("Failed to do totp?");
|
|
|
|
|
|
|
|
// Assert it now works.
|
|
|
|
let _ = rsclient.logout();
|
|
|
|
let res = rsclient
|
|
|
|
.auth_password_totp("demo_account", "sohdi3iuHo6mai7noh0a", totp_chal)
|
|
|
|
.await;
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
2023-03-27 03:38:09 +02:00
|
|
|
// We are now authed as the demo_account, however we need to priv auth to get write
|
|
|
|
// access to self for credential updates.
|
|
|
|
let totp_chal = totp
|
|
|
|
.do_totp_duration_from_epoch(
|
|
|
|
&SystemTime::now()
|
|
|
|
.duration_since(SystemTime::UNIX_EPOCH)
|
|
|
|
.unwrap(),
|
|
|
|
)
|
|
|
|
.expect("Failed to do totp?");
|
|
|
|
|
|
|
|
let res = rsclient
|
|
|
|
.reauth_password_totp("sohdi3iuHo6mai7noh0a", totp_chal)
|
|
|
|
.await;
|
|
|
|
assert!(res.is_ok());
|
2022-05-06 01:52:58 +02:00
|
|
|
|
|
|
|
// Self create the session and remove the totp now.
|
2022-06-05 08:30:08 +02:00
|
|
|
let (session_token, _status) = rsclient
|
2022-05-06 01:52:58 +02:00
|
|
|
.idm_account_credential_update_begin("demo_account")
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
let _status = rsclient
|
2023-01-17 05:14:11 +01:00
|
|
|
.idm_account_credential_update_remove_totp(&session_token, "totp")
|
2022-05-06 01:52:58 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Commit it
|
|
|
|
rsclient
|
|
|
|
.idm_account_credential_update_commit(&session_token)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Assert it now works.
|
|
|
|
let _ = rsclient.logout();
|
|
|
|
let res = rsclient
|
|
|
|
.auth_simple_password("demo_account", "sohdi3iuHo6mai7noh0a")
|
|
|
|
.await;
|
|
|
|
assert!(res.is_ok());
|
|
|
|
}
|
2022-07-30 14:10:24 +02:00
|
|
|
|
2023-03-27 03:38:09 +02:00
|
|
|
async fn setup_demo_account_passkey(rsclient: &KanidmClient) -> WebauthnAuthenticator<SoftPasskey> {
|
2022-07-30 14:10:24 +02:00
|
|
|
let res = rsclient
|
|
|
|
.auth_simple_password("admin", ADMIN_TEST_PASSWORD)
|
|
|
|
.await;
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
|
|
|
// Not recommended in production!
|
|
|
|
rsclient
|
2023-09-16 04:11:06 +02:00
|
|
|
.idm_group_add_members(BUILTIN_GROUP_IDM_ADMINS_V1.name, &["admin"])
|
2022-07-30 14:10:24 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Create an account
|
|
|
|
rsclient
|
2022-09-02 06:21:20 +02:00
|
|
|
.idm_person_account_create("demo_account", "Demo Account")
|
2022-07-30 14:10:24 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Create an intent token for them
|
|
|
|
let intent_token = rsclient
|
2023-06-24 04:24:13 +02:00
|
|
|
.idm_person_account_credential_update_intent("demo_account", Some(1234))
|
2022-07-30 14:10:24 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Logout, we don't need any auth now.
|
|
|
|
let _ = rsclient.logout();
|
|
|
|
// Exchange the intent token
|
|
|
|
let (session_token, _status) = rsclient
|
|
|
|
.idm_account_credential_update_exchange(intent_token)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
let _status = rsclient
|
|
|
|
.idm_account_credential_update_status(&session_token)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Setup and update the passkey
|
2023-08-23 03:17:13 +02:00
|
|
|
let mut wa = WebauthnAuthenticator::new(SoftPasskey::new(true));
|
2022-07-30 14:10:24 +02:00
|
|
|
|
|
|
|
let status = rsclient
|
|
|
|
.idm_account_credential_update_passkey_init(&session_token)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
let passkey_chal = match status.mfaregstate {
|
|
|
|
CURegState::Passkey(c) => Some(c),
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
.expect("Unable to access passkey challenge, invalid state");
|
|
|
|
|
|
|
|
eprintln!("{}", rsclient.get_origin());
|
|
|
|
let passkey_resp = wa
|
|
|
|
.do_registration(rsclient.get_origin().clone(), passkey_chal)
|
|
|
|
.expect("Failed to create soft passkey");
|
|
|
|
|
|
|
|
let label = "Soft Passkey".to_string();
|
|
|
|
|
|
|
|
let status = rsclient
|
|
|
|
.idm_account_credential_update_passkey_finish(&session_token, label, passkey_resp)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
assert!(status.can_commit);
|
|
|
|
assert!(status.passkeys.len() == 1);
|
|
|
|
|
|
|
|
// Commit it
|
|
|
|
rsclient
|
|
|
|
.idm_account_credential_update_commit(&session_token)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Assert it now works.
|
|
|
|
let _ = rsclient.logout();
|
2023-03-27 03:38:09 +02:00
|
|
|
|
|
|
|
wa
|
|
|
|
}
|
|
|
|
|
2023-08-24 01:54:33 +02:00
|
|
|
async fn setup_demo_account_password(
|
|
|
|
rsclient: &KanidmClient,
|
|
|
|
) -> Result<(String, String), ClientError> {
|
|
|
|
let account_name = String::from_str("demo_account").expect("Failed to parse string");
|
|
|
|
|
|
|
|
let account_pass = String::from_str("eicieY7ahchaoCh0eeTa").expect("Failed to parse string");
|
|
|
|
|
|
|
|
rsclient
|
|
|
|
.auth_simple_password("admin", ADMIN_TEST_PASSWORD)
|
|
|
|
.await
|
|
|
|
.expect("Failed to authenticate as admin");
|
|
|
|
|
|
|
|
rsclient
|
|
|
|
.idm_person_account_create("demo_account", "Deeeeemo")
|
|
|
|
.await
|
|
|
|
.expect("Failed to create demo account");
|
|
|
|
|
|
|
|
// First, show there are no auth sessions.
|
|
|
|
let sessions = rsclient
|
|
|
|
.idm_account_list_user_auth_token("demo_account")
|
|
|
|
.await
|
|
|
|
.expect("Failed to list user auth tokens");
|
|
|
|
assert!(sessions.is_empty());
|
|
|
|
|
|
|
|
// Setup the credentials for the account
|
|
|
|
// Create an intent token for them
|
|
|
|
let intent_token = rsclient
|
|
|
|
.idm_person_account_credential_update_intent("demo_account", None)
|
|
|
|
.await
|
|
|
|
.expect("Failed to create intent token");
|
|
|
|
|
|
|
|
// Logout, we don't need any auth now.
|
|
|
|
rsclient.logout().await.expect("Failed to logout");
|
|
|
|
|
|
|
|
// Exchange the intent token
|
|
|
|
let (session_token, _status) = rsclient
|
|
|
|
.idm_account_credential_update_exchange(intent_token)
|
|
|
|
.await
|
|
|
|
.expect("Failed to exchange intent token");
|
|
|
|
|
|
|
|
// Setup and update the password
|
|
|
|
rsclient
|
|
|
|
.idm_account_credential_update_set_password(&session_token, account_pass.as_str())
|
|
|
|
.await
|
|
|
|
.expect("Failed to set password");
|
|
|
|
|
|
|
|
// Commit it
|
|
|
|
rsclient
|
|
|
|
.idm_account_credential_update_commit(&session_token)
|
|
|
|
.await
|
|
|
|
.expect("Failed to commit changes");
|
|
|
|
|
|
|
|
Ok((account_name, account_pass))
|
|
|
|
}
|
|
|
|
|
2023-03-27 03:38:09 +02:00
|
|
|
#[kanidmd_testkit::test]
|
|
|
|
async fn test_server_credential_update_session_passkey(rsclient: KanidmClient) {
|
|
|
|
let mut wa = setup_demo_account_passkey(&rsclient).await;
|
|
|
|
|
2022-07-30 14:10:24 +02:00
|
|
|
let res = rsclient
|
|
|
|
.auth_passkey_begin("demo_account")
|
|
|
|
.await
|
|
|
|
.expect("Failed to start passkey auth");
|
|
|
|
|
|
|
|
let pkc = wa
|
|
|
|
.do_authentication(rsclient.get_origin().clone(), res)
|
2022-12-18 04:26:20 +01:00
|
|
|
.map(Box::new)
|
2022-07-30 14:10:24 +02:00
|
|
|
.expect("Failed to authentication with soft passkey");
|
|
|
|
|
|
|
|
let res = rsclient.auth_passkey_complete(pkc).await;
|
|
|
|
assert!(res.is_ok());
|
|
|
|
}
|
2022-09-25 03:21:30 +02:00
|
|
|
|
2022-10-24 01:50:31 +02:00
|
|
|
#[kanidmd_testkit::test]
|
|
|
|
async fn test_server_api_token_lifecycle(rsclient: KanidmClient) {
|
2022-09-25 03:21:30 +02:00
|
|
|
let res = rsclient
|
2023-10-11 07:44:29 +02:00
|
|
|
.auth_simple_password(ADMIN_TEST_USER, ADMIN_TEST_PASSWORD)
|
2022-09-25 03:21:30 +02:00
|
|
|
.await;
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
2023-10-11 07:44:29 +02:00
|
|
|
let test_service_account_username = "test_service";
|
|
|
|
|
2022-09-25 03:21:30 +02:00
|
|
|
rsclient
|
2023-12-18 00:10:13 +01:00
|
|
|
.idm_service_account_create(
|
|
|
|
test_service_account_username,
|
|
|
|
"Test Service",
|
|
|
|
BUILTIN_GROUP_IDM_ADMINS_V1.name,
|
|
|
|
)
|
2022-09-25 03:21:30 +02:00
|
|
|
.await
|
|
|
|
.expect("Failed to create service account");
|
|
|
|
|
|
|
|
let tokens = rsclient
|
2023-10-11 07:44:29 +02:00
|
|
|
.idm_service_account_list_api_token(test_service_account_username)
|
2022-09-25 03:21:30 +02:00
|
|
|
.await
|
|
|
|
.expect("Failed to list service account api tokens");
|
|
|
|
assert!(tokens.is_empty());
|
|
|
|
|
|
|
|
let token = rsclient
|
2023-10-11 07:44:29 +02:00
|
|
|
.idm_service_account_generate_api_token(
|
|
|
|
test_service_account_username,
|
|
|
|
"test token",
|
|
|
|
None,
|
|
|
|
false,
|
|
|
|
)
|
2022-09-25 03:21:30 +02:00
|
|
|
.await
|
|
|
|
.expect("Failed to create service account api token");
|
|
|
|
|
|
|
|
// Decode it?
|
2023-11-24 03:53:22 +01:00
|
|
|
let token_unverified = JwsCompact::from_str(&token).expect("Failed to parse apitoken");
|
2022-09-25 03:21:30 +02:00
|
|
|
|
2023-11-24 03:53:22 +01:00
|
|
|
let jws_verifier = JwsEs256Verifier::try_from(
|
|
|
|
token_unverified
|
|
|
|
.get_jwk_pubkey()
|
|
|
|
.expect("No pubkey in token"),
|
|
|
|
)
|
|
|
|
.expect("Unable to build verifier");
|
|
|
|
|
|
|
|
let token = jws_verifier
|
|
|
|
.verify(&token_unverified)
|
|
|
|
.map(|j| j.from_json::<ApiToken>().expect("invalid token json"))
|
|
|
|
.expect("Failed to verify token");
|
2022-09-25 03:21:30 +02:00
|
|
|
|
|
|
|
let tokens = rsclient
|
2023-10-11 07:44:29 +02:00
|
|
|
.idm_service_account_list_api_token(test_service_account_username)
|
2022-09-25 03:21:30 +02:00
|
|
|
.await
|
|
|
|
.expect("Failed to list service account api tokens");
|
|
|
|
|
|
|
|
assert!(tokens == vec![token.clone()]);
|
|
|
|
|
|
|
|
rsclient
|
|
|
|
.idm_service_account_destroy_api_token(&token.account_id.to_string(), token.token_id)
|
|
|
|
.await
|
|
|
|
.expect("Failed to destroy service account api token");
|
|
|
|
|
|
|
|
let tokens = rsclient
|
2023-10-11 07:44:29 +02:00
|
|
|
.idm_service_account_list_api_token(test_service_account_username)
|
2022-09-25 03:21:30 +02:00
|
|
|
.await
|
|
|
|
.expect("Failed to list service account api tokens");
|
|
|
|
assert!(tokens.is_empty());
|
|
|
|
|
2023-10-11 07:44:29 +02:00
|
|
|
// test we can add an attribute
|
|
|
|
assert!(rsclient
|
|
|
|
.idm_service_account_add_attr(
|
|
|
|
test_service_account_username,
|
|
|
|
Attribute::Mail.as_ref(),
|
|
|
|
&vec!["test@example.com"]
|
|
|
|
)
|
|
|
|
.await
|
|
|
|
.is_ok());
|
|
|
|
|
|
|
|
// test we can overwrite an attribute
|
|
|
|
let new_displayname = vec!["testing displayname 1235"];
|
|
|
|
assert!(rsclient
|
|
|
|
.idm_service_account_set_attr(
|
|
|
|
test_service_account_username,
|
|
|
|
Attribute::DisplayName.as_ref(),
|
|
|
|
&new_displayname
|
|
|
|
)
|
|
|
|
.await
|
|
|
|
.is_ok());
|
|
|
|
// check it actually set
|
|
|
|
let displayname = rsclient
|
|
|
|
.idm_service_account_get_attr(
|
|
|
|
test_service_account_username,
|
|
|
|
Attribute::DisplayName.as_ref(),
|
|
|
|
)
|
|
|
|
.await
|
|
|
|
.expect("Failed to get displayname")
|
|
|
|
.expect("Failed to unwrap displayname");
|
|
|
|
assert!(new_displayname == displayname);
|
|
|
|
|
|
|
|
rsclient
|
|
|
|
.idm_service_account_purge_attr(test_service_account_username, Attribute::Mail.as_ref())
|
|
|
|
.await
|
|
|
|
.expect("Failed to purge displayname");
|
|
|
|
|
|
|
|
assert!(rsclient
|
|
|
|
.idm_service_account_get_attr(test_service_account_username, Attribute::Mail.as_ref(),)
|
|
|
|
.await
|
|
|
|
.expect("Failed to check mail attr")
|
|
|
|
.is_none());
|
|
|
|
|
|
|
|
assert!(rsclient
|
|
|
|
.idm_service_account_unix_extend(
|
|
|
|
test_service_account_username,
|
|
|
|
Some(58008),
|
|
|
|
Some("/bin/vim")
|
|
|
|
)
|
|
|
|
.await
|
|
|
|
.is_ok());
|
|
|
|
|
|
|
|
assert!(rsclient
|
|
|
|
.idm_service_account_unix_extend(
|
|
|
|
test_service_account_username,
|
|
|
|
Some(1000),
|
|
|
|
Some("/bin/vim")
|
|
|
|
)
|
|
|
|
.await
|
|
|
|
.is_err());
|
|
|
|
|
|
|
|
// because you have to set *something*
|
|
|
|
assert!(rsclient
|
2023-12-18 00:10:13 +01:00
|
|
|
.idm_service_account_update(test_service_account_username, None, None, None, None)
|
2023-10-11 07:44:29 +02:00
|
|
|
.await
|
|
|
|
.is_err());
|
2023-10-26 05:40:45 +02:00
|
|
|
|
|
|
|
// updating the service account details
|
2023-10-11 07:44:29 +02:00
|
|
|
assert!(rsclient
|
|
|
|
.idm_service_account_update(
|
|
|
|
test_service_account_username,
|
2023-10-26 05:40:45 +02:00
|
|
|
None,
|
2023-10-11 07:44:29 +02:00
|
|
|
Some(&format!("{}displayzzzz", test_service_account_username)),
|
2023-12-18 00:10:13 +01:00
|
|
|
None,
|
2023-10-11 07:44:29 +02:00
|
|
|
Some(&[format!("{}@example.crabs", test_service_account_username)]),
|
|
|
|
)
|
|
|
|
.await
|
2023-10-26 05:40:45 +02:00
|
|
|
.is_ok());
|
2023-10-13 00:50:36 +02:00
|
|
|
let pw = rsclient
|
|
|
|
.idm_service_account_generate_password(test_service_account_username)
|
|
|
|
.await
|
|
|
|
.expect("Failed to get a pw for the service account");
|
2023-10-11 07:44:29 +02:00
|
|
|
|
|
|
|
assert!(!pw.is_empty());
|
|
|
|
assert!(pw.is_ascii());
|
|
|
|
|
2023-10-13 00:50:36 +02:00
|
|
|
let res = rsclient
|
|
|
|
.idm_service_account_get_credential_status(test_service_account_username)
|
|
|
|
.await;
|
2023-10-11 07:44:29 +02:00
|
|
|
dbg!(&res);
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
|
|
|
println!(
|
|
|
|
"testing deletion of service account {}",
|
|
|
|
test_service_account_username
|
|
|
|
);
|
|
|
|
assert!(rsclient
|
|
|
|
.idm_service_account_delete(test_service_account_username)
|
|
|
|
.await
|
|
|
|
.is_ok());
|
|
|
|
|
|
|
|
// let's create one and just yolo it into a person
|
|
|
|
// TODO: Turns out this doesn't work because admin doesn't have the right perms to remove `jws_es256_private_key` from the account?
|
|
|
|
// rsclient
|
|
|
|
// .idm_service_account_create(test_service_account_username, "Test Service")
|
|
|
|
// .await
|
|
|
|
// .expect("Failed to create service account");
|
|
|
|
|
|
|
|
// rsclient.idm_service_account_into_person(test_service_account_username).await.expect("Failed to convert service account into person");
|
|
|
|
|
|
|
|
// assert!(rsclient
|
|
|
|
// .idm_person_account_delete(test_service_account_username)
|
|
|
|
// .await
|
|
|
|
// .is_ok());
|
2022-09-25 03:21:30 +02:00
|
|
|
}
|
2022-10-17 12:09:47 +02:00
|
|
|
|
2022-10-24 01:50:31 +02:00
|
|
|
#[kanidmd_testkit::test]
|
|
|
|
async fn test_server_user_auth_token_lifecycle(rsclient: KanidmClient) {
|
2022-10-17 12:09:47 +02:00
|
|
|
let res = rsclient
|
2023-10-11 07:44:29 +02:00
|
|
|
.auth_simple_password(ADMIN_TEST_USER, ADMIN_TEST_PASSWORD)
|
2022-10-17 12:09:47 +02:00
|
|
|
.await;
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
|
|
|
rsclient
|
|
|
|
.idm_person_account_create("demo_account", "Deeeeemo")
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// First, show there are no auth sessions.
|
|
|
|
let sessions = rsclient
|
|
|
|
.idm_account_list_user_auth_token("demo_account")
|
|
|
|
.await
|
|
|
|
.expect("Failed to list user auth tokens");
|
|
|
|
assert!(sessions.is_empty());
|
|
|
|
|
|
|
|
// Setup the credentials for the account
|
|
|
|
|
|
|
|
{
|
|
|
|
// Create an intent token for them
|
|
|
|
let intent_token = rsclient
|
2023-06-24 04:24:13 +02:00
|
|
|
.idm_person_account_credential_update_intent("demo_account", None)
|
2022-10-17 12:09:47 +02:00
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Logout, we don't need any auth now.
|
|
|
|
let _ = rsclient.logout();
|
|
|
|
// Exchange the intent token
|
|
|
|
let (session_token, _status) = rsclient
|
|
|
|
.idm_account_credential_update_exchange(intent_token)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Setup and update the password
|
|
|
|
let _status = rsclient
|
|
|
|
.idm_account_credential_update_set_password(&session_token, "eicieY7ahchaoCh0eeTa")
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Commit it
|
|
|
|
rsclient
|
|
|
|
.idm_account_credential_update_commit(&session_token)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Auth as the user.
|
|
|
|
|
|
|
|
let _ = rsclient.logout();
|
|
|
|
let res = rsclient
|
|
|
|
.auth_simple_password("demo_account", "eicieY7ahchaoCh0eeTa")
|
|
|
|
.await;
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
|
|
|
let token = rsclient.get_token().await.expect("No bearer token present");
|
|
|
|
|
2023-11-24 03:53:22 +01:00
|
|
|
let jwt = JwsCompact::from_str(&token).expect("Failed to parse jwt");
|
|
|
|
|
|
|
|
let jws_verifier =
|
|
|
|
JwsEs256Verifier::try_from(jwt.get_jwk_pubkey().expect("No pubkey in token"))
|
|
|
|
.expect("Unable to build verifier");
|
2022-10-17 12:09:47 +02:00
|
|
|
|
2023-11-24 03:53:22 +01:00
|
|
|
let token: UserAuthToken = jws_verifier
|
|
|
|
.verify(&jwt)
|
|
|
|
.map(|jws| jws.from_json::<UserAuthToken>().expect("Invalid json"))
|
|
|
|
.expect("Unable extract uat");
|
2022-10-17 12:09:47 +02:00
|
|
|
|
|
|
|
let sessions = rsclient
|
|
|
|
.idm_account_list_user_auth_token("demo_account")
|
|
|
|
.await
|
|
|
|
.expect("Failed to list user auth tokens");
|
|
|
|
|
|
|
|
assert!(sessions[0].session_id == token.session_id);
|
|
|
|
|
|
|
|
// idm_account_destroy_user_auth_token
|
|
|
|
rsclient
|
|
|
|
.idm_account_destroy_user_auth_token("demo_account", token.session_id)
|
|
|
|
.await
|
|
|
|
.expect("Failed to destroy user auth token");
|
|
|
|
|
2023-09-16 01:22:11 +02:00
|
|
|
// Since the session is revoked, check with the admin.
|
|
|
|
let res = rsclient
|
2023-10-11 07:44:29 +02:00
|
|
|
.auth_simple_password(ADMIN_TEST_USER, ADMIN_TEST_PASSWORD)
|
2023-09-16 01:22:11 +02:00
|
|
|
.await;
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
2022-10-17 12:09:47 +02:00
|
|
|
let tokens = rsclient
|
|
|
|
.idm_service_account_list_api_token("demo_account")
|
|
|
|
.await
|
|
|
|
.expect("Failed to list user auth tokens");
|
|
|
|
assert!(tokens.is_empty());
|
|
|
|
|
|
|
|
// No need to test expiry, that's validated in the server internal tests.
|
2023-10-11 07:44:29 +02:00
|
|
|
|
|
|
|
// testing idm_account_credential_update_cancel_mfareg
|
|
|
|
let (token, _status) = rsclient
|
|
|
|
.idm_account_credential_update_begin("demo_account")
|
|
|
|
.await
|
|
|
|
.expect("Failed to get token for demo_account");
|
|
|
|
|
|
|
|
println!("trying to cancel the token we just got");
|
|
|
|
assert!(rsclient
|
|
|
|
.idm_account_credential_update_cancel_mfareg(&token)
|
|
|
|
.await
|
|
|
|
.is_ok());
|
2022-10-17 12:09:47 +02:00
|
|
|
}
|
2023-03-27 03:38:09 +02:00
|
|
|
|
|
|
|
#[kanidmd_testkit::test]
|
|
|
|
async fn test_server_user_auth_reauthentication(rsclient: KanidmClient) {
|
|
|
|
let mut wa = setup_demo_account_passkey(&rsclient).await;
|
|
|
|
|
|
|
|
let res = rsclient
|
|
|
|
.auth_passkey_begin("demo_account")
|
|
|
|
.await
|
|
|
|
.expect("Failed to start passkey auth");
|
|
|
|
|
|
|
|
let pkc = wa
|
|
|
|
.do_authentication(rsclient.get_origin().clone(), res)
|
|
|
|
.map(Box::new)
|
|
|
|
.expect("Failed to authentication with soft passkey");
|
|
|
|
|
|
|
|
let res = rsclient.auth_passkey_complete(pkc).await;
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
|
|
|
// Assert we are still readonly
|
|
|
|
let token = rsclient
|
|
|
|
.get_token()
|
|
|
|
.await
|
|
|
|
.expect("Must have a bearer token");
|
|
|
|
|
2023-11-24 03:53:22 +01:00
|
|
|
let jwt = JwsCompact::from_str(&token).expect("Failed to parse jwt");
|
|
|
|
|
|
|
|
let jws_verifier =
|
|
|
|
JwsEs256Verifier::try_from(jwt.get_jwk_pubkey().expect("No pubkey in token"))
|
|
|
|
.expect("Unable to build verifier");
|
|
|
|
|
|
|
|
let uat: UserAuthToken = jws_verifier
|
|
|
|
.verify(&jwt)
|
|
|
|
.map(|jws| jws.from_json::<UserAuthToken>().expect("Invalid json"))
|
|
|
|
.expect("Unable extract uat");
|
2023-03-27 03:38:09 +02:00
|
|
|
|
|
|
|
let now = time::OffsetDateTime::now_utc();
|
2023-04-26 13:55:42 +02:00
|
|
|
assert!(!uat.purpose_readwrite_active(now));
|
2023-03-27 03:38:09 +02:00
|
|
|
|
|
|
|
// The auth is done, now we have to setup to re-auth for our session.
|
|
|
|
// Should we bother looking at the internals of the token here to assert
|
|
|
|
// it all worked? I don't think we have to because the server tests have
|
|
|
|
// already checked all those bits.
|
|
|
|
|
|
|
|
let res = rsclient
|
|
|
|
// TODO! Should we actually be able to track what was used here? Or
|
|
|
|
// do we just assume?
|
|
|
|
.reauth_passkey_begin()
|
|
|
|
.await
|
|
|
|
.expect("Failed to start passkey re-authentication");
|
|
|
|
|
|
|
|
let pkc = wa
|
|
|
|
.do_authentication(rsclient.get_origin().clone(), res)
|
|
|
|
.map(Box::new)
|
|
|
|
.expect("Failed to re-authenticate with soft passkey");
|
|
|
|
|
|
|
|
let res = rsclient.reauth_passkey_complete(pkc).await;
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
|
|
|
// assert we are elevated now
|
|
|
|
let token = rsclient
|
|
|
|
.get_token()
|
|
|
|
.await
|
|
|
|
.expect("Must have a bearer token");
|
|
|
|
|
2023-11-24 03:53:22 +01:00
|
|
|
let jwt = JwsCompact::from_str(&token).expect("Failed to parse jwt");
|
|
|
|
|
|
|
|
let jws_verifier =
|
|
|
|
JwsEs256Verifier::try_from(jwt.get_jwk_pubkey().expect("No pubkey in token"))
|
|
|
|
.expect("Unable to build verifier");
|
|
|
|
|
|
|
|
let uat: UserAuthToken = jws_verifier
|
|
|
|
.verify(&jwt)
|
|
|
|
.map(|jws| jws.from_json::<UserAuthToken>().expect("Invalid json"))
|
|
|
|
.expect("Unable extract uat");
|
2023-03-27 03:38:09 +02:00
|
|
|
|
|
|
|
let now = time::OffsetDateTime::now_utc();
|
|
|
|
eprintln!("{:?} {:?}", now, uat.purpose);
|
2023-04-26 13:55:42 +02:00
|
|
|
assert!(uat.purpose_readwrite_active(now));
|
2023-03-27 03:38:09 +02:00
|
|
|
}
|
2023-08-22 03:00:43 +02:00
|
|
|
|
2023-08-24 01:54:33 +02:00
|
|
|
async fn start_password_session(
|
|
|
|
rsclient: &KanidmClient,
|
|
|
|
username: &str,
|
|
|
|
password: &str,
|
|
|
|
privileged: bool,
|
|
|
|
) -> Result<UserAuthToken, ()> {
|
|
|
|
let client = reqwest::Client::new();
|
|
|
|
|
|
|
|
let authreq = AuthRequest {
|
|
|
|
step: AuthStep::Init2 {
|
|
|
|
username: username.to_string(),
|
|
|
|
issue: AuthIssueSession::Token,
|
|
|
|
privileged,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
let authreq = serde_json::to_string(&authreq).expect("Failed to serialize AuthRequest");
|
|
|
|
|
|
|
|
let res = match client
|
|
|
|
.post(rsclient.make_url("/v1/auth"))
|
|
|
|
.header("Content-Type", "application/json")
|
|
|
|
.body(authreq)
|
|
|
|
.send()
|
|
|
|
.await
|
|
|
|
{
|
|
|
|
Ok(value) => value,
|
|
|
|
Err(error) => panic!("Failed to post: {:#?}", error),
|
|
|
|
};
|
|
|
|
assert_eq!(res.status(), 200);
|
|
|
|
|
2023-10-14 04:39:14 +02:00
|
|
|
let session_id = res.headers().get(KSESSIONID).unwrap();
|
2023-08-24 01:54:33 +02:00
|
|
|
|
|
|
|
let authreq = AuthRequest {
|
|
|
|
step: AuthStep::Begin(AuthMech::Password),
|
|
|
|
};
|
|
|
|
let authreq = serde_json::to_string(&authreq).expect("Failed to serialize AuthRequest");
|
|
|
|
|
|
|
|
let res = match client
|
|
|
|
.post(rsclient.make_url("/v1/auth"))
|
|
|
|
.header("Content-Type", "application/json")
|
2023-10-14 04:39:14 +02:00
|
|
|
.header(KSESSIONID, session_id)
|
2023-08-24 01:54:33 +02:00
|
|
|
.body(authreq)
|
|
|
|
.send()
|
|
|
|
.await
|
|
|
|
{
|
|
|
|
Ok(value) => value,
|
|
|
|
Err(error) => panic!("Failed to post: {:#?}", error),
|
|
|
|
};
|
|
|
|
assert_eq!(res.status(), 200);
|
|
|
|
|
|
|
|
let authreq = AuthRequest {
|
|
|
|
step: AuthStep::Cred(AuthCredential::Password(password.to_string())),
|
|
|
|
};
|
|
|
|
let authreq = serde_json::to_string(&authreq).expect("Failed to serialize AuthRequest");
|
|
|
|
|
|
|
|
let res = match client
|
|
|
|
.post(rsclient.make_url("/v1/auth"))
|
|
|
|
.header("Content-Type", "application/json")
|
2023-10-14 04:39:14 +02:00
|
|
|
.header(KSESSIONID, session_id)
|
2023-08-24 01:54:33 +02:00
|
|
|
.body(authreq)
|
|
|
|
.send()
|
|
|
|
.await
|
|
|
|
{
|
|
|
|
Ok(value) => value,
|
|
|
|
Err(error) => panic!("Failed to post: {:#?}", error),
|
|
|
|
};
|
|
|
|
assert_eq!(res.status(), 200);
|
|
|
|
|
|
|
|
let res: AuthResponse = res.json().await.expect("Failed to read JSON response");
|
|
|
|
let jwt = match res.state {
|
|
|
|
AuthState::Success(val) => val,
|
|
|
|
_ => panic!("Failed to extract jwt"),
|
|
|
|
};
|
|
|
|
|
2023-11-24 03:53:22 +01:00
|
|
|
let jwt = JwsCompact::from_str(&jwt).expect("Failed to parse jwt");
|
|
|
|
|
|
|
|
let jws_verifier =
|
|
|
|
JwsEs256Verifier::try_from(jwt.get_jwk_pubkey().expect("No pubkey in token"))
|
|
|
|
.expect("Unable to build verifier");
|
|
|
|
|
|
|
|
let uat: UserAuthToken = jws_verifier
|
|
|
|
.verify(&jwt)
|
|
|
|
.map(|jws| jws.from_json::<UserAuthToken>().expect("Invalid json"))
|
2023-08-24 01:54:33 +02:00
|
|
|
.expect("Unable extract uat");
|
|
|
|
|
|
|
|
Ok(uat)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[kanidmd_testkit::test]
|
|
|
|
async fn test_server_user_auth_unprivileged(rsclient: KanidmClient) {
|
|
|
|
let (account_name, account_pass) = setup_demo_account_password(&rsclient)
|
|
|
|
.await
|
|
|
|
.expect("Failed to setup demo_account");
|
|
|
|
|
|
|
|
let uat = start_password_session(
|
|
|
|
&rsclient,
|
|
|
|
account_name.as_str(),
|
|
|
|
account_pass.as_str(),
|
|
|
|
false,
|
|
|
|
)
|
|
|
|
.await
|
|
|
|
.expect("Failed to start session");
|
|
|
|
|
|
|
|
match uat.purpose {
|
|
|
|
UatPurpose::ReadOnly => panic!("Unexpected uat purpose"),
|
|
|
|
UatPurpose::ReadWrite { expiry } => {
|
|
|
|
assert!(expiry.is_none())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[kanidmd_testkit::test]
|
|
|
|
async fn test_server_user_auth_privileged_shortcut(rsclient: KanidmClient) {
|
|
|
|
let (account_name, account_pass) = setup_demo_account_password(&rsclient)
|
|
|
|
.await
|
|
|
|
.expect("Failed to setup demo_account");
|
|
|
|
|
|
|
|
let uat = start_password_session(
|
|
|
|
&rsclient,
|
|
|
|
account_name.as_str(),
|
|
|
|
account_pass.as_str(),
|
|
|
|
true,
|
|
|
|
)
|
|
|
|
.await
|
|
|
|
.expect("Failed to start session");
|
|
|
|
|
|
|
|
match uat.purpose {
|
|
|
|
UatPurpose::ReadOnly => panic!("Unexpected uat purpose"),
|
|
|
|
UatPurpose::ReadWrite { expiry } => {
|
|
|
|
assert!(expiry.is_some())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-10-11 07:44:29 +02:00
|
|
|
|
|
|
|
// wanna test how long it takes for testkit to start up? here's your biz.
|
|
|
|
// turns out as of 2023-10-11 on my M2 Max, it's about 1.0 seconds per iteration
|
|
|
|
// #[kanidmd_testkit::test]
|
|
|
|
// fn test_teskit_test_test() {
|
|
|
|
// #[allow(unnameable_test_items)]
|
|
|
|
|
|
|
|
// for _ in 0..15 {
|
|
|
|
// #[kanidmd_testkit::test]
|
|
|
|
// #[allow(dead_code)]
|
|
|
|
// async fn test_teskit_test(rsclient: KanidmClient){
|
|
|
|
// assert!(rsclient.auth_anonymous().await.is_ok());
|
|
|
|
// }
|
|
|
|
|
|
|
|
// tk_test_teskit_test();
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|