add RbacUser* tests and improved http status codes
This commit is contained in:
@ -13,6 +13,7 @@ import org.springframework.web.context.request.WebRequest;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Optional;
|
||||
|
||||
@ControllerAdvice
|
||||
public class RestResponseEntityExceptionHandler
|
||||
@ -22,16 +23,39 @@ public class RestResponseEntityExceptionHandler
|
||||
protected ResponseEntity<CustomErrorResponse> handleConflict(
|
||||
final RuntimeException exc, final WebRequest request) {
|
||||
|
||||
return new ResponseEntity<>(
|
||||
new CustomErrorResponse(request.getContextPath(), exc, HttpStatus.CONFLICT), HttpStatus.CONFLICT);
|
||||
final var message = firstLine(NestedExceptionUtils.getMostSpecificCause(exc).getMessage());
|
||||
return errorResponse(request, HttpStatus.CONFLICT, message);
|
||||
}
|
||||
|
||||
@ExceptionHandler(JpaSystemException.class)
|
||||
protected ResponseEntity<CustomErrorResponse> handleJpaExceptions(
|
||||
final RuntimeException exc, final WebRequest request) {
|
||||
final var message = firstLine(NestedExceptionUtils.getMostSpecificCause(exc).getMessage());
|
||||
return errorResponse(request, httpStatus(message).orElse(HttpStatus.FORBIDDEN), message);
|
||||
}
|
||||
|
||||
private Optional<HttpStatus> httpStatus(final String message) {
|
||||
if (message.startsWith("ERROR: [")) {
|
||||
for (HttpStatus status : HttpStatus.values()) {
|
||||
if (message.startsWith("ERROR: [" + status.value() + "]")) {
|
||||
return Optional.of(status);
|
||||
}
|
||||
}
|
||||
return Optional.of(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private static ResponseEntity<CustomErrorResponse> errorResponse(
|
||||
final WebRequest request,
|
||||
final HttpStatus conflict,
|
||||
final String message) {
|
||||
return new ResponseEntity<>(
|
||||
new CustomErrorResponse(request.getContextPath(), exc, HttpStatus.FORBIDDEN), HttpStatus.FORBIDDEN);
|
||||
new CustomErrorResponse(request.getContextPath(), conflict, message), conflict);
|
||||
}
|
||||
|
||||
private String firstLine(final String message) {
|
||||
return message.split("\\r|\\n|\\r\\n", 0)[0];
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,15 +73,11 @@ class CustomErrorResponse {
|
||||
|
||||
private final String message;
|
||||
|
||||
public CustomErrorResponse(final String path, final RuntimeException exc, final HttpStatus status) {
|
||||
public CustomErrorResponse(final String path, final HttpStatus status, final String message) {
|
||||
this.timestamp = LocalDateTime.now();
|
||||
this.path = path;
|
||||
this.status = status.value();
|
||||
this.error = status.getReasonPhrase();
|
||||
this.message = firstLine(NestedExceptionUtils.getMostSpecificCause(exc).getMessage());
|
||||
}
|
||||
|
||||
private String firstLine(final String message) {
|
||||
return message.split("\\r|\\n|\\r\\n", 0)[0];
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,16 @@
|
||||
package net.hostsharing.hsadminng.rbac.rbacuser;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.media.ArraySchema;
|
||||
import io.swagger.v3.oas.annotations.media.Content;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||
import net.hostsharing.hsadminng.context.Context;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.transaction.Transactional;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
public class RbacUserController {
|
||||
@ -16,9 +21,18 @@ public class RbacUserController {
|
||||
@Autowired
|
||||
private RbacUserRepository rbacUserRepository;
|
||||
|
||||
@GetMapping(value = "/api/rbacuser")
|
||||
@GetMapping(value = "/api/rbacusers")
|
||||
@Operation(description = "List accessible RBAC users with optional filter by name.",
|
||||
responses = {
|
||||
@ApiResponse(responseCode = "200",
|
||||
content = @Content(array = @ArraySchema(
|
||||
schema = @Schema(implementation = RbacUserEntity.class)))),
|
||||
@ApiResponse(responseCode = "401",
|
||||
description = "if the 'current-user' cannot be identified"),
|
||||
@ApiResponse(responseCode = "403",
|
||||
description = "if the 'current-user' is not allowed to assume any of the roles from 'assumed-roles'") })
|
||||
@Transactional
|
||||
public Iterable<RbacUserEntity> listUsers(
|
||||
public List<RbacUserEntity> listUsers(
|
||||
@RequestHeader(name = "current-user") String currentUserName,
|
||||
@RequestHeader(name = "assumed-roles", required = false) String assumedRoles,
|
||||
@RequestParam(name="name", required = false) String userName
|
||||
@ -31,8 +45,15 @@ public class RbacUserController {
|
||||
}
|
||||
|
||||
@GetMapping(value = "/api/rbacuser/{userName}/permissions")
|
||||
@Operation(description = "List all visible permissions granted to the given user; reduced ", responses = {
|
||||
@ApiResponse(responseCode = "200",
|
||||
content = @Content(array = @ArraySchema( schema = @Schema(implementation = RbacUserPermission.class)))),
|
||||
@ApiResponse(responseCode = "401",
|
||||
description = "if the 'current-user' cannot be identified"),
|
||||
@ApiResponse(responseCode = "403",
|
||||
description = "if the 'current-user' is not allowed to view permissions of the given user") })
|
||||
@Transactional
|
||||
public Iterable<RbacUserPermission> listUserPermissions(
|
||||
public List<RbacUserPermission> listUserPermissions(
|
||||
@RequestHeader(name = "current-user") String currentUserName,
|
||||
@RequestHeader(name = "assumed-roles", required = false) String assumedRoles,
|
||||
@PathVariable(name= "userName") String userName
|
||||
|
@ -14,30 +14,6 @@ import java.util.UUID;
|
||||
@Immutable
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
//@SqlResultSetMapping(
|
||||
// name = "rbacUserPermissionMapping",
|
||||
// classes = {
|
||||
// @ConstructorResult(
|
||||
// targetClass = RbacUserPermission.class,
|
||||
// columns = {
|
||||
// @ColumnResult(name = "roleUuid", type = UUID.class),
|
||||
// @ColumnResult(name = "oleName", type = String.class),
|
||||
// @ColumnResult(name = "permissionUuid", type = UUID.class),
|
||||
// @ColumnResult(name = "op", type=String.class),
|
||||
// @ColumnResult(name = "objectTable", type=String.class),
|
||||
// @ColumnResult(name = "objectIdName", type =String.class),
|
||||
// @ColumnResult(name = "objectUuid", type = UUID.class),
|
||||
// @ColumnResult(name = "campId", type = Integer.class),
|
||||
// @ColumnResult(name = "userCount", type = Byte.class)
|
||||
// }
|
||||
// )
|
||||
// }
|
||||
//)
|
||||
//@NamedNativeQuery(
|
||||
// name = "grantedPermissions",
|
||||
// query = "SELECT * FROM grantedPermissions(:userName)",
|
||||
// resultSetMapping = "rbacUserPermissionMapping"
|
||||
//)
|
||||
public class RbacUserEntity {
|
||||
|
||||
@Id
|
||||
|
@ -13,5 +13,5 @@ public interface RbacUserRepository extends Repository<RbacUserEntity, UUID> {
|
||||
List<RbacUserEntity> findByOptionalNameLike(final String userName);
|
||||
|
||||
@Query(value = "SELECT * FROM grantedPermissions(:userName)", nativeQuery = true)
|
||||
Iterable<RbacUserPermission> findPermissionsOfUser(@Param("userName") String userName);
|
||||
List<RbacUserPermission> findPermissionsOfUser(@Param("userName") String userName);
|
||||
}
|
||||
|
Reference in New Issue
Block a user