From 9354c180af86dfed922ad9eb9dc4c0a5c2883bc5 Mon Sep 17 00:00:00 2001 From: Sebastiano Tocci Date: Tue, 23 Apr 2024 02:30:38 +0200 Subject: [PATCH] added profile and `memberof` search to the basic model (#2712) Co-authored-by: Firstyear --- tools/orca/src/generate.rs | 15 ++++++++--- tools/orca/src/model.rs | 40 ++++++++++++++++++++++++++- tools/orca/src/models/basic.rs | 49 +++++++++++++++++++++++++--------- tools/orca/src/populate.rs | 2 +- tools/orca/src/run.rs | 2 ++ 5 files changed, 90 insertions(+), 18 deletions(-) diff --git a/tools/orca/src/generate.rs b/tools/orca/src/generate.rs index 5987a6921..7a14917d1 100644 --- a/tools/orca/src/generate.rs +++ b/tools/orca/src/generate.rs @@ -68,6 +68,16 @@ pub async fn populate(_client: &KanidmOrcaClient, profile: Profile) -> Result Result Result Option<&[&str]> { match self { - ActorRole::None => None, + ActorRole::None + | ActorRole::PeopleSelfReadProfile + | ActorRole::PeopleSelfReadMemberOf => None, ActorRole::PeoplePiiReader => Some(&["idm_people_pii_read"]), ActorRole::PeopleSelfWriteMail => Some(&["idm_people_self_write_mail"]), } @@ -149,6 +155,38 @@ pub async fn logout( )) } +pub async fn person_get_self_account( + client: &KanidmClient, + person: &Person, +) -> Result<(TransitionResult, EventRecord), Error> { + let start = Instant::now(); + let result = client.idm_person_account_get(&person.username).await; + let duration = Instant::now().duration_since(start); + Ok(parse_call_result_into_transition_result_and_event_record( + result, + EventDetail::PersonGetSelfAccount, + start, + duration, + )) +} + +pub async fn person_get_self_memberof( + client: &KanidmClient, + person: &Person, +) -> Result<(TransitionResult, EventRecord), Error> { + let start = Instant::now(); + let result = client + .idm_person_account_get_attr(&person.username, "memberof") + .await; + let duration = Instant::now().duration_since(start); + Ok(parse_call_result_into_transition_result_and_event_record( + result, + EventDetail::PersonGetSelfMemberOf, + start, + duration, + )) +} + fn parse_call_result_into_transition_result_and_event_record( result: Result, details: EventDetail, diff --git a/tools/orca/src/models/basic.rs b/tools/orca/src/models/basic.rs index 318fe0878..baeddeb13 100644 --- a/tools/orca/src/models/basic.rs +++ b/tools/orca/src/models/basic.rs @@ -51,6 +51,12 @@ impl ActorModel for ActorBasic { let values = &[mail.as_str()]; model::person_set_self_mail(client, person, values).await } + TransitionAction::ReadSelfAccount => { + model::person_get_self_account(client, person).await + } + TransitionAction::ReadSelfMemberOf => { + model::person_get_self_memberof(client, person).await + } }?; self.next_state(transition.action, result); @@ -61,28 +67,43 @@ impl ActorModel for ActorBasic { impl ActorBasic { fn next_transition(&mut self, roles: &BTreeSet) -> Transition { + let logout_transition = Transition { + delay: Some(Duration::from_secs(5)), + action: TransitionAction::Logout, + }; match self.state { State::Unauthenticated => Transition { delay: None, action: TransitionAction::Login, }, + // Doing some tests with more people I noticed that if the delay is too low somehow??! the server could start processing the reauth request before + // the auth one, yielding an error, + // TODO!!: understand why that happens State::Authenticated => Transition { - delay: Some(Duration::from_millis(100)), + delay: Some(Duration::from_millis(1000)), action: TransitionAction::PrivilegeReauth, }, - State::AuthenticatedWithReauth => { - if roles.contains(&ActorRole::PeopleSelfWriteMail) { - Transition { + // Since this is the basic model we don't want to get too fancy and do too many things, but since the struct Person + // already comes with a BTreeSet of roles we don't want to change that, so we arbitrarily choose to use just the first role + // (which is always deterministic thanks to the rng seed used to choose the roles) + State::AuthenticatedWithReauth => match roles.first() { + Some(role) => match role { + ActorRole::PeopleSelfWriteMail => Transition { delay: Some(Duration::from_millis(200)), action: TransitionAction::WriteAttributePersonMail, - } - } else { - Transition { - delay: Some(Duration::from_secs(5)), - action: TransitionAction::Logout, - } - } - } + }, + ActorRole::PeopleSelfReadProfile => Transition { + delay: Some(Duration::from_millis(150)), + action: TransitionAction::ReadSelfAccount, + }, + ActorRole::PeopleSelfReadMemberOf => Transition { + delay: Some(Duration::from_millis(330)), + action: TransitionAction::ReadSelfMemberOf, + }, + ActorRole::PeoplePiiReader | ActorRole::None => logout_transition, + }, + None => logout_transition, + }, } } @@ -98,7 +119,9 @@ impl ActorBasic { } ( State::AuthenticatedWithReauth, - TransitionAction::WriteAttributePersonMail, + TransitionAction::WriteAttributePersonMail + | TransitionAction::ReadSelfAccount + | TransitionAction::ReadSelfMemberOf, TransitionResult::Ok, ) => { self.state = State::AuthenticatedWithReauth; diff --git a/tools/orca/src/populate.rs b/tools/orca/src/populate.rs index 594404ca6..9081e720b 100644 --- a/tools/orca/src/populate.rs +++ b/tools/orca/src/populate.rs @@ -40,7 +40,7 @@ async fn preflight_person( if let Some(need_groups) = role.requires_membership_to() { for group_name in need_groups { client - .group_add_members(&group_name, &[person.username.as_str()]) + .group_add_members(group_name, &[person.username.as_str()]) .await?; } } diff --git a/tools/orca/src/run.rs b/tools/orca/src/run.rs index 495a123a2..1bfd7b935 100644 --- a/tools/orca/src/run.rs +++ b/tools/orca/src/run.rs @@ -44,6 +44,8 @@ pub enum EventDetail { Login, Logout, PersonSetSelfMail, + PersonGetSelfAccount, + PersonGetSelfMemberOf, PersonReauth, Error, }