From f07e4b397c60c21ae275a7c98471b64e60f14f04 Mon Sep 17 00:00:00 2001 From: PatrikBuhr Date: Wed, 5 Apr 2023 14:40:07 +0200 Subject: A1 PMS support for fine grained access control -A1 London Issue-ID: CCSDK-3885 Signed-off-by: PatrikBuhr Change-Id: I2ee8f40389d1d53cbfd9433232e0f35f2644361b --- .../configuration/ApplicationConfig.java | 6 ++ .../authorization/AuthorizationCheck.java | 109 +++++++++++++++++++++ .../authorization/AuthorizationConsts.java | 37 +++++++ .../authorization/AuthorizationResult.java | 41 ++++++++ .../authorization/PolicyAuthorizationRequest.java | 77 +++++++++++++++ .../controllers/v2/PolicyAuthorizationRequest.java | 47 --------- .../controllers/v2/PolicyController.java | 78 ++++++++++----- .../controllers/v2/ServiceController.java | 2 - .../repository/Policies.java | 2 +- 9 files changed, 327 insertions(+), 72 deletions(-) create mode 100644 a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/authorization/AuthorizationCheck.java create mode 100644 a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/authorization/AuthorizationConsts.java create mode 100644 a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/authorization/AuthorizationResult.java create mode 100644 a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/authorization/PolicyAuthorizationRequest.java delete mode 100644 a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyAuthorizationRequest.java (limited to 'a1-policy-management/src/main/java/org/onap') diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfig.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfig.java index eea96927..3de674bd 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfig.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/configuration/ApplicationConfig.java @@ -28,6 +28,7 @@ import java.util.HashMap; import java.util.Map; import lombok.Getter; +import lombok.Setter; import org.onap.ccsdk.oran.a1policymanagementservice.configuration.WebClientConfig.HttpProxyConfig; import org.onap.ccsdk.oran.a1policymanagementservice.exceptions.ServiceException; @@ -98,6 +99,11 @@ public class ApplicationConfig { @Value("${app.s3.bucket:}") private String s3Bucket; + @Getter + @Setter + @Value("${app.authorization-provider:}") + private String authProviderUrl; + private Map ricConfigs = new HashMap<>(); private WebClientConfig webClientConfig = null; diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/authorization/AuthorizationCheck.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/authorization/AuthorizationCheck.java new file mode 100644 index 00000000..0f376c06 --- /dev/null +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/authorization/AuthorizationCheck.java @@ -0,0 +1,109 @@ +/*- + * ========================LICENSE_START================================= + * ONAP : ccsdk oran + * ====================================================================== + * Copyright (C) 2023 Nordix Foundation. All rights reserved. + * ====================================================================== + * 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. + * ========================LICENSE_END=================================== + */ + +package org.onap.ccsdk.oran.a1policymanagementservice.controllers.authorization; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import java.lang.invoke.MethodHandles; +import java.util.Map; + +import org.onap.ccsdk.oran.a1policymanagementservice.clients.AsyncRestClient; +import org.onap.ccsdk.oran.a1policymanagementservice.clients.AsyncRestClientFactory; +import org.onap.ccsdk.oran.a1policymanagementservice.clients.SecurityContext; +import org.onap.ccsdk.oran.a1policymanagementservice.configuration.ApplicationConfig; +import org.onap.ccsdk.oran.a1policymanagementservice.controllers.authorization.PolicyAuthorizationRequest.Input.AccessType; +import org.onap.ccsdk.oran.a1policymanagementservice.exceptions.ServiceException; +import org.onap.ccsdk.oran.a1policymanagementservice.repository.Policy; +import org.onap.ccsdk.oran.a1policymanagementservice.repository.PolicyType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; + +import reactor.core.publisher.Mono; + +@Component +public class AuthorizationCheck { + + private final ApplicationConfig applicationConfig; + private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + private final AsyncRestClient restClient; + private static Gson gson = new GsonBuilder().disableHtmlEscaping().create(); + + public AuthorizationCheck(ApplicationConfig applicationConfig, SecurityContext securityContext) { + + this.applicationConfig = applicationConfig; + AsyncRestClientFactory restClientFactory = + new AsyncRestClientFactory(applicationConfig.getWebClientConfig(), securityContext); + this.restClient = restClientFactory.createRestClientUseHttpProxy(""); + } + + public Mono doAccessControl(Map receivedHttpHeaders, Policy policy, AccessType accessType) { + return doAccessControl(receivedHttpHeaders, policy.getType(), accessType) // + .map(x -> policy); + } + + public Mono doAccessControl(Map receivedHttpHeaders, PolicyType type, + AccessType accessType) { + if (this.applicationConfig.getAuthProviderUrl().isEmpty()) { + return Mono.just(type); + } + + String tkn = getAuthToken(receivedHttpHeaders); + PolicyAuthorizationRequest.Input input = PolicyAuthorizationRequest.Input.builder() // + .authToken(tkn) // + .policyTypeId(type.getId()) // + .accessType(accessType).build(); + + PolicyAuthorizationRequest req = PolicyAuthorizationRequest.builder().input(input).build(); + + String url = this.applicationConfig.getAuthProviderUrl(); + return this.restClient.post(url, gson.toJson(req)) // + .doOnError(t -> logger.warn("Error returned from auth server: {}", t.getMessage())) // + .onErrorResume(t -> Mono.just("")) // + .flatMap(this::checkAuthResult) // + .map(rsp -> type); + + } + + private String getAuthToken(Map httpHeaders) { + String tkn = httpHeaders.get("authorization"); + if (tkn == null) { + logger.debug("No authorization token received in {}", httpHeaders); + return ""; + } + tkn = tkn.substring("Bearer ".length()); + return tkn; + } + + private Mono checkAuthResult(String response) { + logger.debug("Auth result: {}", response); + try { + AuthorizationResult res = gson.fromJson(response, AuthorizationResult.class); + return res != null && res.isResult() ? Mono.just(response) + : Mono.error(new ServiceException("Not authorized", HttpStatus.UNAUTHORIZED)); + } catch (Exception e) { + return Mono.error(e); + } + } + +} diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/authorization/AuthorizationConsts.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/authorization/AuthorizationConsts.java new file mode 100644 index 00000000..a905b9d1 --- /dev/null +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/authorization/AuthorizationConsts.java @@ -0,0 +1,37 @@ +/*- + * ========================LICENSE_START================================= + * ONAP : ccsdk oran + * ====================================================================== + * Copyright (C) 2023 Nordix Foundation. All rights reserved. + * ====================================================================== + * 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. + * ========================LICENSE_END=================================== + */ + +package org.onap.ccsdk.oran.a1policymanagementservice.controllers.authorization; + +public class AuthorizationConsts { + + public static final String AUTH_API_NAME = "Authorization API"; + public static final String AUTH_API_DESCRIPTION = + """ + API used for authorization of information A1 policy access (this is provided by an authorization producer such as OPA). + Note that this API is called by PMS, it is not provided. + """; + + public static final String GRANT_ACCESS_SUMMARY = "Request for access authorization."; + public static final String GRANT_ACCESS_DESCRIPTION = "The authorization function decides if access is granted."; + + private AuthorizationConsts() {} + +} diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/authorization/AuthorizationResult.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/authorization/AuthorizationResult.java new file mode 100644 index 00000000..796c44e9 --- /dev/null +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/authorization/AuthorizationResult.java @@ -0,0 +1,41 @@ +/*- + * ========================LICENSE_START================================= + * ONAP : ccsdk oran + * ====================================================================== + * Copyright (C) 2023 Nordix Foundation. All rights reserved. + * ====================================================================== + * 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. + * ========================LICENSE_END=================================== + */ + +package org.onap.ccsdk.oran.a1policymanagementservice.controllers.authorization; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.gson.annotations.SerializedName; + +import io.swagger.v3.oas.annotations.media.Schema; + +import lombok.Builder; +import lombok.Getter; + +@Schema(name = "authorization_result", description = "Result of authorization") +@Builder +public class AuthorizationResult { + + @Schema(name = "result", description = "If true, the access is granted", required = true) + @JsonProperty(value = "result", required = true) + @SerializedName("result") + @Getter + private boolean result; + +} diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/authorization/PolicyAuthorizationRequest.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/authorization/PolicyAuthorizationRequest.java new file mode 100644 index 00000000..8dd4e7bb --- /dev/null +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/authorization/PolicyAuthorizationRequest.java @@ -0,0 +1,77 @@ +/*- + * ========================LICENSE_START================================= + * ONAP : ccsdk oran + * ====================================================================== + * Copyright (C) 2023 Nordix Foundation. All rights reserved. + * ====================================================================== + * 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. + * ========================LICENSE_END=================================== + */ + +package org.onap.ccsdk.oran.a1policymanagementservice.controllers.authorization; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.gson.annotations.SerializedName; + +import io.swagger.v3.oas.annotations.media.Schema; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@Schema(name = "policy_authorization", description = "Authorization request for A1 policy requests") +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Getter +public class PolicyAuthorizationRequest { + + @Schema(name = "input", description = "input") + @Builder + @AllArgsConstructor + @NoArgsConstructor + @Getter + @ToString + public static class Input { + + @Schema(name = "acces_type", description = "Access type") + public enum AccessType { + READ, WRITE, DELETE + } + + @Schema(name = "access_type", description = "Access type", required = true) + @JsonProperty(value = "access_type", required = true) + @SerializedName("access_type") + @Getter + private AccessType accessType; + + @Schema(name = "policy_type_id", description = "Policy type identifier", required = true) + @SerializedName("policy_type_id") + @JsonProperty(value = "policy_type_id", required = true) + private String policyTypeId; + + @Schema(name = "auth_token", description = "Authorization token", required = true) + @SerializedName("auth_token") + @JsonProperty(value = "auth_token", required = true) + private String authToken; + + } + + @Schema(name = "input", description = "Input", required = true) + @JsonProperty(value = "input", required = true) + @SerializedName("input") + private Input input; + +} diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyAuthorizationRequest.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyAuthorizationRequest.java deleted file mode 100644 index 63a53109..00000000 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyAuthorizationRequest.java +++ /dev/null @@ -1,47 +0,0 @@ -/*- - * ========================LICENSE_START================================= - * ONAP : ccsdk oran - * ====================================================================== - * Copyright (C) 2022 Nordix Foundation. All rights reserved. - * ====================================================================== - * 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. - * ========================LICENSE_END=================================== - */ - -package org.onap.ccsdk.oran.a1policymanagementservice.controllers.v2; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.google.gson.annotations.SerializedName; - -import io.swagger.v3.oas.annotations.media.Schema; - -import lombok.Builder; -import lombok.Getter; - - -@Schema(name = "policy_authorization", description = "Authorization request for A1 policy requests") -@Builder -public class PolicyAuthorizationRequest { - - @Schema(name = "acces_type", description = "Access type") - public enum AccessType { - READ, WRITE, DELETE - } - - @Schema(name = "access_type", description = "Access type", required = true) - @JsonProperty(value = "access_type", required = true) - @SerializedName("access_type") - @Getter - private String accessType; - -} diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyController.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyController.java index 395daa30..64905f44 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyController.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/PolicyController.java @@ -36,11 +36,14 @@ import java.time.Instant; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Map; import lombok.Getter; import org.onap.ccsdk.oran.a1policymanagementservice.clients.A1ClientFactory; import org.onap.ccsdk.oran.a1policymanagementservice.controllers.VoidResponse; +import org.onap.ccsdk.oran.a1policymanagementservice.controllers.authorization.AuthorizationCheck; +import org.onap.ccsdk.oran.a1policymanagementservice.controllers.authorization.PolicyAuthorizationRequest.Input.AccessType; import org.onap.ccsdk.oran.a1policymanagementservice.exceptions.EntityNotFoundException; import org.onap.ccsdk.oran.a1policymanagementservice.exceptions.ServiceException; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Lock; @@ -64,11 +67,13 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.reactive.function.client.WebClientException; import org.springframework.web.reactive.function.client.WebClientResponseException; +import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @RestController("PolicyControllerV2") @@ -104,6 +109,9 @@ public class PolicyController { @Autowired private Services services; + @Autowired + private AuthorizationCheck authorization; + private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); private static Gson gson = new GsonBuilder() // .create(); // @@ -175,10 +183,13 @@ public class PolicyController { description = "Policy is not found", // content = @Content(schema = @Schema(implementation = ErrorResponse.ErrorInfo.class))) // }) - public ResponseEntity getPolicy( // - @PathVariable(name = Consts.POLICY_ID_PARAM, required = true) String id) throws EntityNotFoundException { - Policy p = policies.getPolicy(id); - return new ResponseEntity<>(gson.toJson(toPolicyInfo(p)), HttpStatus.OK); + public Mono> getPolicy( // + @PathVariable(name = Consts.POLICY_ID_PARAM, required = true) String id, + @RequestHeader Map headers) throws EntityNotFoundException { + Policy policy = policies.getPolicy(id); + return authorization.doAccessControl(headers, policy, AccessType.READ) // + .map(x -> new ResponseEntity<>((Object) gson.toJson(toPolicyInfo(policy)), HttpStatus.OK)) // + .onErrorResume(this::handleException); } @DeleteMapping(Consts.V2_API_ROOT + "/policies/{policy_id:.+}") @@ -198,12 +209,15 @@ public class PolicyController { content = @Content(schema = @Schema(implementation = ErrorResponse.ErrorInfo.class))) // }) public Mono> deletePolicy( // - @PathVariable(Consts.POLICY_ID_PARAM) String policyId) throws EntityNotFoundException { + @PathVariable(Consts.POLICY_ID_PARAM) String policyId, @RequestHeader Map headers) + throws EntityNotFoundException { Policy policy = policies.getPolicy(policyId); keepServiceAlive(policy.getOwnerServiceId()); - return policy.getRic().getLock().lock(LockType.SHARED, "deletePolicy") // - .flatMap(grant -> deletePolicy(grant, policy)); + return authorization.doAccessControl(headers, policy, AccessType.WRITE) + .flatMap(x -> policy.getRic().getLock().lock(LockType.SHARED, "deletePolicy")) // + .flatMap(grant -> deletePolicy(grant, policy)) // + .onErrorResume(this::handleException); } Mono> deletePolicy(Lock.Grant grant, Policy policy) { @@ -232,7 +246,8 @@ public class PolicyController { description = "Near-RT RIC or policy type is not found", // content = @Content(schema = @Schema(implementation = ErrorResponse.ErrorInfo.class))) // }) - public Mono> putPolicy(@RequestBody PolicyInfo policyInfo) throws EntityNotFoundException { + public Mono> putPolicy(@RequestBody PolicyInfo policyInfo, + @RequestHeader Map headers) throws EntityNotFoundException { if (!policyInfo.validate()) { return ErrorResponse.createMono("Missing required parameter in body", HttpStatus.BAD_REQUEST); @@ -255,8 +270,10 @@ public class PolicyController { .statusNotificationUri(policyInfo.statusNotificationUri == null ? "" : policyInfo.statusNotificationUri) // .build(); - return ric.getLock().lock(LockType.SHARED, "putPolicy") // - .flatMap(grant -> putPolicy(grant, policy)); + return authorization.doAccessControl(headers, policy, AccessType.WRITE) // + .flatMap(x -> ric.getLock().lock(LockType.SHARED, "putPolicy")) // + .flatMap(grant -> putPolicy(grant, policy)) // + .onErrorResume(this::handleException); } private Mono> putPolicy(Lock.Grant grant, Policy policy) { @@ -285,6 +302,9 @@ public class PolicyController { } else if (throwable instanceof RejectionException) { RejectionException e = (RejectionException) throwable; return ErrorResponse.createMono(e.getMessage(), e.getStatus()); + } else if (throwable instanceof ServiceException) { + ServiceException e = (ServiceException) throwable; + return ErrorResponse.createMono(e.getMessage(), e.getHttpStatus()); } else { return ErrorResponse.createMono(throwable.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); } @@ -339,7 +359,7 @@ public class PolicyController { description = "Near-RT RIC, policy type or service not found", // content = @Content(schema = @Schema(implementation = ErrorResponse.ErrorInfo.class))) // }) - public ResponseEntity getPolicyInstances( // + public Mono> getPolicyInstances( // @Parameter(name = Consts.POLICY_TYPE_ID_PARAM, required = false, description = "Select policies with a given type identity.") // @RequestParam(name = Consts.POLICY_TYPE_ID_PARAM, required = false) String typeId, // @@ -351,8 +371,8 @@ public class PolicyController { @RequestParam(name = Consts.SERVICE_ID_PARAM, required = false) String service, @Parameter(name = Consts.TYPE_NAME_PARAM, required = false, // description = "Select policies of a given type name (type identity has the format )") // - @RequestParam(name = Consts.TYPE_NAME_PARAM, required = false) String typeName) - throws EntityNotFoundException // + @RequestParam(name = Consts.TYPE_NAME_PARAM, required = false) String typeName, + @RequestHeader Map headers) throws EntityNotFoundException // { if ((typeId != null && this.policyTypes.get(typeId) == null)) { throw new EntityNotFoundException("Policy type identity not found"); @@ -361,8 +381,14 @@ public class PolicyController { throw new EntityNotFoundException("Near-RT RIC not found"); } - String filteredPolicies = policiesToJson(policies.filterPolicies(typeId, ric, service, typeName)); - return new ResponseEntity<>(filteredPolicies, HttpStatus.OK); + Collection filtered = policies.filterPolicies(typeId, ric, service, typeName); + return Flux.fromIterable(filtered) // + .flatMap(policy -> authorization.doAccessControl(headers, policy, AccessType.READ)) // + .doOnError(e -> logger.debug("Unauthorized to read policy: {}", e.getMessage())) // + .onErrorResume(e -> Mono.empty()) // + .collectList() // + .map(authPolicies -> policiesToJson(authPolicies)) // + .map(str -> new ResponseEntity<>(str, HttpStatus.OK)); } @GetMapping(path = Consts.V2_API_ROOT + "/policies", produces = MediaType.APPLICATION_JSON_VALUE) // @@ -375,7 +401,7 @@ public class PolicyController { description = "Near-RT RIC or type not found", // content = @Content(schema = @Schema(implementation = ErrorResponse.ErrorInfo.class))) // }) - public ResponseEntity getPolicyIds( // + public Mono> getPolicyIds( // @Parameter(name = Consts.POLICY_TYPE_ID_PARAM, required = false, // description = "Select policies of a given policy type identity.") // @RequestParam(name = Consts.POLICY_TYPE_ID_PARAM, required = false) String policyTypeId, // @@ -387,8 +413,8 @@ public class PolicyController { @RequestParam(name = Consts.SERVICE_ID_PARAM, required = false) String serviceId, @Parameter(name = Consts.TYPE_NAME_PARAM, required = false, // description = "Select policies of types with the given type name (type identity has the format )") // - @RequestParam(name = Consts.TYPE_NAME_PARAM, required = false) String typeName) - throws EntityNotFoundException // + @RequestParam(name = Consts.TYPE_NAME_PARAM, required = false) String typeName, + @RequestHeader Map headers) throws EntityNotFoundException // { if ((policyTypeId != null && this.policyTypes.get(policyTypeId) == null)) { throw new EntityNotFoundException("Policy type not found"); @@ -397,8 +423,14 @@ public class PolicyController { throw new EntityNotFoundException("Near-RT RIC not found"); } - String policyIdsJson = toPolicyIdsJson(policies.filterPolicies(policyTypeId, ricId, serviceId, typeName)); - return new ResponseEntity<>(policyIdsJson, HttpStatus.OK); + Collection filtered = policies.filterPolicies(policyTypeId, ricId, serviceId, typeName); + return Flux.fromIterable(filtered) // + .flatMap(policy -> authorization.doAccessControl(headers, policy, AccessType.READ)) // + .doOnError(e -> logger.debug("Unauthorized to read policy: {}", e.getMessage())) // + .onErrorResume(e -> Mono.empty()) // + .collectList() // + .map(authPolicies -> toPolicyIdsJson(authPolicies)) // + .map(policyIdsJson -> new ResponseEntity<>(policyIdsJson, HttpStatus.OK)); } @GetMapping(path = Consts.V2_API_ROOT + "/policies/{policy_id}/status", produces = MediaType.APPLICATION_JSON_VALUE) @@ -412,10 +444,12 @@ public class PolicyController { content = @Content(schema = @Schema(implementation = ErrorResponse.ErrorInfo.class))) // }) public Mono> getPolicyStatus( // - @PathVariable(Consts.POLICY_ID_PARAM) String policyId) throws EntityNotFoundException { + @PathVariable(Consts.POLICY_ID_PARAM) String policyId, @RequestHeader Map headers) + throws EntityNotFoundException { Policy policy = policies.getPolicy(policyId); - return a1ClientFactory.createA1Client(policy.getRic()) // + return authorization.doAccessControl(headers, policy, AccessType.READ) // + .flatMap(notUsed -> a1ClientFactory.createA1Client(policy.getRic())) // .flatMap(client -> client.getPolicyStatus(policy).onErrorResume(e -> Mono.just("{}"))) // .flatMap(status -> createPolicyStatus(policy, status)) // .onErrorResume(this::handleException); diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ServiceController.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ServiceController.java index c3f41768..ed97820f 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ServiceController.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/controllers/v2/ServiceController.java @@ -43,7 +43,6 @@ import org.onap.ccsdk.oran.a1policymanagementservice.repository.Policies; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Policy; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Service; import org.onap.ccsdk.oran.a1policymanagementservice.repository.Services; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -71,7 +70,6 @@ public class ServiceController { private static Gson gson = new GsonBuilder().create(); - @Autowired ServiceController(Services services, Policies policies) { this.services = services; this.policies = policies; diff --git a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/repository/Policies.java b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/repository/Policies.java index 77ac0f4a..7eddeae1 100644 --- a/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/repository/Policies.java +++ b/a1-policy-management/src/main/java/org/onap/ccsdk/oran/a1policymanagementservice/repository/Policies.java @@ -197,7 +197,7 @@ public class Policies { byte[] bytes = gson.toJson(toStorageObject(policy)).getBytes(); this.dataStore.writeObject(this.getPath(policy), bytes) // - .doOnError(t -> logger.error("Could not store job in S3, reason: {}", t.getMessage())) // + .doOnError(t -> logger.error("Could not store policy in S3, reason: {}", t.getMessage())) // .subscribe(); } -- cgit 1.2.3-korg