Closes #2348 - adds feature to request the current user via /users?currentUser
Signed-off-by: Kálmán Képes <2853992+nyuuyn@users.noreply.github.com>
This commit is contained in:
parent
44c023746d
commit
208ee77474
|
@ -11,6 +11,9 @@ Whenever a parameter is a complex type, the attributes of the value-object can b
|
|||
For example, a complex parameter with the name "complex-query-param" and attributes "attribute1" and "attribute2" would be specified in the following way: +
|
||||
complex-query-param={"attribute1":"value1","attribute2":"value2"}
|
||||
|
||||
Whenever a parameter is a value-less type (e.g owner-is-null and current-user) it is expected to be defined without a value,
|
||||
i.e., it should be specified as ?parameter and not ?parameter= or ?parameter=someValue
|
||||
|
||||
=== Hypermedia Support
|
||||
|
||||
NOTE: HATEOAS support is still in development.
|
||||
|
|
|
@ -38,7 +38,7 @@ public class QueryParamsValidator {
|
|||
checkExactParam(request, "owner-is-null");
|
||||
}
|
||||
|
||||
private static void checkExactParam(HttpServletRequest request, String queryParameter) {
|
||||
public static void checkExactParam(HttpServletRequest request, String queryParameter) {
|
||||
String queryString = request.getQueryString();
|
||||
boolean containParam = queryString != null && queryString.contains(queryParameter);
|
||||
if (containParam) {
|
||||
|
|
|
@ -2,6 +2,8 @@ package pro.taskana.user.rest;
|
|||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.hateoas.config.EnableHypermediaSupport;
|
||||
import org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType;
|
||||
|
@ -18,7 +20,9 @@ import org.springframework.web.bind.annotation.RequestParam;
|
|||
import org.springframework.web.bind.annotation.RestController;
|
||||
import pro.taskana.common.api.exceptions.InvalidArgumentException;
|
||||
import pro.taskana.common.api.exceptions.NotAuthorizedException;
|
||||
import pro.taskana.common.api.security.CurrentUserContext;
|
||||
import pro.taskana.common.rest.RestEndpoints;
|
||||
import pro.taskana.common.rest.util.QueryParamsValidator;
|
||||
import pro.taskana.user.api.UserService;
|
||||
import pro.taskana.user.api.exceptions.UserAlreadyExistException;
|
||||
import pro.taskana.user.api.exceptions.UserNotFoundException;
|
||||
|
@ -34,10 +38,15 @@ public class UserController {
|
|||
private final UserService userService;
|
||||
private final UserRepresentationModelAssembler userAssembler;
|
||||
|
||||
private final CurrentUserContext currentUserContext;
|
||||
|
||||
@Autowired
|
||||
UserController(UserService userService, UserRepresentationModelAssembler userAssembler) {
|
||||
UserController(UserService userService,
|
||||
UserRepresentationModelAssembler userAssembler,
|
||||
CurrentUserContext currentUserContext) {
|
||||
this.userService = userService;
|
||||
this.userAssembler = userAssembler;
|
||||
this.currentUserContext = currentUserContext;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -54,24 +63,39 @@ public class UserController {
|
|||
public ResponseEntity<UserRepresentationModel> getUser(@PathVariable String userId)
|
||||
throws UserNotFoundException, InvalidArgumentException {
|
||||
User user = userService.getUser(userId);
|
||||
|
||||
return ResponseEntity.ok(userAssembler.toModel(user));
|
||||
}
|
||||
|
||||
/**
|
||||
* This endpoint retrieves multiple Users. If a userId can't be found in the database it will be
|
||||
* ignored. If none of the given userIds is valid, the returned list will be empty.
|
||||
* If currentUser is set, the current User from the context will be retrieved as well
|
||||
*
|
||||
* @title Get multiple Users
|
||||
* @param request the HttpServletRequest of the request itself
|
||||
* @param userIds the ids of the requested Users
|
||||
* @param currentUser Indicates whether to fetch the current user or not as well
|
||||
* @return the requested Users
|
||||
* @throws InvalidArgumentException if the userIds are null or empty
|
||||
* @throws UserNotFoundException if the current User was not found
|
||||
*/
|
||||
@GetMapping(RestEndpoints.URL_USERS)
|
||||
@Transactional(readOnly = true, rollbackFor = Exception.class)
|
||||
public ResponseEntity<UserCollectionRepresentationModel> getUsers(
|
||||
@RequestParam(name = "user-id") String[] userIds) throws InvalidArgumentException {
|
||||
List<User> users = userService.getUsers(new HashSet<>(List.of(userIds)));
|
||||
HttpServletRequest request,
|
||||
@RequestParam(name = "user-id", required = false) String[] userIds,
|
||||
@RequestParam(name = "current-user", required = false) String currentUser)
|
||||
throws InvalidArgumentException, UserNotFoundException {
|
||||
Set<User> users = new HashSet<>();
|
||||
|
||||
if (userIds != null) {
|
||||
users.addAll(userService.getUsers(new HashSet<>(List.of(userIds))));
|
||||
}
|
||||
|
||||
if (currentUser != null) {
|
||||
QueryParamsValidator.checkExactParam(request, "current-user");
|
||||
users.add(userService.getUser(this.currentUserContext.getUserid()));
|
||||
}
|
||||
|
||||
return ResponseEntity.ok(userAssembler.toTaskanaCollectionModel(users));
|
||||
}
|
||||
|
|
|
@ -63,6 +63,94 @@ class UserControllerIntTest {
|
|||
.containsExactlyInAnyOrder("Max", "Elena");
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_ReturnCurrentUser() {
|
||||
String url = restHelper.toUrl(RestEndpoints.URL_USERS) + "?current-user";
|
||||
HttpEntity<?> auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1"));
|
||||
|
||||
ResponseEntity<UserCollectionRepresentationModel> response =
|
||||
TEMPLATE.exchange(
|
||||
url,
|
||||
HttpMethod.GET,
|
||||
auth,
|
||||
ParameterizedTypeReference.forType(UserCollectionRepresentationModel.class));
|
||||
assertThat(response.getBody()).isNotNull();
|
||||
assertThat(response.getBody().getContent()).hasSize(1);
|
||||
assertThat(response.getBody().getContent()).extracting("userId").containsExactly("teamlead-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_ReturnExceptionCurrentUserWithBadValue() {
|
||||
String url = restHelper.toUrl(RestEndpoints.URL_USERS) + "?current-user=asd";
|
||||
HttpEntity<?> auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1"));
|
||||
|
||||
ThrowingCallable httpCall =
|
||||
() -> TEMPLATE.exchange(
|
||||
url,
|
||||
HttpMethod.GET,
|
||||
auth,
|
||||
ParameterizedTypeReference.forType(UserCollectionRepresentationModel.class));
|
||||
assertThatThrownBy(httpCall)
|
||||
.isInstanceOf(HttpStatusCodeException.class)
|
||||
.extracting(HttpStatusCodeException.class::cast)
|
||||
.extracting(HttpStatusCodeException::getStatusCode)
|
||||
.isEqualTo(HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_ReturnExceptionCurrentUserWithEmptyValue() {
|
||||
String url = restHelper.toUrl(RestEndpoints.URL_USERS) + "?current-user=";
|
||||
HttpEntity<?> auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1"));
|
||||
|
||||
ThrowingCallable httpCall =
|
||||
() -> TEMPLATE.exchange(
|
||||
url,
|
||||
HttpMethod.GET,
|
||||
auth,
|
||||
ParameterizedTypeReference.forType(UserCollectionRepresentationModel.class));
|
||||
assertThatThrownBy(httpCall)
|
||||
.isInstanceOf(HttpStatusCodeException.class)
|
||||
.extracting(HttpStatusCodeException.class::cast)
|
||||
.extracting(HttpStatusCodeException::getStatusCode)
|
||||
.isEqualTo(HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_ReturnOnlyCurrentUserWhileUsingUserIds() {
|
||||
String url = restHelper.toUrl(RestEndpoints.URL_USERS) + "?current-user&user-id=teamlead-1";
|
||||
HttpEntity<?> auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1"));
|
||||
|
||||
ResponseEntity<UserCollectionRepresentationModel> response =
|
||||
TEMPLATE.exchange(
|
||||
url,
|
||||
HttpMethod.GET,
|
||||
auth,
|
||||
ParameterizedTypeReference.forType(UserCollectionRepresentationModel.class));
|
||||
assertThat(response.getBody()).isNotNull();
|
||||
assertThat(response.getBody().getContent()).hasSize(1);
|
||||
assertThat(response.getBody().getContent()).extracting("userId").containsExactly("teamlead-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_ReturnExistingUsersAndCurrentUser() throws Exception {
|
||||
String url = restHelper.toUrl(RestEndpoints.URL_USERS)
|
||||
+ "?user-id=user-1-1&user-id=USER-1-2¤t-user";
|
||||
HttpEntity<?> auth = new HttpEntity<>(RestHelper.generateHeadersForUser("teamlead-1"));
|
||||
|
||||
ResponseEntity<UserCollectionRepresentationModel> responseEntity =
|
||||
TEMPLATE.exchange(
|
||||
url,
|
||||
HttpMethod.GET,
|
||||
auth,
|
||||
ParameterizedTypeReference.forType(UserCollectionRepresentationModel.class));
|
||||
UserCollectionRepresentationModel response = responseEntity.getBody();
|
||||
assertThat(response).isNotNull();
|
||||
assertThat(response.getContent()).hasSize(3);
|
||||
assertThat(response.getContent())
|
||||
.extracting("userId")
|
||||
.containsExactlyInAnyOrder("user-1-1", "user-1-2", "teamlead-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void should_ReturnExistingUsers_When_ParameterContainsDuplicateAndInvalidIds() throws Exception {
|
||||
// also testing different query parameter format
|
||||
|
|
Loading…
Reference in New Issue