From 76a10671d818fd769754aa805b315ed60e50b565 Mon Sep 17 00:00:00 2001 From: Marc Date: Thu, 12 Dec 2024 16:53:31 +0100 Subject: [PATCH 1/2] fix: Validate search scope when scheduled event [DHIS2-17335][2.39] --- ...eCheckSecurityOwnershipValidationHook.java | 9 ++++- .../EventSecurityImportValidationTest.java | 38 +++++++++++++++++-- .../events-scheduled-with-registration.json | 29 ++++++++++++++ 3 files changed, 71 insertions(+), 5 deletions(-) create mode 100644 dhis-2/dhis-test-integration/src/test/resources/tracker/validations/events-scheduled-with-registration.json diff --git a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/validation/hooks/PreCheckSecurityOwnershipValidationHook.java b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/validation/hooks/PreCheckSecurityOwnershipValidationHook.java index c5326fe88325..40e75f76375f 100644 --- a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/validation/hooks/PreCheckSecurityOwnershipValidationHook.java +++ b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/validation/hooks/PreCheckSecurityOwnershipValidationHook.java @@ -317,7 +317,14 @@ public void validateEvent(ValidationErrorReporter reporter, TrackerBundle bundle if (organisationUnit == null) { log.warn("ProgramStageInstance " + event.getEvent() + ORG_UNIT_NO_USER_ASSIGNED); } else { - checkOrgUnitInCaptureScope(reporter, bundle, event, organisationUnit); + checkEventOrgUnitWriteAccess( + reporter, + event, + organisationUnit, + strategy.isCreate() + ? event.isCreatableInSearchScope() + : bundle.getPreheat().getEvent(event.getUid()).isCreatableInSearchScope(), + bundle.getUser()); } } diff --git a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/validation/EventSecurityImportValidationTest.java b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/validation/EventSecurityImportValidationTest.java index bd75e5b67af4..dd5ad45a246e 100644 --- a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/validation/EventSecurityImportValidationTest.java +++ b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/validation/EventSecurityImportValidationTest.java @@ -27,8 +27,10 @@ */ package org.hisp.dhis.tracker.validation; +import static org.hisp.dhis.tracker.Assertions.assertHasError; import static org.hisp.dhis.tracker.Assertions.assertHasOnlyErrors; import static org.hisp.dhis.tracker.Assertions.assertNoErrors; +import static org.hisp.dhis.tracker.report.TrackerErrorCode.E1000; import static org.hisp.dhis.tracker.validation.Users.USER_3; import static org.hisp.dhis.tracker.validation.Users.USER_4; import static org.hisp.dhis.tracker.validation.Users.USER_5; @@ -37,6 +39,7 @@ import java.util.Calendar; import java.util.Date; import java.util.HashSet; +import java.util.Set; import org.hisp.dhis.common.IdentifiableObjectManager; import org.hisp.dhis.common.ValueType; import org.hisp.dhis.dataelement.DataElement; @@ -201,16 +204,12 @@ private void setupMetadata() { trackedEntityProgramOwnerService.updateTrackedEntityProgramOwner( maleA.getUid(), programA.getUid(), organisationUnitA.getUid()); manager.update(programA); - User user = userService.getUser(USER_5); OrganisationUnit qfUVllTs6cS = organisationUnitService.getOrganisationUnit("QfUVllTs6cS"); - user.addOrganisationUnit(qfUVllTs6cS); - user.addOrganisationUnit(organisationUnitA); User adminUser = userService.getUser(ADMIN_USER_UID); adminUser.addOrganisationUnit(organisationUnitA); Program p = programService.getProgram("prabcdefghA"); p.addOrganisationUnit(qfUVllTs6cS); programService.updateProgram(p); - manager.update(user); manager.update(adminUser); } @@ -259,4 +258,35 @@ void testNoUncompleteEventAuth() throws IOException { trackerImportReport = trackerImportService.importTracker(trackerBundleParams); assertHasOnlyErrors(trackerImportReport, TrackerErrorCode.E1083); } + + @Test + void shouldSucceedWhenCreatingScheduledEventFromInsideSearchOrgUnit() throws IOException { + TrackerImportParams trackerBundleParams = + fromJson("tracker/validations/events-scheduled-with-registration.json"); + OrganisationUnit orgUnit = organisationUnitService.getOrganisationUnit("QfUVllTs6cS"); + User user = userService.getUser(USER_5); + user.setTeiSearchOrganisationUnits(Set.of(orgUnit)); + manager.update(user); + injectSecurityContext(user); + trackerBundleParams.setUser(user); + + TrackerImportReport importReport = trackerImportService.importTracker(trackerBundleParams); + + assertNoErrors(importReport); + } + + @Test + void shouldFailWhenCreatingScheduledEventFromOutsideSearchOrgUnit() throws IOException { + TrackerImportParams trackerBundleParams = + fromJson("tracker/validations/events-scheduled-with-registration.json"); + TrackerImportParams params = TrackerImportParams.builder().build(); + params.setImportStrategy(TrackerImportStrategy.CREATE); + User user = userService.getUser(USER_5); + injectSecurityContext(user); + trackerBundleParams.setUser(user); + + TrackerImportReport importReport = trackerImportService.importTracker(trackerBundleParams); + + assertHasError(importReport, E1000); + } } diff --git a/dhis-2/dhis-test-integration/src/test/resources/tracker/validations/events-scheduled-with-registration.json b/dhis-2/dhis-test-integration/src/test/resources/tracker/validations/events-scheduled-with-registration.json new file mode 100644 index 000000000000..aaa75ec5d0a4 --- /dev/null +++ b/dhis-2/dhis-test-integration/src/test/resources/tracker/validations/events-scheduled-with-registration.json @@ -0,0 +1,29 @@ +{ + "events": [ + { + "event": "ZwwuwNp6gVd", + "status": "SCHEDULE", + "program": { + "idScheme": "UID", + "identifier": "E8o1E9tAppy" + }, + "programStage": { + "idScheme": "UID", + "identifier": "Qmqxq907VNz" + }, + "enrollment": "MNWZ6hnuhSw", + "orgUnit": { + "idScheme": "UID", + "identifier": "QfUVllTs6cS" + }, + "orgUnitName": "TA org_unit lvl2", + "scheduledAt": "2019-08-19T13:59:13.688", + "storedBy": "admin", + "deleted": false, + "attributeOptionCombo": { + "idScheme": "UID", + "identifier": "HllvX50cXC0" + } + } + ] +} \ No newline at end of file From de4ba48bb83642734968eb43f62fd08baad6156d Mon Sep 17 00:00:00 2001 From: Marc Date: Thu, 12 Dec 2024 17:29:46 +0100 Subject: [PATCH 2/2] fix: Use PSI to figure out if creatable in search scope [DHIS2-17335][2.39] --- .../hooks/PreCheckSecurityOwnershipValidationHook.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/validation/hooks/PreCheckSecurityOwnershipValidationHook.java b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/validation/hooks/PreCheckSecurityOwnershipValidationHook.java index 40e75f76375f..003616b90f06 100644 --- a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/validation/hooks/PreCheckSecurityOwnershipValidationHook.java +++ b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/validation/hooks/PreCheckSecurityOwnershipValidationHook.java @@ -323,7 +323,7 @@ public void validateEvent(ValidationErrorReporter reporter, TrackerBundle bundle organisationUnit, strategy.isCreate() ? event.isCreatableInSearchScope() - : bundle.getPreheat().getEvent(event.getUid()).isCreatableInSearchScope(), + : programStageInstance.isCreatableInSearchScope(), bundle.getUser()); } }