Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Return search scope and capture scope for events [TECH-1663][2.38] #15578

Merged
merged 1 commit into from
Nov 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,6 @@ public class EventQueryParams {

private Boolean followUp;

// TODO Default set to DESCENDANTS to replicate master, but this will need to be fixed in
// https://dhis2.atlassian.net/browse/TECH-1588
private OrganisationUnitSelectionMode orgUnitSelectionMode =
OrganisationUnitSelectionMode.ACCESSIBLE;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,13 @@ public class JdbcEventStore implements EventStore {

private static final String DOT_NAME = ".name)";

private static final String USER_SCOPE_ORG_UNIT_PATH_LIKE_MATCH_QUERY =
" ou.path like CONCAT(orgunit.path, '%') ";

private static String getCustomOrgUnitPathLikeMatchQuery(String orgUnitPath) {
return " ou.path like CONCAT('" + orgUnitPath + "', '%' ) ";
}

private static final Map<String, String> QUERY_PARAM_COL_MAP =
ImmutableMap.<String, String>builder()
.put(EVENT_ID, "psi_uid")
Expand Down Expand Up @@ -322,10 +329,6 @@ public class JdbcEventStore implements EventStore {
+ " where uid = ?;";
}

private static final String COLUMN_USER_UID = "u_uid";

private static final String COLUMN_ORG_UNIT_PATH = "ou_path";

private static final String PERCENTAGE_SIGN = ", '%' ";

// -------------------------------------------------------------------------
Expand Down Expand Up @@ -1310,75 +1313,91 @@ private String createAccessibleSql(User user, EventQueryParams params) {
return createCaptureSql(user);
}

return " EXISTS(SELECT ss.organisationunitid "
+ " FROM userteisearchorgunits ss "
+ " JOIN organisationunit orgunit ON orgunit.organisationunitid = ss.organisationunitid "
+ " JOIN userinfo u ON u.userinfoid = ss.userinfoid "
+ " WHERE u.uid = '"
+ user.getUid()
+ "'"
+ " AND ou.path like CONCAT(orgunit.path, '%')) ";
return getSearchAndCaptureScopeOrgUnitPathMatchQuery(
USER_SCOPE_ORG_UNIT_PATH_LIKE_MATCH_QUERY, user.getUid());
}

private String createDescendantsSql(User user, EventQueryParams params) {

if (isProgramRestricted(params.getProgram())) {
return createCaptureScopeQuery(
user,
" AND ou.path like CONCAT('"
+ params.getOrgUnit().getPath()
+ "'"
+ PERCENTAGE_SIGN
+ ")");
user, " AND " + getCustomOrgUnitPathLikeMatchQuery(params.getOrgUnit().getPath()));
}

return " ou.path like CONCAT('" + params.getOrgUnit().getPath() + "'" + PERCENTAGE_SIGN + ") ";
return getSearchAndCaptureScopeOrgUnitPathMatchQuery(
getCustomOrgUnitPathLikeMatchQuery(params.getOrgUnit().getPath()), user.getUid());
}

private String createChildrenSql(User user, EventQueryParams params) {

String customChildrenQuery =
" AND (ou.hierarchylevel = "
+ params.getOrgUnit().getHierarchyLevel()
+ " OR ou.hierarchylevel = "
+ (params.getOrgUnit().getHierarchyLevel() + 1)
+ " ) ";

if (isProgramRestricted(params.getProgram())) {
String childrenSqlClause =
" AND ou.path like CONCAT('"
+ params.getOrgUnit().getPath()
+ "'"
+ PERCENTAGE_SIGN
+ ") "
+ " AND (ou.hierarchylevel = "
+ params.getOrgUnit().getHierarchyLevel()
+ " OR ou.hierarchylevel = "
+ (params.getOrgUnit().getHierarchyLevel() + 1)
+ " )";

return createCaptureScopeQuery(user, childrenSqlClause);
}

return " ou.path like CONCAT('"
+ params.getOrgUnit().getPath()
+ "'"
+ PERCENTAGE_SIGN
+ ") "
+ " AND (ou.hierarchylevel = "
+ params.getOrgUnit().getHierarchyLevel()
+ " OR ou.hierarchylevel = "
+ (params.getOrgUnit().getHierarchyLevel() + 1)
+ " ) ";
return createCaptureScopeQuery(
user,
" AND "
+ getCustomOrgUnitPathLikeMatchQuery(params.getOrgUnit().getPath())
+ customChildrenQuery);
}

