diff options
author | Fiete Ostkamp <fiete.ostkamp@telekom.de> | 2024-12-17 09:09:23 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@onap.org> | 2024-12-17 09:09:23 +0000 |
commit | 11fa7721b17cd453583a3c0f91107794e837f7d6 (patch) | |
tree | 424559f732cb34dcb06981c55be8ffaac6c0dda1 | |
parent | d4f1e5129ff72bc0af6f29e9b9c3eb0c362f4d6e (diff) | |
parent | c5fab8a832454dd8c641dd2991cb91e3c8f688ca (diff) |
14 files changed, 279 insertions, 92 deletions
diff --git a/app/src/main/resources/application-access-control.yml b/app/src/main/resources/application-access-control.yml deleted file mode 100644 index 6fda781..0000000 --- a/app/src/main/resources/application-access-control.yml +++ /dev/null @@ -1,21 +0,0 @@ -bff: - access-control: - ACTIONS_CREATE: [ portal_admin, portal_designer, portal_operator ] - ACTIONS_GET: [ portal_admin, portal_designer, portal_operator ] - ACTIONS_LIST: [ portal_admin, portal_designer, portal_operator ] - ACTIVE_ALARM_LIST: [portal_admin, portal_designer, portal_operator] - KEY_ENCRYPT_BY_USER: [portal_admin, portal_designer, portal_operator] - KEY_ENCRYPT_BY_VALUE: [portal_admin, portal_designer, portal_operator] - PREFERENCES_CREATE: [portal_admin, portal_designer, portal_operator] - PREFERENCES_GET: [portal_admin, portal_designer, portal_operator] - PREFERENCES_UPDATE: [portal_admin, portal_designer, portal_operator] - ROLE_LIST: ["*"] - USER_CREATE: [portal_admin, portal_designer, portal_operator] - USER_DELETE: [portal_admin, portal_designer, portal_operator] - USER_GET: [portal_admin, portal_designer, portal_operator] - USER_LIST_AVAILABLE_ROLES: [portal_admin, portal_designer, portal_operator] - USER_LIST_ROLES: [portal_admin, portal_designer, portal_operator] - USER_LIST: [portal_admin, portal_designer, portal_operator] - USER_UPDATE_PASSWORD: [portal_admin, portal_designer, portal_operator] - USER_UPDATE_ROLES: [portal_admin, portal_designer, portal_operator] - USER_UPDATE: [portal_admin, portal_designer, portal_operator] diff --git a/app/src/main/resources/application.yml b/app/src/main/resources/application.yml index a99ff0b..f93d4d6 100644 --- a/app/src/main/resources/application.yml +++ b/app/src/main/resources/application.yml @@ -52,8 +52,10 @@ bff: preferences-url: ${PREFERENCES_URL} history-url: ${HISTORY_URL} keycloak-url: ${KEYCLOAK_URL} + keycloak-client-id: ${KEYCLOAK_CLIENT_ID} endpoints: unauthenticated: /api-docs.html, /api.yaml, /webjars/**, /actuator/** + rbac: - endpoints-excluded: /actuator/**, **/actuator/**, */actuator/**, /**/actuator/**, /*/actuator/** + endpoints-excluded: ${RBAC_EXCLUDED_ENDPOINTS}:-/api-docs.html, /api.yaml, /webjars/**, /actuator/**, /users**, /roles**, /preferences**, /actions**} diff --git a/app/src/test/java/org/onap/portalng/bff/BaseIntegrationTest.java b/app/src/test/java/org/onap/portalng/bff/BaseIntegrationTest.java index a69516c..63d702c 100644 --- a/app/src/test/java/org/onap/portalng/bff/BaseIntegrationTest.java +++ b/app/src/test/java/org/onap/portalng/bff/BaseIntegrationTest.java @@ -115,6 +115,20 @@ public abstract class BaseIntegrationTest { .put("session_state", UUID.randomUUID().toString()) .put("scope", "email profile") .toString()))); + + /* + * MockAuth for new RBAC permission via keycloak + */ + WireMock.stubFor( + WireMock.post( + WireMock.urlMatching( + String.format("/realms/%s/protocol/openid-connect/token", realm))) + .withRequestBody( + WireMock.containing("grant_type=urn:ietf:params:oauth:grant-type:uma-ticket")) + .willReturn( + WireMock.aResponse() + .withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE) + .withBody(objectMapper.createObjectNode().put("result", "true").toString()))); } /** diff --git a/app/src/test/java/org/onap/portalng/bff/rbac/RoleBaseAccessIntegrationTest.java b/app/src/test/java/org/onap/portalng/bff/rbac/RoleBaseAccessIntegrationTest.java new file mode 100644 index 0000000..2c89547 --- /dev/null +++ b/app/src/test/java/org/onap/portalng/bff/rbac/RoleBaseAccessIntegrationTest.java @@ -0,0 +1,104 @@ +/* + * + * Copyright (c) 2024. Deutsche Telekom AG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * + * + */ + +package org.onap.portalng.bff.rbac; + +import com.github.tomakehurst.wiremock.client.WireMock; +import io.restassured.http.Header; +import org.junit.jupiter.api.Test; +import org.onap.portalng.bff.BaseIntegrationTest; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; + +public class RoleBaseAccessIntegrationTest extends BaseIntegrationTest { + + @Test + void thatRoleIsNotSufficient() { + + WireMock.stubFor( + WireMock.post( + WireMock.urlMatching( + String.format("/realms/%s/protocol/openid-connect/token", realm))) + .withRequestBody( + WireMock.containing("grant_type=urn:ietf:params:oauth:grant-type:uma-ticket")) + .willReturn( + WireMock.aResponse() + .withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE) + .withStatus(HttpStatus.FORBIDDEN.value()))); + + requestSpecification() + .given() + .accept(MediaType.APPLICATION_JSON_VALUE) + .header(new Header("X-Request-Id", "addf6005-3075-4c80-b7bc-2c70b7d42b57")) + .when() + .get("/roles") + .then() + .statusCode(HttpStatus.FORBIDDEN.value()); + } + + @Test + void thatResourceIsNotAvailable() { + + WireMock.stubFor( + WireMock.post( + WireMock.urlMatching( + String.format("/realms/%s/protocol/openid-connect/token", realm))) + .withRequestBody( + WireMock.containing("grant_type=urn:ietf:params:oauth:grant-type:uma-ticket")) + .willReturn( + WireMock.aResponse() + .withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE) + .withStatus(HttpStatus.BAD_REQUEST.value()))); + + requestSpecification() + .given() + .accept(MediaType.APPLICATION_JSON_VALUE) + .header(new Header("X-Request-Id", "addf6005-3075-4c80-b7bc-2c70b7d42b57")) + .when() + .get("/roles") + .then() + .statusCode(HttpStatus.FORBIDDEN.value()); + } + + @Test + void thatRoleBaseCheckIsMalformed() { + + WireMock.stubFor( + WireMock.post( + WireMock.urlMatching( + String.format("/realms/%s/protocol/openid-connect/token", realm))) + .withRequestBody( + WireMock.containing("grant_type=urn:ietf:params:oauth:grant-type:uma-ticket")) + .willReturn( + WireMock.aResponse() + .withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE) + .withBody(objectMapper.createObjectNode().put("result", "false").toString()))); + + requestSpecification() + .given() + .accept(MediaType.APPLICATION_JSON_VALUE) + .header(new Header("X-Request-Id", "addf6005-3075-4c80-b7bc-2c70b7d42b57")) + .when() + .get("/roles") + .then() + .statusCode(HttpStatus.FORBIDDEN.value()); + } +} diff --git a/app/src/test/resources/application-development.yml b/app/src/test/resources/application-development.yml index 23602d1..5dbb9f6 100644 --- a/app/src/test/resources/application-development.yml +++ b/app/src/test/resources/application-development.yml @@ -30,3 +30,8 @@ bff: preferences-url: http://localhost:${wiremock.server.port} history-url: http://localhost:${wiremock.server.port} keycloak-url: http://localhost:${wiremock.server.port} + keycloak-client-id: test + endpoints: + unauthenticated: /api-docs.html, /api.yaml, /webjars/**, /actuator/** + rbac: + endpoints-excluded: /api-docs.html, /api.yaml, /webjars/**, /actuator/** diff --git a/app/src/test/resources/application.yml b/app/src/test/resources/application.yml index 04e6a57..7764fbf 100644 --- a/app/src/test/resources/application.yml +++ b/app/src/test/resources/application.yml @@ -27,8 +27,8 @@ bff: preferences-url: http://localhost:${wiremock.server.port} history-url: http://localhost:${wiremock.server.port} keycloak-url: http://localhost:${wiremock.server.port} + keycloak-client-id: test endpoints: unauthenticated: /api-docs.html, /api.yaml, /webjars/**, /actuator/** rbac: - endpoints-excluded: /actuator/**, **/actuator/**, */actuator/**, /**/actuator/**, /*/actuator/** - + endpoints-excluded: /api-docs.html, /api.yaml, /webjars/**, /actuator/** diff --git a/lib/src/main/java/org/onap/portalng/bff/config/BffConfig.java b/lib/src/main/java/org/onap/portalng/bff/config/BffConfig.java index 3fada84..786f4bc 100644 --- a/lib/src/main/java/org/onap/portalng/bff/config/BffConfig.java +++ b/lib/src/main/java/org/onap/portalng/bff/config/BffConfig.java @@ -45,6 +45,7 @@ public class BffConfig { @NotBlank private final String preferencesUrl; @NotBlank private final String historyUrl; @NotBlank private final String keycloakUrl; + @NotBlank private final String keycloakClientId; @NotNull private final Map<String, Set<String>> accessControl; diff --git a/lib/src/main/java/org/onap/portalng/bff/config/KeycloakPermissionFilter.java b/lib/src/main/java/org/onap/portalng/bff/config/KeycloakPermissionFilter.java new file mode 100644 index 0000000..f6b7d21 --- /dev/null +++ b/lib/src/main/java/org/onap/portalng/bff/config/KeycloakPermissionFilter.java @@ -0,0 +1,122 @@ +/* + * + * Copyright (c) 2024. Deutsche Telekom AG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * + * + */ + +package org.onap.portalng.bff.config; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.server.ServerWebExchange; +import org.springframework.web.server.WebFilter; +import org.springframework.web.server.WebFilterChain; +import reactor.core.publisher.Mono; + +@Component +@Slf4j +public class KeycloakPermissionFilter implements WebFilter { + + private final WebClient webClient; + + private final ObjectMapper objectMapper; + private final BffConfig bffConfig; + + @Value("${bff.rbac.endpoints-excluded}") + private String[] EXCLUDED_PATHS; + + public KeycloakPermissionFilter( + WebClient.Builder webClientBuilder, ObjectMapper objectMapper, BffConfig bffConfig) { + this.webClient = webClientBuilder.build(); + this.objectMapper = objectMapper; + this.bffConfig = bffConfig; + } + + @Override + public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) { + String accessToken = exchange.getRequest().getHeaders().getFirst(HttpHeaders.AUTHORIZATION); + String uri = exchange.getRequest().getURI().getPath(); + String method = exchange.getRequest().getMethod().toString(); + + for (String excludedPath : EXCLUDED_PATHS) { + if (uri.matches(excludedPath.replace("**", ".*"))) { + return chain.filter(exchange); + } + } + + String body = + new StringBuilder() + .append("grant_type=urn:ietf:params:oauth:grant-type:uma-ticket") + .append("&audience=") + .append(bffConfig.getKeycloakClientId()) + .append("&permission_resource_format=uri") + .append("&permission_resource_matching_uri=true") + .append("&permission=") + .append(uri) + .append("#") + .append(method) + .append("&response_mode=decision") + .toString(); + + return webClient + .post() + .uri( + bffConfig.getKeycloakUrl() + + "/realms/" + + bffConfig.getRealm() + + "/protocol/openid-connect/token") + .header(HttpHeaders.AUTHORIZATION, accessToken) + .contentType(MediaType.APPLICATION_FORM_URLENCODED) + .bodyValue(body) + .retrieve() + .bodyToMono(String.class) + .flatMap( + response -> { + if (isPermissionGranted(response)) { + return chain.filter(exchange); + } else { + exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN); + return exchange.getResponse().setComplete(); + } + }) + .onErrorResume( + ex -> { + exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN); + return exchange.getResponse().setComplete(); + }); + } + + private boolean isPermissionGranted(String response) { + try { + JsonNode jsonNode = objectMapper.readTree(response); + if (jsonNode.has("result") && jsonNode.get("result").asBoolean()) { + return true; + } + } catch (Exception e) { + log.error("Error parsing JSON response", e); + } + return false; + } +} diff --git a/lib/src/main/java/org/onap/portalng/bff/config/SecurityConfig.java b/lib/src/main/java/org/onap/portalng/bff/config/SecurityConfig.java index 4ae842a..6c5e8ea 100644 --- a/lib/src/main/java/org/onap/portalng/bff/config/SecurityConfig.java +++ b/lib/src/main/java/org/onap/portalng/bff/config/SecurityConfig.java @@ -23,10 +23,12 @@ package org.onap.portalng.bff.config; import static org.springframework.security.config.Customizer.withDefaults; +import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; +import org.springframework.security.config.web.server.SecurityWebFiltersOrder; import org.springframework.security.config.web.server.ServerHttpSecurity; import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientManager; import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProvider; @@ -38,8 +40,11 @@ import org.springframework.security.web.server.SecurityWebFilterChain; @Configuration @EnableWebFluxSecurity +@RequiredArgsConstructor public class SecurityConfig { + private final KeycloakPermissionFilter keycloakPermissionFilter; + @Value("${bff.endpoints.unauthenticated}") private String[] unauthenticatedEndpoints; @@ -59,6 +64,7 @@ public class SecurityConfig { .authenticated()) .oauth2ResourceServer(ServerHttpSecurity.OAuth2ResourceServerSpec::jwt) .oauth2Client(withDefaults()) + .addFilterAfter(keycloakPermissionFilter, SecurityWebFiltersOrder.AUTHORIZATION) .build(); } diff --git a/lib/src/main/java/org/onap/portalng/bff/controller/AbstractBffController.java b/lib/src/main/java/org/onap/portalng/bff/controller/AbstractBffController.java index afcb448..c311cb9 100644 --- a/lib/src/main/java/org/onap/portalng/bff/controller/AbstractBffController.java +++ b/lib/src/main/java/org/onap/portalng/bff/controller/AbstractBffController.java @@ -22,9 +22,6 @@ package org.onap.portalng.bff.controller; import org.onap.portalng.bff.config.BffConfig; -import org.onap.portalng.bff.config.IdTokenExchangeFilterFunction; -import org.springframework.web.server.ServerWebExchange; -import reactor.core.publisher.Mono; public abstract class AbstractBffController { @@ -33,14 +30,4 @@ public abstract class AbstractBffController { protected AbstractBffController(BffConfig bffConfig) { this.bffConfig = bffConfig; } - - public Mono<Void> checkRoleAccess(String method, ServerWebExchange exchange) { - return bffConfig - .getRoles(method) - .flatMap( - roles -> - roles.contains("*") - ? Mono.empty() - : IdTokenExchangeFilterFunction.validateAccess(exchange, roles)); - } } diff --git a/lib/src/main/java/org/onap/portalng/bff/controller/ActionsController.java b/lib/src/main/java/org/onap/portalng/bff/controller/ActionsController.java index 8b8f615..9d7706c 100644 --- a/lib/src/main/java/org/onap/portalng/bff/controller/ActionsController.java +++ b/lib/src/main/java/org/onap/portalng/bff/controller/ActionsController.java @@ -34,9 +34,6 @@ import reactor.core.publisher.Mono; @RestController public class ActionsController extends AbstractBffController implements ActionsApi { - public static final String CREATE = "ACTIONS_CREATE"; - public static final String GET = "ACTIONS_GET"; - public static final String LIST = "ACTIONS_LIST"; private final ActionService actionService; @@ -51,8 +48,7 @@ public class ActionsController extends AbstractBffController implements ActionsA String xRequestId, Mono<CreateActionRequestApiDto> createActionRequestApiDto, ServerWebExchange exchange) { - return checkRoleAccess(CREATE, exchange) - .then(createActionRequestApiDto) + return createActionRequestApiDto .flatMap(action -> actionService.createAction(userId, xRequestId, action)) .map(ResponseEntity::ok); } @@ -65,8 +61,8 @@ public class ActionsController extends AbstractBffController implements ActionsA Integer showLastHours, String xRequestId, ServerWebExchange exchange) { - return checkRoleAccess(GET, exchange) - .then(actionService.getActions(userId, xRequestId, page, pageSize, showLastHours)) + return actionService + .getActions(userId, xRequestId, page, pageSize, showLastHours) .map(ResponseEntity::ok); } @@ -77,8 +73,8 @@ public class ActionsController extends AbstractBffController implements ActionsA Integer showLastHours, String xRequestId, ServerWebExchange exchange) { - return checkRoleAccess(LIST, exchange) - .then(actionService.listActions(xRequestId, page, pageSize, showLastHours)) + return actionService + .listActions(xRequestId, page, pageSize, showLastHours) .map(ResponseEntity::ok); } } diff --git a/lib/src/main/java/org/onap/portalng/bff/controller/PreferencesController.java b/lib/src/main/java/org/onap/portalng/bff/controller/PreferencesController.java index af665db..b8b428f 100644 --- a/lib/src/main/java/org/onap/portalng/bff/controller/PreferencesController.java +++ b/lib/src/main/java/org/onap/portalng/bff/controller/PreferencesController.java @@ -34,9 +34,6 @@ import reactor.core.publisher.Mono; @RestController public class PreferencesController extends AbstractBffController implements PreferencesApi { - public static final String CREATE = "PREFERENCES_CREATE"; - public static final String GET = "PREFERENCES_GET"; - public static final String UPDATE = "PREFERENCES_UPDATE"; private final PreferencesService preferencesService; @@ -48,9 +45,7 @@ public class PreferencesController extends AbstractBffController implements Pref @Override public Mono<ResponseEntity<PreferencesResponseApiDto>> getPreferences( String xRequestId, ServerWebExchange exchange) { - return checkRoleAccess(GET, exchange) - .then(preferencesService.getPreferences(xRequestId)) - .map(ResponseEntity::ok); + return preferencesService.getPreferences(xRequestId).map(ResponseEntity::ok); } @Override @@ -58,8 +53,7 @@ public class PreferencesController extends AbstractBffController implements Pref @Valid Mono<CreatePreferencesRequestApiDto> preferencesApiDto, String xRequestId, ServerWebExchange exchange) { - return checkRoleAccess(CREATE, exchange) - .then(preferencesApiDto) + return preferencesApiDto .flatMap(request -> preferencesService.createPreferences(xRequestId, request)) .map(ResponseEntity::ok); } @@ -69,8 +63,7 @@ public class PreferencesController extends AbstractBffController implements Pref @Valid Mono<CreatePreferencesRequestApiDto> preferencesApiDto, String xRequestId, ServerWebExchange exchange) { - return checkRoleAccess(UPDATE, exchange) - .then(preferencesApiDto) + return preferencesApiDto .flatMap(request -> preferencesService.updatePreferences(xRequestId, request)) .map(ResponseEntity::ok); } diff --git a/lib/src/main/java/org/onap/portalng/bff/controller/RolesController.java b/lib/src/main/java/org/onap/portalng/bff/controller/RolesController.java index 69b4093..1d948a2 100644 --- a/lib/src/main/java/org/onap/portalng/bff/controller/RolesController.java +++ b/lib/src/main/java/org/onap/portalng/bff/controller/RolesController.java @@ -33,8 +33,6 @@ import reactor.core.publisher.Mono; @RestController public class RolesController extends AbstractBffController implements RolesApi { - public static final String LIST = "ROLE_LIST"; - private final KeycloakService keycloakService; public RolesController(BffConfig bffConfig, KeycloakService keycloakService) { @@ -45,8 +43,8 @@ public class RolesController extends AbstractBffController implements RolesApi { @Override public Mono<ResponseEntity<RoleListResponseApiDto>> listRoles( String xRequestId, ServerWebExchange exchange) { - return checkRoleAccess(LIST, exchange) - .thenMany(keycloakService.listRoles(xRequestId)) + return keycloakService + .listRoles(xRequestId) .collectList() .map(roles -> new RoleListResponseApiDto().items(roles).totalCount(roles.size())) .map(ResponseEntity::ok); diff --git a/lib/src/main/java/org/onap/portalng/bff/controller/UsersController.java b/lib/src/main/java/org/onap/portalng/bff/controller/UsersController.java index a8561af..3efb28f 100644 --- a/lib/src/main/java/org/onap/portalng/bff/controller/UsersController.java +++ b/lib/src/main/java/org/onap/portalng/bff/controller/UsersController.java @@ -40,16 +40,6 @@ import reactor.core.publisher.Mono; @RestController public class UsersController extends AbstractBffController implements UsersApi { - public static final String CREATE = "USER_CREATE"; - public static final String GET = "USER_GET"; - public static final String UPDATE = "USER_UPDATE"; - public static final String DELETE = "USER_DELETE"; - public static final String LIST = "USER_LIST"; - public static final String UPDATE_PASSWORD = "USER_UPDATE_PASSWORD"; - public static final String UPDATE_ROLES = "USER_UPDATE_ROLES"; - public static final String LIST_ROLES = "USER_LIST_ROLES"; - public static final String LIST_AVAILABLE_ROLES = "USER_LIST_AVAILABLE_ROLES"; - private final KeycloakService keycloakService; public UsersController(BffConfig bffConfig, KeycloakService keycloakService) { @@ -60,17 +50,15 @@ public class UsersController extends AbstractBffController implements UsersApi { @Override public Mono<ResponseEntity<UserResponseApiDto>> createUser( Mono<CreateUserRequestApiDto> requestMono, String xRequestId, ServerWebExchange exchange) { - return checkRoleAccess(CREATE, exchange) - .then(requestMono.flatMap(request -> keycloakService.createUser(request, xRequestId))) + return requestMono + .flatMap(request -> keycloakService.createUser(request, xRequestId)) .map(ResponseEntity::ok); } @Override public Mono<ResponseEntity<UserResponseApiDto>> getUser( String userId, String xRequestId, ServerWebExchange exchange) { - return checkRoleAccess(GET, exchange) - .then(keycloakService.getUser(userId, xRequestId)) - .map(ResponseEntity::ok); + return keycloakService.getUser(userId, xRequestId).map(ResponseEntity::ok); } @Override @@ -79,8 +67,7 @@ public class UsersController extends AbstractBffController implements UsersApi { Mono<UpdateUserRequestApiDto> requestMono, String xRequestId, ServerWebExchange exchange) { - return checkRoleAccess(UPDATE, exchange) - .then(requestMono) + return requestMono .flatMap(request -> keycloakService.updateUser(userId, request, xRequestId)) .map(ResponseEntity::ok); } @@ -88,8 +75,8 @@ public class UsersController extends AbstractBffController implements UsersApi { @Override public Mono<ResponseEntity<Void>> deleteUser( String userId, String xRequestId, ServerWebExchange exchange) { - return checkRoleAccess(DELETE, exchange) - .then(keycloakService.deleteUser(userId, xRequestId)) + return keycloakService + .deleteUser(userId, xRequestId) .thenReturn(ResponseEntity.noContent().build()); } @@ -97,9 +84,7 @@ public class UsersController extends AbstractBffController implements UsersApi { public Mono<ResponseEntity<UserListResponseApiDto>> listUsers( Integer page, Integer pageSize, String xRequestId, ServerWebExchange exchange) { - return checkRoleAccess(LIST, exchange) - .then(keycloakService.listUsers(page, pageSize, xRequestId)) - .map(ResponseEntity::ok); + return keycloakService.listUsers(page, pageSize, xRequestId).map(ResponseEntity::ok); } @Override @@ -108,8 +93,7 @@ public class UsersController extends AbstractBffController implements UsersApi { Mono<UpdateUserPasswordRequestApiDto> requestMono, String xRequestId, ServerWebExchange exchange) { - return checkRoleAccess(UPDATE_PASSWORD, exchange) - .then(requestMono) + return requestMono .flatMap(request -> keycloakService.updateUserPassword(userId, request)) .thenReturn(ResponseEntity.noContent().build()); } @@ -117,24 +101,20 @@ public class UsersController extends AbstractBffController implements UsersApi { @Override public Mono<ResponseEntity<RoleListResponseApiDto>> listAvailableRoles( String userId, String xRequestId, ServerWebExchange exchange) { - return checkRoleAccess(LIST_AVAILABLE_ROLES, exchange) - .then(keycloakService.getAvailableRoles(userId, xRequestId)) - .map(ResponseEntity::ok); + return keycloakService.getAvailableRoles(userId, xRequestId).map(ResponseEntity::ok); } @Override public Mono<ResponseEntity<RoleListResponseApiDto>> listAssignedRoles( String userId, String xRequestId, ServerWebExchange exchange) { - return checkRoleAccess(LIST_ROLES, exchange) - .then(keycloakService.getAssignedRoles(userId, xRequestId)) - .map(ResponseEntity::ok); + return keycloakService.getAssignedRoles(userId, xRequestId).map(ResponseEntity::ok); } @Override public Mono<ResponseEntity<RoleListResponseApiDto>> updateAssignedRoles( String userId, String xRequestId, Flux<RoleApiDto> rolesFlux, ServerWebExchange exchange) { - return checkRoleAccess(UPDATE_ROLES, exchange) - .then(rolesFlux.collectList()) + return rolesFlux + .collectList() .flatMap(roles -> keycloakService.updateAssignedRoles(userId, roles, xRequestId)) .map(ResponseEntity::ok); } |