From d897efdd5f9731f560cee5e0ec4f3028f90caf87 Mon Sep 17 00:00:00 2001 From: Marc Date: Thu, 12 Dec 2024 16:39:49 +0100 Subject: [PATCH] fix: Validate search scope when scheduled event [DHIS2-17335][2.40] --- .../event/SecurityOwnershipValidator.java | 23 ++++-------- .../EventSecurityImportValidationTest.java | 37 +++++++++++++++++-- .../events-scheduled-with-registration.json | 29 +++++++++++++++ 3 files changed, 70 insertions(+), 19 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/validator/event/SecurityOwnershipValidator.java b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/validation/validator/event/SecurityOwnershipValidator.java index d8cdf13a4cd5..9292f299dc04 100644 --- a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/validation/validator/event/SecurityOwnershipValidator.java +++ b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/validation/validator/event/SecurityOwnershipValidator.java @@ -111,13 +111,18 @@ public void validate(Reporter reporter, TrackerBundle bundle, Event event) { organisationUnit = bundle.getPreheat().getOrganisationUnit(event.getOrgUnit()); } - // If event is newly created, or going to be deleted, capture scope - // has to be checked if (program.isWithoutRegistration() || strategy.isCreate() || strategy.isDelete()) { if (organisationUnit == null) { log.warn(ORG_UNIT_NO_USER_ASSIGNED, event.getEvent()); } else { - checkOrgUnitInCaptureScope(reporter, bundle, event, organisationUnit); + checkEventOrgUnitWriteAccess( + reporter, + event, + organisationUnit, + strategy.isCreate() + ? event.isCreatableInSearchScope() + : bundle.getPreheat().getEvent(event.getUid()).isCreatableInSearchScope(), + bundle.getUser()); } } String teUid = getTeUidFromEvent(bundle, event, program); @@ -253,18 +258,6 @@ public boolean needsToRun(TrackerImportStrategy strategy) { return true; } - private void checkOrgUnitInCaptureScope( - Reporter reporter, TrackerBundle bundle, TrackerDto dto, OrganisationUnit orgUnit) { - User user = bundle.getUser(); - - checkNotNull(user, USER_CANT_BE_NULL); - checkNotNull(orgUnit, ORGANISATION_UNIT_CANT_BE_NULL); - - if (!organisationUnitService.isInUserHierarchyCached(user, orgUnit)) { - reporter.addError(dto, ValidationCode.E1000, user, orgUnit); - } - } - private void checkTeiTypeAndTeiProgramAccess( Reporter reporter, TrackerDto dto, 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 96ae711cc5e5..6c224837d444 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,6 +27,7 @@ */ 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.validation.Users.USER_3; @@ -37,6 +38,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; @@ -200,16 +202,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); } @@ -258,4 +256,35 @@ void testNoUncompleteEventAuth() throws IOException { importReport = trackerImportService.importTracker(trackerBundleParams); assertHasOnlyErrors(importReport, ValidationCode.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); + + ImportReport 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); + + ImportReport importReport = trackerImportService.importTracker(trackerBundleParams); + + assertHasError(importReport, ValidationCode.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