copy-documentation-to-static-folder
prepare-package
diff --git a/rest/taskana-rest-spring-example-wildfly/src/main/java/pro/taskana/wildfly/security/ElytronToJaasFilter.java b/rest/taskana-rest-spring-example-wildfly/src/main/java/pro/taskana/wildfly/security/ElytronToJaasFilter.java
index 83b9cd404..098fbbc02 100644
--- a/rest/taskana-rest-spring-example-wildfly/src/main/java/pro/taskana/wildfly/security/ElytronToJaasFilter.java
+++ b/rest/taskana-rest-spring-example-wildfly/src/main/java/pro/taskana/wildfly/security/ElytronToJaasFilter.java
@@ -7,8 +7,6 @@ import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.GenericFilterBean;
import org.wildfly.security.auth.server.SecurityDomain;
import org.wildfly.security.auth.server.SecurityIdentity;
@@ -24,52 +22,45 @@ public class ElytronToJaasFilter extends GenericFilterBean {
throws IOException, ServletException {
SecurityIdentity securityIdentity = getSecurityIdentity();
if (securityIdentity != null) {
- Roles roles = securityIdentity.getRoles();
- Subject subject = obtainSubject(request);
- if (subject != null) {
- if (subject.getPrincipals().size() == 0) {
- subject.getPrincipals().add(securityIdentity.getPrincipal());
- }
- if (subject.getPrincipals(GroupPrincipal.class).size() == 0) {
- roles.forEach(role -> subject.getPrincipals().add(new GroupPrincipal(role)));
- }
- }
+ applySecurityIdentityToSubject(securityIdentity);
}
chain.doFilter(request, response);
}
- /**
- * Obtains the Subject
to run as or null
if no Subject
is
- * available.
- *
- * The default implementation attempts to obtain the Subject
from the
- * SecurityContext
's Authentication
. If it is of type
- * JaasAuthenticationToken
and is authenticated, the Subject
is returned from
- * it. Otherwise, null
is returned.
- *
- * @param request the current ServletRequest
- * @return the Subject to run as or null
if no Subject
is available.
- */
- protected Subject obtainSubject(ServletRequest request) {
- Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
- if (logger.isDebugEnabled()) {
- logger.debug("Attempting to obtainSubject using authentication : " + authentication);
- }
- if (authentication == null) {
- return null;
- }
- if (!authentication.isAuthenticated()) {
- return null;
+ private void applySecurityIdentityToSubject(SecurityIdentity securityIdentity) {
+ Roles roles = securityIdentity.getRoles();
+ Subject subject = obtainSubject();
+ if (subject != null) {
+ if (subject.getPrincipals().size() == 0) {
+ subject.getPrincipals().add(securityIdentity.getPrincipal());
+ }
+ if (subject.getPrincipals(GroupPrincipal.class).size() == 0) {
+ roles.forEach(role -> subject.getPrincipals().add(new GroupPrincipal(role)));
+ }
+ if (logger.isDebugEnabled()) {
+ logger.debug("Current JAAS subject after applying Elytron SecurityIdentity: " + subject);
+ }
}
+ }
- return Subject.getSubject(AccessController.getContext());
+ private Subject obtainSubject() {
+ Subject subject = Subject.getSubject(AccessController.getContext());
+ if (logger.isDebugEnabled()) {
+ logger.debug("Current JAAS subject: " + subject);
+ }
+ return subject;
}
private SecurityIdentity getSecurityIdentity() {
SecurityDomain current = SecurityDomain.getCurrent();
+ SecurityIdentity identity = null;
if (current != null) {
- return current.getCurrentSecurityIdentity();
+ identity = current.getCurrentSecurityIdentity();
}
- return null;
+ if (logger.isDebugEnabled()) {
+ logger.debug("Current Elytron SecurityIdentity: " + identity);
+ }
+
+ return identity;
}
}
diff --git a/rest/taskana-rest-spring-example-wildfly/src/main/java/pro/taskana/wildfly/security/LogoutController.java b/rest/taskana-rest-spring-example-wildfly/src/main/java/pro/taskana/wildfly/security/LogoutController.java
new file mode 100644
index 000000000..fa6905ebb
--- /dev/null
+++ b/rest/taskana-rest-spring-example-wildfly/src/main/java/pro/taskana/wildfly/security/LogoutController.java
@@ -0,0 +1,49 @@
+package pro.taskana.wildfly.security;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.servlet.view.RedirectView;
+
+/** The logout controller. */
+@Controller
+public class LogoutController {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(LogoutController.class);
+
+ @GetMapping(path = "/logout")
+ public RedirectView loginErrorGet(HttpServletRequest request) {
+ return logout(request);
+ }
+
+ @PostMapping(path = "/logout")
+ public RedirectView loginErrorPost(HttpServletRequest request) {
+ return logout(request);
+ }
+
+ public RedirectView logout(HttpServletRequest request) {
+
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("Logging out...");
+ }
+
+ if (request.getSession(false) != null) {
+ request.getSession(false).invalidate(); // remove session.
+ }
+ if (request.getSession() != null) {
+ request.getSession().invalidate(); // remove session.
+ }
+
+ try {
+ request.logout();
+ } catch (ServletException e) {
+ LOGGER.warn("Exception caught while logging out: {}", e.getMessage());
+ }
+
+ return new RedirectView("/", true);
+ }
+}
diff --git a/rest/taskana-rest-spring-example-wildfly/src/main/java/pro/taskana/wildfly/security/WildflyWebSecurityConfig.java b/rest/taskana-rest-spring-example-wildfly/src/main/java/pro/taskana/wildfly/security/WildflyWebSecurityConfig.java
index db33a796b..b0ed2b225 100644
--- a/rest/taskana-rest-spring-example-wildfly/src/main/java/pro/taskana/wildfly/security/WildflyWebSecurityConfig.java
+++ b/rest/taskana-rest-spring-example-wildfly/src/main/java/pro/taskana/wildfly/security/WildflyWebSecurityConfig.java
@@ -1,29 +1,17 @@
package pro.taskana.wildfly.security;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
-import org.springframework.core.annotation.Order;
-import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.AuthenticationException;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.authority.SimpleGrantedAuthority;
-import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.security.core.userdetails.UsernameNotFoundException;
-import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider;
-import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
-import org.springframework.security.web.authentication.preauth.j2ee.J2eePreAuthenticatedProcessingFilter;
-import org.wildfly.security.auth.server.SecurityDomain;
-import org.wildfly.security.auth.server.SecurityIdentity;
-import org.wildfly.security.authz.Roles;
-
-import pro.taskana.rest.security.WebSecurityConfig;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.web.jaasapi.JaasApiIntegrationFilter;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+import org.springframework.web.filter.CorsFilter;
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* Default basic configuration for taskana web example running on Wildfly / JBoss with Elytron or
@@ -31,111 +19,46 @@ import pro.taskana.rest.security.WebSecurityConfig;
*/
@Configuration
@EnableWebSecurity
-@Order(1)
-public class WildflyWebSecurityConfig extends WebSecurityConfig {
-
- @Value("${devMode:false}")
- private boolean devMode;
+public class WildflyWebSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
- public J2eePreAuthenticatedProcessingFilter preAuthFilter() {
- J2eePreAuthenticatedProcessingFilter filter = new J2eePreAuthenticatedProcessingFilter();
- filter.setAuthenticationManager(preAuthManager());
+ public WebMvcConfigurer corsConfigurer() {
+ return new CorsWebMvcConfigurer();
+ }
+
+ @Bean
+ public FilterRegistrationBean corsFilter() {
+ final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+ CorsConfiguration config = new CorsConfiguration();
+ config.setAllowCredentials(true);
+ config.addAllowedOrigin("*");
+ config.addAllowedHeader("*");
+ config.addAllowedMethod("*");
+ source.registerCorsConfiguration("/**", config);
+ FilterRegistrationBean bean = new FilterRegistrationBean<>(new CorsFilter(source));
+ bean.setOrder(0);
+ return bean;
+ }
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ http.addFilter(jaasApiIntegrationFilter())
+ .addFilterAfter(new ElytronToJaasFilter(), JaasApiIntegrationFilter.class)
+ .csrf()
+ .disable();
+ }
+
+ protected JaasApiIntegrationFilter jaasApiIntegrationFilter() {
+ JaasApiIntegrationFilter filter = new JaasApiIntegrationFilter();
+ filter.setCreateEmptySubject(true);
return filter;
}
- @Bean
- public AuthenticationManager preAuthManager() {
- return new AuthenticationManager() {
-
- @Override
- public Authentication authenticate(Authentication authentication)
- throws AuthenticationException {
- return preauthAuthProvider().authenticate(authentication);
- }
- };
- }
-
- @Bean
- public PreAuthenticatedAuthenticationProvider preauthAuthProvider() {
- PreAuthenticatedAuthenticationProvider preauthAuthProvider =
- new PreAuthenticatedAuthenticationProvider();
- preauthAuthProvider.setPreAuthenticatedUserDetailsService(authenticationUserDetailsService());
- return preauthAuthProvider;
- }
-
- @Bean
- public AuthenticationUserDetailsService
- authenticationUserDetailsService() {
- return new PreAuthenticatedAuthenticationTokenAuthenticationUserDetailsService();
- }
-
- private static class PreAuthenticatedAuthenticationTokenAuthenticationUserDetailsService
- implements AuthenticationUserDetailsService {
+ private static class CorsWebMvcConfigurer implements WebMvcConfigurer {
@Override
- public UserDetails loadUserDetails(PreAuthenticatedAuthenticationToken token)
- throws UsernameNotFoundException {
- return new MyUserDetails(token);
- }
-
- private static class MyUserDetails implements UserDetails {
-
- private static final long serialVersionUID = 1L;
- private final PreAuthenticatedAuthenticationToken token;
-
- public MyUserDetails(PreAuthenticatedAuthenticationToken token) {
- this.token = token;
- }
-
- @Override
- public Collection extends GrantedAuthority> getAuthorities() {
- List authorities = new ArrayList<>();
- SecurityIdentity securityIdentity = getSecurityIdentity();
- if (securityIdentity != null) {
- Roles roles = securityIdentity.getRoles();
- roles.forEach(role -> authorities.add(new SimpleGrantedAuthority(role)));
- }
- return authorities;
- }
-
- @Override
- public String getPassword() {
- return (String) token.getCredentials();
- }
-
- @Override
- public String getUsername() {
- return token.getName();
- }
-
- @Override
- public boolean isAccountNonExpired() {
- return true;
- }
-
- @Override
- public boolean isAccountNonLocked() {
- return true;
- }
-
- @Override
- public boolean isCredentialsNonExpired() {
- return true;
- }
-
- @Override
- public boolean isEnabled() {
- return true;
- }
-
- private SecurityIdentity getSecurityIdentity() {
- SecurityDomain current = SecurityDomain.getCurrent();
- if (current != null) {
- return current.getCurrentSecurityIdentity();
- }
- return null;
- }
+ public void addCorsMappings(CorsRegistry registry) {
+ registry.addMapping("/**").allowedOrigins("*");
}
}
}
diff --git a/rest/taskana-rest-spring-example-wildfly/src/main/resources/application.properties b/rest/taskana-rest-spring-example-wildfly/src/main/resources/application.properties
index 70f050fbc..a3f4c6ad2 100644
--- a/rest/taskana-rest-spring-example-wildfly/src/main/resources/application.properties
+++ b/rest/taskana-rest-spring-example-wildfly/src/main/resources/application.properties
@@ -5,27 +5,29 @@ taskana.schemaName=TASKANA
####### properties to connect to LDAP
taskana.ldap.serverUrl=ldap://localhost:10389
-taskana.ldap.bindDn=uid=admin,ou=system
+taskana.ldap.bindDn=uid=admin
taskana.ldap.bindPassword=secret
-taskana.ldap.baseDn=o=TaskanaTest
-####### properties that control search for users and groups
-taskana.ldap.userSearchBase=ou=people
+taskana.ldap.baseDn=ou=Test,O=TASKANA
+taskana.ldap.userSearchBase=cn=users
taskana.ldap.userSearchFilterName=objectclass
taskana.ldap.userSearchFilterValue=person
taskana.ldap.userFirstnameAttribute=givenName
taskana.ldap.userLastnameAttribute=sn
taskana.ldap.userIdAttribute=uid
-taskana.ldap.groupSearchBase=ou=groups
+taskana.ldap.groupSearchBase=
taskana.ldap.groupSearchFilterName=objectclass
-taskana.ldap.groupSearchFilterValue=groupOfUniqueNames
+taskana.ldap.groupSearchFilterValue=groupofuniquenames
taskana.ldap.groupNameAttribute=cn
taskana.ldap.minSearchForLength=3
taskana.ldap.maxNumberOfReturnedAccessIds=50
-taskana.ldap.groupsOfUser=memberUid
+taskana.ldap.groupsOfUser=uniquemember
+
####### JobScheduler cron expression that specifies when the JobSchedler runs
taskana.jobscheduler.async.cron=0 * * * * *
+
####### cache static resources properties
spring.resources.cache.cachecontrol.cache-private=true
+
####### for upload of big workbasket- or classification-files
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB
@@ -38,3 +40,11 @@ server.tomcat.max-swallow-size=-1
####### tomcat is not detecting the x-forward headers from bluemix as a trustworthy proxy
server.tomcat.remoteip.internal-proxies=.*
server.forward-headers-strategy=native
+
+# Embedded Spring LDAP server
+spring.ldap.embedded.base-dn= OU=Test,O=TASKANA
+spring.ldap.embedded.credential.username= uid=admin
+spring.ldap.embedded.credential.password= secret
+spring.ldap.embedded.ldif=classpath:taskana-example.ldif
+spring.ldap.embedded.port= 10389
+spring.ldap.embedded.validation.enabled=false
diff --git a/rest/taskana-rest-spring-example-wildfly/src/main/webapp/WEB-INF/classes/logging.properties b/rest/taskana-rest-spring-example-wildfly/src/main/webapp/WEB-INF/classes/logging.properties
deleted file mode 100644
index fff4dd26a..000000000
--- a/rest/taskana-rest-spring-example-wildfly/src/main/webapp/WEB-INF/classes/logging.properties
+++ /dev/null
@@ -1,49 +0,0 @@
-# Note this file has been generated and will be overwritten if a
-# logging subsystem has been defined in the XML configuration.
-
-
-# Additional loggers to configure (the root logger is always configured)
-loggers=sun.rmi,org.jboss.as.config,com.arjuna,org.springframework,pro.taskana
-
-logger.level=INFO
-logger.handlers=FILE,CONSOLE
-
-logger.org.springframework.level=INFO
-logger.org.springframework.useParentHandlers=true
-
-logger.pro.taskana.level=INFO
-logger.pro.taskana.useParentHandlers=true
-
-logger.sun.rmi.level=WARN
-logger.sun.rmi.useParentHandlers=true
-
-logger.org.jboss.as.config.level=WARN
-logger.org.jboss.as.config.useParentHandlers=true
-
-logger.com.arjuna.level=WARN
-logger.com.arjuna.useParentHandlers=true
-
-handler.CONSOLE=org.jboss.logmanager.handlers.ConsoleHandler
-handler.CONSOLE.formatter=COLOR-PATTERN
-handler.CONSOLE.properties=autoFlush,target,enabled
-handler.CONSOLE.autoFlush=true
-handler.CONSOLE.target=SYSTEM_OUT
-handler.CONSOLE.enabled=true
-
-handler.FILE=org.jboss.logmanager.handlers.PeriodicRotatingFileHandler
-handler.FILE.formatter=PATTERN
-handler.FILE.properties=append,autoFlush,enabled,suffix,fileName
-handler.FILE.constructorProperties=fileName,append
-handler.FILE.append=true
-handler.FILE.autoFlush=true
-handler.FILE.enabled=true
-handler.FILE.suffix=.yyyy-MM-dd
-handler.FILE.fileName=${project.buildDir}/taskana/rest/taskana-rest-spring-example-wildfly/target/wildfly-11.0.0.Final/standalone/log/server.log
-
-formatter.PATTERN=org.jboss.logmanager.formatters.PatternFormatter
-formatter.PATTERN.properties=pattern
-formatter.PATTERN.pattern=%d{yyyy-MM-dd HH\:mm\:ss,SSS} %-5p [%c] (%t) %s%e%n
-
-formatter.COLOR-PATTERN=org.jboss.logmanager.formatters.PatternFormatter
-formatter.COLOR-PATTERN.properties=pattern
-formatter.COLOR-PATTERN.pattern=%K{level}%d{HH\:mm\:ss,SSS} %-5p [%c] (%t) %s%e%n
diff --git a/rest/taskana-rest-spring-example-wildfly/src/main/webapp/WEB-INF/jboss-web.xml b/rest/taskana-rest-spring-example-wildfly/src/main/webapp/WEB-INF/jboss-web.xml
index d4a965ce8..ada1b1905 100644
--- a/rest/taskana-rest-spring-example-wildfly/src/main/webapp/WEB-INF/jboss-web.xml
+++ b/rest/taskana-rest-spring-example-wildfly/src/main/webapp/WEB-INF/jboss-web.xml
@@ -4,4 +4,5 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee http://www.jboss.org/j2ee/schema/jboss-web_7_2.xsd">
/taskana
-
\ No newline at end of file
+ taskanaApplicationDomain
+
diff --git a/rest/taskana-rest-spring-example-wildfly/src/main/webapp/WEB-INF/web.xml b/rest/taskana-rest-spring-example-wildfly/src/main/webapp/WEB-INF/web.xml
index a415719e8..ddef49be3 100644
--- a/rest/taskana-rest-spring-example-wildfly/src/main/webapp/WEB-INF/web.xml
+++ b/rest/taskana-rest-spring-example-wildfly/src/main/webapp/WEB-INF/web.xml
@@ -1,15 +1,45 @@
-
- TaskanaRestWildflySpring
-
-
- FORM
-
- /login
- /loginerror
-
-
-
\ No newline at end of file
+ TaskanaRestWildflySpring
+
+ COOKIE
+
+
+ index.html
+
+
+
+ taskana-web
+ /*
+
+
+ *
+
+
+
+
+ Public
+ /css/main.css
+ /css/bootstrap/4.1.3/bootstrap.min.css
+ /css/bootstrap/4.1.3/bootstrap.min.css.map
+ /img/logo.png
+ /logout
+
+
+
+
+ *
+
+
+ FORM
+ taskanaApplicationDomain
+
+ /login
+ /login?error
+
+
+
diff --git a/rest/taskana-rest-spring-example-wildfly/src/test/java/pro/taskana/TaskanaWildflyTest.java b/rest/taskana-rest-spring-example-wildfly/src/test/java/pro/taskana/TaskanaWildflyTest.java
index 8b165f84f..a4f81b648 100644
--- a/rest/taskana-rest-spring-example-wildfly/src/test/java/pro/taskana/TaskanaWildflyTest.java
+++ b/rest/taskana-rest-spring-example-wildfly/src/test/java/pro/taskana/TaskanaWildflyTest.java
@@ -1,10 +1,16 @@
package pro.taskana;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
import java.io.File;
+import java.util.ArrayList;
import java.util.Collections;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.container.test.api.RunAsClient;
@@ -15,17 +21,22 @@ import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.shrinkwrap.resolver.api.maven.Maven;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.hateoas.MediaTypes;
+import org.springframework.hateoas.mediatype.hal.Jackson2HalModule;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
-import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;
+import pro.taskana.common.rest.models.AccessIdRepresentationModel;
import pro.taskana.common.rest.models.TaskanaUserInfoRepresentationModel;
+import pro.taskana.task.rest.models.TaskRepresentationModel;
/**
* This test class is configured to run with postgres DB if you want to run it with h2 it is needed.
@@ -34,9 +45,22 @@ import pro.taskana.common.rest.models.TaskanaUserInfoRepresentationModel;
@RunWith(Arquillian.class)
public class TaskanaWildflyTest {
+ private static final Logger LOGGER = LoggerFactory.getLogger(TaskanaWildflyTest.class);
+
+ public static final String AUTHORIZATION_TEAMLEAD_1 = "Basic dGVhbWxlYWQtMTp0ZWFtbGVhZC0x";
+
@Deployment(testable = false)
public static Archive> createTestArchive() {
+ String applicationPropertyFile = "application.properties";
+ String dbType = System.getProperty("db.type");
+ if (dbType != null && !dbType.isEmpty()) {
+ applicationPropertyFile = "application-" + dbType + ".properties";
+ }
+
+ LOGGER.info(
+ "Running with db.type '{}' and using property file '{}'", dbType, applicationPropertyFile);
+
File[] files =
Maven.resolver()
.loadPomFromFile("pom.xml")
@@ -48,35 +72,95 @@ public class TaskanaWildflyTest {
return ShrinkWrap.create(WebArchive.class, "taskana.war")
.addPackages(true, "pro.taskana")
.addAsResource("taskana.properties")
- .addAsResource("application.properties")
- .addAsResource("project-defaults.yml")
+ .addAsResource(applicationPropertyFile, "application.properties")
+ .addAsResource("taskana-test.ldif")
+ .addAsWebInfResource("int-test-web.xml", "web.xml")
+ .addAsWebInfResource("int-test-jboss-web.xml", "jboss-web.xml")
.addAsLibraries(files);
}
@Test
@RunAsClient
- public void shouldGetStatusOK() {
-
- HttpHeaders headers = new HttpHeaders();
- HttpEntity request = new HttpEntity<>(headers);
+ public void should_ReturnUserInformationForAuthenticatedUser_IfRequested() {
+ HttpEntity httpEntity = new HttpEntity<>(getHeadersTeamlead_1());
ResponseEntity response =
getRestTemplate()
.exchange(
- "http://127.0.0.1:" + "8090" + "/api/v1/current-user-info",
+ "http://127.0.0.1:" + "8080" + "/taskana/api/v1/current-user-info",
HttpMethod.GET,
- request,
+ httpEntity,
ParameterizedTypeReference.forType(TaskanaUserInfoRepresentationModel.class));
assertEquals(HttpStatus.OK, response.getStatusCode());
+ TaskanaUserInfoRepresentationModel currentUser = response.getBody();
+ assertEquals("teamlead-1", currentUser.getUserId());
+ assertEquals(4, currentUser.getGroupIds().size());
+ assertEquals(3, currentUser.getRoles().size());
}
- private RestTemplate getRestTemplate() {
+ @Test
+ @RunAsClient
+ public void should_ReturnUserFromLdap_WhenWildcardSearchIsConducted() {
+ HttpEntity httpEntity = new HttpEntity<>(getHeadersTeamlead_1());
+ ResponseEntity response =
+ getRestTemplate()
+ .exchange(
+ "http://127.0.0.1:8080/taskana/api/v1/access-ids?search-for=rig",
+ HttpMethod.GET,
+ httpEntity,
+ ParameterizedTypeReference.forType(AccessIdListResource.class));
+ assertEquals(HttpStatus.OK, response.getStatusCode());
+ AccessIdListResource accessIdList = response.getBody();
+ assertEquals(2, accessIdList.size());
+ }
+
+ @Test
+ @RunAsClient
+ public void should_ReturnTask_WhenRequested() {
+ HttpEntity httpEntity = new HttpEntity<>(getHeadersTeamlead_1());
+ ResponseEntity response =
+ getRestTemplate()
+ .exchange(
+ "http://127.0.0.1:8080/taskana/api/v1/tasks/TKI:000000000000000000000000000000000001",
+ HttpMethod.GET,
+ httpEntity,
+ ParameterizedTypeReference.forType(TaskRepresentationModel.class));
+ assertEquals(HttpStatus.OK, response.getStatusCode());
+ assertThat(response.getBody()).isNotNull();
+ }
+
+ /**
+ * Return a REST template which is capable of dealing with responses in HAL format.
+ *
+ * @return RestTemplate
+ */
+ private static RestTemplate getRestTemplate() {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
+ mapper.registerModule(new Jackson2HalModule());
+ mapper
+ .registerModule(new ParameterNamesModule())
+ .registerModule(new Jdk8Module())
+ .registerModule(new JavaTimeModule());
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
- converter.setSupportedMediaTypes(MediaType.parseMediaTypes("application/json"));
+ converter.setSupportedMediaTypes(Collections.singletonList(MediaTypes.HAL_JSON));
converter.setObjectMapper(mapper);
- return new RestTemplate(Collections.singletonList(converter));
+ RestTemplate template = new RestTemplate();
+ // important to add first to ensure priority
+ template.getMessageConverters().add(0, converter);
+ return template;
+ }
+
+ private HttpHeaders getHeadersTeamlead_1() {
+ HttpHeaders headers = new HttpHeaders();
+ headers.add("Authorization", AUTHORIZATION_TEAMLEAD_1);
+ headers.add("Content-Type", "application/json");
+ return headers;
+ }
+
+ static class AccessIdListResource extends ArrayList {
+ private static final long serialVersionUID = 1L;
}
}
diff --git a/rest/taskana-rest-spring-example-wildfly/src/test/resources/application-postgres.properties b/rest/taskana-rest-spring-example-wildfly/src/test/resources/application-postgres.properties
new file mode 100644
index 000000000..df080c351
--- /dev/null
+++ b/rest/taskana-rest-spring-example-wildfly/src/test/resources/application-postgres.properties
@@ -0,0 +1,46 @@
+logging.level.pro.taskana=DEBUG
+logging.level.org.springframework=DEBUG
+
+######## Taskana DB #######
+datasource.jndi=java:/TaskanaDS/PostgreSQL
+taskana.schemaName=taskana
+
+devMode=true
+
+####### properties to connect to LDAP
+taskana.ldap.serverUrl=ldap://localhost:10389
+taskana.ldap.bindDn=uid=admin
+taskana.ldap.bindPassword=secret
+taskana.ldap.baseDn=ou=Test,O=TASKANA
+taskana.ldap.userSearchBase=cn=users
+taskana.ldap.userSearchFilterName=objectclass
+taskana.ldap.userSearchFilterValue=person
+taskana.ldap.userFirstnameAttribute=givenName
+taskana.ldap.userLastnameAttribute=sn
+taskana.ldap.userIdAttribute=uid
+taskana.ldap.groupSearchBase=
+taskana.ldap.groupSearchFilterName=objectclass
+taskana.ldap.groupSearchFilterValue=groupOfUniqueNames
+taskana.ldap.groupNameAttribute=cn
+taskana.ldap.minSearchForLength=3
+taskana.ldap.maxNumberOfReturnedAccessIds=50
+taskana.ldap.groupsOfUser=uniquemember
+
+####### JobScheduler cron expression that specifies when the JobSchedler runs
+taskana.jobscheduler.async.cron=0 * * * * *
+
+####### cache static resources propertiesgit add --
+spring.resources.cache.cachecontrol.cache-private=true
+spring.main.allow-bean-definition-overriding=true
+
+####### tomcat is not detecting the x-forward headers from bluemix as a trustworthy proxy
+server.tomcat.remoteip.internal-proxies=.*
+server.forward-headers-strategy=native
+
+# Embedded Spring LDAP server
+spring.ldap.embedded.base-dn= OU=Test,O=TASKANA
+spring.ldap.embedded.credential.username= uid=admin
+spring.ldap.embedded.credential.password= secret
+spring.ldap.embedded.ldif=classpath:taskana-test.ldif
+spring.ldap.embedded.port= 10389
+spring.ldap.embedded.validation.enabled=false
diff --git a/rest/taskana-rest-spring-example-wildfly/src/test/resources/application.properties b/rest/taskana-rest-spring-example-wildfly/src/test/resources/application.properties
index b324dc0dc..3723cd88b 100644
--- a/rest/taskana-rest-spring-example-wildfly/src/test/resources/application.properties
+++ b/rest/taskana-rest-spring-example-wildfly/src/test/resources/application.properties
@@ -1,31 +1,34 @@
-logging.level.pro.taskana=INFO
-### logging.level.org.springframework=DEBUG
+logging.level.pro.taskana=DEBUG
+logging.level.org.springframework=DEBUG
+
######## Taskana DB #######
-datasource.jndi=java:jboss/datasources/TestDS
-taskana.schemaName=taskana
+datasource.jndi=java:/TaskanaDS/H2
+taskana.schemaName=TASKANA
devMode=true
+
####### properties to connect to LDAP
taskana.ldap.serverUrl=ldap://localhost:10389
-taskana.ldap.bindDn=uid=admin,ou=system
+taskana.ldap.bindDn=uid=admin
taskana.ldap.bindPassword=secret
-taskana.ldap.baseDn=o=TaskanaTest
-####### properties that control search for users and groups
-taskana.ldap.userSearchBase=ou=people
+taskana.ldap.baseDn=ou=Test,O=TASKANA
+taskana.ldap.userSearchBase=cn=users
taskana.ldap.userSearchFilterName=objectclass
taskana.ldap.userSearchFilterValue=person
taskana.ldap.userFirstnameAttribute=givenName
taskana.ldap.userLastnameAttribute=sn
taskana.ldap.userIdAttribute=uid
-taskana.ldap.groupSearchBase=ou=groups
+taskana.ldap.groupSearchBase=
taskana.ldap.groupSearchFilterName=objectclass
taskana.ldap.groupSearchFilterValue=groupOfUniqueNames
taskana.ldap.groupNameAttribute=cn
taskana.ldap.minSearchForLength=3
taskana.ldap.maxNumberOfReturnedAccessIds=50
-taskana.ldap.groupsOfUser=memberUid
+taskana.ldap.groupsOfUser=uniquemember
+
####### JobScheduler cron expression that specifies when the JobSchedler runs
taskana.jobscheduler.async.cron=0 * * * * *
+
####### cache static resources propertiesgit add --
spring.resources.cache.cachecontrol.cache-private=true
spring.main.allow-bean-definition-overriding=true
@@ -33,3 +36,11 @@ spring.main.allow-bean-definition-overriding=true
####### tomcat is not detecting the x-forward headers from bluemix as a trustworthy proxy
server.tomcat.remoteip.internal-proxies=.*
server.forward-headers-strategy=native
+
+# Embedded Spring LDAP server
+spring.ldap.embedded.base-dn= OU=Test,O=TASKANA
+spring.ldap.embedded.credential.username= uid=admin
+spring.ldap.embedded.credential.password= secret
+spring.ldap.embedded.ldif=classpath:taskana-test.ldif
+spring.ldap.embedded.port= 10389
+spring.ldap.embedded.validation.enabled=false
diff --git a/rest/taskana-rest-spring-example-wildfly/src/test/resources/arquillian.xml b/rest/taskana-rest-spring-example-wildfly/src/test/resources/arquillian.xml
new file mode 100644
index 000000000..5ce724d17
--- /dev/null
+++ b/rest/taskana-rest-spring-example-wildfly/src/test/resources/arquillian.xml
@@ -0,0 +1,16 @@
+
+
+
+
+ target/wildfly-13.0.0.Final
+ ../../../../src/test/resources/int-test-standalone.xml
+
+ -Djava.util.logging.manager=org.jboss.logmanager.LogManager
+
+
+
\ No newline at end of file
diff --git a/rest/taskana-rest-spring-example-wildfly/src/test/resources/int-test-jboss-web.xml b/rest/taskana-rest-spring-example-wildfly/src/test/resources/int-test-jboss-web.xml
new file mode 100644
index 000000000..ada1b1905
--- /dev/null
+++ b/rest/taskana-rest-spring-example-wildfly/src/test/resources/int-test-jboss-web.xml
@@ -0,0 +1,8 @@
+
+
+ /taskana
+ taskanaApplicationDomain
+
diff --git a/rest/taskana-rest-spring-example-wildfly/src/test/resources/int-test-standalone.xml b/rest/taskana-rest-spring-example-wildfly/src/test/resources/int-test-standalone.xml
new file mode 100644
index 000000000..049ab7988
--- /dev/null
+++ b/rest/taskana-rest-spring-example-wildfly/src/test/resources/int-test-standalone.xml
@@ -0,0 +1,849 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
+
+ h2
+
+ sa
+ sa
+
+
+
+ jdbc:h2:mem:test;DB_CLOSE_DELAY=-1
+
+ org.h2.Driver
+ h2
+
+ sa
+ sa
+
+
+ false
+
+
+
+
+ jdbc:postgresql://localhost:50102/postgres
+
+ org.postgresql.Driver
+ postgresql
+
+ postgres
+ postgres
+
+
+ false
+
+
+
+
+
+ org.h2.jdbcx.JdbcDataSource
+
+
+
+ org.postgresql.Driver
+
+
+
+
+
+
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ${jboss.bind.address:127.0.0.1}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/rest/taskana-rest-spring-example-wildfly/src/test/resources/int-test-web.xml b/rest/taskana-rest-spring-example-wildfly/src/test/resources/int-test-web.xml
new file mode 100644
index 000000000..23f569d4d
--- /dev/null
+++ b/rest/taskana-rest-spring-example-wildfly/src/test/resources/int-test-web.xml
@@ -0,0 +1,41 @@
+
+
+ TaskanaRestWildflySpring
+
+ COOKIE
+
+
+ index.html
+
+
+
+ taskana-web
+ /*
+
+
+ *
+
+
+
+
+ Public
+ /css/main.css
+ /css/bootstrap/4.1.3/bootstrap.min.css
+ /css/bootstrap/4.1.3/bootstrap.min.css.map
+ /img/logo.png
+ /logout
+
+
+
+
+ *
+
+
+ BASIC
+ taskanaApplicationDomain
+
+
diff --git a/rest/taskana-rest-spring-example-wildfly/src/test/resources/module.xml b/rest/taskana-rest-spring-example-wildfly/src/test/resources/module.xml
new file mode 100644
index 000000000..42d3a28d7
--- /dev/null
+++ b/rest/taskana-rest-spring-example-wildfly/src/test/resources/module.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/rest/taskana-rest-spring-example-wildfly/src/test/resources/project-defaults.yml b/rest/taskana-rest-spring-example-wildfly/src/test/resources/project-defaults.yml
deleted file mode 100644
index 511c208c5..000000000
--- a/rest/taskana-rest-spring-example-wildfly/src/test/resources/project-defaults.yml
+++ /dev/null
@@ -1,19 +0,0 @@
-swarm:
- port:
- offset: 10
- datasources:
- data-sources:
- TestDS:
- driver-name: postgresql
- connection-url: jdbc:postgresql://localhost:50102/postgres
- user-name: postgres
- password: postgres
- jdbc-drivers:
- mypostgres:
- driver-class-name: org.postgresql.Driver
- xa-datasource-name: org.postgresql.xa.PGXADataSource
- driver-module-name: org.postgresql
- myh2:
- driver-class-name: org.h2.Driver
- xa-datasource-name: org.h2.jdbcx.JdbcDataSource
- driver-module-name: com.h2database.h2
diff --git a/rest/taskana-rest-spring-example-wildfly/src/test/resources/taskana-test.ldif b/rest/taskana-rest-spring-example-wildfly/src/test/resources/taskana-test.ldif
new file mode 100644
index 000000000..a4196c95c
--- /dev/null
+++ b/rest/taskana-rest-spring-example-wildfly/src/test/resources/taskana-test.ldif
@@ -0,0 +1,258 @@
+######################
+# Base Structure
+######################
+dn: OU=Test,O=TASKANA
+ou: Organisationseinheit
+objectclass: top
+objectclass: organizationalUnit
+
+dn: cn=groups,OU=Test,O=TASKANA
+cn: groups
+objectclass: top
+objectclass: container
+
+dn: cn=users,OU=Test,O=TASKANA
+cn: users
+objectclass: top
+objectclass: container
+
+dn: cn=organisation,OU=Test,O=TASKANA
+cn: organisation
+objectclass: top
+objectclass: container
+
+
+########################
+# Users General
+########################
+dn: uid=monitor,cn=users,OU=Test,O=TASKANA
+objectclass: inetorgperson
+objectclass: organizationalperson
+objectclass: person
+objectclass: top
+givenName: Monitor
+description: desc
+uid: monitor
+sn: Monitor
+ou: Organisationseinheit/Organisationseinheit IT
+cn: monitor monitor
+userPassword: monitor
+
+dn: uid=taskadmin,cn=users,OU=Test,O=TASKANA
+objectclass: inetorgperson
+objectclass: organizationalperson
+objectclass: person
+objectclass: top
+givenName: Task
+description: desc
+uid: taskadmin
+sn: Admin
+ou: Organisationseinheit/Organisationseinheit IT
+cn: Task admin
+userPassword: taskadmin
+
+dn: uid=admin,cn=users,OU=Test,O=TASKANA
+objectclass: inetorgperson
+objectclass: organizationalperson
+objectclass: person
+objectclass: top
+givenName: Admin
+description: desc
+uid: admin
+sn: Admin
+ou: Organisationseinheit/Organisationseinheit IT
+cn: Admin Admin
+userPassword: admin
+
+dn: uid=businessadmin,cn=users,OU=Test,O=TASKANA
+objectclass: inetorgperson
+objectclass: organizationalperson
+objectclass: person
+objectclass: top
+givenName: Business
+description: desc
+uid: businessadmin
+sn: Admin
+ou: Organisationseinheit/Organisationseinheit IT
+cn: Business Admin
+userPassword: businessadmin
+
+########################
+# Users KSC 1
+########################
+dn: uid=teamlead-1,cn=users,OU=Test,O=TASKANA
+objectclass: inetorgperson
+objectclass: organizationalperson
+objectclass: person
+objectclass: top
+givenName: Titus
+description: desc
+uid: teamlead-1
+sn: Toll
+ou: Organisationseinheit/Organisationseinheit KSC/Organisationseinheit KSC 1
+cn: Titus Toll
+userPassword: teamlead-1
+
+dn: uid=user-1-1,cn=users,OU=Test,O=TASKANA
+objectclass: inetorgperson
+objectclass: organizationalperson
+objectclass: person
+objectclass: top
+givenName: Max
+description: desc
+uid: user-1-1
+sn: Mustermann
+ou: Organisationseinheit/Organisationseinheit KSC/Organisationseinheit KSC 1
+cn: Max Mustermann
+userPassword: user-1-1
+
+dn: uid=user-1-2,cn=users,OU=Test,O=TASKANA
+objectclass: inetorgperson
+objectclass: organizationalperson
+objectclass: person
+objectclass: top
+givenName: Elena
+description: desc
+uid: user-1-2
+sn: Eifrig
+ou: Organisationseinheit/Organisationseinheit KSC/Organisationseinheit KSC 1
+cn: Elena Eifrig
+userPassword: user-1-2
+
+########################
+# Users KSC 2
+########################
+dn: uid=teamlead-2,cn=users,OU=Test,O=TASKANA
+objectclass: inetorgperson
+objectclass: organizationalperson
+objectclass: person
+objectclass: top
+givenName: Frauke
+description: desc
+uid: teamlead-2
+sn: Faul
+ou: Organisationseinheit/Organisationseinheit KSC/Organisationseinheit KSC 2
+cn: Frauke Faul
+userPassword: teamlead-2
+
+dn: uid=user-2-1,cn=users,OU=Test,O=TASKANA
+objectclass: inetorgperson
+objectclass: organizationalperson
+objectclass: person
+objectclass: top
+givenName: Simone
+description: desc
+uid: user-2-1
+sn: Müller
+ou: Organisationseinheit/Organisationseinheit KSC/Organisationseinheit KSC 2
+cn: Simone Müller
+userPassword: user-2-1
+
+dn: uid=user-2-2,cn=users,OU=Test,O=TASKANA
+objectclass: inetorgperson
+objectclass: organizationalperson
+objectclass: person
+objectclass: top
+givenName: Tim
+description: desc
+uid: user-2-2
+sn:: U2NobMOkZnJpZw==
+ou: Organisationseinheit/Organisationseinheit KSC/Organisationseinheit KSC 2
+cn:: VGltIFNjaGzDpGZyaWc=
+userPassword: user-2-1
+
+########################
+# Users Domäne B
+########################
+dn: uid=user-b-1,cn=users,OU=Test,O=TASKANA
+objectclass: inetorgperson
+objectclass: organizationalperson
+objectclass: person
+objectclass: top
+givenName: Bernd
+description: desc
+uid: user-b-1
+sn: Bern
+ou: Organisationseinheit/Organisationseinheit B
+cn: Bernd Bern
+userPassword: user-b-1
+
+dn: uid=user-b-2,cn=users,OU=Test,O=TASKANA
+objectclass: inetorgperson
+objectclass: organizationalperson
+objectclass: person
+objectclass: top
+givenName: Brunhilde
+description: desc
+uid: user-b-2
+sn: Bio
+ou: Organisationseinheit/Organisationseinheit B
+cn: Brunhilde Bio
+userPassword: user-b-2
+
+
+########################
+# Groups
+########################
+dn: cn=ksc-users,cn=groups,OU=Test,O=TASKANA
+uniquemember: uid=user-1-1,cn=users,OU=Test,O=TASKANA
+uniquemember: uid=user-1-2,cn=users,OU=Test,O=TASKANA
+uniquemember: uid=user-2-1,cn=users,OU=Test,O=TASKANA
+uniquemember: uid=user-2-2,cn=users,OU=Test,O=TASKANA
+cn: ksc-users
+objectclass: groupofuniquenames
+objectclass: top
+
+dn: cn=ksc-teamleads,cn=groups,OU=Test,O=TASKANA
+uniquemember: uid=teamlead-1,cn=users,OU=Test,O=TASKANA
+uniquemember: uid=teamlead-2,cn=users,OU=Test,O=TASKANA
+cn: ksc-teamleads
+objectclass: groupofuniquenames
+objectclass: top
+
+dn: cn=business-admins,cn=groups,OU=Test,O=TASKANA
+uniquemember: uid=teamlead-1,cn=users,OU=Test,O=TASKANA
+uniquemember: uid=teamlead-2,cn=users,OU=Test,O=TASKANA
+uniquemember: uid=businessadmin,cn=users,OU=Test,O=TASKANA
+cn: business-admins
+objectclass: groupofuniquenames
+objectclass: top
+
+dn: cn=monitor-users,cn=groups,OU=Test,O=TASKANA
+uniquemember: uid=teamlead-1,cn=users,OU=Test,O=TASKANA
+uniquemember: uid=teamlead-2,cn=users,OU=Test,O=TASKANA
+cn: monitor-users
+objectclass: groupofuniquenames
+objectclass: top
+
+######################
+# Organizational Units
+######################
+dn: cn=Organisationseinheit KSC,cn=organisation,OU=Test,O=TASKANA
+cn: Organisationseinheit KSC
+uniquemember: cn=Organisationseinheit KSC 1,cn=Organisationseinheit KSC,cn=organisation,OU=Test,O=TASKANA
+uniquemember: cn=Organisationseinheit KSC 2,cn=Organisationseinheit KSC,cn=organisation,OU=Test,O=TASKANA
+objectclass: groupofuniquenames
+objectclass: top
+
+dn: cn=Organisationseinheit KSC 1,cn=Organisationseinheit KSC,cn=organisation,OU=Test,O=TASKANA
+uniquemember: uid=teamlead-1,cn=users,OU=Test,O=TASKANA
+uniquemember: uid=user-1-1,cn=users,OU=Test,O=TASKANA
+uniquemember: uid=user-1-2,cn=users,OU=Test,O=TASKANA
+cn: Organisationseinheit KSC 1
+objectclass: groupofuniquenames
+objectclass: top
+
+dn: cn=Organisationseinheit KSC 2,cn=Organisationseinheit KSC,cn=organisation,OU=Test,O=TASKANA
+uniquemember: uid=teamlead-2,cn=users,OU=Test,O=TASKANA
+uniquemember: uid=user-2-1,cn=users,OU=Test,O=TASKANA
+uniquemember: uid=user-2-2,cn=users,OU=Test,O=TASKANA
+cn: Organisationseinheit KSC 2
+objectclass: groupofuniquenames
+objectclass: top
+
+dn: cn=Organisationseinheit B,cn=organisation,OU=Test,O=TASKANA
+cn: Organisationseinheit B
+objectclass: groupofuniquenames
+objectclass: top
+