From 08571e7216750b41cddedc4d28dd561898f07d84 Mon Sep 17 00:00:00 2001 From: Benjamin Eckstein <13351939+benjamineckstein@users.noreply.github.com> Date: Wed, 29 Jan 2020 16:21:19 +0100 Subject: [PATCH] TSK-1024: Add tests for ldapclient --- pom.xml | 3 + rest/taskana-rest-spring/pom.xml | 24 +++++++ .../java/pro/taskana/ldap/LdapClient.java | 29 +++++++-- .../java/pro/taskana/ldap/LdapClientTest.java | 63 +++++++++++++++++++ 4 files changed, 113 insertions(+), 6 deletions(-) create mode 100644 rest/taskana-rest-spring/src/test/java/pro/taskana/ldap/LdapClientTest.java diff --git a/pom.xml b/pom.xml index 52d8ca033..29dcea80f 100644 --- a/pom.xml +++ b/pom.xml @@ -75,6 +75,9 @@ 0.13.0 3.2.4 3.2.4 + + 1.9.7 + 1.9.7 2.0.5 2.2 3.1.12 diff --git a/rest/taskana-rest-spring/pom.xml b/rest/taskana-rest-spring/pom.xml index bbfefa2a3..38d74ffdf 100644 --- a/rest/taskana-rest-spring/pom.xml +++ b/rest/taskana-rest-spring/pom.xml @@ -139,6 +139,30 @@ ${version.spring.restdocs} test + + org.mockito + mockito-core + ${version.mockito} + test + + + org.mockito + mockito-junit-jupiter + ${version.junit.mockito} + test + + + net.bytebuddy + byte-buddy + ${version.byte-buddy} + test + + + net.bytebuddy + byte-buddy-agent + ${version.byte-buddy-agent} + test + com.h2database h2 diff --git a/rest/taskana-rest-spring/src/main/java/pro/taskana/ldap/LdapClient.java b/rest/taskana-rest-spring/src/main/java/pro/taskana/ldap/LdapClient.java index 49de6975c..51aa85f4b 100644 --- a/rest/taskana-rest-spring/src/main/java/pro/taskana/ldap/LdapClient.java +++ b/rest/taskana-rest-spring/src/main/java/pro/taskana/ldap/LdapClient.java @@ -1,6 +1,7 @@ package pro.taskana.ldap; import java.util.List; +import java.util.regex.Pattern; import javax.annotation.PostConstruct; import javax.naming.directory.SearchControls; import org.slf4j.Logger; @@ -64,6 +65,8 @@ public class LdapClient { private String groupsOfUser; + private String baseDn; + private int minSearchForLength; private int maxNumberOfReturnedAccessIds; @@ -182,16 +185,22 @@ public class LdapClient { 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 + // given 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 + // (?i) --> case insensitive replacement + String nameWithoutBaseDn = name.replaceAll("(?i)" + Pattern.quote("," + baseDn), ""); + LOGGER.debug( + "Removes baseDN {} from given DN. New DN to be used: {}", baseDn, nameWithoutBaseDn); String[] groupAttributesToReturn; if (CN.equals(groupNameAttribute)) { groupAttributesToReturn = new String[] {CN}; } else { groupAttributesToReturn = new String[] {getGroupNameAttribute(), CN}; } - final AccessIdResource accessId = - ldapTemplate.lookup(name, groupAttributesToReturn, new GroupContextMapper()); + ldapTemplate.lookup(nameWithoutBaseDn, groupAttributesToReturn, new GroupContextMapper()); LOGGER.debug("Exit from searchGroupByDn. Retrieved the following group: {}", accessId); return accessId; } @@ -261,6 +270,10 @@ public class LdapClient { return env.getProperty("taskana.ldap.groupSearchBase"); } + public String getBaseDn() { + return env.getProperty("taskana.ldap.baseDn"); + } + public String getGroupSearchFilterName() { return env.getProperty("taskana.ldap.groupSearchFilterName"); } @@ -298,7 +311,7 @@ public class LdapClient { } @PostConstruct - private void init() { + void init() { LOGGER.debug("Entry to init()"); String strMinSearchForLength = getMinSearchForLengthAsString(); if (strMinSearchForLength == null || strMinSearchForLength.isEmpty()) { @@ -326,6 +339,7 @@ public class LdapClient { groupSearchFilterValue = getGroupSearchFilterValue(); groupNameAttribute = getGroupNameAttribute(); groupsOfUser = getGroupsOfUser(); + baseDn = getBaseDn(); ldapTemplate.setDefaultCountLimit(maxNumberOfReturnedAccessIds); @@ -364,6 +378,9 @@ public class LdapClient { 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); } @@ -383,7 +400,7 @@ public class LdapClient { } /** Context Mapper for user entries. */ - private class UserContextMapper extends AbstractContextMapper { + class UserContextMapper extends AbstractContextMapper { @Override public AccessIdResource doMapFromContext(final DirContextOperations context) { @@ -397,7 +414,7 @@ public class LdapClient { } /** Context Mapper for user entries. */ - private class GroupContextMapper extends AbstractContextMapper { + class GroupContextMapper extends AbstractContextMapper { @Override public AccessIdResource doMapFromContext(final DirContextOperations context) { diff --git a/rest/taskana-rest-spring/src/test/java/pro/taskana/ldap/LdapClientTest.java b/rest/taskana-rest-spring/src/test/java/pro/taskana/ldap/LdapClientTest.java new file mode 100644 index 000000000..afaf4d8a7 --- /dev/null +++ b/rest/taskana-rest-spring/src/test/java/pro/taskana/ldap/LdapClientTest.java @@ -0,0 +1,63 @@ +package pro.taskana.ldap; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.lenient; +import static org.mockito.Mockito.verify; + +import java.util.stream.Stream; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoSettings; +import org.springframework.core.env.Environment; +import org.springframework.ldap.core.LdapTemplate; + +@MockitoSettings +class LdapClientTest { + + @Mock Environment environment; + + @Mock LdapTemplate ldapTemplate; + + @InjectMocks LdapClient cut; + + @Test + void testLdap() { + + setUpEnvMock(); + cut.init(); + + cut.searchGroupByDn("cn=developersgroup,ou=groups,o=taskanatest"); + + verify(ldapTemplate) + .lookup( + eq("cn=developersgroup,ou=groups"), any(), any(LdapClient.GroupContextMapper.class)); + } + + private void setUpEnvMock() { + Stream.of( + new String[][] { + {"taskana.ldap.useLdap", "true"}, + {"taskana.ldap.baseDn", "o=TaskanaTest"}, + {"taskana.ldap.userSearchBase", "ou=people"}, + {"taskana.ldap.userSearchFilterName", "objectclass"}, + {"taskana.ldap.groupsOfUser", "memberUid"}, + {"taskana.ldap.groupNameAttribute", "cn"}, + {"taskana.ldap.groupSearchFilterValue", "groupOfUniqueNames"}, + {"taskana.ldap.groupSearchFilterName", "objectclass"}, + {"taskana.ldap.groupSearchBase", "ou=groups"}, + {"taskana.ldap.userIdAttribute", "uid"}, + {"taskana.ldap.userLastnameAttribute", "sn"}, + {"taskana.ldap.userFirstnameAttribute", "givenName"}, + {"taskana.ldap.userFirstnameAttribute", "givenName"}, + {"taskana.ldap.userSearchFilterValue", "person"}, + {"taskana.ldap.bindDn", "uid=admin,ou=system"}, + {"taskana.ldap.bindPassword", "secret"}, + {"taskana.ldap.serverUrl", "ldap://localhost:10389"}, + }) + .forEach( + strings -> + lenient().when(this.environment.getProperty(strings[0])).thenReturn(strings[1])); + } +}