2018-10-03 13:21:21 +02:00
|
|
|
extern crate actix;
|
|
|
|
use actix::prelude::*;
|
|
|
|
|
|
|
|
extern crate rsidm;
|
2018-11-26 07:13:22 +01:00
|
|
|
use rsidm::config::Configuration;
|
2019-05-15 02:36:18 +02:00
|
|
|
use rsidm::constants::UUID_ADMIN;
|
2018-11-26 07:13:22 +01:00
|
|
|
use rsidm::core::create_server_core;
|
2019-07-12 07:28:46 +02:00
|
|
|
use rsidm::proto::v1::{
|
|
|
|
AuthCredential, AuthRequest, AuthResponse, AuthState, AuthStep, CreateRequest, Entry,
|
|
|
|
OperationResponse, WhoamiRequest,
|
|
|
|
};
|
2018-10-03 13:21:21 +02:00
|
|
|
|
2018-11-26 07:13:22 +01:00
|
|
|
extern crate reqwest;
|
|
|
|
|
2018-10-03 13:21:21 +02:00
|
|
|
extern crate futures;
|
2019-05-08 02:39:46 +02:00
|
|
|
// use futures::future;
|
|
|
|
// use futures::future::Future;
|
2018-10-03 13:21:21 +02:00
|
|
|
|
2019-07-12 07:28:46 +02:00
|
|
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
2018-11-26 07:13:22 +01:00
|
|
|
use std::sync::mpsc;
|
|
|
|
use std::thread;
|
|
|
|
|
2019-07-12 07:28:46 +02:00
|
|
|
extern crate env_logger;
|
2018-10-03 13:21:21 +02:00
|
|
|
extern crate tokio;
|
|
|
|
|
2019-07-12 07:28:46 +02:00
|
|
|
static PORT_ALLOC: AtomicUsize = AtomicUsize::new(8080);
|
|
|
|
|
2018-09-29 09:54:16 +02:00
|
|
|
// Test external behaviorus of the service.
|
|
|
|
|
2019-07-12 07:28:46 +02:00
|
|
|
fn run_test(test_fn: fn(reqwest::Client, &str) -> ()) {
|
|
|
|
let _ = env_logger::builder().is_test(true).try_init();
|
|
|
|
let (tx, rx) = mpsc::channel();
|
|
|
|
let port = PORT_ALLOC.fetch_add(1, Ordering::SeqCst);
|
|
|
|
let mut config = Configuration::new();
|
|
|
|
config.address = format!("127.0.0.1:{}", port);
|
|
|
|
// 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());
|
|
|
|
});
|
|
|
|
});
|
|
|
|
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 client = reqwest::Client::builder()
|
|
|
|
.cookie_store(true)
|
|
|
|
.build()
|
|
|
|
.expect("Unexpected reqwest builder failure!");
|
|
|
|
let addr = format!("http://127.0.0.1:{}", port);
|
2018-11-26 07:13:22 +01:00
|
|
|
|
2019-07-12 07:28:46 +02:00
|
|
|
test_fn(client, addr.as_str());
|
|
|
|
|
|
|
|
// We DO NOT need teardown, as sqlite is in mem
|
|
|
|
// let the tables hit the floor
|
|
|
|
let _ = sys.stop();
|
2018-09-29 09:54:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2018-11-26 07:13:22 +01:00
|
|
|
fn test_server_proto() {
|
2019-07-12 07:28:46 +02:00
|
|
|
run_test(|client: reqwest::Client, addr: &str| {
|
2018-11-27 11:48:21 +01:00
|
|
|
let e: Entry = serde_json::from_str(
|
|
|
|
r#"{
|
|
|
|
"attrs": {
|
|
|
|
"class": ["person"],
|
|
|
|
"name": ["testperson"],
|
|
|
|
"description": ["testperson"],
|
|
|
|
"displayname": ["testperson"]
|
|
|
|
}
|
|
|
|
}"#,
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
|
2019-05-15 02:36:18 +02:00
|
|
|
let c = CreateRequest {
|
|
|
|
entries: vec![e],
|
|
|
|
user_uuid: UUID_ADMIN.to_string(),
|
|
|
|
};
|
2018-11-26 07:13:22 +01:00
|
|
|
|
2019-07-12 07:28:46 +02:00
|
|
|
let dest = format!("{}/v1/create", addr);
|
|
|
|
|
2018-11-26 07:13:22 +01:00
|
|
|
let mut response = client
|
2019-07-12 07:28:46 +02:00
|
|
|
.post(dest.as_str())
|
2018-11-26 07:13:22 +01:00
|
|
|
.body(serde_json::to_string(&c).unwrap())
|
|
|
|
.send()
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
println!("{:?}", response);
|
2019-03-01 07:15:31 +01:00
|
|
|
let r: OperationResponse = serde_json::from_str(response.text().unwrap().as_str()).unwrap();
|
2018-11-26 07:13:22 +01:00
|
|
|
|
|
|
|
println!("{:?}", r);
|
|
|
|
|
|
|
|
// deserialise the response here
|
|
|
|
// check it's valid.
|
|
|
|
|
|
|
|
()
|
|
|
|
});
|
2018-10-03 13:21:21 +02:00
|
|
|
}
|
|
|
|
|
2019-07-12 07:28:46 +02:00
|
|
|
#[test]
|
|
|
|
fn test_server_whoami_anonymous() {
|
|
|
|
run_test(|client: reqwest::Client, addr: &str| {
|
|
|
|
// First show we are un-authenticated.
|
|
|
|
let whoami_dest = format!("{}/v1/whoami", addr);
|
|
|
|
let auth_dest = format!("{}/v1/auth", addr);
|
|
|
|
|
|
|
|
let response = client.get(whoami_dest.as_str()).send().unwrap();
|
|
|
|
|
|
|
|
// https://docs.rs/reqwest/0.9.15/reqwest/struct.Response.html
|
|
|
|
println!("{:?}", response);
|
|
|
|
|
|
|
|
assert!(response.status() == reqwest::StatusCode::UNAUTHORIZED);
|
|
|
|
|
|
|
|
// Now login as anonymous
|
|
|
|
|
|
|
|
// Setup the auth initialisation
|
|
|
|
let auth_init = AuthRequest {
|
|
|
|
step: AuthStep::Init("anonymous".to_string(), None),
|
|
|
|
};
|
|
|
|
|
|
|
|
let mut response = client
|
|
|
|
.post(auth_dest.as_str())
|
|
|
|
.body(serde_json::to_string(&auth_init).unwrap())
|
|
|
|
.send()
|
|
|
|
.unwrap();
|
|
|
|
assert!(response.status() == reqwest::StatusCode::OK);
|
|
|
|
// Check that we got the next step
|
|
|
|
let r: AuthResponse = serde_json::from_str(response.text().unwrap().as_str()).unwrap();
|
|
|
|
println!("==> AUTHRESPONSE ==> {:?}", r);
|
|
|
|
|
|
|
|
assert!(match &r.state {
|
|
|
|
AuthState::Continue(all_list) => {
|
|
|
|
// Check anonymous is present? It will fail on next step if not ...
|
|
|
|
true
|
|
|
|
}
|
|
|
|
_ => false,
|
|
|
|
});
|
|
|
|
|
|
|
|
// Send the credentials required now
|
|
|
|
let auth_anon = AuthRequest {
|
|
|
|
step: AuthStep::Creds(vec![AuthCredential::Anonymous]),
|
|
|
|
};
|
|
|
|
|
|
|
|
let mut response = client
|
|
|
|
.post(auth_dest.as_str())
|
|
|
|
.body(serde_json::to_string(&auth_anon).unwrap())
|
|
|
|
.send()
|
|
|
|
.unwrap();
|
|
|
|
assert!(response.status() == reqwest::StatusCode::OK);
|
|
|
|
// Check that we got the next step
|
|
|
|
let r: AuthResponse = serde_json::from_str(response.text().unwrap().as_str()).unwrap();
|
|
|
|
println!("==> AUTHRESPONSE ==> {:?}", r);
|
|
|
|
|
|
|
|
assert!(match &r.state {
|
|
|
|
AuthState::Success(uat) => {
|
|
|
|
println!("==> Authed as uat; {:?}", uat);
|
|
|
|
true
|
|
|
|
}
|
|
|
|
_ => false,
|
|
|
|
});
|
|
|
|
|
|
|
|
// Now do a whoami.
|
|
|
|
let mut response = client.get(whoami_dest.as_str()).send().unwrap();
|
|
|
|
println!("WHOAMI -> {}", response.text().unwrap().as_str());
|
|
|
|
println!("WHOAMI STATUS -> {}", response.status());
|
|
|
|
assert!(response.status() == reqwest::StatusCode::OK);
|
|
|
|
|
|
|
|
// Check the json now ... response.json()
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test hitting all auth-required endpoints and assert they give unauthorized.
|
|
|
|
|
2018-10-03 13:21:21 +02:00
|
|
|
/*
|
|
|
|
#[test]
|
|
|
|
fn test_be_create_user() {
|
2018-11-07 08:27:11 +01:00
|
|
|
run_test!(|log, server: actix::Addr<QueryServer>| {
|
|
|
|
let r1 = server.search();
|
|
|
|
assert!(r1.len() == 0);
|
|
|
|
|
|
|
|
let cr = server.create();
|
|
|
|
assert!(cr.is_ok());
|
|
|
|
|
|
|
|
let r2 = server.search();
|
|
|
|
assert!(r2.len() == 1);
|
|
|
|
|
|
|
|
future::ok(())
|
2018-09-29 09:54:16 +02:00
|
|
|
});
|
|
|
|
}
|
2018-10-03 13:21:21 +02:00
|
|
|
*/
|