From bd986378df49a0233ed38790d8e90bb79a0a39a4 Mon Sep 17 00:00:00 2001 From: Loup Federico <16464925+Sh099078@users.noreply.github.com> Date: Mon, 20 Jul 2026 20:52:27 +0200 Subject: [PATCH] editoast: authz: refactorize several tests to use TestExtClient API - Add missing authz functions in TestExtClient API. - Use TestExtClient whenever possible in `authz` tests. Signed-off-by: Loup Federico <16464925+Sh099078@users.noreply.github.com> --- editoast/authz/src/v2/group.rs | 90 +++------- editoast/authz/src/v2/infra.rs | 39 +--- editoast/authz/src/v2/roles.rs | 215 +++++++++-------------- editoast/authz/src/v2/rolling_stock.rs | 39 ++-- editoast/authz/src/v2/test_client_ext.rs | 39 ++++ 5 files changed, 162 insertions(+), 260 deletions(-) diff --git a/editoast/authz/src/v2/group.rs b/editoast/authz/src/v2/group.rs index 1e510b54ef5..525de92c58e 100644 --- a/editoast/authz/src/v2/group.rs +++ b/editoast/authz/src/v2/group.rs @@ -106,31 +106,23 @@ mod tests { use crate::Subject; use crate::v2::TestClientExt as _; - use crate::v2::special_authorizers::Authorize; use super::*; #[tokio::test] async fn add_members_idempotent() { let openfga = crate::authz_client!(); - let authorize = Authorize(&openfga); - add_members(Group(1), HashSet::from_iter([User(1), User(2)])) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() + openfga + .add_members(Group(1), HashSet::from_iter([User(1), User(2)])) .await; assert_eq!( openfga.group_members(&Group(1)).await, HashSet::from_iter([User(1), User(2)]) ); - add_members(Group(1), HashSet::from_iter([User(1), User(2)])) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() + openfga + .add_members(Group(1), HashSet::from_iter([User(1), User(2)])) .await; assert_eq!( openfga.group_members(&Group(1)).await, @@ -141,24 +133,17 @@ mod tests { #[tokio::test] async fn add_members_intersecting_calls() { let openfga = crate::authz_client!(); - let authorize = Authorize(&openfga); - add_members(Group(1), HashSet::from_iter([User(1), User(2)])) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() + openfga + .add_members(Group(1), HashSet::from_iter([User(1), User(2)])) .await; assert_eq!( openfga.group_members(&Group(1)).await, HashSet::from_iter([User(1), User(2)]) ); - add_members(Group(1), HashSet::from_iter([User(1), User(3)])) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() + openfga + .add_members(Group(1), HashSet::from_iter([User(1), User(3)])) .await; assert_eq!( openfga.group_members(&Group(1)).await, @@ -169,35 +154,25 @@ mod tests { #[tokio::test] async fn remove_members_idempotent() { let openfga = crate::authz_client!(); - let authorize = Authorize(&openfga); - add_members(Group(1), HashSet::from_iter([User(1), User(2)])) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() + openfga + .add_members(Group(1), HashSet::from_iter([User(1), User(2)])) .await; assert_eq!( openfga.group_members(&Group(1)).await, HashSet::from_iter([User(1), User(2)]) ); - remove_members(Group(1), HashSet::from_iter([User(1), User(2)])) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() + openfga + .remove_members(Group(1), HashSet::from_iter([User(1), User(2)])) .await; assert_eq!( openfga.group_members(&Group(1)).await, HashSet::from_iter([]) ); - remove_members(Group(1), HashSet::from_iter([User(1), User(2)])) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() + openfga + .remove_members(Group(1), HashSet::from_iter([User(1), User(2)])) .await; assert_eq!( openfga.group_members(&Group(1)).await, @@ -208,35 +183,25 @@ mod tests { #[tokio::test] async fn remove_members_intersecting_calls() { let openfga = crate::authz_client!(); - let authorize = Authorize(&openfga); - add_members(Group(1), HashSet::from_iter([User(1), User(2), User(3)])) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() + openfga + .add_members(Group(1), HashSet::from_iter([User(1), User(2), User(3)])) .await; assert_eq!( openfga.group_members(&Group(1)).await, HashSet::from_iter([User(1), User(2), User(3)]) ); - remove_members(Group(1), HashSet::from_iter([User(1), User(2)])) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() + openfga + .remove_members(Group(1), HashSet::from_iter([User(1), User(2)])) .await; assert_eq!( openfga.group_members(&Group(1)).await, HashSet::from_iter([User(3)]) ); - remove_members(Group(1), HashSet::from_iter([User(1), User(3)])) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() + openfga + .remove_members(Group(1), HashSet::from_iter([User(1), User(3)])) .await; assert_eq!( openfga.group_members(&Group(1)).await, @@ -253,19 +218,12 @@ mod tests { #[tokio::test] async fn user_groups_some() { let openfga = crate::authz_client!(); - let authorize = Authorize(&openfga); - add_members(Group(1), HashSet::from_iter([User(1), User(2)])) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() + openfga + .add_members(Group(1), HashSet::from_iter([User(1), User(2)])) .await; - add_members(Group(2), HashSet::from_iter([User(1)])) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() + openfga + .add_members(Group(2), HashSet::from_iter([User(1)])) .await; assert_eq!( diff --git a/editoast/authz/src/v2/infra.rs b/editoast/authz/src/v2/infra.rs index 84409494dc6..eb0f19b815d 100644 --- a/editoast/authz/src/v2/infra.rs +++ b/editoast/authz/src/v2/infra.rs @@ -467,14 +467,10 @@ mod tests { #[tokio::test] async fn user_infra_direct_grant() { let openfga = crate::authz_client!(); - let authorize = Authorize(&openfga); let infra_grant = async |user_id: i64| { - infra_direct_grant(Subject::user(user_id), Infra(1)) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() + openfga + .infra_direct_grant(Subject::user(user_id), Infra(1)) .await }; @@ -497,14 +493,10 @@ mod tests { #[tokio::test] async fn group_infra_direct_grant() { let openfga = crate::authz_client!(); - let authorize = Authorize(&openfga); let infra_grant = async |group_id: i64| { - infra_direct_grant(Subject::group(group_id), Infra(1)) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() + openfga + .infra_direct_grant(Subject::group(group_id), Infra(1)) .await }; @@ -527,7 +519,6 @@ mod tests { #[tokio::test] async fn no_inference_infra_direct_grant() { let openfga = crate::authz_client!(); - let authorize = Authorize(&openfga); openfga .prepare_writes() @@ -543,20 +534,14 @@ mod tests { .unwrap(); let user_direct_grant = async |user_id: i64| { - infra_direct_grant(Subject::user(user_id), Infra(1)) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() + openfga + .infra_direct_grant(Subject::user(user_id), Infra(1)) .await }; let group_direct_grant = async |group_id: i64| { - infra_direct_grant(Subject::group(group_id), Infra(1)) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() + openfga + .infra_direct_grant(Subject::group(group_id), Infra(1)) .await }; @@ -574,7 +559,6 @@ mod tests { #[should_panic] async fn infra_direct_grant_inconsistent_state_panics() { let openfga = crate::authz_client!(); - let authorize = Authorize(&openfga); openfga .prepare_writes() @@ -584,12 +568,7 @@ mod tests { .await .unwrap(); - infra_direct_grant(Subject::user(1), Infra(1)) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() - .await; + openfga.infra_direct_grant(Subject::user(1), Infra(1)).await; } #[rstest::rstest] diff --git a/editoast/authz/src/v2/roles.rs b/editoast/authz/src/v2/roles.rs index 17163232349..e0bd0d5ba56 100644 --- a/editoast/authz/src/v2/roles.rs +++ b/editoast/authz/src/v2/roles.rs @@ -89,39 +89,30 @@ mod tests { use rstest::rstest; use crate::v2::TestClientExt as _; - use crate::v2::add_members; - use crate::v2::special_authorizers::Authorize; use super::*; #[tokio::test] async fn add_roles_idempotent() { let openfga = crate::authz_client!(); - let authorize = Authorize(&openfga); - add_roles( - Subject::user(1), - HashSet::from_iter([Role::Admin, Role::Stdcm]), - ) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() - .await; + openfga + .add_roles( + Subject::user(1), + HashSet::from_iter([Role::Admin, Role::Stdcm]), + ) + .await; assert_eq!( openfga.subject_roles(&Subject::user(1)).await, HashSet::from_iter([Role::Admin, Role::Stdcm]) ); - add_roles( - Subject::user(1), - HashSet::from_iter([Role::Admin, Role::Stdcm]), - ) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() - .await; + openfga + .add_roles( + Subject::user(1), + HashSet::from_iter([Role::Admin, Role::Stdcm]), + ) + .await; assert_eq!( openfga.subject_roles(&Subject::user(1)).await, HashSet::from_iter([Role::Admin, Role::Stdcm]) @@ -131,31 +122,24 @@ mod tests { #[tokio::test] async fn add_roles_intersecting_calls() { let openfga = crate::authz_client!(); - let authorize = Authorize(&openfga); - add_roles( - Subject::user(1), - HashSet::from_iter([Role::Admin, Role::Stdcm]), - ) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() - .await; + openfga + .add_roles( + Subject::user(1), + HashSet::from_iter([Role::Admin, Role::Stdcm]), + ) + .await; assert_eq!( openfga.subject_roles(&Subject::user(1)).await, HashSet::from_iter([Role::Admin, Role::Stdcm]) ); - add_roles( - Subject::user(1), - HashSet::from_iter([Role::Admin, Role::OperationalStudies]), - ) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() - .await; + openfga + .add_roles( + Subject::user(1), + HashSet::from_iter([Role::Admin, Role::OperationalStudies]), + ) + .await; assert_eq!( openfga.subject_roles(&Subject::user(1)).await, HashSet::from_iter([Role::Admin, Role::Stdcm, Role::OperationalStudies]) @@ -165,45 +149,35 @@ mod tests { #[tokio::test] async fn remove_roles_idempotent() { let openfga = crate::authz_client!(); - let authorize = Authorize(&openfga); - add_roles( - Subject::user(1), - HashSet::from_iter([Role::Admin, Role::Stdcm]), - ) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() - .await; + openfga + .add_roles( + Subject::user(1), + HashSet::from_iter([Role::Admin, Role::Stdcm]), + ) + .await; assert_eq!( openfga.subject_roles(&Subject::user(1)).await, HashSet::from_iter([Role::Admin, Role::Stdcm]) ); - remove_roles( - Subject::user(1), - HashSet::from_iter([Role::Admin, Role::Stdcm]), - ) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() - .await; + openfga + .remove_roles( + Subject::user(1), + HashSet::from_iter([Role::Admin, Role::Stdcm]), + ) + .await; assert_eq!( openfga.subject_roles(&Subject::user(1)).await, HashSet::from_iter([]) ); - remove_roles( - Subject::user(1), - HashSet::from_iter([Role::Admin, Role::Stdcm]), - ) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() - .await; + openfga + .remove_roles( + Subject::user(1), + HashSet::from_iter([Role::Admin, Role::Stdcm]), + ) + .await; assert_eq!( openfga.subject_roles(&Subject::user(1)).await, HashSet::from_iter([]) @@ -213,45 +187,35 @@ mod tests { #[tokio::test] async fn remove_roles_intersecting_calls() { let openfga = crate::authz_client!(); - let authorize = Authorize(&openfga); - add_roles( - Subject::user(1), - HashSet::from_iter([Role::Admin, Role::Stdcm, Role::OperationalStudies]), - ) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() - .await; + openfga + .add_roles( + Subject::user(1), + HashSet::from_iter([Role::Admin, Role::Stdcm, Role::OperationalStudies]), + ) + .await; assert_eq!( openfga.subject_roles(&Subject::user(1)).await, HashSet::from_iter([Role::Admin, Role::Stdcm, Role::OperationalStudies]) ); - remove_roles( - Subject::user(1), - HashSet::from_iter([Role::Admin, Role::Stdcm]), - ) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() - .await; + openfga + .remove_roles( + Subject::user(1), + HashSet::from_iter([Role::Admin, Role::Stdcm]), + ) + .await; assert_eq!( openfga.subject_roles(&Subject::user(1)).await, HashSet::from_iter([Role::OperationalStudies]) ); - remove_roles( - Subject::user(1), - HashSet::from_iter([Role::Admin, Role::OperationalStudies]), - ) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() - .await; + openfga + .remove_roles( + Subject::user(1), + HashSet::from_iter([Role::Admin, Role::OperationalStudies]), + ) + .await; assert_eq!( openfga.subject_roles(&Subject::user(1)).await, HashSet::from_iter([]) @@ -261,28 +225,18 @@ mod tests { #[tokio::test] async fn inherited_roles_from_group() { let openfga = crate::authz_client!(); - let authorize = Authorize(&openfga); // 1: Admin // 2: nothing // 10: Stdcm w/ 1 & 2 - add_roles(Subject::user(1), HashSet::from_iter([Role::Admin])) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() + openfga + .add_roles(Subject::user(1), HashSet::from_iter([Role::Admin])) .await; - add_roles(Subject::group(10), HashSet::from_iter([Role::Stdcm])) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() + openfga + .add_roles(Subject::group(10), HashSet::from_iter([Role::Stdcm])) .await; - add_members(Group(10), HashSet::from_iter([User(1), User(2)])) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() + openfga + .add_members(Group(10), HashSet::from_iter([User(1), User(2)])) .await; assert_eq!( @@ -299,20 +253,14 @@ mod tests { ); // 11: OperationalStudies w/ 2 - add_roles( - Subject::group(11), - HashSet::from_iter([Role::OperationalStudies]), - ) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() - .await; - add_members(Group(11), HashSet::from_iter([User(2)])) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() + openfga + .add_roles( + Subject::group(11), + HashSet::from_iter([Role::OperationalStudies]), + ) + .await; + openfga + .add_members(Group(11), HashSet::from_iter([User(2)])) .await; assert_eq!( @@ -333,15 +281,12 @@ mod tests { ); // 11: nothing w/ 2 - remove_roles( - Subject::group(11), - HashSet::from_iter([Role::OperationalStudies]), - ) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() - .await; + openfga + .remove_roles( + Subject::group(11), + HashSet::from_iter([Role::OperationalStudies]), + ) + .await; assert_eq!( openfga.subject_roles(&Subject::group(10)).await, diff --git a/editoast/authz/src/v2/rolling_stock.rs b/editoast/authz/src/v2/rolling_stock.rs index e5ecd0f7650..348f55a07d0 100644 --- a/editoast/authz/src/v2/rolling_stock.rs +++ b/editoast/authz/src/v2/rolling_stock.rs @@ -482,14 +482,10 @@ mod tests { #[tokio::test] async fn user_rolling_stock_direct_grant() { let openfga = crate::authz_client!(); - let authorize = Authorize(&openfga); let rolling_stock_grant = async |user_id: i64| { - rolling_stock_direct_grant(Subject::user(user_id), RollingStock(1)) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() + openfga + .rolling_stock_direct_grant(Subject::user(user_id), RollingStock(1)) .await }; @@ -518,14 +514,10 @@ mod tests { #[tokio::test] async fn group_rolling_stock_direct_grant() { let openfga = crate::authz_client!(); - let authorize = Authorize(&openfga); let rolling_stock_grant = async |group_id: i64| { - rolling_stock_direct_grant(Subject::group(group_id), RollingStock(1)) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() + openfga + .rolling_stock_direct_grant(Subject::group(group_id), RollingStock(1)) .await }; @@ -560,7 +552,6 @@ mod tests { #[tokio::test] async fn no_inference_rolling_stock_direct_grant() { let openfga = crate::authz_client!(); - let authorize = Authorize(&openfga); openfga .prepare_writes() @@ -580,19 +571,13 @@ mod tests { .unwrap(); let user_direct_grant = async |user_id: i64| { - rolling_stock_direct_grant(Subject::user(user_id), RollingStock(1)) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() + openfga + .rolling_stock_direct_grant(Subject::user(user_id), RollingStock(1)) .await }; let group_direct_grant = async |group_id: i64| { - rolling_stock_direct_grant(Subject::group(group_id), RollingStock(1)) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() + openfga + .rolling_stock_direct_grant(Subject::group(group_id), RollingStock(1)) .await }; @@ -610,7 +595,6 @@ mod tests { #[should_panic] async fn rolling_stock_direct_grant_inconsistent_state_panics() { let openfga = crate::authz_client!(); - let authorize = Authorize(&openfga); openfga .prepare_writes() @@ -620,11 +604,8 @@ mod tests { .await .unwrap(); - rolling_stock_direct_grant(Subject::user(1), RollingStock(1)) - .authorize(&authorize) - .await - .unwrap() - .unwrap_authorized() + openfga + .rolling_stock_direct_grant(Subject::user(1), RollingStock(1)) .await; } diff --git a/editoast/authz/src/v2/test_client_ext.rs b/editoast/authz/src/v2/test_client_ext.rs index 8ca91d76b54..f2ea8e38a27 100644 --- a/editoast/authz/src/v2/test_client_ext.rs +++ b/editoast/authz/src/v2/test_client_ext.rs @@ -14,12 +14,16 @@ use crate::Subject; use crate::User; use crate::model::RollingStockPrivilege; use crate::v2::ResourcesList; +use crate::v2::add_members; +use crate::v2::add_roles; use crate::v2::infra_direct_grant; use crate::v2::infra_effective_grant; use crate::v2::infra_granted_subjects; use crate::v2::infra_privileges; use crate::v2::infra_revoke_grant; use crate::v2::infra_set_grant; +use crate::v2::remove_members; +use crate::v2::remove_roles; use crate::v2::rolling_stock_direct_grant; use crate::v2::rolling_stock_effective_grant; use crate::v2::rolling_stock_granted_subjects; @@ -30,8 +34,12 @@ use crate::v2::user_groups; pub trait TestClientExt { async fn subject_roles(&self, subject: &Subject) -> HashSet; + async fn add_roles(&self, subject: Subject, roles: HashSet); + async fn remove_roles(&self, subject: Subject, roles: HashSet); async fn group_members(&self, group: &Group) -> HashSet; async fn user_groups(&self, user: User) -> HashSet; + async fn add_members(&self, group: Group, members: HashSet); + async fn remove_members(&self, group: Group, members: HashSet); async fn infra_effective_grant(&self, subject: Subject, infra: Infra) -> Option; async fn infra_direct_grant( @@ -88,6 +96,21 @@ impl TestClientExt for fga::Client { .into_iter() .collect() } + async fn add_roles(&self, subject: Subject, roles: HashSet) { + let authorize = special_authorizers::Authorize(self); + authorize + .access_value(add_roles(subject, roles)) + .await + .unwrap() + } + + async fn remove_roles(&self, subject: Subject, roles: HashSet) { + let authorize = special_authorizers::Authorize(self); + authorize + .access_value(remove_roles(subject, roles)) + .await + .unwrap() + } async fn group_members(&self, group: &Group) -> HashSet { self.list_users(Group::member().query_users(group)) @@ -108,6 +131,22 @@ impl TestClientExt for fga::Client { .collect() } + async fn add_members(&self, group: Group, members: HashSet) { + let authorize = special_authorizers::Authorize(self); + authorize + .access_value(add_members(group, members)) + .await + .unwrap() + } + + async fn remove_members(&self, group: Group, members: HashSet) { + let authorize = special_authorizers::Authorize(self); + authorize + .access_value(remove_members(group, members)) + .await + .unwrap() + } + async fn infra_effective_grant(&self, subject: Subject, infra: Infra) -> Option { let authorize = special_authorizers::Authorize(self); authorize