2019-07-29 09:09:09 +02:00
|
|
|
#![deny(warnings)]
|
|
|
|
|
2020-01-08 11:49:26 +01:00
|
|
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
|
|
|
use std::sync::mpsc;
|
|
|
|
use std::thread;
|
2019-09-09 12:32:49 +02:00
|
|
|
|
2019-09-14 15:44:08 +02:00
|
|
|
use kanidm::config::{Configuration, IntegrationTestConfig};
|
|
|
|
use kanidm::core::create_server_core;
|
2020-01-08 11:49:26 +01:00
|
|
|
use kanidm_client::{KanidmClient, KanidmClientBuilder};
|
2019-10-05 02:40:43 +02:00
|
|
|
use kanidm_proto::v1::{Entry, Filter, Modify, ModifyList};
|
2018-10-03 13:21:21 +02:00
|
|
|
|
2020-01-08 11:49:26 +01:00
|
|
|
use actix::prelude::*;
|
|
|
|
use log::debug;
|
2018-10-03 13:21:21 +02:00
|
|
|
|
2019-07-12 07:28:46 +02:00
|
|
|
static PORT_ALLOC: AtomicUsize = AtomicUsize::new(8080);
|
2020-01-09 11:07:14 +01:00
|
|
|
static ADMIN_TEST_PASSWORD: &str = "integration test admin password";
|
|
|
|
static ADMIN_TEST_PASSWORD_CHANGE: &str = "integration test admin new🎉";
|
2020-02-29 05:02:14 +01:00
|
|
|
static UNIX_TEST_PASSWORD: &str = "unix test user password";
|
2019-07-12 07:28:46 +02:00
|
|
|
|
2018-09-29 09:54:16 +02:00
|
|
|
// Test external behaviorus of the service.
|
|
|
|
|
2019-09-14 15:44:08 +02:00
|
|
|
fn run_test(test_fn: fn(KanidmClient) -> ()) {
|
2020-03-24 23:30:01 +01:00
|
|
|
// ::std::env::set_var("RUST_LOG", "actix_web=debug,kanidm=debug");
|
2019-07-12 07:28:46 +02:00
|
|
|
let _ = env_logger::builder().is_test(true).try_init();
|
|
|
|
let (tx, rx) = mpsc::channel();
|
|
|
|
let port = PORT_ALLOC.fetch_add(1, Ordering::SeqCst);
|
2019-09-04 03:06:37 +02:00
|
|
|
|
|
|
|
let int_config = Box::new(IntegrationTestConfig {
|
|
|
|
admin_password: ADMIN_TEST_PASSWORD.to_string(),
|
|
|
|
});
|
|
|
|
|
2019-07-12 07:28:46 +02:00
|
|
|
let mut config = Configuration::new();
|
|
|
|
config.address = format!("127.0.0.1:{}", port);
|
2019-09-04 03:06:37 +02:00
|
|
|
config.secure_cookies = false;
|
|
|
|
config.integration_test_config = Some(int_config);
|
2019-07-12 07:28:46 +02:00
|
|
|
// Setup the config ...
|
|
|
|
|
|
|
|
thread::spawn(move || {
|
|
|
|
// Spawn a thread for the test runner, this should have a unique
|
|
|
|
// port....
|
|
|
|
System::run(move || {
|
|
|
|
create_server_core(config);
|
|
|
|
|
|
|
|
// This appears to be bind random ...
|
|
|
|
// let srv = srv.bind("127.0.0.1:0").unwrap();
|
|
|
|
let _ = tx.send(System::current());
|
2020-03-07 01:49:39 +01:00
|
|
|
})
|
|
|
|
.expect("unable to start system");
|
2019-07-12 07:28:46 +02:00
|
|
|
});
|
|
|
|
let sys = rx.recv().unwrap();
|
|
|
|
System::set_current(sys.clone());
|
2018-11-26 07:13:22 +01:00
|
|
|
|
2019-07-12 07:28:46 +02:00
|
|
|
// Do we need any fixtures?
|
|
|
|
// Yes probably, but they'll need to be futures as well ...
|
|
|
|
// later we could accept fixture as it's own future for re-use
|
2018-09-29 09:54:16 +02:00
|
|
|
|
2019-07-12 07:28:46 +02:00
|
|
|
// Setup the client, and the address we selected.
|
|
|
|
let addr = format!("http://127.0.0.1:{}", port);
|
2019-11-19 02:50:37 +01:00
|
|
|
let rsclient = KanidmClientBuilder::new()
|
|
|
|
.address(addr)
|
|
|
|
.build()
|
|
|
|
.expect("Failed to build client");
|
2018-11-26 07:13:22 +01:00
|
|
|
|
2019-09-09 12:32:49 +02:00
|
|
|
test_fn(rsclient);
|
2019-07-12 07:28:46 +02:00
|
|
|
|
|
|
|
// We DO NOT need teardown, as sqlite is in mem
|
|
|
|
// let the tables hit the floor
|
2020-01-09 11:07:14 +01:00
|
|
|
sys.stop();
|
2018-09-29 09:54:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2019-09-09 12:32:49 +02:00
|
|
|
fn test_server_create() {
|
2019-09-14 15:44:08 +02:00
|
|
|
run_test(|rsclient: KanidmClient| {
|
2018-11-27 11:48:21 +01:00
|
|
|
let e: Entry = serde_json::from_str(
|
|
|
|
r#"{
|
|
|
|
"attrs": {
|
2019-11-02 02:15:15 +01:00
|
|
|
"class": ["account"],
|
2018-11-27 11:48:21 +01:00
|
|
|
"name": ["testperson"],
|
|
|
|
"displayname": ["testperson"]
|
|
|
|
}
|
|
|
|
}"#,
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
|
2019-09-09 12:32:49 +02:00
|
|
|
// Not logged in - should fail!
|
|
|
|
let res = rsclient.create(vec![e.clone()]);
|
|
|
|
assert!(res.is_err());
|
2018-11-26 07:13:22 +01:00
|
|
|
|
2019-09-09 12:32:49 +02:00
|
|
|
let a_res = rsclient.auth_simple_password("admin", ADMIN_TEST_PASSWORD);
|
|
|
|
assert!(a_res.is_ok());
|
2018-11-26 07:13:22 +01:00
|
|
|
|
2019-09-09 12:32:49 +02:00
|
|
|
let res = rsclient.create(vec![e]);
|
|
|
|
assert!(res.is_ok());
|
2018-11-26 07:13:22 +01:00
|
|
|
});
|
2018-10-03 13:21:21 +02:00
|
|
|
}
|
|
|
|
|
2019-10-05 02:40:43 +02:00
|
|
|
#[test]
|
|
|
|
fn test_server_modify() {
|
|
|
|
run_test(|rsclient: KanidmClient| {
|
|
|
|
// Build a self mod.
|
|
|
|
|
|
|
|
let f = Filter::SelfUUID;
|
|
|
|
let m = ModifyList::new_list(vec![
|
|
|
|
Modify::Purged("displayname".to_string()),
|
|
|
|
Modify::Present("displayname".to_string(), "test".to_string()),
|
|
|
|
]);
|
|
|
|
|
|
|
|
// Not logged in - should fail!
|
|
|
|
let res = rsclient.modify(f.clone(), m.clone());
|
|
|
|
assert!(res.is_err());
|
|
|
|
|
|
|
|
let a_res = rsclient.auth_simple_password("admin", ADMIN_TEST_PASSWORD);
|
|
|
|
assert!(a_res.is_ok());
|
|
|
|
|
2020-01-09 11:07:14 +01:00
|
|
|
let res = rsclient.modify(f, m);
|
2019-10-05 02:40:43 +02:00
|
|
|
println!("{:?}", res);
|
|
|
|
assert!(res.is_ok());
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-07-12 07:28:46 +02:00
|
|
|
#[test]
|
|
|
|
fn test_server_whoami_anonymous() {
|
2019-09-14 15:44:08 +02:00
|
|
|
run_test(|rsclient: KanidmClient| {
|
2019-07-12 07:28:46 +02:00
|
|
|
// First show we are un-authenticated.
|
2019-09-09 12:32:49 +02:00
|
|
|
let pre_res = rsclient.whoami();
|
|
|
|
// This means it was okay whoami, but no uat attached.
|
|
|
|
assert!(pre_res.unwrap().is_none());
|
2019-07-12 07:28:46 +02:00
|
|
|
|
|
|
|
// Now login as anonymous
|
2019-09-09 12:32:49 +02:00
|
|
|
let res = rsclient.auth_anonymous();
|
|
|
|
assert!(res.is_ok());
|
2019-09-04 03:06:37 +02:00
|
|
|
|
|
|
|
// Now do a whoami.
|
2019-09-11 04:21:15 +02:00
|
|
|
let (_e, uat) = match rsclient.whoami().unwrap() {
|
|
|
|
Some((e, uat)) => (e, uat),
|
|
|
|
None => panic!(),
|
|
|
|
};
|
|
|
|
debug!("{}", uat);
|
|
|
|
assert!(uat.name == "anonymous");
|
2019-09-04 03:06:37 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_server_whoami_admin_simple_password() {
|
2019-09-14 15:44:08 +02:00
|
|
|
run_test(|rsclient: KanidmClient| {
|
2019-09-04 03:06:37 +02:00
|
|
|
// First show we are un-authenticated.
|
2019-09-09 12:32:49 +02:00
|
|
|
let pre_res = rsclient.whoami();
|
|
|
|
// This means it was okay whoami, but no uat attached.
|
|
|
|
assert!(pre_res.unwrap().is_none());
|
2019-09-04 03:06:37 +02:00
|
|
|
|
2019-09-09 12:32:49 +02:00
|
|
|
let res = rsclient.auth_simple_password("admin", ADMIN_TEST_PASSWORD);
|
|
|
|
assert!(res.is_ok());
|
2019-07-12 07:28:46 +02:00
|
|
|
|
|
|
|
// Now do a whoami.
|
2019-09-11 04:21:15 +02:00
|
|
|
let (_e, uat) = match rsclient.whoami().unwrap() {
|
|
|
|
Some((e, uat)) => (e, uat),
|
|
|
|
None => panic!(),
|
|
|
|
};
|
|
|
|
debug!("{}", uat);
|
|
|
|
assert!(uat.name == "admin");
|
2019-07-12 07:28:46 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-10-03 13:21:21 +02:00
|
|
|
#[test]
|
2019-09-15 20:05:26 +02:00
|
|
|
fn test_server_search() {
|
|
|
|
run_test(|rsclient: KanidmClient| {
|
|
|
|
// First show we are un-authenticated.
|
|
|
|
let pre_res = rsclient.whoami();
|
|
|
|
// This means it was okay whoami, but no uat attached.
|
|
|
|
assert!(pre_res.unwrap().is_none());
|
2018-11-07 08:27:11 +01:00
|
|
|
|
2019-09-15 20:05:26 +02:00
|
|
|
let res = rsclient.auth_simple_password("admin", ADMIN_TEST_PASSWORD);
|
|
|
|
assert!(res.is_ok());
|
2018-11-07 08:27:11 +01:00
|
|
|
|
2019-09-15 20:05:26 +02:00
|
|
|
let rset = rsclient
|
2019-10-07 00:41:30 +02:00
|
|
|
.search(Filter::Eq("name".to_string(), "admin".to_string()))
|
2019-09-15 20:05:26 +02:00
|
|
|
.unwrap();
|
|
|
|
println!("{:?}", rset);
|
|
|
|
let e = rset.first().unwrap();
|
|
|
|
// Check it's admin.
|
|
|
|
println!("{:?}", e);
|
|
|
|
let name = e.attrs.get("name").unwrap();
|
|
|
|
assert!(name == &vec!["admin".to_string()]);
|
2018-09-29 09:54:16 +02:00
|
|
|
});
|
|
|
|
}
|
2019-09-15 20:05:26 +02:00
|
|
|
|
2019-09-27 01:59:23 +02:00
|
|
|
#[test]
|
|
|
|
fn test_server_admin_change_simple_password() {
|
|
|
|
run_test(|mut rsclient: KanidmClient| {
|
|
|
|
// First show we are un-authenticated.
|
|
|
|
let pre_res = rsclient.whoami();
|
|
|
|
// 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);
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
|
|
|
// Now change the password.
|
2020-01-09 11:07:14 +01:00
|
|
|
rsclient
|
2019-09-27 01:59:23 +02:00
|
|
|
.idm_account_set_password(ADMIN_TEST_PASSWORD_CHANGE.to_string())
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Now "reset" the client.
|
|
|
|
let _ = rsclient.logout();
|
|
|
|
// Old password fails
|
|
|
|
let res = rsclient.auth_simple_password("admin", ADMIN_TEST_PASSWORD);
|
|
|
|
assert!(res.is_err());
|
|
|
|
// New password works!
|
|
|
|
let res = rsclient.auth_simple_password("admin", ADMIN_TEST_PASSWORD_CHANGE);
|
|
|
|
assert!(res.is_ok());
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-10-07 00:41:30 +02:00
|
|
|
// Add a test for reseting another accounts pws via the rest api
|
|
|
|
#[test]
|
|
|
|
fn test_server_admin_reset_simple_password() {
|
|
|
|
run_test(|rsclient: KanidmClient| {
|
|
|
|
let res = rsclient.auth_simple_password("admin", ADMIN_TEST_PASSWORD);
|
|
|
|
assert!(res.is_ok());
|
|
|
|
// Create a diff account
|
|
|
|
let e: Entry = serde_json::from_str(
|
|
|
|
r#"{
|
|
|
|
"attrs": {
|
2019-11-02 02:15:15 +01:00
|
|
|
"class": ["account"],
|
2019-10-07 00:41:30 +02:00
|
|
|
"name": ["testperson"],
|
|
|
|
"displayname": ["testperson"]
|
|
|
|
}
|
|
|
|
}"#,
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Not logged in - should fail!
|
2020-01-09 11:07:14 +01:00
|
|
|
let res = rsclient.create(vec![e]);
|
2019-10-07 00:41:30 +02:00
|
|
|
assert!(res.is_ok());
|
|
|
|
// By default, admin's can't actually administer accounts, so mod them into
|
|
|
|
// the account admin group.
|
2019-11-02 02:15:15 +01:00
|
|
|
let f = Filter::Eq("name".to_string(), "idm_admins".to_string());
|
2019-10-07 00:41:30 +02:00
|
|
|
let m = ModifyList::new_list(vec![Modify::Present(
|
|
|
|
"member".to_string(),
|
2019-11-02 02:15:15 +01:00
|
|
|
"system_admins".to_string(),
|
2019-10-07 00:41:30 +02:00
|
|
|
)]);
|
2020-01-09 11:07:14 +01:00
|
|
|
let res = rsclient.modify(f, m);
|
2019-10-07 00:41:30 +02:00
|
|
|
assert!(res.is_ok());
|
|
|
|
|
2019-12-12 23:49:32 +01:00
|
|
|
// Now set it's password - should be rejected based on low quality
|
2019-10-07 00:41:30 +02:00
|
|
|
let res = rsclient.idm_account_primary_credential_set_password("testperson", "password");
|
2019-12-12 23:49:32 +01:00
|
|
|
assert!(res.is_err());
|
|
|
|
// Set the password to ensure it's good
|
|
|
|
let res = rsclient.idm_account_primary_credential_set_password(
|
|
|
|
"testperson",
|
|
|
|
"tai4eCohtae9aegheo3Uw0oobahVighaig6heeli",
|
|
|
|
);
|
2019-10-07 00:41:30 +02:00
|
|
|
assert!(res.is_ok());
|
|
|
|
// Check it stuck.
|
2019-11-19 02:50:37 +01:00
|
|
|
let tclient = rsclient.new_session().expect("failed to build new session");
|
2019-10-07 00:41:30 +02:00
|
|
|
assert!(tclient
|
2019-12-12 23:49:32 +01:00
|
|
|
.auth_simple_password("testperson", "tai4eCohtae9aegheo3Uw0oobahVighaig6heeli")
|
2019-10-07 00:41:30 +02:00
|
|
|
.is_ok());
|
|
|
|
|
|
|
|
// Generate a pw instead
|
|
|
|
let res = rsclient.idm_account_primary_credential_set_generated("testperson");
|
|
|
|
assert!(res.is_ok());
|
|
|
|
let gpw = res.unwrap();
|
2019-11-19 02:50:37 +01:00
|
|
|
let tclient = rsclient.new_session().expect("failed to build new session");
|
2019-10-07 00:41:30 +02:00
|
|
|
assert!(tclient
|
|
|
|
.auth_simple_password("testperson", gpw.as_str())
|
|
|
|
.is_ok());
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-10-05 02:40:43 +02:00
|
|
|
// test the rest group endpoint.
|
|
|
|
#[test]
|
|
|
|
fn test_server_rest_group_read() {
|
|
|
|
run_test(|rsclient: KanidmClient| {
|
|
|
|
let res = rsclient.auth_simple_password("admin", ADMIN_TEST_PASSWORD);
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
|
|
|
// List the groups
|
|
|
|
let g_list = rsclient.idm_group_list().unwrap();
|
2020-01-09 11:07:14 +01:00
|
|
|
assert!(!g_list.is_empty());
|
2019-10-05 02:40:43 +02:00
|
|
|
|
|
|
|
let g = rsclient.idm_group_get("idm_admins").unwrap();
|
|
|
|
assert!(g.is_some());
|
|
|
|
println!("{:?}", g);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-11-02 02:15:15 +01:00
|
|
|
#[test]
|
|
|
|
fn test_server_rest_group_lifecycle() {
|
|
|
|
run_test(|rsclient: KanidmClient| {
|
|
|
|
let res = rsclient.auth_simple_password("admin", ADMIN_TEST_PASSWORD);
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
|
|
|
// List the groups
|
|
|
|
let g_list = rsclient.idm_group_list().unwrap();
|
2020-01-09 11:07:14 +01:00
|
|
|
assert!(!g_list.is_empty());
|
2019-11-02 02:15:15 +01:00
|
|
|
|
|
|
|
// Create a new group
|
|
|
|
rsclient.idm_group_create("demo_group").unwrap();
|
|
|
|
|
|
|
|
// List again, ensure one more.
|
|
|
|
let g_list_2 = rsclient.idm_group_list().unwrap();
|
|
|
|
assert!(g_list_2.len() > g_list.len());
|
|
|
|
|
|
|
|
// Test modifications to the group
|
|
|
|
|
|
|
|
// Add a member.
|
|
|
|
rsclient
|
|
|
|
.idm_group_add_members("demo_group", vec!["admin"])
|
|
|
|
.unwrap();
|
|
|
|
let members = rsclient.idm_group_get_members("demo_group").unwrap();
|
|
|
|
assert!(members == Some(vec!["admin".to_string()]));
|
|
|
|
|
|
|
|
// Set the list of members
|
|
|
|
rsclient
|
|
|
|
.idm_group_set_members("demo_group", vec!["admin", "demo_group"])
|
|
|
|
.unwrap();
|
|
|
|
let members = rsclient.idm_group_get_members("demo_group").unwrap();
|
|
|
|
assert!(members == Some(vec!["admin".to_string(), "demo_group".to_string()]));
|
|
|
|
|
|
|
|
// Remove a member from the group
|
|
|
|
/*
|
|
|
|
rsclient
|
|
|
|
.idm_group_remove_member("demo_group", "demo_group")
|
|
|
|
.unwrap();
|
|
|
|
let members = rsclient.idm_group_get_members("demo_group").unwrap();
|
|
|
|
assert!(members == vec!["admin".to_string()]);
|
|
|
|
*/
|
|
|
|
|
|
|
|
// purge members
|
|
|
|
rsclient.idm_group_purge_members("demo_group").unwrap();
|
|
|
|
let members = rsclient.idm_group_get_members("demo_group").unwrap();
|
|
|
|
assert!(members == None);
|
|
|
|
|
|
|
|
// Delete the group
|
|
|
|
rsclient.idm_group_delete("demo_group").unwrap();
|
|
|
|
let g_list_3 = rsclient.idm_group_list().unwrap();
|
|
|
|
assert!(g_list_3.len() == g_list.len());
|
|
|
|
|
|
|
|
// Check we can get an exact group
|
|
|
|
let g = rsclient.idm_group_get("idm_admins").unwrap();
|
|
|
|
assert!(g.is_some());
|
|
|
|
println!("{:?}", g);
|
|
|
|
|
|
|
|
// They should have members
|
|
|
|
let members = rsclient.idm_group_get_members("idm_admins").unwrap();
|
|
|
|
println!("{:?}", members);
|
|
|
|
assert!(members == Some(vec!["idm_admin".to_string()]));
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-10-05 02:40:43 +02:00
|
|
|
#[test]
|
|
|
|
fn test_server_rest_account_read() {
|
|
|
|
run_test(|rsclient: KanidmClient| {
|
|
|
|
let res = rsclient.auth_simple_password("admin", ADMIN_TEST_PASSWORD);
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
|
|
|
// List the accounts
|
|
|
|
let a_list = rsclient.idm_account_list().unwrap();
|
2020-01-09 11:07:14 +01:00
|
|
|
assert!(!a_list.is_empty());
|
2019-10-05 02:40:43 +02:00
|
|
|
|
|
|
|
let a = rsclient.idm_account_get("admin").unwrap();
|
|
|
|
assert!(a.is_some());
|
|
|
|
println!("{:?}", a);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_server_rest_schema_read() {
|
|
|
|
run_test(|rsclient: KanidmClient| {
|
|
|
|
let res = rsclient.auth_simple_password("admin", ADMIN_TEST_PASSWORD);
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
|
|
|
// List the schema
|
|
|
|
let s_list = rsclient.idm_schema_list().unwrap();
|
2020-01-09 11:07:14 +01:00
|
|
|
assert!(!s_list.is_empty());
|
2019-10-05 02:40:43 +02:00
|
|
|
|
|
|
|
let a_list = rsclient.idm_schema_attributetype_list().unwrap();
|
2020-01-09 11:07:14 +01:00
|
|
|
assert!(!a_list.is_empty());
|
2019-10-05 02:40:43 +02:00
|
|
|
|
|
|
|
let c_list = rsclient.idm_schema_classtype_list().unwrap();
|
2020-01-09 11:07:14 +01:00
|
|
|
assert!(!c_list.is_empty());
|
2019-10-05 02:40:43 +02:00
|
|
|
|
|
|
|
// Get an attr/class
|
|
|
|
let a = rsclient.idm_schema_attributetype_get("name").unwrap();
|
|
|
|
assert!(a.is_some());
|
|
|
|
println!("{:?}", a);
|
|
|
|
|
|
|
|
let c = rsclient.idm_schema_classtype_get("account").unwrap();
|
|
|
|
assert!(c.is_some());
|
|
|
|
println!("{:?}", c);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-10-31 01:48:15 +01:00
|
|
|
// Test resetting a radius cred, and then checking/viewing it.
|
|
|
|
#[test]
|
|
|
|
fn test_server_radius_credential_lifecycle() {
|
|
|
|
run_test(|rsclient: KanidmClient| {
|
|
|
|
let res = rsclient.auth_simple_password("admin", ADMIN_TEST_PASSWORD);
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
|
|
|
// Should have no radius secret
|
|
|
|
let n_sec = rsclient.idm_account_radius_credential_get("admin").unwrap();
|
|
|
|
assert!(n_sec.is_none());
|
|
|
|
|
|
|
|
// Set one
|
|
|
|
let sec1 = rsclient
|
|
|
|
.idm_account_radius_credential_regenerate("admin")
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Should be able to get it.
|
|
|
|
let r_sec = rsclient.idm_account_radius_credential_get("admin").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("admin").unwrap();
|
|
|
|
assert!(sec1 == r_tok.secret);
|
2020-01-09 11:07:14 +01:00
|
|
|
assert!(r_tok.name == "admin");
|
2019-10-31 01:48:15 +01:00
|
|
|
|
|
|
|
// Reset it
|
|
|
|
let sec2 = rsclient
|
|
|
|
.idm_account_radius_credential_regenerate("admin")
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Should be different
|
|
|
|
println!("s1 {} != s2 {}", sec1, sec2);
|
|
|
|
assert!(sec1 != sec2);
|
|
|
|
|
|
|
|
// Delete it
|
|
|
|
let res = rsclient.idm_account_radius_credential_delete("admin");
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
|
|
|
// No secret
|
|
|
|
let n_sec = rsclient.idm_account_radius_credential_get("admin").unwrap();
|
|
|
|
assert!(n_sec.is_none());
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-11-02 02:15:15 +01:00
|
|
|
#[test]
|
|
|
|
fn test_server_rest_account_lifecycle() {
|
|
|
|
run_test(|rsclient: KanidmClient| {
|
|
|
|
let res = rsclient.auth_simple_password("admin", ADMIN_TEST_PASSWORD);
|
|
|
|
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
|
|
|
|
.idm_group_add_members("idm_account_write_priv", vec!["admin"])
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Create a new account
|
|
|
|
rsclient
|
|
|
|
.idm_account_create("demo_account", "Deeeeemo")
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// View the account
|
|
|
|
rsclient.idm_account_get("demo_account").unwrap();
|
|
|
|
|
|
|
|
// change the name?
|
|
|
|
rsclient
|
|
|
|
.idm_account_set_displayname("demo_account", "Demo Account")
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Delete the account
|
|
|
|
rsclient.idm_account_delete("demo_account").unwrap();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-11-16 05:40:45 +01:00
|
|
|
#[test]
|
|
|
|
fn test_server_rest_sshkey_lifecycle() {
|
|
|
|
run_test(|rsclient: KanidmClient| {
|
|
|
|
let res = rsclient.auth_simple_password("admin", ADMIN_TEST_PASSWORD);
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
|
|
|
// Get the keys, should be empty vec.
|
|
|
|
let sk1 = rsclient.idm_account_get_ssh_pubkeys("admin").unwrap();
|
2020-01-09 11:07:14 +01:00
|
|
|
assert!(sk1.is_empty());
|
2019-11-16 05:40:45 +01:00
|
|
|
|
|
|
|
// 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.idm_account_post_ssh_pubkey("admin", "inv", "invalid key");
|
|
|
|
assert!(r1.is_err());
|
|
|
|
|
|
|
|
// Post a valid key
|
|
|
|
let r2 = rsclient
|
|
|
|
.idm_account_post_ssh_pubkey("admin", "k1", "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAeGW1P6Pc2rPq0XqbRaDKBcXZUPRklo0L1EyR30CwoP william@amethyst");
|
|
|
|
println!("{:?}", r2);
|
|
|
|
assert!(r2.is_ok());
|
|
|
|
|
|
|
|
// Get, should have the key
|
|
|
|
let sk2 = rsclient.idm_account_get_ssh_pubkeys("admin").unwrap();
|
|
|
|
assert!(sk2.len() == 1);
|
|
|
|
|
|
|
|
// Post a valid key
|
|
|
|
let r3 = rsclient
|
|
|
|
.idm_account_post_ssh_pubkey("admin", "k2", "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBx4TpJYQjd0YI5lQIHqblIsCIK5NKVFURYS/eM3o6/Z william@amethyst");
|
|
|
|
assert!(r3.is_ok());
|
|
|
|
|
|
|
|
// Get, should have both keys.
|
|
|
|
let sk3 = rsclient.idm_account_get_ssh_pubkeys("admin").unwrap();
|
|
|
|
assert!(sk3.len() == 2);
|
|
|
|
|
|
|
|
// Delete a key (by tag)
|
|
|
|
let r4 = rsclient.idm_account_delete_ssh_pubkey("admin", "k1");
|
|
|
|
assert!(r4.is_ok());
|
|
|
|
|
|
|
|
// Get, should have remaining key.
|
|
|
|
let sk4 = rsclient.idm_account_get_ssh_pubkeys("admin").unwrap();
|
|
|
|
assert!(sk4.len() == 1);
|
|
|
|
|
|
|
|
// get by tag
|
|
|
|
let skn = rsclient.idm_account_get_ssh_pubkey("admin", "k2");
|
|
|
|
assert!(skn.is_ok());
|
|
|
|
assert!(skn.unwrap() == Some("ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBx4TpJYQjd0YI5lQIHqblIsCIK5NKVFURYS/eM3o6/Z william@amethyst".to_string()));
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-11-29 01:48:22 +01:00
|
|
|
#[test]
|
|
|
|
fn test_server_rest_domain_lifecycle() {
|
|
|
|
run_test(|rsclient: KanidmClient| {
|
|
|
|
let res = rsclient.auth_simple_password("admin", ADMIN_TEST_PASSWORD);
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
|
|
|
let mut dlist = rsclient.idm_domain_list().unwrap();
|
|
|
|
assert!(dlist.len() == 1);
|
|
|
|
|
|
|
|
let dlocal = rsclient.idm_domain_get("domain_local").unwrap();
|
|
|
|
// There should be one, and it's the domain_local
|
|
|
|
assert!(dlist.pop().unwrap().attrs == dlocal.attrs);
|
|
|
|
|
|
|
|
// Change the ssid
|
|
|
|
rsclient
|
|
|
|
.idm_domain_set_ssid("domain_local", "new_ssid")
|
|
|
|
.unwrap();
|
|
|
|
// check get and get the ssid and domain info
|
|
|
|
let nssid = rsclient.idm_domain_get_ssid("domain_local").unwrap();
|
|
|
|
assert!(nssid == "new_ssid");
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-02-13 00:43:01 +01:00
|
|
|
#[test]
|
|
|
|
fn test_server_rest_posix_lifecycle() {
|
|
|
|
run_test(|rsclient: KanidmClient| {
|
|
|
|
let res = rsclient.auth_simple_password("admin", ADMIN_TEST_PASSWORD);
|
|
|
|
assert!(res.is_ok());
|
|
|
|
// Not recommended in production!
|
|
|
|
rsclient
|
|
|
|
.idm_group_add_members("idm_admins", vec!["admin"])
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Create a new account
|
|
|
|
rsclient
|
|
|
|
.idm_account_create("posix_account", "Posix Demo Account")
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Extend the account with posix attrs.
|
|
|
|
rsclient
|
|
|
|
.idm_account_unix_extend("posix_account", None, None)
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Create a group
|
|
|
|
|
|
|
|
// Extend the group with posix attrs
|
|
|
|
rsclient.idm_group_create("posix_group").unwrap();
|
|
|
|
rsclient
|
|
|
|
.idm_group_add_members("posix_group", vec!["posix_account"])
|
|
|
|
.unwrap();
|
|
|
|
rsclient.idm_group_unix_extend("posix_group", None).unwrap();
|
|
|
|
|
|
|
|
// Open a new connection as anonymous
|
|
|
|
let res = rsclient.auth_anonymous();
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
|
|
|
// Get the account by name
|
|
|
|
let r = rsclient
|
|
|
|
.idm_account_unix_token_get("posix_account")
|
|
|
|
.unwrap();
|
|
|
|
// Get the account by gidnumber
|
|
|
|
let r1 = rsclient
|
|
|
|
.idm_account_unix_token_get(r.gidnumber.to_string().as_str())
|
|
|
|
.unwrap();
|
|
|
|
// get the account by spn
|
|
|
|
let r2 = rsclient.idm_account_unix_token_get(r.spn.as_str()).unwrap();
|
|
|
|
// get the account by uuid
|
|
|
|
let r3 = rsclient
|
|
|
|
.idm_account_unix_token_get(r.uuid.as_str())
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
println!("{:?}", r);
|
|
|
|
assert!(r.name == "posix_account");
|
|
|
|
assert!(r1.name == "posix_account");
|
|
|
|
assert!(r2.name == "posix_account");
|
|
|
|
assert!(r3.name == "posix_account");
|
|
|
|
|
|
|
|
// get the group by nam
|
|
|
|
let r = rsclient.idm_group_unix_token_get("posix_group").unwrap();
|
|
|
|
// Get the group by gidnumber
|
|
|
|
let r1 = rsclient
|
|
|
|
.idm_group_unix_token_get(r.gidnumber.to_string().as_str())
|
|
|
|
.unwrap();
|
|
|
|
// get the group spn
|
|
|
|
let r2 = rsclient.idm_group_unix_token_get(r.spn.as_str()).unwrap();
|
|
|
|
// get the group by uuid
|
|
|
|
let r3 = rsclient.idm_group_unix_token_get(r.uuid.as_str()).unwrap();
|
|
|
|
|
|
|
|
println!("{:?}", r);
|
|
|
|
assert!(r.name == "posix_group");
|
|
|
|
assert!(r1.name == "posix_group");
|
|
|
|
assert!(r2.name == "posix_group");
|
|
|
|
assert!(r3.name == "posix_group");
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-02-29 05:02:14 +01:00
|
|
|
#[test]
|
|
|
|
fn test_server_rest_posix_auth_lifecycle() {
|
|
|
|
run_test(|rsclient: KanidmClient| {
|
|
|
|
let res = rsclient.auth_simple_password("admin", ADMIN_TEST_PASSWORD);
|
|
|
|
assert!(res.is_ok());
|
|
|
|
// Get an anon connection
|
|
|
|
let anon_rsclient = rsclient.new_session().unwrap();
|
|
|
|
assert!(anon_rsclient.auth_anonymous().is_ok());
|
|
|
|
|
|
|
|
// Not recommended in production!
|
|
|
|
rsclient
|
|
|
|
.idm_group_add_members("idm_admins", vec!["admin"])
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Setup a unix user
|
|
|
|
rsclient
|
|
|
|
.idm_account_create("posix_account", "Posix Demo Account")
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Extend the account with posix attrs.
|
|
|
|
rsclient
|
|
|
|
.idm_account_unix_extend("posix_account", None, None)
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// add their password (unix self)
|
|
|
|
rsclient
|
|
|
|
.idm_account_unix_cred_put("posix_account", UNIX_TEST_PASSWORD)
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// attempt to verify (good, anon-conn)
|
|
|
|
let r1 = anon_rsclient.idm_account_unix_cred_verify("posix_account", UNIX_TEST_PASSWORD);
|
|
|
|
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");
|
|
|
|
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
|
|
|
|
.idm_account_unix_cred_delete("posix_account")
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// attempt to verify (good pw, should fail, anon-conn)
|
|
|
|
let r3 = anon_rsclient.idm_account_unix_cred_verify("posix_account", UNIX_TEST_PASSWORD);
|
|
|
|
match r3 {
|
|
|
|
Ok(None) => {}
|
|
|
|
_ => assert!(false),
|
|
|
|
};
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-03-24 23:21:49 +01:00
|
|
|
#[test]
|
|
|
|
fn test_server_rest_recycle_lifecycle() {
|
|
|
|
run_test(|rsclient: KanidmClient| {
|
|
|
|
let res = rsclient.auth_simple_password("admin", ADMIN_TEST_PASSWORD);
|
|
|
|
assert!(res.is_ok());
|
|
|
|
|
|
|
|
// Not recommended in production!
|
|
|
|
rsclient
|
|
|
|
.idm_group_add_members("idm_admins", vec!["admin"])
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Setup a unix user
|
|
|
|
rsclient
|
|
|
|
.idm_account_create("recycle_account", "Recycle Demo Account")
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// delete them
|
|
|
|
rsclient.idm_account_delete("recycle_account").unwrap();
|
|
|
|
|
|
|
|
// not there
|
|
|
|
let acc = rsclient.idm_account_get("recycle_account").unwrap();
|
|
|
|
assert!(acc.is_none());
|
|
|
|
|
|
|
|
// list the recycle bin
|
|
|
|
let r_list = rsclient.recycle_bin_list().unwrap();
|
|
|
|
|
|
|
|
assert!(r_list.len() == 1);
|
|
|
|
// get the user in recycle bin
|
|
|
|
let r_user = rsclient.recycle_bin_get("recycle_account").unwrap();
|
|
|
|
assert!(r_user.is_some());
|
|
|
|
|
|
|
|
// revive
|
|
|
|
rsclient.recycle_bin_revive("recycle_account").unwrap();
|
|
|
|
|
|
|
|
// they are there!
|
|
|
|
let acc = rsclient.idm_account_get("recycle_account").unwrap();
|
|
|
|
assert!(acc.is_some());
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-03-26 23:27:07 +01:00
|
|
|
#[test]
|
|
|
|
fn test_server_rest_account_import_password() {
|
|
|
|
run_test(|mut rsclient: KanidmClient| {
|
|
|
|
let res = rsclient.auth_simple_password("admin", ADMIN_TEST_PASSWORD);
|
|
|
|
assert!(res.is_ok());
|
|
|
|
// To enable the admin to actually make some of these changes, we have
|
|
|
|
// to make them a password import admin. NOT recommended in production!
|
|
|
|
rsclient
|
|
|
|
.idm_group_add_members("idm_people_account_password_import_priv", vec!["admin"])
|
|
|
|
.unwrap();
|
|
|
|
rsclient
|
|
|
|
.idm_group_add_members("idm_people_extend_priv", vec!["admin"])
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Create a new account
|
|
|
|
rsclient
|
|
|
|
.idm_account_create("demo_account", "Deeeeemo")
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Make them a person, so we can import the password
|
|
|
|
rsclient.idm_account_person_extend("demo_account").unwrap();
|
|
|
|
|
|
|
|
// Attempt to import a bad password
|
|
|
|
let r = rsclient.idm_account_primary_credential_import_password("demo_account", "password");
|
|
|
|
assert!(r.is_err());
|
|
|
|
|
|
|
|
// Import a good password
|
|
|
|
// eicieY7ahchaoCh0eeTa
|
|
|
|
// pbkdf2_sha256$36000$xIEozuZVAoYm$uW1b35DUKyhvQAf1mBqMvoBDcqSD06juzyO/nmyV0+w=
|
|
|
|
rsclient
|
|
|
|
.idm_account_primary_credential_import_password(
|
|
|
|
"demo_account",
|
|
|
|
"pbkdf2_sha256$36000$xIEozuZVAoYm$uW1b35DUKyhvQAf1mBqMvoBDcqSD06juzyO/nmyV0+w=",
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// Now show we can auth with it
|
|
|
|
// "reset" the client.
|
|
|
|
let _ = rsclient.logout();
|
|
|
|
let res = rsclient.auth_simple_password("demo_account", "eicieY7ahchaoCh0eeTa");
|
|
|
|
assert!(res.is_ok());
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-10-31 01:48:15 +01:00
|
|
|
// Test the self version of the radius path.
|
|
|
|
|
2019-09-15 20:05:26 +02:00
|
|
|
// Test hitting all auth-required endpoints and assert they give unauthorized.
|