diff --git a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/OperationsParamsValidator.java b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/OperationsParamsValidator.java index 2f290a910b59..95b044b91786 100644 --- a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/OperationsParamsValidator.java +++ b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/OperationsParamsValidator.java @@ -64,7 +64,7 @@ public static void validateOrgUnitMode( private static void validateUserCanSearchOrgUnitModeALL(User user) throws BadRequestException { if (user != null && !(user.isSuper() - || user.isAuthorized(F_TRACKED_ENTITY_INSTANCE_SEARCH_IN_ALL_ORGUNITS.name()))) { + || user.isAuthorized(F_TRACKED_ENTITY_INSTANCE_SEARCH_IN_ALL_ORGUNITS))) { throw new BadRequestException( "Current user is not authorized to query across all organisation units"); } diff --git a/dhis-2/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/deprecated/tracker/EnrollmentCriteriaMapper.java b/dhis-2/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/deprecated/tracker/EnrollmentCriteriaMapper.java index 46f412461dd5..bebbdec6bac1 100644 --- a/dhis-2/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/deprecated/tracker/EnrollmentCriteriaMapper.java +++ b/dhis-2/dhis-web-api/src/main/java/org/hisp/dhis/webapi/controller/deprecated/tracker/EnrollmentCriteriaMapper.java @@ -28,7 +28,9 @@ package org.hisp.dhis.webapi.controller.deprecated.tracker; import static org.hisp.dhis.common.OrganisationUnitSelectionMode.ACCESSIBLE; +import static org.hisp.dhis.common.OrganisationUnitSelectionMode.ALL; import static org.hisp.dhis.common.OrganisationUnitSelectionMode.CAPTURE; +import static org.hisp.dhis.security.Authorities.F_TRACKED_ENTITY_INSTANCE_SEARCH_IN_ALL_ORGUNITS; import static org.hisp.dhis.webapi.controller.event.mapper.OrderParamsHelper.toOrderParams; import java.util.Date; @@ -145,6 +147,14 @@ public EnrollmentQueryParams getFromUrl( } } + if (ouMode == ALL + && (user != null + && !user.isSuper() + && !user.isAuthorized(F_TRACKED_ENTITY_INSTANCE_SEARCH_IN_ALL_ORGUNITS))) { + throw new IllegalQueryException( + "Current user is not authorized to query across all organisation units"); + } + Program pr = programUid != null ? programService.getProgram(programUid) : null; if (programUid != null && pr == null) { diff --git a/dhis-2/dhis-web-api/src/test/java/org/hisp/dhis/webapi/controller/deprecated/tracker/EnrollmentCriteriaMapperTest.java b/dhis-2/dhis-web-api/src/test/java/org/hisp/dhis/webapi/controller/deprecated/tracker/EnrollmentCriteriaMapperTest.java index df118624a617..d2164f1e1f7b 100644 --- a/dhis-2/dhis-web-api/src/test/java/org/hisp/dhis/webapi/controller/deprecated/tracker/EnrollmentCriteriaMapperTest.java +++ b/dhis-2/dhis-web-api/src/test/java/org/hisp/dhis/webapi/controller/deprecated/tracker/EnrollmentCriteriaMapperTest.java @@ -28,19 +28,21 @@ package org.hisp.dhis.webapi.controller.deprecated.tracker; import static org.hisp.dhis.common.OrganisationUnitSelectionMode.ACCESSIBLE; +import static org.hisp.dhis.common.OrganisationUnitSelectionMode.ALL; import static org.hisp.dhis.common.OrganisationUnitSelectionMode.CAPTURE; import static org.hisp.dhis.common.OrganisationUnitSelectionMode.CHILDREN; import static org.hisp.dhis.common.OrganisationUnitSelectionMode.DESCENDANTS; import static org.hisp.dhis.common.OrganisationUnitSelectionMode.SELECTED; +import static org.hisp.dhis.security.Authorities.F_TRACKED_ENTITY_INSTANCE_SEARCH_IN_ALL_ORGUNITS; import static org.hisp.dhis.utils.Assertions.assertNotEmpty; import static org.hisp.dhis.utils.Assertions.assertStartsWith; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.when; +import com.google.common.collect.Sets; import java.util.Set; import org.hisp.dhis.common.IllegalQueryException; -import org.hisp.dhis.feedback.ForbiddenException; import org.hisp.dhis.organisationunit.OrganisationUnit; import org.hisp.dhis.organisationunit.OrganisationUnitService; import org.hisp.dhis.program.EnrollmentQueryParams; @@ -53,6 +55,8 @@ import org.hisp.dhis.trackedentity.TrackedEntityTypeService; import org.hisp.dhis.user.CurrentUserService; import org.hisp.dhis.user.User; +import org.hisp.dhis.user.UserRole; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -265,7 +269,7 @@ void shouldFailWhenOrgUnitSuppliedAndOrgUnitModeCapture() { } @Test - void shouldMapOrgUnitModeWhenOrgUnitSuppliedAndOrgUnitModeSelected() throws ForbiddenException { + void shouldMapOrgUnitModeWhenOrgUnitSuppliedAndOrgUnitModeSelected() { when(programService.getProgram(PROGRAM_UID)).thenReturn(program); when(organisationUnitService.getOrganisationUnit(ORG_UNIT1)).thenReturn(organisationUnit); when(organisationUnitService.isInUserHierarchy( @@ -298,8 +302,7 @@ void shouldMapOrgUnitModeWhenOrgUnitSuppliedAndOrgUnitModeSelected() throws Forb } @Test - void shouldMapOrgUnitModeWhenOrgUnitSuppliedAndOrgUnitModeDescendants() - throws ForbiddenException { + void shouldMapOrgUnitModeWhenOrgUnitSuppliedAndOrgUnitModeDescendants() { when(programService.getProgram(PROGRAM_UID)).thenReturn(program); when(organisationUnitService.getOrganisationUnit(ORG_UNIT1)).thenReturn(organisationUnit); when(organisationUnitService.isInUserHierarchy( @@ -332,7 +335,7 @@ void shouldMapOrgUnitModeWhenOrgUnitSuppliedAndOrgUnitModeDescendants() } @Test - void shouldMapOrgUnitModeWhenOrgUnitSuppliedAndOrgUnitModeChildren() throws ForbiddenException { + void shouldMapOrgUnitModeWhenOrgUnitSuppliedAndOrgUnitModeChildren() { when(programService.getProgram(PROGRAM_UID)).thenReturn(program); when(organisationUnitService.getOrganisationUnit(ORG_UNIT1)).thenReturn(organisationUnit); when(organisationUnitService.isInUserHierarchy( @@ -363,4 +366,119 @@ void shouldMapOrgUnitModeWhenOrgUnitSuppliedAndOrgUnitModeChildren() throws Forb assertEquals(CHILDREN, enrollmentQueryParams.getOrganisationUnitMode()); } + + @Test + void shouldMapParamsWhenOrgUnitModeAllAndUserIsSuperuser() { + when(programService.getProgram(PROGRAM_UID)).thenReturn(program); + when(organisationUnitService.getOrganisationUnit(ORG_UNIT1)).thenReturn(organisationUnit); + when(trackedEntityTypeService.getTrackedEntityType(ENTITY_TYPE)).thenReturn(trackedEntityType); + when(trackedEntityService.getTrackedEntity(TRACKED_ENTITY)).thenReturn(trackedEntity); + + User superuser = new User(); + UserRole userRole = new UserRole(); + userRole.setAuthorities(Sets.newHashSet("ALL")); + superuser.setUserRoles(Set.of(userRole)); + + when(currentUserService.getCurrentUser()).thenReturn(superuser); + + EnrollmentQueryParams enrollmentQueryParams = + mapper.getFromUrl( + ORG_UNITS, + ALL, + null, + "lastUpdated", + PROGRAM_UID, + ProgramStatus.ACTIVE, + null, + null, + ENTITY_TYPE, + TRACKED_ENTITY, + false, + 1, + 1, + false, + false, + false, + null); + + assertEquals(ALL, enrollmentQueryParams.getOrganisationUnitMode()); + } + + @Test + void shouldMapParamsWhenOrgUnitModeAllAndUserIsAuthorized() { + when(programService.getProgram(PROGRAM_UID)).thenReturn(program); + when(organisationUnitService.getOrganisationUnit(ORG_UNIT1)).thenReturn(organisationUnit); + when(trackedEntityTypeService.getTrackedEntityType(ENTITY_TYPE)).thenReturn(trackedEntityType); + when(trackedEntityService.getTrackedEntity(TRACKED_ENTITY)).thenReturn(trackedEntity); + + User superuser = new User(); + UserRole userRole = new UserRole(); + userRole.setAuthorities(Sets.newHashSet("ALL")); + superuser.setUserRoles(Set.of(userRole)); + + when(currentUserService.getCurrentUser()).thenReturn(superuser); + + EnrollmentQueryParams enrollmentQueryParams = + mapper.getFromUrl( + ORG_UNITS, + ALL, + null, + "lastUpdated", + PROGRAM_UID, + ProgramStatus.ACTIVE, + null, + null, + ENTITY_TYPE, + TRACKED_ENTITY, + false, + 1, + 1, + false, + false, + false, + null); + + assertEquals(ALL, enrollmentQueryParams.getOrganisationUnitMode()); + } + + @Test + void shouldFailWhenOrgUnitModeAllAndUserNotAuthorized() { + when(organisationUnitService.getOrganisationUnit(ORG_UNIT1)).thenReturn(organisationUnit); + when(organisationUnitService.isInUserHierarchy( + organisationUnit.getUid(), user.getTeiSearchOrganisationUnitsWithFallback())) + .thenReturn(true); + + User superuser = new User(); + UserRole userRole = new UserRole(); + userRole.setAuthorities( + Sets.newHashSet(F_TRACKED_ENTITY_INSTANCE_SEARCH_IN_ALL_ORGUNITS.name())); + superuser.setUserRoles(Set.of(userRole)); + + IllegalQueryException exception = + Assertions.assertThrows( + IllegalQueryException.class, + () -> + mapper.getFromUrl( + ORG_UNITS, + ALL, + null, + "lastUpdated", + PROGRAM_UID, + ProgramStatus.ACTIVE, + null, + null, + ENTITY_TYPE, + TRACKED_ENTITY, + false, + 1, + 1, + false, + false, + false, + null)); + + Assertions.assertEquals( + "Current user is not authorized to query across all organisation units", + exception.getMessage()); + } }