TSK-1308: User must be in role ADMIN, BUSINESS_ADMIN to use AccessIdSrv.
This commit is contained in:
parent
553c1d9f83
commit
382b8366bf
|
|
@ -11,7 +11,10 @@ import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import pro.taskana.common.api.TaskanaEngine;
|
||||||
|
import pro.taskana.common.api.TaskanaRole;
|
||||||
import pro.taskana.common.api.exceptions.InvalidArgumentException;
|
import pro.taskana.common.api.exceptions.InvalidArgumentException;
|
||||||
|
import pro.taskana.common.api.exceptions.NotAuthorizedException;
|
||||||
import pro.taskana.common.rest.ldap.LdapClient;
|
import pro.taskana.common.rest.ldap.LdapClient;
|
||||||
import pro.taskana.common.rest.models.AccessIdRepresentationModel;
|
import pro.taskana.common.rest.models.AccessIdRepresentationModel;
|
||||||
|
|
||||||
|
|
@ -26,19 +29,24 @@ public class AccessIdController {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(AccessIdController.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(AccessIdController.class);
|
||||||
|
|
||||||
LdapClient ldapClient;
|
private final LdapClient ldapClient;
|
||||||
|
private final TaskanaEngine taskanaEngine;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public AccessIdController(LdapClient ldapClient) {
|
public AccessIdController(LdapClient ldapClient, TaskanaEngine taskanaEngine) {
|
||||||
this.ldapClient = ldapClient;
|
this.ldapClient = ldapClient;
|
||||||
|
this.taskanaEngine = taskanaEngine;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(path = Mapping.URL_ACCESSID)
|
@GetMapping(path = Mapping.URL_ACCESSID)
|
||||||
public ResponseEntity<List<AccessIdRepresentationModel>> validateAccessIds(
|
public ResponseEntity<List<AccessIdRepresentationModel>> validateAccessIds(
|
||||||
@RequestParam("search-for") String searchFor) throws InvalidArgumentException {
|
@RequestParam("search-for") String searchFor)
|
||||||
|
throws InvalidArgumentException, NotAuthorizedException {
|
||||||
|
|
||||||
LOGGER.debug("Entry to validateAccessIds(search-for= {})", searchFor);
|
LOGGER.debug("Entry to validateAccessIds(search-for= {})", searchFor);
|
||||||
|
|
||||||
|
taskanaEngine.checkRoleMembership(TaskanaRole.ADMIN, TaskanaRole.BUSINESS_ADMIN);
|
||||||
|
|
||||||
if (searchFor.length() < ldapClient.getMinSearchForLength()) {
|
if (searchFor.length() < ldapClient.getMinSearchForLength()) {
|
||||||
throw new InvalidArgumentException(
|
throw new InvalidArgumentException(
|
||||||
"searchFor string '"
|
"searchFor string '"
|
||||||
|
|
@ -58,19 +66,24 @@ public class AccessIdController {
|
||||||
|
|
||||||
@GetMapping(path = Mapping.URL_ACCESSID_GROUPS)
|
@GetMapping(path = Mapping.URL_ACCESSID_GROUPS)
|
||||||
public ResponseEntity<List<AccessIdRepresentationModel>> getGroupsByAccessId(
|
public ResponseEntity<List<AccessIdRepresentationModel>> getGroupsByAccessId(
|
||||||
@RequestParam("access-id") String accessId) throws InvalidArgumentException {
|
@RequestParam("access-id") String accessId)
|
||||||
|
throws InvalidArgumentException, NotAuthorizedException {
|
||||||
|
|
||||||
LOGGER.debug("Entry to getGroupsByAccessId(access-id= {})", accessId);
|
LOGGER.debug("Entry to getGroupsByAccessId(access-id= {})", accessId);
|
||||||
|
|
||||||
|
taskanaEngine.checkRoleMembership(TaskanaRole.ADMIN, TaskanaRole.BUSINESS_ADMIN);
|
||||||
|
|
||||||
if (!validateAccessId(accessId)) {
|
if (!validateAccessId(accessId)) {
|
||||||
throw new InvalidArgumentException("The accessId is invalid");
|
throw new InvalidArgumentException("The accessId is invalid");
|
||||||
}
|
}
|
||||||
List<AccessIdRepresentationModel> accessIds;
|
|
||||||
ResponseEntity<List<AccessIdRepresentationModel>> response;
|
List<AccessIdRepresentationModel> accessIds =
|
||||||
accessIds = ldapClient.searchGroupsAccessIdIsMemberOf(accessId);
|
ldapClient.searchGroupsAccessIdIsMemberOf(accessId);
|
||||||
response = ResponseEntity.ok(accessIds);
|
ResponseEntity<List<AccessIdRepresentationModel>> response = ResponseEntity.ok(accessIds);
|
||||||
|
|
||||||
if (LOGGER.isDebugEnabled()) {
|
if (LOGGER.isDebugEnabled()) {
|
||||||
LOGGER.debug("Exit from getGroupsByAccessId(), returning {}", response);
|
LOGGER.debug("Exit from getGroupsByAccessId(), returning {}", response);
|
||||||
}
|
}
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -183,15 +183,15 @@ public class LdapClient {
|
||||||
return accessId;
|
return accessId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<AccessIdRepresentationModel> searchGroupsAccessIdIsMemberOf(final String name)
|
public List<AccessIdRepresentationModel> searchGroupsAccessIdIsMemberOf(final String accessId)
|
||||||
throws InvalidArgumentException {
|
throws InvalidArgumentException {
|
||||||
LOGGER.debug("entry to searchGroupsAccessIdIsMemberOf(name = {}).", name);
|
LOGGER.debug("entry to searchGroupsAccessIdIsMemberOf(name = {}).", accessId);
|
||||||
isInitOrFail();
|
isInitOrFail();
|
||||||
testMinSearchForLength(name);
|
testMinSearchForLength(accessId);
|
||||||
|
|
||||||
final AndFilter andFilter = new AndFilter();
|
final AndFilter andFilter = new AndFilter();
|
||||||
andFilter.and(new EqualsFilter(getGroupSearchFilterName(), getGroupSearchFilterValue()));
|
andFilter.and(new EqualsFilter(getGroupSearchFilterName(), getGroupSearchFilterValue()));
|
||||||
andFilter.and(new LikeFilter(getGroupsOfUser(), "*" + name + "*"));
|
andFilter.and(new LikeFilter(getGroupsOfUser(), "*" + accessId + "*"));
|
||||||
|
|
||||||
String[] userAttributesToReturn = {getUserIdAttribute(), getGroupNameAttribute()};
|
String[] userAttributesToReturn = {getUserIdAttribute(), getGroupNameAttribute()};
|
||||||
|
|
||||||
|
|
@ -202,6 +202,7 @@ public class LdapClient {
|
||||||
SearchControls.SUBTREE_SCOPE,
|
SearchControls.SUBTREE_SCOPE,
|
||||||
userAttributesToReturn,
|
userAttributesToReturn,
|
||||||
new GroupContextMapper());
|
new GroupContextMapper());
|
||||||
|
|
||||||
LOGGER.debug(
|
LOGGER.debug(
|
||||||
"exit from searchGroupsAccessIdIsMemberOf. Retrieved the following accessIds: {}.",
|
"exit from searchGroupsAccessIdIsMemberOf. Retrieved the following accessIds: {}.",
|
||||||
accessIds);
|
accessIds);
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.core.ParameterizedTypeReference;
|
import org.springframework.core.ParameterizedTypeReference;
|
||||||
|
import org.springframework.http.HttpEntity;
|
||||||
import org.springframework.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
|
|
@ -116,16 +117,16 @@ class AccessIdControllerIntTest {
|
||||||
restHelper.defaultRequest(),
|
restHelper.defaultRequest(),
|
||||||
ParameterizedTypeReference.forType(AccessIdListResource.class));
|
ParameterizedTypeReference.forType(AccessIdListResource.class));
|
||||||
|
|
||||||
List<AccessIdRepresentationModel> body = response.getBody();
|
assertThat(response.getBody())
|
||||||
assertThat(body).isNotNull();
|
.isNotNull()
|
||||||
assertThat(body)
|
|
||||||
.extracting(AccessIdRepresentationModel::getAccessId)
|
.extracting(AccessIdRepresentationModel::getAccessId)
|
||||||
.usingElementComparator(String.CASE_INSENSITIVE_ORDER)
|
.usingElementComparator(String.CASE_INSENSITIVE_ORDER)
|
||||||
.containsExactlyInAnyOrder(
|
.containsExactlyInAnyOrder(
|
||||||
"cn=ksc-teamleads,cn=groups,OU=Test,O=TASKANA",
|
"cn=ksc-teamleads,cn=groups,OU=Test,O=TASKANA",
|
||||||
"cn=business-admins,cn=groups,OU=Test,O=TASKANA",
|
"cn=business-admins,cn=groups,OU=Test,O=TASKANA",
|
||||||
"cn=monitor-users,cn=groups,OU=Test,O=TASKANA",
|
"cn=monitor-users,cn=groups,OU=Test,O=TASKANA",
|
||||||
"cn=Organisationseinheit KSC 2,cn=Organisationseinheit KSC,cn=organisation,OU=Test,O=TASKANA");
|
"cn=Organisationseinheit KSC 2,"
|
||||||
|
+ "cn=Organisationseinheit KSC,cn=organisation,OU=Test,O=TASKANA");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -139,14 +140,45 @@ class AccessIdControllerIntTest {
|
||||||
restHelper.defaultRequest(),
|
restHelper.defaultRequest(),
|
||||||
ParameterizedTypeReference.forType(AccessIdListResource.class));
|
ParameterizedTypeReference.forType(AccessIdListResource.class));
|
||||||
|
|
||||||
List<AccessIdRepresentationModel> body = response.getBody();
|
assertThat(response.getBody())
|
||||||
assertThat(body).isNotNull();
|
.isNotNull()
|
||||||
assertThat(body)
|
|
||||||
.extracting(AccessIdRepresentationModel::getAccessId)
|
.extracting(AccessIdRepresentationModel::getAccessId)
|
||||||
.usingElementComparator(String.CASE_INSENSITIVE_ORDER)
|
.usingElementComparator(String.CASE_INSENSITIVE_ORDER)
|
||||||
.containsExactlyInAnyOrder("cn=Organisationseinheit KSC,cn=organisation,OU=Test,O=TASKANA");
|
.containsExactlyInAnyOrder("cn=Organisationseinheit KSC,cn=organisation,OU=Test,O=TASKANA");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void should_throwNotAuthorizedException_ifCallerOfGroupRetrievalIsNotAdminOrBusinessAdmin() {
|
||||||
|
ThrowingCallable call =
|
||||||
|
() ->
|
||||||
|
template.exchange(
|
||||||
|
restHelper.toUrl(Mapping.URL_ACCESSID_GROUPS) + "?access-id=teamlead-2",
|
||||||
|
HttpMethod.GET,
|
||||||
|
new HttpEntity<>(restHelper.getHeadersUser_1_1()),
|
||||||
|
ParameterizedTypeReference.forType(AccessIdListResource.class));
|
||||||
|
|
||||||
|
assertThatThrownBy(call)
|
||||||
|
.isInstanceOf(HttpClientErrorException.class)
|
||||||
|
.extracting(ex -> ((HttpClientErrorException) ex).getStatusCode())
|
||||||
|
.isEqualTo(HttpStatus.FORBIDDEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void should_throwNotAuthorizedException_ifCallerOfValidationIsNotAdminOrBusinessAdmin() {
|
||||||
|
ThrowingCallable call =
|
||||||
|
() ->
|
||||||
|
template.exchange(
|
||||||
|
restHelper.toUrl(Mapping.URL_ACCESSID) + "?search-for=al",
|
||||||
|
HttpMethod.GET,
|
||||||
|
new HttpEntity<>(restHelper.getHeadersUser_1_1()),
|
||||||
|
ParameterizedTypeReference.forType(AccessIdListResource.class));
|
||||||
|
|
||||||
|
assertThatThrownBy(call)
|
||||||
|
.isInstanceOf(HttpClientErrorException.class)
|
||||||
|
.extracting(ex -> ((HttpClientErrorException) ex).getStatusCode())
|
||||||
|
.isEqualTo(HttpStatus.FORBIDDEN);
|
||||||
|
}
|
||||||
|
|
||||||
static class AccessIdListResource extends ArrayList<AccessIdRepresentationModel> {
|
static class AccessIdListResource extends ArrayList<AccessIdRepresentationModel> {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ class TaskControllerIntTest {
|
||||||
TASK_SUMMARY_PAGE_MODEL_TYPE);
|
TASK_SUMMARY_PAGE_MODEL_TYPE);
|
||||||
assertThat(response.getBody()).isNotNull();
|
assertThat(response.getBody()).isNotNull();
|
||||||
assertThat((response.getBody()).getLink(IanaLinkRelations.SELF)).isNotNull();
|
assertThat((response.getBody()).getLink(IanaLinkRelations.SELF)).isNotNull();
|
||||||
assertThat(response.getBody().getContent()).hasSize(25);
|
assertThat(response.getBody().getContent()).hasSize(48);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -465,7 +465,7 @@ class TaskControllerIntTest {
|
||||||
request,
|
request,
|
||||||
TASK_SUMMARY_PAGE_MODEL_TYPE);
|
TASK_SUMMARY_PAGE_MODEL_TYPE);
|
||||||
assertThat(response.getBody()).isNotNull();
|
assertThat(response.getBody()).isNotNull();
|
||||||
assertThat((response.getBody()).getContent()).hasSize(25);
|
assertThat((response.getBody()).getContent()).hasSize(48);
|
||||||
|
|
||||||
response =
|
response =
|
||||||
TEMPLATE.exchange(
|
TEMPLATE.exchange(
|
||||||
|
|
@ -476,8 +476,8 @@ class TaskControllerIntTest {
|
||||||
assertThat(response.getBody()).isNotNull();
|
assertThat(response.getBody()).isNotNull();
|
||||||
assertThat((response.getBody()).getContent()).hasSize(5);
|
assertThat((response.getBody()).getContent()).hasSize(5);
|
||||||
assertThat(response.getBody().getRequiredLink(IanaLinkRelations.LAST).getHref())
|
assertThat(response.getBody().getRequiredLink(IanaLinkRelations.LAST).getHref())
|
||||||
.contains("page=5");
|
.contains("page=10");
|
||||||
assertThat("TKI:000000000000000000000000000000000023")
|
assertThat("TKI:000000000000000000000000000000000005")
|
||||||
.isEqualTo(response.getBody().getContent().iterator().next().getTaskId());
|
.isEqualTo(response.getBody().getContent().iterator().next().getTaskId());
|
||||||
|
|
||||||
assertThat(response.getBody().getLink(IanaLinkRelations.SELF)).isNotNull();
|
assertThat(response.getBody().getLink(IanaLinkRelations.SELF)).isNotNull();
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ class WorkbasketControllerIntTest {
|
||||||
WORKBASKET_SUMMARY_PAGE_MODEL_TYPE);
|
WORKBASKET_SUMMARY_PAGE_MODEL_TYPE);
|
||||||
assertThat(response.getBody()).isNotNull();
|
assertThat(response.getBody()).isNotNull();
|
||||||
assertThat(response.getBody().getRequiredLink(IanaLinkRelations.SELF)).isNotNull();
|
assertThat(response.getBody().getRequiredLink(IanaLinkRelations.SELF)).isNotNull();
|
||||||
assertThat(response.getBody().getContent()).hasSize(3);
|
assertThat(response.getBody().getContent()).hasSize(6);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue