From 7bc81973c823789debc000858f7777d120709ac4 Mon Sep 17 00:00:00 2001 From: Ittay Stern Date: Tue, 11 Feb 2020 13:56:54 +0200 Subject: Filter owning-entities from /category_parameter by permissions Implemented in CategoryParameterServiceWithRoles and injected to MaintenanceController, but still reachable because shouldTreatPermissions() is "false". Issue-ID: VID-758 Change-Id: I716202ca944af9b0de9c151d75d50b5df41a8171 Signed-off-by: Ittay Stern --- .../onap/vid/controller/PropertyController.java | 20 ++-- .../vid/services/CategoryParameterServiceImpl.java | 2 + .../services/CategoryParameterServiceWithRoles.kt | 60 +++++++++++ .../vid/controller/PropertyControllerTest.java | 3 +- .../CategoryParameterServiceWithRolesTest.kt | 114 +++++++++++++++++++++ 5 files changed, 190 insertions(+), 9 deletions(-) create mode 100644 vid-app-common/src/main/java/org/onap/vid/services/CategoryParameterServiceWithRoles.kt create mode 100644 vid-app-common/src/test/java/org/onap/vid/services/CategoryParameterServiceWithRolesTest.kt diff --git a/vid-app-common/src/main/java/org/onap/vid/controller/PropertyController.java b/vid-app-common/src/main/java/org/onap/vid/controller/PropertyController.java index 7f127886b..0b42bcb4e 100644 --- a/vid-app-common/src/main/java/org/onap/vid/controller/PropertyController.java +++ b/vid-app-common/src/main/java/org/onap/vid/controller/PropertyController.java @@ -21,23 +21,27 @@ package org.onap.vid.controller; +import static org.onap.vid.utils.Logging.getMethodName; +import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR; +import static org.springframework.http.HttpStatus.OK; + +import javax.servlet.http.HttpServletRequest; import org.onap.portalsdk.core.controller.RestrictedBaseController; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; import org.onap.vid.category.CategoryParametersResponse; import org.onap.vid.model.CategoryParameter.Family; import org.onap.vid.services.CategoryParameterService; +import org.onap.vid.services.CategoryParameterServiceWithRoles; import org.onap.vid.utils.SystemPropertiesWrapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.ModelAndView; -import javax.servlet.http.HttpServletRequest; - -import static org.onap.vid.utils.Logging.getMethodName; -import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR; -import static org.springframework.http.HttpStatus.OK; - @RestController public class PropertyController extends RestrictedBaseController { @@ -47,7 +51,7 @@ public class PropertyController extends RestrictedBaseController { private final SystemPropertiesWrapper systemPropertiesWrapper; @Autowired - public PropertyController(CategoryParameterService service, SystemPropertiesWrapper systemPropertiesWrapper) { + public PropertyController(CategoryParameterServiceWithRoles service, SystemPropertiesWrapper systemPropertiesWrapper) { categoryParameterService = service; this.systemPropertiesWrapper = systemPropertiesWrapper; } diff --git a/vid-app-common/src/main/java/org/onap/vid/services/CategoryParameterServiceImpl.java b/vid-app-common/src/main/java/org/onap/vid/services/CategoryParameterServiceImpl.java index 98a84c26c..f4d21e842 100644 --- a/vid-app-common/src/main/java/org/onap/vid/services/CategoryParameterServiceImpl.java +++ b/vid-app-common/src/main/java/org/onap/vid/services/CategoryParameterServiceImpl.java @@ -30,6 +30,7 @@ import org.onap.vid.model.CategoryParameterOption; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; import org.onap.portalsdk.core.service.DataAccessService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Service; import javax.ws.rs.ForbiddenException; @@ -38,6 +39,7 @@ import java.util.stream.Collectors; @Service +@Primary public class CategoryParameterServiceImpl implements CategoryParameterService { public static final String OPTION_ALREADY_EXIST_FOR_CATEGORY = "Option %s already exist for category %s"; diff --git a/vid-app-common/src/main/java/org/onap/vid/services/CategoryParameterServiceWithRoles.kt b/vid-app-common/src/main/java/org/onap/vid/services/CategoryParameterServiceWithRoles.kt new file mode 100644 index 000000000..f059e590c --- /dev/null +++ b/vid-app-common/src/main/java/org/onap/vid/services/CategoryParameterServiceWithRoles.kt @@ -0,0 +1,60 @@ +package org.onap.vid.services + +import com.fasterxml.jackson.annotation.JsonIgnore +import org.onap.vid.category.CategoryParameterOptionRep +import org.onap.vid.category.CategoryParametersResponse +import org.onap.vid.model.CategoryParameter +import org.onap.vid.roles.RoleProvider +import org.onap.vid.roles.WithPermissionPropertiesOwningEntity +import org.springframework.beans.factory.annotation.Qualifier +import org.springframework.stereotype.Service +import org.togglz.core.manager.FeatureManager +import javax.servlet.http.HttpServletRequest + +@Service +@Qualifier("WithRoles") +class CategoryParameterServiceWithRoles( + private val categoryParameterService: CategoryParameterService, + private val featureManager: FeatureManager, + private val roleProvider: RoleProvider, + private val request: HttpServletRequest +) : CategoryParameterService by categoryParameterService { + + private val owningEntityKey = "owningEntity" + + private fun shouldTreatPermissions() = false + + override fun getCategoryParameters(familyName: CategoryParameter.Family?): CategoryParametersResponse { + val categoryParameters = + categoryParameterService.getCategoryParameters(familyName) + + return if (shouldTreatPermissions()) { + treatPermissions(categoryParameters) + } else { + categoryParameters + } + } + + internal fun treatPermissions(categoryParametersResponse: CategoryParametersResponse): CategoryParametersResponse { + val extractedCategoryParameters = categoryParametersResponse.categoryParameters + val owningEntities = extractedCategoryParameters[owningEntityKey] + + return CategoryParametersResponse( + extractedCategoryParameters + (owningEntityKey to removeNonPermitted(owningEntities))) + } + + private fun removeNonPermitted(owningEntities: MutableList?): List? { + val userRolesValidator = roleProvider.getUserRolesValidator(request) + return owningEntities + ?.map { OwningEntityOptionRep(it) } + ?.filter { userRolesValidator.isServicePermitted(it) } + } + + + class OwningEntityOptionRep(categoryParameterOptionRep: CategoryParameterOptionRep) : + CategoryParameterOptionRep(categoryParameterOptionRep.id, categoryParameterOptionRep.name), + WithPermissionPropertiesOwningEntity { + override val owningEntityId: String? + @JsonIgnore get() = id + } +} diff --git a/vid-app-common/src/test/java/org/onap/vid/controller/PropertyControllerTest.java b/vid-app-common/src/test/java/org/onap/vid/controller/PropertyControllerTest.java index fd8fdcf54..7fcf0fe38 100644 --- a/vid-app-common/src/test/java/org/onap/vid/controller/PropertyControllerTest.java +++ b/vid-app-common/src/test/java/org/onap/vid/controller/PropertyControllerTest.java @@ -39,6 +39,7 @@ import org.onap.vid.category.CategoryParameterOptionRep; import org.onap.vid.category.CategoryParametersResponse; import org.onap.vid.model.CategoryParameter.Family; import org.onap.vid.services.CategoryParameterService; +import org.onap.vid.services.CategoryParameterServiceWithRoles; import org.onap.vid.utils.SystemPropertiesWrapper; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; @@ -58,7 +59,7 @@ public class PropertyControllerTest { private ObjectMapper objectMapper; @Mock - private CategoryParameterService service; + private CategoryParameterServiceWithRoles service; @Mock private SystemPropertiesWrapper systemPropertiesWrapper; diff --git a/vid-app-common/src/test/java/org/onap/vid/services/CategoryParameterServiceWithRolesTest.kt b/vid-app-common/src/test/java/org/onap/vid/services/CategoryParameterServiceWithRolesTest.kt new file mode 100644 index 000000000..2582012d9 --- /dev/null +++ b/vid-app-common/src/test/java/org/onap/vid/services/CategoryParameterServiceWithRolesTest.kt @@ -0,0 +1,114 @@ +package org.onap.vid.services + +import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper +import com.fasterxml.jackson.module.kotlin.readValue +import net.javacrumbs.jsonunit.JsonMatchers.jsonEquals +import net.javacrumbs.jsonunit.JsonMatchers.jsonPartEquals +import org.hamcrest.CoreMatchers.allOf +import org.hamcrest.MatcherAssert.assertThat +import org.intellij.lang.annotations.Language +import org.mockito.ArgumentMatchers.any +import org.mockito.InjectMocks +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.Mockito.mock +import org.mockito.invocation.InvocationOnMock +import org.onap.vid.category.CategoryParameterOptionRep +import org.onap.vid.category.CategoryParametersResponse +import org.onap.vid.roles.RoleProvider +import org.onap.vid.roles.RoleValidator +import org.onap.vid.services.CategoryParameterServiceWithRoles.OwningEntityOptionRep +import org.onap.vid.testUtils.TestUtils +import org.testng.annotations.BeforeMethod +import org.testng.annotations.Test +import org.togglz.core.manager.FeatureManager +import javax.servlet.http.HttpServletRequest +import org.mockito.Mockito.`when` as _when + +class CategoryParameterServiceWithRolesTest { + + @Mock lateinit var categoryParameterService: CategoryParameterService + @Mock lateinit var featureManager: FeatureManager + @Mock lateinit var roleProvider: RoleProvider + @Mock lateinit var request: HttpServletRequest + + private lateinit var alwaysTrueRoles: RoleValidator + private lateinit var alwaysFalseRoles: RoleValidator + + @InjectMocks + lateinit var categoryParameterServiceWithRoles: CategoryParameterServiceWithRoles; + + @BeforeMethod + fun initMocks() { + TestUtils.initMockitoMocks(this) + + alwaysTrueRoles = mock(RoleValidator::class.java, Mockito.withSettings().defaultAnswer { o: InvocationOnMock? -> true }) + alwaysFalseRoles = mock(RoleValidator::class.java) + } + + @Test + fun `treatPermissions -- given no permissions -- owningEntity lists is empty, the rest left intact`() { + _when(roleProvider.getUserRolesValidator(any())).thenReturn(alwaysFalseRoles) + + assertThat( + categoryParameterServiceWithRoles.treatPermissions(categoryParametersResponse), + allOf( + jsonPartEquals("categoryParameters.owningEntity", emptyList()), + jsonEquals(categoryParametersResponse) + .whenIgnoringPaths("categoryParameters.owningEntity") + ) + ) + } + + @Test + fun `treatPermissions -- given all permissions -- response left intact`() { + _when(roleProvider.getUserRolesValidator(any())).thenReturn(alwaysTrueRoles) + + assertThat( + categoryParameterServiceWithRoles.treatPermissions(categoryParametersResponse), + jsonEquals(categoryParametersResponse) + ) + } + + @Test + fun `treatPermissions -- given permission to WayneHolland -- only one owningEntity WayneHolland is left`() { + val wayneHolland = CategoryParameterOptionRep("d61e6f2d-12fa-4cc2-91df-7c244011d6fc", "WayneHolland") + + val roleValidatorForWayneHolland = mock(RoleValidator::class.java) + _when(roleValidatorForWayneHolland.isServicePermitted(OwningEntityOptionRep(wayneHolland))).thenReturn(true) + + _when(roleProvider.getUserRolesValidator(any())).thenReturn(roleValidatorForWayneHolland) + + assertThat( + categoryParameterServiceWithRoles.treatPermissions(categoryParametersResponse), + jsonPartEquals("categoryParameters.owningEntity", listOf(wayneHolland)) + ) + } + + + + @Language("JSON") val categoryParametersResponse: CategoryParametersResponse = + jacksonObjectMapper().readValue(""" + { + "categoryParameters": { + "lineOfBusiness": [ + { "id": "ONAP", "name": "ONAP" }, + { "id": "zzz1", "name": "zzz1" } + ], + "owningEntity": [ + { "id": "b1a9a80e-71b8-4176-9ac6-d265bf30e9d9", "name": "Melissa" }, + { "id": "d61e6f2d-12fa-4cc2-91df-7c244011d6fc", "name": "WayneHolland" } + ], + "project": [ + { "id": "WATKINS", "name": "WATKINS" }, + { "id": "yyy1", "name": "yyy1" } + ], + "platform": [ + { "id": "platform", "name": "platform" }, + { "id": "xxx1", "name": "xxx1" } + ] + } + }""") + + +} \ No newline at end of file -- cgit 1.2.3-korg