use std::sync::Arc;
use gunnar_grpc::{ControlPlane, ServerConfig};
use gunnar_server::control_plane::CoreControlPlane;
use gunnar_server::stores::ServerStores;
use nornir_identity::Relay;
fn person(stores: &ServerStores, id: &str, kind: gunnar_core::PrincipalKind) {
stores
.auth()
.add_principal(gunnar_core::Principal {
id: id.to_owned(),
name: id.to_owned(),
kind,
created: 0,
})
.expect("principal");
}
fn relay() -> Relay {
Relay {
rp_id: "console.example".into(),
origin: "https://console.example".into(),
client: None,
}
}
#[test]
fn an_invite_survives_a_restart_and_goes_with_its_principal() {
let dir = tempfile::tempdir().expect("tempdir");
let secret = {
let stores = Arc::new(ServerStores::open(dir.path()).expect("stores"));
person(&stores, "kim", gunnar_core::PrincipalKind::User);
let control: Arc<dyn ControlPlane> = Arc::new(CoreControlPlane::new(Arc::clone(&stores)));
let identity =
gunnar_server::identity::build(dir.path(), control, &ServerConfig::default(), false);
identity
.enrolment("kim", "boss", None)
.expect("kim's link")
.secret
};
let on_disk = std::fs::read_to_string(dir.path().join(gunnar_server::identity::FILE))
.expect("identity.json");
assert!(!on_disk.contains(&secret), "a secret on disk");
let stores = Arc::new(ServerStores::open(dir.path()).expect("stores, reopened"));
let plane = Arc::new(CoreControlPlane::new(Arc::clone(&stores)));
let control: Arc<dyn ControlPlane> = plane.clone();
let identity =
gunnar_server::identity::build(dir.path(), control, &ServerConfig::default(), false);
let opened = identity
.redeem_start(&secret, "", &relay())
.expect("the link after a restart");
assert_eq!(opened.user_id, "kim");
plane.remove_principal("kim").expect("removed");
assert!(
identity.redeem_start(&secret, "", &relay()).is_err(),
"the link outlived kim"
);
}