AccessController.java 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. package com.provectus.kafka.ui.controller;
  2. import com.provectus.kafka.ui.api.AuthorizationApi;
  3. import com.provectus.kafka.ui.model.ActionDTO;
  4. import com.provectus.kafka.ui.model.AuthenticationInfoDTO;
  5. import com.provectus.kafka.ui.model.ResourceTypeDTO;
  6. import com.provectus.kafka.ui.model.UserInfoDTO;
  7. import com.provectus.kafka.ui.model.UserPermissionDTO;
  8. import com.provectus.kafka.ui.model.rbac.Permission;
  9. import com.provectus.kafka.ui.service.rbac.AccessControlService;
  10. import java.security.Principal;
  11. import java.util.Collection;
  12. import java.util.Collections;
  13. import java.util.List;
  14. import java.util.Objects;
  15. import java.util.stream.Collectors;
  16. import javax.annotation.Nullable;
  17. import lombok.RequiredArgsConstructor;
  18. import lombok.extern.slf4j.Slf4j;
  19. import org.springframework.http.ResponseEntity;
  20. import org.springframework.security.core.context.ReactiveSecurityContextHolder;
  21. import org.springframework.security.core.context.SecurityContext;
  22. import org.springframework.web.bind.annotation.RestController;
  23. import org.springframework.web.server.ServerWebExchange;
  24. import reactor.core.publisher.Mono;
  25. @RestController
  26. @RequiredArgsConstructor
  27. @Slf4j
  28. public class AccessController implements AuthorizationApi {
  29. private final AccessControlService accessControlService;
  30. public Mono<ResponseEntity<AuthenticationInfoDTO>> getUserAuthInfo(ServerWebExchange exchange) {
  31. Mono<List<UserPermissionDTO>> permissions = accessControlService.getUser()
  32. .map(user -> accessControlService.getRoles()
  33. .stream()
  34. .filter(role -> user.groups().contains(role.getName()))
  35. .map(role -> mapPermissions(role.getPermissions(), role.getClusters()))
  36. .flatMap(Collection::stream)
  37. .collect(Collectors.toList())
  38. )
  39. .switchIfEmpty(Mono.just(Collections.emptyList()));
  40. Mono<String> userName = ReactiveSecurityContextHolder.getContext()
  41. .map(SecurityContext::getAuthentication)
  42. .map(Principal::getName);
  43. return userName
  44. .zipWith(permissions)
  45. .map(data -> {
  46. var dto = new AuthenticationInfoDTO(accessControlService.isRbacEnabled());
  47. dto.setUserInfo(new UserInfoDTO(data.getT1(), data.getT2()));
  48. return dto;
  49. })
  50. .switchIfEmpty(Mono.just(new AuthenticationInfoDTO(accessControlService.isRbacEnabled())))
  51. .map(ResponseEntity::ok);
  52. }
  53. private List<UserPermissionDTO> mapPermissions(List<Permission> permissions, List<String> clusters) {
  54. return permissions
  55. .stream()
  56. .map(permission -> {
  57. UserPermissionDTO dto = new UserPermissionDTO();
  58. dto.setClusters(clusters);
  59. dto.setResource(ResourceTypeDTO.fromValue(permission.getResource().toString().toUpperCase()));
  60. dto.setValue(permission.getValue());
  61. dto.setActions(permission.getActions()
  62. .stream()
  63. .map(String::toUpperCase)
  64. .map(this::mapAction)
  65. .filter(Objects::nonNull)
  66. .collect(Collectors.toList()));
  67. return dto;
  68. })
  69. .collect(Collectors.toList());
  70. }
  71. @Nullable
  72. private ActionDTO mapAction(String name) {
  73. try {
  74. return ActionDTO.fromValue(name);
  75. } catch (IllegalArgumentException e) {
  76. log.warn("Unknown Action [{}], skipping", name);
  77. return null;
  78. }
  79. }
  80. }