TSK-1634: Endpoint in AccessIdController to search users and members of groups configured with TASKANA user role
This commit is contained in:
parent
4c94281a64
commit
38363b81d6
|
@ -14,6 +14,7 @@ taskana.ldap.userFirstnameAttribute=givenName
|
|||
taskana.ldap.userLastnameAttribute=sn
|
||||
taskana.ldap.userFullnameAttribute=cn
|
||||
taskana.ldap.userIdAttribute=uid
|
||||
taskana.ldap.userMemberOfGroupAttribute=
|
||||
taskana.ldap.groupSearchBase=cn=groups
|
||||
taskana.ldap.groupSearchFilterName=objectclass
|
||||
taskana.ldap.groupSearchFilterValue=groupOfUniqueNames
|
||||
|
|
|
@ -68,6 +68,7 @@ taskana.ldap.userFirstnameAttribute=givenName
|
|||
taskana.ldap.userLastnameAttribute=sn
|
||||
taskana.ldap.userFullnameAttribute=cn
|
||||
taskana.ldap.userIdAttribute=uid
|
||||
taskana.ldap.userMemberOfGroupAttribute=
|
||||
taskana.ldap.groupSearchBase=
|
||||
taskana.ldap.groupSearchFilterName=objectclass
|
||||
taskana.ldap.groupSearchFilterValue=groupofuniquenames
|
||||
|
|
|
@ -24,6 +24,7 @@ taskana.ldap.userFirstnameAttribute=givenName
|
|||
taskana.ldap.userLastnameAttribute=sn
|
||||
taskana.ldap.userFullnameAttribute=cn
|
||||
taskana.ldap.userIdAttribute=uid
|
||||
taskana.ldap.userMemberOfGroupAttribute=
|
||||
taskana.ldap.groupSearchBase=cn=groups
|
||||
taskana.ldap.groupSearchFilterName=objectclass
|
||||
taskana.ldap.groupSearchFilterValue=groupOfUniqueNames
|
||||
|
|
|
@ -19,6 +19,7 @@ taskana.ldap.userFirstnameAttribute=givenName
|
|||
taskana.ldap.userLastnameAttribute=sn
|
||||
taskana.ldap.userFullnameAttribute=cn
|
||||
taskana.ldap.userIdAttribute=uid
|
||||
taskana.ldap.userMemberOfGroupAttribute=
|
||||
taskana.ldap.groupSearchBase=
|
||||
taskana.ldap.groupSearchFilterName=objectclass
|
||||
taskana.ldap.groupSearchFilterValue=groupOfUniqueNames
|
||||
|
|
|
@ -19,6 +19,7 @@ taskana.ldap.userFirstnameAttribute=givenName
|
|||
taskana.ldap.userLastnameAttribute=sn
|
||||
taskana.ldap.userFullnameAttribute=cn
|
||||
taskana.ldap.userIdAttribute=uid
|
||||
taskana.ldap.userMemberOfGroupAttribute=
|
||||
taskana.ldap.groupSearchBase=
|
||||
taskana.ldap.groupSearchFilterName=objectclass
|
||||
taskana.ldap.groupSearchFilterValue=groupOfUniqueNames
|
||||
|
|
|
@ -62,6 +62,47 @@ public class AccessIdController {
|
|||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* This endpoint searches users for a provided name or Access Id. It will only search and return
|
||||
* users and members of groups which are configured with the requested TASKANA role. This
|
||||
* search will only work if the users in the configured LDAP have an attribute that shows their
|
||||
* group memberships, e.g. "memberOf"
|
||||
*
|
||||
* @title Search for Access Id (users) in TASKANA user role
|
||||
* @param nameOrAccessId the name or Access Id which should be searched for.
|
||||
* @param role the role for which all users should be searched for
|
||||
* @return a list of all found Access Ids (users)
|
||||
* @throws InvalidArgumentException if the provided search for Access Id is shorter than the
|
||||
* configured one.
|
||||
*/
|
||||
@GetMapping(path = RestEndpoints.URL_USER)
|
||||
public ResponseEntity<List<AccessIdRepresentationModel>> searchUsersByNameOrAccessIdForRole(
|
||||
@RequestParam("search-for") String nameOrAccessId, @RequestParam("role") String role)
|
||||
throws InvalidArgumentException {
|
||||
|
||||
LOGGER.debug(
|
||||
"Entry to searchUsersByNameOrAccessIdForRole(search-for= {}, role= {})",
|
||||
nameOrAccessId,
|
||||
role);
|
||||
|
||||
if (role.equals("user")) {
|
||||
List<AccessIdRepresentationModel> accessIdUsers =
|
||||
ldapClient.searchUsersByNameOrAccessIdInUserRole(nameOrAccessId);
|
||||
ResponseEntity<List<AccessIdRepresentationModel>> response = ResponseEntity.ok(accessIdUsers);
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug(
|
||||
"Exit from searchUsersByNameOrAccessIdForRole(), returning {}", response);
|
||||
}
|
||||
|
||||
return response;
|
||||
} else {
|
||||
throw new InvalidArgumentException(
|
||||
String.format(
|
||||
"Requested users for not supported role %s. Only role 'user' is supported'", role));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This endpoint retrieves all groups a given Access Id belongs to.
|
||||
*
|
||||
|
|
|
@ -17,6 +17,7 @@ public final class RestEndpoints {
|
|||
|
||||
// access id endpoints
|
||||
public static final String URL_ACCESS_ID = API_V1 + "access-ids";
|
||||
public static final String URL_USER = API_V1 + "users";
|
||||
public static final String URL_ACCESS_ID_GROUPS = API_V1 + "access-ids/groups";
|
||||
|
||||
// import / export endpoints
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.util.ArrayList;
|
|||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
@ -23,6 +24,8 @@ import org.springframework.ldap.filter.WhitespaceWildcardsFilter;
|
|||
import org.springframework.ldap.support.LdapNameBuilder;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
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;
|
||||
|
@ -34,6 +37,7 @@ public class LdapClient {
|
|||
private static final Logger LOGGER = LoggerFactory.getLogger(LdapClient.class);
|
||||
private static final String CN = "cn";
|
||||
|
||||
private final TaskanaEngineConfiguration taskanaEngineConfiguration;
|
||||
private final Environment env;
|
||||
private final LdapTemplate ldapTemplate;
|
||||
private boolean active = false;
|
||||
|
@ -42,9 +46,13 @@ public class LdapClient {
|
|||
private String message;
|
||||
|
||||
@Autowired
|
||||
public LdapClient(Environment env, LdapTemplate ldapTemplate) {
|
||||
public LdapClient(
|
||||
Environment env,
|
||||
LdapTemplate ldapTemplate,
|
||||
TaskanaEngineConfiguration taskanaEngineConfiguration) {
|
||||
this.env = env;
|
||||
this.ldapTemplate = ldapTemplate;
|
||||
this.taskanaEngineConfiguration = taskanaEngineConfiguration;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -83,6 +91,49 @@ public class LdapClient {
|
|||
return result;
|
||||
}
|
||||
|
||||
public List<AccessIdRepresentationModel> searchUsersByNameOrAccessIdInUserRole(
|
||||
final String nameOrAccessId) throws InvalidArgumentException {
|
||||
|
||||
LOGGER.debug(
|
||||
"entry to searchUsersByNameOrAccessIdInUserRoleGroups(nameOrAccessId = {}).",
|
||||
nameOrAccessId);
|
||||
|
||||
isInitOrFail();
|
||||
testMinSearchForLength(nameOrAccessId);
|
||||
|
||||
final OrFilter userDetailsOrFilter = new OrFilter();
|
||||
userDetailsOrFilter.or(
|
||||
new WhitespaceWildcardsFilter(getUserFirstnameAttribute(), nameOrAccessId));
|
||||
userDetailsOrFilter.or(
|
||||
new WhitespaceWildcardsFilter(getUserLastnameAttribute(), nameOrAccessId));
|
||||
userDetailsOrFilter.or(
|
||||
new WhitespaceWildcardsFilter(getUserFullnameAttribute(), nameOrAccessId));
|
||||
userDetailsOrFilter.or(new WhitespaceWildcardsFilter(getUserIdAttribute(), nameOrAccessId));
|
||||
|
||||
Set<String> userGroups = taskanaEngineConfiguration.getRoleMap().get(TaskanaRole.USER);
|
||||
|
||||
final OrFilter groupMembershipOrFilter = new OrFilter();
|
||||
userGroups.forEach(
|
||||
group ->
|
||||
groupMembershipOrFilter.or(new EqualsFilter(getUserMemberOfGroupAttribute(), group)));
|
||||
|
||||
final AndFilter andFilter = new AndFilter();
|
||||
andFilter.and(userDetailsOrFilter);
|
||||
andFilter.and(groupMembershipOrFilter);
|
||||
|
||||
final List<AccessIdRepresentationModel> accessIds =
|
||||
ldapTemplate.search(
|
||||
getUserSearchBase(),
|
||||
andFilter.encode(),
|
||||
SearchControls.SUBTREE_SCOPE,
|
||||
getLookUpUserAttributesToReturn(),
|
||||
new UserContextMapper());
|
||||
LOGGER.debug(
|
||||
"exit from searchUsersByNameOrAccessIdInUserRoleGroups. Retrieved the following users: {}.",
|
||||
accessIds);
|
||||
return accessIds;
|
||||
}
|
||||
|
||||
public List<AccessIdRepresentationModel> searchUsersByNameOrAccessId(final String name)
|
||||
throws InvalidArgumentException {
|
||||
LOGGER.debug("entry to searchUsersByNameOrAccessId(name = {}).", name);
|
||||
|
@ -278,6 +329,10 @@ public class LdapClient {
|
|||
return LdapSettings.TASKANA_LDAP_USER_ID_ATTRIBUTE.getValueFromEnv(env);
|
||||
}
|
||||
|
||||
public String getUserMemberOfGroupAttribute() {
|
||||
return LdapSettings.TASKANA_LDAP_USER_MEMBER_OF_GROUP_ATTRIBUTE.getValueFromEnv(env);
|
||||
}
|
||||
|
||||
public String getGroupSearchBase() {
|
||||
return LdapSettings.TASKANA_LDAP_GROUP_SEARCH_BASE.getValueFromEnv(env);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ enum LdapSettings {
|
|||
TASKANA_LDAP_USER_LASTNAME_ATTRIBUTE("taskana.ldap.userLastnameAttribute"),
|
||||
TASKANA_LDAP_USER_FULLNAME_ATTRIBUTE("taskana.ldap.userFullnameAttribute"),
|
||||
TASKANA_LDAP_USER_ID_ATTRIBUTE("taskana.ldap.userIdAttribute"),
|
||||
TASKANA_LDAP_USER_MEMBER_OF_GROUP_ATTRIBUTE("taskana.ldap.userMemberOfGroupAttribute"),
|
||||
TASKANA_LDAP_GROUP_SEARCH_BASE("taskana.ldap.groupSearchBase"),
|
||||
TASKANA_LDAP_BASE_DN("taskana.ldap.baseDn"),
|
||||
TASKANA_LDAP_GROUP_SEARCH_FILTER_NAME("taskana.ldap.groupSearchFilterName"),
|
||||
|
|
|
@ -11,7 +11,10 @@ import static org.mockito.Mockito.verify;
|
|||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.Stream;
|
||||
|
@ -23,6 +26,8 @@ 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.SystemException;
|
||||
import pro.taskana.common.rest.models.AccessIdRepresentationModel;
|
||||
|
||||
|
@ -33,6 +38,8 @@ class LdapClientTest {
|
|||
|
||||
@Mock LdapTemplate ldapTemplate;
|
||||
|
||||
@Mock TaskanaEngineConfiguration taskanaEngineConfiguration;
|
||||
|
||||
@InjectMocks LdapClient cut;
|
||||
|
||||
@Test
|
||||
|
@ -90,6 +97,27 @@ class LdapClientTest {
|
|||
assertThat(accessIds.get(3).getAccessId()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_ReturnAllUsersAndMembersOfGroupsWithTaskanaUserRole() throws Exception {
|
||||
|
||||
setUpEnvMock();
|
||||
cut.init();
|
||||
|
||||
AccessIdRepresentationModel user = new AccessIdRepresentationModel("testU", "testUId");
|
||||
|
||||
Set<String> groupsOfUserRole = new HashSet<>();
|
||||
Map<TaskanaRole, Set<String>> roleMap = new HashMap<>();
|
||||
roleMap.put(TaskanaRole.USER, groupsOfUserRole);
|
||||
|
||||
when(taskanaEngineConfiguration.getRoleMap()).thenReturn(roleMap);
|
||||
|
||||
when(ldapTemplate.search(
|
||||
any(String.class), any(), anyInt(), any(), any(LdapClient.UserContextMapper.class)))
|
||||
.thenReturn(List.of(user));
|
||||
|
||||
assertThat(cut.searchUsersByNameOrAccessIdInUserRole("test")).hasSize(1).containsExactly(user);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLdap_getNameWithoutBaseDn() {
|
||||
|
||||
|
@ -159,6 +187,7 @@ class LdapClientTest {
|
|||
{"taskana.ldap.groupSearchFilterName", "objectclass"},
|
||||
{"taskana.ldap.groupSearchBase", "ou=groups"},
|
||||
{"taskana.ldap.userIdAttribute", "uid"},
|
||||
{"taskana.ldap.userMemberOfGroupAttribute", "memberOf"},
|
||||
{"taskana.ldap.userLastnameAttribute", "sn"},
|
||||
{"taskana.ldap.userFirstnameAttribute", "givenName"},
|
||||
{"taskana.ldap.userFullnameAttribute", "cn"},
|
||||
|
|
|
@ -23,6 +23,7 @@ taskana.ldap.userFirstnameAttribute=givenName
|
|||
taskana.ldap.userLastnameAttribute=sn
|
||||
taskana.ldap.userFullnameAttribute=cn
|
||||
taskana.ldap.userIdAttribute=uid
|
||||
taskana.ldap.userMemberOfGroupAttribute=
|
||||
taskana.ldap.groupSearchBase=
|
||||
taskana.ldap.groupSearchFilterName=objectclass
|
||||
taskana.ldap.groupSearchFilterValue=groupOfUniqueNames
|
||||
|
|
Loading…
Reference in New Issue