return getSearchAndCaptureScopeOrgUnitPathMatchQuery(
getCustomOrgUnitPathLikeMatchQuery(params.getOrgUnit().getPath()) + customChildrenQuery,
user.getUid());
}

private String createSelectedSql(User user, EventQueryParams params) {

String orgUnitPathEqualsMatchQuery =
" ou.path = '"
+ params.getOrgUnit().getPath()
+ "' "
+ " AND "
+ USER_SCOPE_ORG_UNIT_PATH_LIKE_MATCH_QUERY;

if (isProgramRestricted(params.getProgram())) {
String customSelectedClause = " AND ou.path = '" + params.getOrgUnit().getPath() + "' ";
return createCaptureScopeQuery(user, customSelectedClause);
}

return " ou.path = '" + params.getOrgUnit().getPath() + "' ";
return getSearchAndCaptureScopeOrgUnitPathMatchQuery(
orgUnitPathEqualsMatchQuery, user.getUid());
}

private boolean isProgramRestricted(Program program) {
return program != null && (program.isProtected() || program.isClosed());
}

private static String getSearchAndCaptureScopeOrgUnitPathMatchQuery(
String orgUnitMatcher, String userId) {
return " (EXISTS(SELECT ss.organisationunitid "
+ " FROM userteisearchorgunits ss "
+ " JOIN userinfo u ON u.userinfoid = ss.userinfoid "
+ " JOIN organisationunit orgunit ON orgunit.organisationunitid = ss.organisationunitid "
+ " WHERE u.uid = "
+ "'"
+ userId
+ "'"
+ " AND "
+ orgUnitMatcher
+ " AND p.accesslevel in ('OPEN', 'AUDITED')) "
+ " OR EXISTS(SELECT cs.organisationunitid "
+ " FROM usermembership cs "
+ " JOIN userinfo u ON u.userinfoid = cs.userinfoid "
+ " JOIN organisationunit orgunit ON orgunit.organisationunitid = cs.organisationunitid "
+ " WHERE u.uid = "
+ "'"
+ userId
+ "'"
+ " AND "
+ orgUnitMatcher
+ " )) ";
}

private boolean isUserSearchScopeNotSet(User user) {
return user.getTeiSearchOrganisationUnits().isEmpty();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import com.google.common.collect.Lists;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import org.hamcrest.CoreMatchers;
import org.hisp.dhis.TransactionalIntegrationTest;
import org.hisp.dhis.common.CodeGenerator;
Expand Down Expand Up @@ -165,7 +166,7 @@ protected void setUpTest() throws Exception {
manager.update(programStageA);
manager.update(programStageB);
manager.update(programA);
createUserAndInjectSecurityContext(true);
createUserAndInjectSecurityContext(Set.of(organisationUnitA, organisationUnitB), true);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
*/
package org.hisp.dhis.tracker;

import static org.hisp.dhis.common.OrganisationUnitSelectionMode.SELECTED;
import static org.hisp.dhis.util.DateUtils.parseDate;
import static org.hisp.dhis.utils.Assertions.assertContains;
import static org.hisp.dhis.utils.Assertions.assertContainsOnly;
Expand All @@ -50,7 +51,6 @@
import org.hisp.dhis.common.IdSchemes;
import org.hisp.dhis.common.IdentifiableObject;
import org.hisp.dhis.common.IdentifiableObjectManager;
import org.hisp.dhis.common.OrganisationUnitSelectionMode;
import org.hisp.dhis.common.Pager;
import org.hisp.dhis.common.SlimPager;
import org.hisp.dhis.dxf2.events.event.Event;
Expand Down Expand Up @@ -183,7 +183,7 @@ void shouldReturnPaginatedEventsWithNotesGivenNonDefaultPageSize() {
@Test
void testExportEvents() {
EventQueryParams params = new EventQueryParams();
params.setOrgUnitSelectionMode(OrganisationUnitSelectionMode.SELECTED);
params.setOrgUnitSelectionMode(SELECTED);
params.setOrgUnit(orgUnit);

List<String> events = eventsFunction.apply(params);
Expand All @@ -195,7 +195,7 @@ void testExportEvents() {
@Test
void testExportEventsWhenFilteringByEnrollment() {
EventQueryParams params = new EventQueryParams();
params.setOrgUnitSelectionMode(OrganisationUnitSelectionMode.SELECTED);
params.setOrgUnitSelectionMode(SELECTED);
params.setOrgUnit(orgUnit);
params.setProgramInstances(Set.of("nxP7UnKhomJ"));

Expand Down
Loading