diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/common/rest/ldap/LdapClient.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/common/rest/ldap/LdapClient.java index 998fbb44a..8f47255cd 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/common/rest/ldap/LdapClient.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/common/rest/ldap/LdapClient.java @@ -252,8 +252,10 @@ public class LdapClient { final AndFilter andFilter = new AndFilter(); andFilter.and(new EqualsFilter(getGroupSearchFilterName(), getGroupSearchFilterValue())); final OrFilter orFilter = new OrFilter(); - orFilter.or(new EqualsFilter(getGroupsOfUser(), accessId)); - orFilter.or(new EqualsFilter(getGroupsOfUser(), dn)); + if (!"DN".equalsIgnoreCase(getGroupsOfUserType())) { + orFilter.or(new EqualsFilter(getGroupsOfUserName(), accessId)); + } + orFilter.or(new EqualsFilter(getGroupsOfUserName(), dn)); andFilter.and(orFilter); String[] userAttributesToReturn = {getUserIdAttribute(), getGroupNameAttribute()}; @@ -302,11 +304,7 @@ public class LdapClient { andFilter.encode(), SearchControls.SUBTREE_SCOPE, null, - new AbstractContextMapper() { - public String doMapFromContext(DirContextOperations ctx) { - return getDnFromContext(ctx); - } - }); + new DnStringContextMapper()); if (distinguishedNames == null || distinguishedNames.isEmpty()) { return null; @@ -456,8 +454,16 @@ public class LdapClient { return maxNumberOfReturnedAccessIds; } - public String getGroupsOfUser() { - return LdapSettings.TASKANA_LDAP_GROUPS_OF_USER.getValueFromEnv(env); + public String getGroupsOfUserName() { + String groupsOfUser = LdapSettings.TASKANA_LDAP_GROUPS_OF_USER_NAME.getValueFromEnv(env); + if (groupsOfUser == null || groupsOfUser.isEmpty()) { + groupsOfUser = LdapSettings.TASKANA_LDAP_GROUPS_OF_USER.getValueFromEnv(env); + } + return groupsOfUser; + } + + public String getGroupsOfUserType() { + return LdapSettings.TASKANA_LDAP_GROUPS_OF_USER_TYPE.getValueFromEnv(env); } public boolean isUser(String accessId) { @@ -565,6 +571,9 @@ public class LdapClient { .filter(p -> !p.equals(LdapSettings.TASKANA_LDAP_USER_ORG_LEVEL_2_ATTRIBUTE)) .filter(p -> !p.equals(LdapSettings.TASKANA_LDAP_USER_ORG_LEVEL_3_ATTRIBUTE)) .filter(p -> !p.equals(LdapSettings.TASKANA_LDAP_USER_ORG_LEVEL_4_ATTRIBUTE)) + .filter(p -> !p.equals(LdapSettings.TASKANA_LDAP_GROUPS_OF_USER)) + .filter(p -> !p.equals(LdapSettings.TASKANA_LDAP_GROUPS_OF_USER_NAME)) + .filter(p -> !p.equals(LdapSettings.TASKANA_LDAP_GROUPS_OF_USER_TYPE)) .filter(p -> p.getValueFromEnv(env) == null) .collect(Collectors.toList()); } @@ -667,4 +676,11 @@ public class LdapClient { return accessId; } } + + class DnStringContextMapper extends AbstractContextMapper { + @Override + public String doMapFromContext(DirContextOperations ctx) { + return getDnFromContext(ctx); + } + } } diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/common/rest/ldap/LdapSettings.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/common/rest/ldap/LdapSettings.java index f626f236c..00c465482 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/common/rest/ldap/LdapSettings.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/common/rest/ldap/LdapSettings.java @@ -26,7 +26,9 @@ enum LdapSettings { TASKANA_LDAP_GROUP_NAME_ATTRIBUTE("taskana.ldap.groupNameAttribute"), TASKANA_LDAP_MIN_SEARCH_FOR_LENGTH("taskana.ldap.minSearchForLength"), TASKANA_LDAP_MAX_NUMBER_OF_RETURNED_ACCESS_IDS("taskana.ldap.maxNumberOfReturnedAccessIds"), - TASKANA_LDAP_GROUPS_OF_USER("taskana.ldap.groupsOfUser"); + TASKANA_LDAP_GROUPS_OF_USER("taskana.ldap.groupsOfUser"), + TASKANA_LDAP_GROUPS_OF_USER_NAME("taskana.ldap.groupsOfUser.name"), + TASKANA_LDAP_GROUPS_OF_USER_TYPE("taskana.ldap.groupsOfUser.type"); private final String key; diff --git a/rest/taskana-rest-spring/src/test/java/pro/taskana/common/rest/ldap/LdapClientTest.java b/rest/taskana-rest-spring/src/test/java/pro/taskana/common/rest/ldap/LdapClientTest.java index e38d91145..81bc14b51 100644 --- a/rest/taskana-rest-spring/src/test/java/pro/taskana/common/rest/ldap/LdapClientTest.java +++ b/rest/taskana-rest-spring/src/test/java/pro/taskana/common/rest/ldap/LdapClientTest.java @@ -11,6 +11,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -23,12 +24,14 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; +import org.mockito.Spy; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.core.env.Environment; import org.springframework.ldap.core.LdapTemplate; import pro.taskana.TaskanaEngineConfiguration; import pro.taskana.common.api.TaskanaRole; +import pro.taskana.common.api.exceptions.InvalidArgumentException; import pro.taskana.common.api.exceptions.SystemException; import pro.taskana.common.rest.models.AccessIdRepresentationModel; @@ -41,7 +44,7 @@ class LdapClientTest { @Mock TaskanaEngineConfiguration taskanaEngineConfiguration; - @InjectMocks LdapClient cut; + @Spy @InjectMocks LdapClient cut; @Test void testLdap_searchGroupByDn() { @@ -122,6 +125,37 @@ class LdapClientTest { .isEqualTo("cn=developersgroup,ou=groups"); } + @Test + void shouldNot_CreateOrCriteriaWithDnAndAccessIdString_When_PropertyTypeIsSet() + throws InvalidArgumentException { + + setUpEnvMock(); + lenient().when(this.environment.getProperty("taskana.ldap.groupsOfUser.type")).thenReturn("dn"); + lenient() + .when( + ldapTemplate.search( + any(String.class), + eq("(&(objectclass=person)(uid=user-1-1))"), + eq(2), + any(), + any(LdapClient.DnStringContextMapper.class))) + .thenReturn(Collections.singletonList("uid=user-1-1,cn=users,OU=Test,O=TASKANA")); + + cut.init(); + + cut.searchGroupsAccessIdIsMemberOf("user-1-1"); + + String expectedFilterValue = + "(&(objectclass=groupOfUniqueNames)(memberUid=uid=user-1-1,cn=users,OU=Test,O=TASKANA))"; + verify(ldapTemplate) + .search( + any(String.class), + eq(expectedFilterValue), + anyInt(), + any(), + any(LdapClient.GroupContextMapper.class)); + } + @Test void testLdap_getFirstPageOfaResultList() { setUpEnvMock(); @@ -148,8 +182,9 @@ class LdapClientTest { void testLdap_checkForMissingConfigurations() { // optional config fields: minSearchForLength, maxNumberOfReturnedAccessIds, userPhoneAttribute, // userMobilePhoneAttribute, userEmailAttribute, userOrglevel1Attribute, userOrglevel2Attribute, - // userOrglevel3Attribute, userOrglevel4Attribute - assertThat(cut.checkForMissingConfigurations()).hasSize(LdapSettings.values().length - 9); + // userOrglevel3Attribute, userOrglevel4Attribute, groupsOfUser, groupsOfUserName, + // groupOfUserType + assertThat(cut.checkForMissingConfigurations()).hasSize(LdapSettings.values().length - 12); } @Test diff --git a/rest/taskana-rest-spring/src/test/resources/application.properties b/rest/taskana-rest-spring/src/test/resources/application.properties index 76605096c..5b51fe08d 100644 --- a/rest/taskana-rest-spring/src/test/resources/application.properties +++ b/rest/taskana-rest-spring/src/test/resources/application.properties @@ -38,6 +38,7 @@ taskana.ldap.groupNameAttribute=cn taskana.ldap.minSearchForLength=3 taskana.ldap.maxNumberOfReturnedAccessIds=50 taskana.ldap.groupsOfUser=uniquemember +taskana.ldap.groupsOfUser.type= # Embedded Spring LDAP server spring.ldap.embedded.base-dn= OU=Test,O=TASKANA spring.ldap.embedded.credential.username= uid=admin