TSK-1024: Make LdapClient more testable

This commit is contained in:
Benjamin Eckstein 2020-01-30 14:28:04 +01:00
parent 57cb37fb0d
commit a1f1e72afc
4 changed files with 244 additions and 165 deletions

View File

@ -1,7 +1,11 @@
package pro.taskana.ldap; package pro.taskana.ldap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import javax.naming.directory.SearchControls; import javax.naming.directory.SearchControls;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -30,7 +34,8 @@ import pro.taskana.rest.resource.AccessIdResource;
@Component @Component
public class LdapClient { public class LdapClient {
public static final String TASKANA_USE_LDAP_PROP_NAME = "taskana.ldap.useLdap"; static final String MISSING_CONFIGURATION_S =
"LdapClient was called but is not active due to missing configuration: %s ";
private static final Logger LOGGER = LoggerFactory.getLogger(LdapClient.class); private static final Logger LOGGER = LoggerFactory.getLogger(LdapClient.class);
@ -38,35 +43,12 @@ public class LdapClient {
private boolean active = false; private boolean active = false;
@Autowired private Environment env; @Autowired
private Environment env;
@Autowired(required = false) @Autowired(required = false)
private LdapTemplate ldapTemplate; private LdapTemplate ldapTemplate;
private String userSearchBase;
private String userSearchFilterName;
private String userSearchFilterValue;
private String userFirstnameAttribute;
private String userLastnameAttribute;
private String userIdAttribute;
private String groupSearchBase;
private String groupSearchFilterName;
private String groupSearchFilterValue;
private String groupNameAttribute;
private String groupsOfUser;
private String baseDn;
private int minSearchForLength; private int minSearchForLength;
private int maxNumberOfReturnedAccessIds; private int maxNumberOfReturnedAccessIds;
@ -84,27 +66,23 @@ public class LdapClient {
public List<AccessIdResource> searchUsersAndGroups(final String name) public List<AccessIdResource> searchUsersAndGroups(final String name)
throws InvalidArgumentException { throws InvalidArgumentException {
LOGGER.debug("entry to searchUsersAndGroups(name = {})", name); LOGGER.debug("entry to searchUsersAndGroups(name = {})", name);
if (!active) { isInitOrFail();
throw new SystemException(
"LdapClient was called but is not active due to missing configuration: " + message);
}
testMinSearchForLength(name); testMinSearchForLength(name);
List<AccessIdResource> accessIds = searchUsersByName(name); List<AccessIdResource> accessIds = new ArrayList<>(searchUsersByName(name));
accessIds.addAll(searchGroupsByName(name)); accessIds.addAll(searchGroupsByName(name));
// TODO: remove try/catch as once the fix is verified // TODO: remove try/catch as once the fix is verified
try { try {
accessIds.add(searchGroupByDn(name)); AccessIdResource groupByDn = searchGroupByDn(name);
if (groupByDn != null) {
accessIds.add(searchGroupByDn(name));
}
} catch (Throwable t) { } catch (Throwable t) {
t.printStackTrace(); LOGGER.error("unexpected error while searching group by dn", t);
} }
accessIds.sort( sortListOfAccessIdResources(accessIds);
(AccessIdResource a, AccessIdResource b) -> { List<AccessIdResource> result = getFirstPageOfaResultList(accessIds);
return a.getAccessId().compareToIgnoreCase(b.getAccessId());
});
List<AccessIdResource> result =
accessIds.subList(0, Math.min(accessIds.size(), maxNumberOfReturnedAccessIds));
LOGGER.debug( LOGGER.debug(
"exit from searchUsersAndGroups(name = {}). Returning {} users and groups: {}", "exit from searchUsersAndGroups(name = {}). Returning {} users and groups: {}",
name, name,
@ -117,10 +95,7 @@ public class LdapClient {
public List<AccessIdResource> searchUsersByName(final String name) public List<AccessIdResource> searchUsersByName(final String name)
throws InvalidArgumentException { throws InvalidArgumentException {
LOGGER.debug("entry to searchUsersByName(name = {}).", name); LOGGER.debug("entry to searchUsersByName(name = {}).", name);
if (!active) { isInitOrFail();
throw new SystemException(
"LdapClient was called but is not active due to missing configuration: " + message);
}
testMinSearchForLength(name); testMinSearchForLength(name);
final AndFilter andFilter = new AndFilter(); final AndFilter andFilter = new AndFilter();
@ -152,17 +127,14 @@ public class LdapClient {
public List<AccessIdResource> searchGroupsByName(final String name) public List<AccessIdResource> searchGroupsByName(final String name)
throws InvalidArgumentException { throws InvalidArgumentException {
LOGGER.debug("entry to searchGroupsByName(name = {}).", name); LOGGER.debug("entry to searchGroupsByName(name = {}).", name);
if (!active) { isInitOrFail();
throw new SystemException(
"LdapClient was called but is not active due to missing configuration: " + message);
}
testMinSearchForLength(name); testMinSearchForLength(name);
final AndFilter andFilter = new AndFilter(); final AndFilter andFilter = new AndFilter();
andFilter.and(new EqualsFilter(getGroupSearchFilterName(), getGroupSearchFilterValue())); andFilter.and(new EqualsFilter(getGroupSearchFilterName(), getGroupSearchFilterValue()));
final OrFilter orFilter = new OrFilter(); final OrFilter orFilter = new OrFilter();
orFilter.or(new WhitespaceWildcardsFilter(getGroupNameAttribute(), name)); orFilter.or(new WhitespaceWildcardsFilter(getGroupNameAttribute(), name));
if (!CN.equals(groupNameAttribute)) { if (!CN.equals(getGroupNameAttribute())) {
orFilter.or(new WhitespaceWildcardsFilter(CN, name)); orFilter.or(new WhitespaceWildcardsFilter(CN, name));
} }
andFilter.and(orFilter); andFilter.and(orFilter);
@ -182,17 +154,14 @@ public class LdapClient {
public AccessIdResource searchGroupByDn(final String name) { public AccessIdResource searchGroupByDn(final String name) {
LOGGER.debug("entry to searchGroupByDn(name = {}).", name); LOGGER.debug("entry to searchGroupByDn(name = {}).", name);
if (!active) { isInitOrFail();
throw new SystemException(
"LdapClient was called but is not active due to missing configuration: " + message);
}
// Obviously Spring LdapTemplate does have a inconsistency and always adds the base name to the // Obviously Spring LdapTemplate does have a inconsistency and always adds the base name to the
// given DN. // given DN.
// https://stackoverflow.com/questions/55285743/spring-ldaptemplate-how-to-lookup-fully-qualified-dn-with-configured-base-dn // https://stackoverflow.com/questions/55285743/spring-ldaptemplate-how-to-lookup-fully-qualified-dn-with-configured-base-dn
// Therefore we have to remove the base name from the dn before performing the lookup // Therefore we have to remove the base name from the dn before performing the lookup
String nameWithoutBaseDn = getNameWithoutBaseDn(name); String nameWithoutBaseDn = getNameWithoutBaseDn(name);
LOGGER.debug( LOGGER.debug(
"Removes baseDN {} from given DN. New DN to be used: {}", baseDn, nameWithoutBaseDn); "Removes baseDN {} from given DN. New DN to be used: {}", getBaseDn(), nameWithoutBaseDn);
final AccessIdResource accessId = final AccessIdResource accessId =
ldapTemplate.lookup( ldapTemplate.lookup(
nameWithoutBaseDn, getLookUpGoupAttributesToReturn(), new GroupContextMapper()); nameWithoutBaseDn, getLookUpGoupAttributesToReturn(), new GroupContextMapper());
@ -200,26 +169,14 @@ public class LdapClient {
return accessId; return accessId;
} }
String getNameWithoutBaseDn(String name) { List<AccessIdResource> getFirstPageOfaResultList(List<AccessIdResource> accessIds) {
// (?i) --> case insensitive replacement return accessIds.subList(0, Math.min(accessIds.size(), maxNumberOfReturnedAccessIds));
return name.replaceAll("(?i)" + Pattern.quote("," + baseDn), "");
}
String[] getLookUpGoupAttributesToReturn() {
if (CN.equals(groupNameAttribute)) {
return new String[] {CN};
} else {
return new String[] {getGroupNameAttribute(), CN};
}
} }
public List<AccessIdResource> searchGroupsofUsersIsMember(final String name) public List<AccessIdResource> searchGroupsofUsersIsMember(final String name)
throws InvalidArgumentException { throws InvalidArgumentException {
LOGGER.debug("entry to searchGroupsofUsersIsMember(name = {}).", name); LOGGER.debug("entry to searchGroupsofUsersIsMember(name = {}).", name);
if (!active) { isInitOrFail();
throw new SystemException(
"LdapClient was called but is not active due to missing configuration: " + message);
}
testMinSearchForLength(name); testMinSearchForLength(name);
final AndFilter andFilter = new AndFilter(); final AndFilter andFilter = new AndFilter();
@ -241,69 +198,99 @@ public class LdapClient {
return accessIds; return accessIds;
} }
public boolean useLdap() { void isInitOrFail() {
String useLdap = env.getProperty(TASKANA_USE_LDAP_PROP_NAME); if (!active) {
if (useLdap == null || useLdap.isEmpty()) { throw new SystemException(String.format(MISSING_CONFIGURATION_S, message));
return false;
} else {
return Boolean.parseBoolean(useLdap);
} }
} }
void sortListOfAccessIdResources(List<AccessIdResource> accessIds) {
accessIds.sort(
(AccessIdResource a, AccessIdResource b) ->
a.getAccessId().compareToIgnoreCase(b.getAccessId()));
}
String getNameWithoutBaseDn(String name) {
// (?i) --> case insensitive replacement
return name.replaceAll("(?i)" + Pattern.quote("," + getBaseDn()), "");
}
String[] getLookUpGoupAttributesToReturn() {
if (CN.equals(getGroupNameAttribute())) {
return new String[]{CN};
} else {
return new String[]{getGroupNameAttribute(), CN};
}
}
public boolean useLdap() {
String useLdap = LdapSettings.TASKANA_LDAP_USE_LDAP.getValueFromEnv(env);
return Boolean.parseBoolean(useLdap);
}
public String getUserSearchBase() { public String getUserSearchBase() {
return env.getProperty("taskana.ldap.userSearchBase"); return LdapSettings.TASKANA_LDAP_USER_SEARCH_BASE.getValueFromEnv(env);
} }
public String getUserSearchFilterName() { public String getUserSearchFilterName() {
return env.getProperty("taskana.ldap.userSearchFilterName"); return LdapSettings.TASKANA_LDAP_USER_SEARCH_FILTER_NAME.getValueFromEnv(env);
} }
public String getUserSearchFilterValue() { public String getUserSearchFilterValue() {
return env.getProperty("taskana.ldap.userSearchFilterValue"); return LdapSettings.TASKANA_LDAP_USER_SEARCH_FILTER_VALUE.getValueFromEnv(env);
} }
public String getUserFirstnameAttribute() { public String getUserFirstnameAttribute() {
return env.getProperty("taskana.ldap.userFirstnameAttribute"); return LdapSettings.TASKANA_LDAP_USER_FIRSTNAME_ATTRIBUTE.getValueFromEnv(env);
} }
public String getUserLastnameAttribute() { public String getUserLastnameAttribute() {
return env.getProperty("taskana.ldap.userLastnameAttribute"); return LdapSettings.TASKANA_LDAP_USER_LASTNAME_ATTRIBUTE.getValueFromEnv(env);
} }
public String getUserIdAttribute() { public String getUserIdAttribute() {
return env.getProperty("taskana.ldap.userIdAttribute"); return LdapSettings.TASKANA_LDAP_USER_ID_ATTRIBUTE.getValueFromEnv(env);
} }
public String getGroupSearchBase() { public String getGroupSearchBase() {
return env.getProperty("taskana.ldap.groupSearchBase"); return LdapSettings.TASKANA_LDAP_GROUP_SEARCH_BASE.getValueFromEnv(env);
} }
public String getBaseDn() { public String getBaseDn() {
return env.getProperty("taskana.ldap.baseDn"); return LdapSettings.TASKANA_LDAP_BASE_DN.getValueFromEnv(env);
} }
public String getGroupSearchFilterName() { public String getGroupSearchFilterName() {
return env.getProperty("taskana.ldap.groupSearchFilterName"); return LdapSettings.TASKANA_LDAP_GROUP_SEARCH_FILTER_NAME.getValueFromEnv(env);
} }
public String getGroupSearchFilterValue() { public String getGroupSearchFilterValue() {
return env.getProperty("taskana.ldap.groupSearchFilterValue"); return LdapSettings.TASKANA_LDAP_GROUP_SEARCH_FILTER_VALUE.getValueFromEnv(env);
} }
public String getGroupNameAttribute() { public String getGroupNameAttribute() {
return env.getProperty("taskana.ldap.groupNameAttribute"); return LdapSettings.TASKANA_LDAP_GROUP_NAME_ATTRIBUTE.getValueFromEnv(env);
} }
public String getMinSearchForLengthAsString() { public int calcMinSearchForLength(int defaultValue) {
return env.getProperty("taskana.ldap.minSearchForLength"); String envValue = LdapSettings.TASKANA_LDAP_MIN_SEARCH_FOR_LENGTH.getValueFromEnv(env);
if (envValue == null || envValue.isEmpty()) {
return defaultValue;
}
return Integer.parseInt(envValue);
} }
public int getMinSearchForLength() { public int getMinSearchForLength() {
return minSearchForLength; return minSearchForLength;
} }
public String getMaxNumberOfReturnedAccessIdsAsString() { public int calcMaxNumberOfReturnedAccessIds(int defaultValue) {
return env.getProperty("taskana.ldap.maxNumberOfReturnedAccessIds"); String envValue =
LdapSettings.TASKANA_LDAP_MAX_NUMBER_OF_RETURNED_ACCESS_IDS.getValueFromEnv(env);
if (envValue == null || envValue.isEmpty()) {
return defaultValue;
}
return Integer.parseInt(envValue);
} }
public int getMaxNumberOfReturnedAccessIds() { public int getMaxNumberOfReturnedAccessIds() {
@ -311,7 +298,7 @@ public class LdapClient {
} }
public String getGroupsOfUser() { public String getGroupsOfUser() {
return env.getProperty("taskana.ldap.groupsOfUser"); return LdapSettings.TASKANA_LDAP_GROUPS_OF_USER.getValueFromEnv(env);
} }
public boolean isGroup(String accessId) { public boolean isGroup(String accessId) {
@ -321,75 +308,19 @@ public class LdapClient {
@PostConstruct @PostConstruct
void init() { void init() {
LOGGER.debug("Entry to init()"); LOGGER.debug("Entry to init()");
String strMinSearchForLength = getMinSearchForLengthAsString(); minSearchForLength = calcMinSearchForLength(3);
if (strMinSearchForLength == null || strMinSearchForLength.isEmpty()) { maxNumberOfReturnedAccessIds = calcMaxNumberOfReturnedAccessIds(50);
minSearchForLength = 3;
} else {
minSearchForLength = Integer.parseInt(strMinSearchForLength);
}
String strMaxNumberOfReturnedAccessIds = getMaxNumberOfReturnedAccessIdsAsString();
if (strMaxNumberOfReturnedAccessIds == null || strMaxNumberOfReturnedAccessIds.isEmpty()) {
maxNumberOfReturnedAccessIds = 50;
} else {
maxNumberOfReturnedAccessIds = Integer.parseInt(strMaxNumberOfReturnedAccessIds);
}
if (useLdap()) { if (useLdap()) {
userSearchBase = getUserSearchBase();
userSearchFilterName = getUserSearchFilterName();
userSearchFilterValue = getUserSearchFilterValue();
userFirstnameAttribute = getUserFirstnameAttribute();
userLastnameAttribute = getUserLastnameAttribute();
userIdAttribute = getUserIdAttribute();
groupSearchBase = getGroupSearchBase();
groupSearchFilterName = getGroupSearchFilterName();
groupSearchFilterValue = getGroupSearchFilterValue();
groupNameAttribute = getGroupNameAttribute();
groupsOfUser = getGroupsOfUser();
baseDn = getBaseDn();
ldapTemplate.setDefaultCountLimit(maxNumberOfReturnedAccessIds); ldapTemplate.setDefaultCountLimit(maxNumberOfReturnedAccessIds);
final String emptyMessage = "taskana.ldap.useLdap is set to true, but"; final List<LdapSettings> missingConfigurations = checkForMissingConfigurations();
message = emptyMessage;
if (userSearchBase == null) { if (missingConfigurations.size() > 0) {
message += " taskana.ldap.userSearchBase is not configured."; message =
} String.format(
if (userSearchFilterName == null) { "taskana.ldap.useLdap is set to true, but following configurations are missing: %s",
message += " taskana.ldap.userSearchFilterName is not configured."; missingConfigurations);
}
if (userSearchFilterValue == null) {
message += " taskana.ldap.userSearchFilterValue is not configured.";
}
if (userFirstnameAttribute == null) {
message += " taskana.ldap.userFirstnameAttribute is not configured.";
}
if (userLastnameAttribute == null) {
message += " taskana.ldap.userLastnameAttribute is not configured.";
}
if (userIdAttribute == null) {
message += " taskana.ldap.userIdAttribute is not configured.";
}
if (groupSearchBase == null) {
message += " taskana.ldap.groupSearchBase is not configured.";
}
if (groupSearchFilterName == null) {
message += " taskana.ldap.groupSearchFilterName is not configured.";
}
if (groupSearchFilterValue == null) {
message += " taskana.ldap.groupSearchFilterValue is not configured.";
}
if (groupNameAttribute == null) {
message += " taskana.ldap.groupNameAttribute is not configured.";
}
if (groupsOfUser == null) {
message += " taskana.ldap.groupsOfUser is not configured.";
}
if (baseDn == null) {
message += " taskana.ldap.baseDn is not configured.";
}
if (!message.equals(emptyMessage)) {
throw new SystemException(message); throw new SystemException(message);
} }
active = true; active = true;
@ -397,17 +328,27 @@ public class LdapClient {
LOGGER.debug("Exit from init()"); LOGGER.debug("Exit from init()");
} }
private void testMinSearchForLength(final String name) throws InvalidArgumentException { List<LdapSettings> checkForMissingConfigurations() {
return Arrays.stream(LdapSettings.values())
// optional settings
.filter(p -> !p.equals(LdapSettings.TASKANA_LDAP_MAX_NUMBER_OF_RETURNED_ACCESS_IDS))
.filter(p -> !p.equals(LdapSettings.TASKANA_LDAP_MIN_SEARCH_FOR_LENGTH))
.filter(p -> Objects.isNull(p.getValueFromEnv(env)))
.collect(Collectors.toList());
}
void testMinSearchForLength(final String name) throws InvalidArgumentException {
if (name == null || name.length() < minSearchForLength) { if (name == null || name.length() < minSearchForLength) {
throw new InvalidArgumentException( throw new InvalidArgumentException(
"searchFor string " String.format(
+ name "search for string %s is too short. Minimum Length is %s",
+ " is too short. Minimum Length = " name, getMinSearchForLength()));
+ getMinSearchForLength());
} }
} }
/** Context Mapper for user entries. */ /**
* Context Mapper for user entries.
*/
class GroupContextMapper extends AbstractContextMapper<AccessIdResource> { class GroupContextMapper extends AbstractContextMapper<AccessIdResource> {
@Override @Override
@ -419,8 +360,10 @@ public class LdapClient {
} }
} }
/** Context Mapper for user entries. */ /**
private class UserContextMapper extends AbstractContextMapper<AccessIdResource> { * Context Mapper for user entries.
*/
class UserContextMapper extends AbstractContextMapper<AccessIdResource> {
@Override @Override
public AccessIdResource doMapFromContext(final DirContextOperations context) { public AccessIdResource doMapFromContext(final DirContextOperations context) {
@ -428,7 +371,7 @@ public class LdapClient {
accessId.setAccessId(context.getStringAttribute(getUserIdAttribute())); accessId.setAccessId(context.getStringAttribute(getUserIdAttribute()));
String firstName = context.getStringAttribute(getUserFirstnameAttribute()); String firstName = context.getStringAttribute(getUserFirstnameAttribute());
String lastName = context.getStringAttribute(getUserLastnameAttribute()); String lastName = context.getStringAttribute(getUserLastnameAttribute());
accessId.setName(lastName + ", " + firstName); accessId.setName(String.format("%s, %s", lastName, firstName));
return accessId; return accessId;
} }
} }

View File

@ -53,7 +53,8 @@ public class LdapConfiguration {
@Override @Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
String useLdap = context.getEnvironment().getProperty(LdapClient.TASKANA_USE_LDAP_PROP_NAME); String useLdap =
context.getEnvironment().getProperty(LdapSettings.TASKANA_LDAP_USE_LDAP.getKey());
if (useLdap == null || useLdap.isEmpty()) { if (useLdap == null || useLdap.isEmpty()) {
return false; return false;
} else { } else {

View File

@ -0,0 +1,46 @@
package pro.taskana.ldap;
import org.springframework.core.env.Environment;
/**
* Required settings to run ldap.
*/
enum LdapSettings {
TASKANA_LDAP_USE_LDAP("taskana.ldap.useLdap"),
TASKANA_LDAP_USER_SEARCH_BASE("taskana.ldap.userSearchBase"),
TASKANA_LDAP_USER_SEARCH_FILTER_NAME("taskana.ldap.userSearchFilterName"),
TASKANA_LDAP_USER_SEARCH_FILTER_VALUE("taskana.ldap.userSearchFilterValue"),
TASKANA_LDAP_USER_FIRSTNAME_ATTRIBUTE("taskana.ldap.userFirstnameAttribute"),
TASKANA_LDAP_USER_LASTNAME_ATTRIBUTE("taskana.ldap.userLastnameAttribute"),
TASKANA_LDAP_USER_ID_ATTRIBUTE("taskana.ldap.userIdAttribute"),
TASKANA_LDAP_GROUP_SEARCH_BASE("taskana.ldap.groupSearchBase"),
TASKANA_LDAP_BASE_DN("taskana.ldap.baseDn"),
TASKANA_LDAP_GROUP_SEARCH_FILTER_NAME("taskana.ldap.groupSearchFilterName"),
TASKANA_LDAP_GROUP_SEARCH_FILTER_VALUE("taskana.ldap.groupSearchFilterValue"),
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");
private final String key;
LdapSettings(String key) {
this.key = key;
}
String getKey() {
return key;
}
String getValueFromEnv(Environment env) {
if (env == null) {
return null;
}
return env.getProperty(key);
}
@Override
public String toString() {
return key;
}
}

View File

@ -1,11 +1,20 @@
package pro.taskana.ldap; package pro.taskana.ldap;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import static pro.taskana.ldap.LdapSettings.TASKANA_LDAP_USE_LDAP;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
@ -15,6 +24,10 @@ import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import org.springframework.ldap.core.LdapTemplate; import org.springframework.ldap.core.LdapTemplate;
import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.exceptions.SystemException;
import pro.taskana.rest.resource.AccessIdResource;
@ExtendWith(MockitoExtension.class) @ExtendWith(MockitoExtension.class)
class LdapClientTest { class LdapClientTest {
@ -37,6 +50,25 @@ class LdapClientTest {
eq("cn=developersgroup,ou=groups"), any(), any(LdapClient.GroupContextMapper.class)); eq("cn=developersgroup,ou=groups"), any(), any(LdapClient.GroupContextMapper.class));
} }
@Test
void testLdap_searchUsersAndGroups() throws InvalidArgumentException {
setUpEnvMock();
cut.init();
AccessIdResource group = new AccessIdResource("testG", "testGId");
AccessIdResource user = new AccessIdResource("testU", "testUId");
when(ldapTemplate.search(
any(String.class), any(), anyInt(), any(), any(LdapClient.GroupContextMapper.class)))
.thenReturn(Collections.singletonList(group));
when(ldapTemplate.search(
any(String.class), any(), anyInt(), any(), any(LdapClient.UserContextMapper.class)))
.thenReturn(Collections.singletonList(user));
assertThat(cut.searchUsersAndGroups("test")).hasSize(2).containsExactlyInAnyOrder(user, group);
}
@Test @Test
void testLdap_getNameWithoutBaseDn() { void testLdap_getNameWithoutBaseDn() {
@ -46,6 +78,63 @@ class LdapClientTest {
.isEqualTo("cn=developersgroup,ou=groups"); .isEqualTo("cn=developersgroup,ou=groups");
} }
@Test
void testLdap_notConfigured() {
lenient().when(this.environment.getProperty(TASKANA_LDAP_USE_LDAP.getKey())).thenReturn("true");
assertThatThrownBy(() -> cut.init()).isInstanceOf(SystemException.class);
}
@Test
void testLdap_getFirstPageOfaResultList() {
setUpEnvMock();
cut.init();
List<AccessIdResource> result =
IntStream.range(0, 100)
.mapToObj(i -> new AccessIdResource("" + i, "" + i))
.collect(Collectors.toList());
assertThat(cut.getFirstPageOfaResultList(result))
.hasSize(cut.getMaxNumberOfReturnedAccessIds());
}
@Test
void testLdap_useLdap_null() {
when(this.environment.getProperty(TASKANA_LDAP_USE_LDAP.getKey())).thenReturn(null);
assertThat(cut.useLdap()).isFalse();
}
@Test
void testLdap_useLdap_empty() {
when(this.environment.getProperty(TASKANA_LDAP_USE_LDAP.getKey())).thenReturn("");
assertThat(cut.useLdap()).isFalse();
}
@Test
void testLdap_useLdap_true() {
when(this.environment.getProperty(TASKANA_LDAP_USE_LDAP.getKey())).thenReturn("true");
assertThat(cut.useLdap()).isTrue();
}
@Test
void testLdap_isInitorFail() {
assertThatThrownBy(() -> cut.isInitOrFail()).isInstanceOf(SystemException.class);
setUpEnvMock();
cut.init();
assertThatCode(() -> cut.isInitOrFail()).doesNotThrowAnyException();
}
@Test
void testLdap_checkForMissingConfigurations() {
// optional config fields
// minSearchForLength, maxNumberOfReturnedAccessIds
assertThat(new LdapClient().checkForMissingConfigurations())
.hasSize(LdapSettings.values().length - 2);
}
private void setUpEnvMock() { private void setUpEnvMock() {
Stream.of( Stream.of(