From 0cd9645a9dc83b9a5a2eddcc15cdfaf30fdade3a Mon Sep 17 00:00:00 2001 From: Dominik Mizyn Date: Mon, 7 Oct 2019 13:10:38 +0200 Subject: [PATCH] WidgetsController test coverage up WidgetsController test coverage up Issue-ID: PORTAL-710 Change-Id: Ie2473ea00ac5cb569a9461060924427d5cceada0 Signed-off-by: Dominik Mizyn --- .../aop/service/PersUserWidgetServiceAOP.java | 72 +++++++++++ .../onap/portal/aop/service/WidgetServiceAOP.java | 5 +- .../onap/portal/controller/WidgetsController.java | 67 ++++------- .../java/org/onap/portal/dao/fn/FnUserRoleDao.java | 58 +++++++++ .../portal/domain/db/ep/EpPersUserWidgetSel.java | 2 +- .../org/onap/portal/domain/db/fn/FnUserRole.java | 15 ++- .../transport/WidgetCatalogPersonalization.java | 3 + .../onap/portal/service/PersUserWidgetService.java | 58 ++++----- .../org/onap/portal/service/WidgetService.java | 28 ++--- .../onap/portal/service/fn/FnUserRoleService.java | 65 ++++++++++ .../portal/controller/WidgetsControllerTest.java | 131 ++++++++++++++++++--- 11 files changed, 389 insertions(+), 115 deletions(-) create mode 100644 portal-BE/src/main/java/org/onap/portal/aop/service/PersUserWidgetServiceAOP.java create mode 100644 portal-BE/src/main/java/org/onap/portal/dao/fn/FnUserRoleDao.java create mode 100644 portal-BE/src/main/java/org/onap/portal/service/fn/FnUserRoleService.java diff --git a/portal-BE/src/main/java/org/onap/portal/aop/service/PersUserWidgetServiceAOP.java b/portal-BE/src/main/java/org/onap/portal/aop/service/PersUserWidgetServiceAOP.java new file mode 100644 index 00000000..79326618 --- /dev/null +++ b/portal-BE/src/main/java/org/onap/portal/aop/service/PersUserWidgetServiceAOP.java @@ -0,0 +1,72 @@ +/* + * ============LICENSE_START========================================== + * ONAP Portal + * =================================================================== + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Modifications Copyright (c) 2019 Samsung + * =================================================================== + * + * Unless otherwise specified, all software contained herein is licensed + * under the Apache License, Version 2.0 (the "License"); + * you may not use this software 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. + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * 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.portal.aop.service; + +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.onap.portal.domain.db.fn.FnUser; +import org.onap.portal.domain.dto.transport.WidgetCatalogPersonalization; +import org.onap.portal.validation.DataValidator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Aspect +@Component +public class PersUserWidgetServiceAOP { + + private static final Logger LOGGER = LoggerFactory.getLogger(PersUserWidgetServiceAOP.class); + + private final DataValidator dataValidator; + + @Autowired + public PersUserWidgetServiceAOP(DataValidator dataValidator) { + this.dataValidator = dataValidator; + } + + @Before("execution(* org.onap.portal.service.PersUserWidgetService.setPersUserAppValue(..)) && args(user, personalization)") + public void setOnboardingWidget(FnUser user, WidgetCatalogPersonalization personalization) { + if (!dataValidator.isValid(personalization)) { + throw new IllegalArgumentException(dataValidator.getConstraintViolationsString(personalization)); + } + } +} diff --git a/portal-BE/src/main/java/org/onap/portal/aop/service/WidgetServiceAOP.java b/portal-BE/src/main/java/org/onap/portal/aop/service/WidgetServiceAOP.java index cc168578..14172937 100644 --- a/portal-BE/src/main/java/org/onap/portal/aop/service/WidgetServiceAOP.java +++ b/portal-BE/src/main/java/org/onap/portal/aop/service/WidgetServiceAOP.java @@ -2,7 +2,6 @@ package org.onap.portal.aop.service; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; -import org.onap.portal.domain.db.fn.FnUser; import org.onap.portal.domain.dto.transport.OnboardingWidget; import org.onap.portal.validation.DataValidator; import org.slf4j.Logger; @@ -24,8 +23,8 @@ public class WidgetServiceAOP { this.dataValidator = dataValidator; } - @Before("execution(* org.onap.portal.service.WidgetService.setOnboardingWidget(..)) && args(fnUser, onboardingWidget)") - public void setOnboardingWidget(final FnUser fnUser, OnboardingWidget onboardingWidget) { + @Before("execution(* org.onap.portal.service.WidgetService.setOnboardingWidget(..)) && args(userId, onboardingWidget)") + public void setOnboardingWidget(final Long userId, OnboardingWidget onboardingWidget) { if (!dataValidator.isValid(onboardingWidget)) { throw new IllegalArgumentException(dataValidator.getConstraintViolationsString(onboardingWidget)); } diff --git a/portal-BE/src/main/java/org/onap/portal/controller/WidgetsController.java b/portal-BE/src/main/java/org/onap/portal/controller/WidgetsController.java index 571cbc13..556c7ef3 100644 --- a/portal-BE/src/main/java/org/onap/portal/controller/WidgetsController.java +++ b/portal-BE/src/main/java/org/onap/portal/controller/WidgetsController.java @@ -49,7 +49,6 @@ import org.onap.portal.domain.db.fn.FnUser; import org.onap.portal.domain.dto.transport.FieldsValidator; import org.onap.portal.domain.dto.transport.OnboardingWidget; import org.onap.portal.domain.dto.transport.WidgetCatalogPersonalization; -import org.onap.portal.exception.NotValidDataException; import org.onap.portal.logging.aop.EPAuditLog; import org.onap.portal.service.AdminRolesService; import org.onap.portal.service.PersUserWidgetService; @@ -128,7 +127,7 @@ public class WidgetsController { onboardingWidget.setId(widgetId); onboardingWidget.normalize(); try { - fieldsValidator = widgetService.setOnboardingWidget(user, onboardingWidget); + fieldsValidator = widgetService.setOnboardingWidget(user.getUserId(), onboardingWidget); response.setStatus(fieldsValidator.getHttpStatusCode().intValue()); } catch (IllegalArgumentException e) { fieldsValidator = new FieldsValidator(); @@ -143,37 +142,25 @@ public class WidgetsController { return fieldsValidator; } - private boolean userHasPermissions(FnUser user, HttpServletResponse response, String invocator) { - if (!adminRolesService.isSuperAdmin(user) && !adminRolesService.isAccountAdmin(user)) { - EcompPortalUtils.setBadPermissions(user, response, invocator); - return false; - } - return true; - } - @PostMapping(value = {"/portalApi/widgets"}, produces = MediaType.APPLICATION_JSON_VALUE) + @PreAuthorize("hasRole('System_Administrator') and hasRole('Account_Administrator')") public FieldsValidator postOnboardingWidget(Principal principal, HttpServletResponse response, @RequestBody OnboardingWidget onboardingWidget) { FnUser user = fnUserService.loadUserByUsername(principal.getName()); - FieldsValidator fieldsValidator = new FieldsValidator(); + FieldsValidator fieldsValidator; - if (onboardingWidget != null) { - if (!dataValidator.isValid(onboardingWidget)) { - fieldsValidator.setHttpStatusCode((long) HttpServletResponse.SC_NOT_ACCEPTABLE); - return fieldsValidator; - } - } + onboardingWidget.setId(null); + onboardingWidget.normalize(); - if (userHasPermissions(user, response, "postOnboardingWidget")) { - onboardingWidget.setId(null); - onboardingWidget.normalize(); - try { - fieldsValidator = widgetService.setOnboardingWidget(user, onboardingWidget); - } catch (Exception e) { - fieldsValidator.setHttpStatusCode((long) HttpServletResponse.SC_BAD_REQUEST); - } - response.setStatus(fieldsValidator.getHttpStatusCode().intValue()); + try { + fieldsValidator = widgetService.setOnboardingWidget(user.getUserId(), onboardingWidget); + } catch (IllegalArgumentException e) { + fieldsValidator = new FieldsValidator(); + fieldsValidator.setHttpStatusCode((long) HttpServletResponse.SC_NOT_ACCEPTABLE); + fieldsValidator.addProblematicFieldName(e.getMessage()); + return fieldsValidator; } + response.setStatus(fieldsValidator.getHttpStatusCode().intValue()); EcompPortalUtils .logAndSerializeObject(logger, "/portalApi/widgets", "POST result =", response.getStatus()); @@ -181,15 +168,14 @@ public class WidgetsController { } @DeleteMapping(value = {"/portalApi/widgets/{widgetId}"}, produces = MediaType.APPLICATION_JSON_VALUE) + @PreAuthorize("hasRole('System_Administrator') and hasRole('Account_Administrator')") public FieldsValidator deleteOnboardingWidget(Principal principal, HttpServletResponse response, @PathVariable("widgetId") Long widgetId) { FnUser user = fnUserService.loadUserByUsername(principal.getName()); - FieldsValidator fieldsValidator = null; + FieldsValidator fieldsValidator; - if (userHasPermissions(user, response, "deleteOnboardingWidget")) { - fieldsValidator = widgetService.deleteOnboardingWidget(user, widgetId); - response.setStatus(fieldsValidator.getHttpStatusCode().intValue()); - } + fieldsValidator = widgetService.deleteOnboardingWidget(user, widgetId); + response.setStatus(fieldsValidator.getHttpStatusCode().intValue()); EcompPortalUtils.logAndSerializeObject(logger, "/portalApi/widgets/" + widgetId, "DELETE result =", response.getStatus()); @@ -202,23 +188,16 @@ public class WidgetsController { FieldsValidator result = new FieldsValidator(); FnUser user = fnUserService.loadUserByUsername(principal.getName()); - if (persRequest != null) { - if (!dataValidator.isValid(persRequest)) { - result.setHttpStatusCode((long) HttpServletResponse.SC_NOT_ACCEPTABLE); - return result; - } - } try { assert persRequest != null; - if (persRequest.getWidgetId() == null || user == null) { - EcompPortalUtils.setBadPermissions(user, response, "putWidgetCatalogSelection"); - } else { - persUserWidgetService - .setPersUserAppValue(user, persRequest.getWidgetId(), persRequest.getSelect()); - } + persUserWidgetService + .setPersUserAppValue(user, persRequest); + } catch (IllegalArgumentException iae) { + logger.error(EELFLoggerDelegate.errorLogger, "Failed in putAppCatalogSelection", iae); + response.sendError(HttpServletResponse.SC_NOT_ACCEPTABLE, iae.getMessage()); } catch (Exception e) { logger.error(EELFLoggerDelegate.errorLogger, "Failed in putAppCatalogSelection", e); - response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.toString()); + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); } result.setHttpStatusCode((long) HttpServletResponse.SC_OK); return result; diff --git a/portal-BE/src/main/java/org/onap/portal/dao/fn/FnUserRoleDao.java b/portal-BE/src/main/java/org/onap/portal/dao/fn/FnUserRoleDao.java new file mode 100644 index 00000000..ee1ebdd0 --- /dev/null +++ b/portal-BE/src/main/java/org/onap/portal/dao/fn/FnUserRoleDao.java @@ -0,0 +1,58 @@ +/* + * ============LICENSE_START========================================== + * ONAP Portal + * =================================================================== + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Modifications Copyright (c) 2019 Samsung + * =================================================================== + * + * Unless otherwise specified, all software contained herein is licensed + * under the Apache License, Version 2.0 (the "License"); + * you may not use this software 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. + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * 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.portal.dao.fn; + +import java.util.List; +import java.util.Optional; +import org.onap.portal.domain.db.fn.FnUserRole; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; + +@Repository +@Transactional +public interface FnUserRoleDao extends JpaRepository { + + @Query + Optional> getAdminUserRoles(final @Param("USERID") Long userId, final @Param("ROLEID") Long roleId, final @Param("APPID") Long appId); +} diff --git a/portal-BE/src/main/java/org/onap/portal/domain/db/ep/EpPersUserWidgetSel.java b/portal-BE/src/main/java/org/onap/portal/domain/db/ep/EpPersUserWidgetSel.java index 9cee72a3..4b2785f1 100644 --- a/portal-BE/src/main/java/org/onap/portal/domain/db/ep/EpPersUserWidgetSel.java +++ b/portal-BE/src/main/java/org/onap/portal/domain/db/ep/EpPersUserWidgetSel.java @@ -82,7 +82,7 @@ CREATE TABLE `ep_pers_user_widget_sel` ( @NamedQueries({ @NamedQuery( name = "EpPersUserWidgetSel.getEpPersUserWidgetSelForUserIdAndWidgetId", - query = "FROM EpPersUserWidgetSel WHERE userId = :USERID and widgetId = :WIDGETID") + query = "FROM EpPersUserWidgetSel WHERE userId.userId = :USERID and widgetId.widgetId = :WIDGETID") }) @Table(name = "ep_pers_user_widget_sel", uniqueConstraints = { @UniqueConstraint(columnNames = {"user_id", "widget_id"}) diff --git a/portal-BE/src/main/java/org/onap/portal/domain/db/fn/FnUserRole.java b/portal-BE/src/main/java/org/onap/portal/domain/db/fn/FnUserRole.java index 390ef8b4..4e783764 100644 --- a/portal-BE/src/main/java/org/onap/portal/domain/db/fn/FnUserRole.java +++ b/portal-BE/src/main/java/org/onap/portal/domain/db/fn/FnUserRole.java @@ -53,6 +53,8 @@ import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.NamedNativeQueries; import javax.persistence.NamedNativeQuery; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; import javax.persistence.OneToOne; import javax.persistence.Table; import javax.persistence.UniqueConstraint; @@ -82,16 +84,25 @@ CREATE TABLE `fn_user_role` ( @NamedNativeQueries({ @NamedNativeQuery( name = "FnUserRole.retrieveUserRoleOnUserIdAndRoleIdAndAppId", - query = "select * from FnUserRole where user_id= :userId" + query = "FROM FnUserRole where user_id= :userId" + " and role_id= :roleId" + " and app_id= :appId"), @NamedNativeQuery( name = "FnUserRole.retrieveCachedAppRolesForUser", - query = "select * from FnUserRole where user_id= :userId" + query = "FROM FnUserRole where user_id= :userId" + " and user_id= :userId" + " and app_id= :appId") }) +@NamedQueries({ + @NamedQuery( + name = "FnUserRole.getAdminUserRoles", + query = "FROM FnUserRole fn " + + "WHERE fn.userId.userId = :USERID " + + "AND fn.roleId.roleId = :ROLEID " + + "AND fn.appId.appId = :APPID") +}) + @Table( name = "fn_user_role", indexes = { diff --git a/portal-BE/src/main/java/org/onap/portal/domain/dto/transport/WidgetCatalogPersonalization.java b/portal-BE/src/main/java/org/onap/portal/domain/dto/transport/WidgetCatalogPersonalization.java index b9e54bfc..d9053f03 100644 --- a/portal-BE/src/main/java/org/onap/portal/domain/dto/transport/WidgetCatalogPersonalization.java +++ b/portal-BE/src/main/java/org/onap/portal/domain/dto/transport/WidgetCatalogPersonalization.java @@ -40,6 +40,7 @@ package org.onap.portal.domain.dto.transport; +import javax.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; @@ -51,7 +52,9 @@ import lombok.Setter; @AllArgsConstructor public class WidgetCatalogPersonalization { + @NotNull private Long widgetId; + @NotNull private Boolean select; } diff --git a/portal-BE/src/main/java/org/onap/portal/service/PersUserWidgetService.java b/portal-BE/src/main/java/org/onap/portal/service/PersUserWidgetService.java index 364085c4..38a0a408 100644 --- a/portal-BE/src/main/java/org/onap/portal/service/PersUserWidgetService.java +++ b/portal-BE/src/main/java/org/onap/portal/service/PersUserWidgetService.java @@ -46,14 +46,22 @@ import java.util.stream.Collectors; import org.onap.portal.dao.ep.EpPersUserWidgetSelDao; import org.onap.portal.dao.fn.EpWidgetCatalogDao; import org.onap.portal.domain.db.ep.EpPersUserWidgetSel; +import org.onap.portal.domain.db.ep.EpWidgetCatalog; import org.onap.portal.domain.db.fn.FnUser; import org.onap.portal.domain.dto.ecomp.PersUserWidgetSelection; +import org.onap.portal.domain.dto.transport.WidgetCatalogPersonalization; +import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; @Service +@Transactional public class PersUserWidgetService { + private static final Logger LOGGER = LoggerFactory.getLogger(PersUserWidgetService.class); private final EpPersUserWidgetSelDao epPersUserWidgetSelDao; private final EpWidgetCatalogDao epWidgetCatalogDao; @@ -64,44 +72,36 @@ public class PersUserWidgetService { this.epWidgetCatalogDao = epWidgetCatalogDao; } - public void setPersUserAppValue(FnUser user, Long widgetId, Boolean select) { - if (user == null || widgetId == null) { - throw new IllegalArgumentException("setPersUserAppValue: Null values"); - } - - List persList = getUserWidgetSelction(user, widgetId); + public void setPersUserAppValue(FnUser user, WidgetCatalogPersonalization personalization) { + List persList = getUserWidgetSelction(user, personalization.getWidgetId()); + LOGGER.info("Error: " + persList.size()); // Key constraint limits to 1 row - PersUserWidgetSelection persRow = null; + PersUserWidgetSelection persRow; if (persList.size() == 1) { persRow = persList.get(0); } else { - persRow = new PersUserWidgetSelection(null, user.getId(), widgetId, null); + persRow = new PersUserWidgetSelection(null, user.getUserId(), personalization.getWidgetId(), null); } - if (select) { - if (persRow.getId() != null) { - epPersUserWidgetSelDao.deleteById(persRow.getId()); - } - persRow.setStatusCode("S"); // show - EpPersUserWidgetSel epPersUserWidgetSel = new EpPersUserWidgetSel(); - epPersUserWidgetSel.setUserId(user); - epPersUserWidgetSel.setWidgetId(epWidgetCatalogDao.findById(widgetId).get()); - epPersUserWidgetSelDao.saveAndFlush(epPersUserWidgetSel); - } else { - if (persRow.getId() != null) { - epPersUserWidgetSelDao.deleteById(persRow.getId()); - } - persRow.setStatusCode("H"); // Hide - EpPersUserWidgetSel epPersUserWidgetSel = new EpPersUserWidgetSel(); - epPersUserWidgetSel.setUserId(user); - epPersUserWidgetSel.setWidgetId(epWidgetCatalogDao.findById(widgetId).get()); - epPersUserWidgetSelDao.saveAndFlush(epPersUserWidgetSel); + + if (persRow.getId() != null) { + epPersUserWidgetSelDao.deleteById(persRow.getId()); } + + persRow.setStatusCode(personalization.getSelect() ? "S" : "H"); // Show / Hide + EpPersUserWidgetSel epPersUserWidgetSel = new EpPersUserWidgetSel(); + epPersUserWidgetSel.setUserId(user); + epPersUserWidgetSel.setWidgetId( + epWidgetCatalogDao.findById(personalization.getWidgetId()).orElse(new EpWidgetCatalog())); + epPersUserWidgetSelDao.saveAndFlush(epPersUserWidgetSel); } private List getUserWidgetSelction(FnUser user, Long widgetId) { - return epPersUserWidgetSelDao.getEpPersUserWidgetSelForUserIdAndWidgetId(user.getId(), widgetId) - .orElse(new ArrayList<>()).stream().map( - this::epPersUserWidgetSelToPersUserWidgetSelection).collect(Collectors.toList()); + return epPersUserWidgetSelDao + .getEpPersUserWidgetSelForUserIdAndWidgetId(user.getId(), widgetId) + .orElse(new ArrayList<>()) + .stream() + .map(this::epPersUserWidgetSelToPersUserWidgetSelection) + .collect(Collectors.toList()); } private PersUserWidgetSelection epPersUserWidgetSelToPersUserWidgetSelection(EpPersUserWidgetSel widgetSel) { diff --git a/portal-BE/src/main/java/org/onap/portal/service/WidgetService.java b/portal-BE/src/main/java/org/onap/portal/service/WidgetService.java index 90d6ab78..ba5deaa4 100644 --- a/portal-BE/src/main/java/org/onap/portal/service/WidgetService.java +++ b/portal-BE/src/main/java/org/onap/portal/service/WidgetService.java @@ -44,14 +44,14 @@ import java.util.ArrayList; import java.util.List; import javax.persistence.EntityManager; import javax.servlet.http.HttpServletResponse; -import javax.validation.constraints.NotNull; import org.onap.portal.dao.fn.FnWidgetDao; import org.onap.portal.domain.db.fn.FnUser; +import org.onap.portal.domain.db.fn.FnUserRole; import org.onap.portal.domain.db.fn.FnWidget; import org.onap.portal.domain.dto.ecomp.EPUserApp; -import org.onap.portal.domain.dto.ecomp.Widget; import org.onap.portal.domain.dto.transport.FieldsValidator; import org.onap.portal.domain.dto.transport.OnboardingWidget; +import org.onap.portal.service.fn.FnUserRoleService; import org.onap.portal.utils.EPCommonSystemProperties; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; import org.springframework.beans.factory.annotation.Autowired; @@ -82,13 +82,15 @@ public class WidgetService { private final AdminRolesService adminRolesService; private final EntityManager entityManager; private final FnWidgetDao fnWidgetDao; + private final FnUserRoleService fnUserRoleService; @Autowired public WidgetService(final AdminRolesService adminRolesService, final EntityManager entityManager, - final FnWidgetDao fnWidgetDao) { + final FnWidgetDao fnWidgetDao, FnUserRoleService fnUserRoleService) { this.adminRolesService = adminRolesService; this.entityManager = entityManager; this.fnWidgetDao = fnWidgetDao; + this.fnUserRoleService = fnUserRoleService; } private static final Object syncRests = new Object(); @@ -127,8 +129,8 @@ public class WidgetService { } @PreAuthorize("hasRole('System_Administrator')") - public FieldsValidator setOnboardingWidget(final FnUser user, final OnboardingWidget onboardingWidget) { - return this.updateOrSaveWidget(true, user.getId(), onboardingWidget); + public FieldsValidator setOnboardingWidget(final Long userId, final OnboardingWidget onboardingWidget) { + return this.updateOrSaveWidget(true, userId, onboardingWidget); } private FieldsValidator updateOrSaveWidget(boolean superAdmin, Long userId, OnboardingWidget onboardingWidget) { @@ -157,22 +159,14 @@ public class WidgetService { private boolean isUserAdminOfAppForWidget(boolean superAdmin, Long userId, Long appId) { if (!superAdmin) { - List userRoles = getAdminUserRoles(userId, appId); + List userRoles = getAdminUserRoles(userId, appId); return (userRoles.size() > 0); } return true; } - private List getAdminUserRoles(Long userId, Long appId) { - return entityManager.createQuery( - "SELECT new org.onap.portal.domain.dto.ecomp.EPUserApp(fn.userId, fn.roleId, fn.appId) FROM FnUserRole fn" - + "WHERE fn.userId = :USERID " - + "AND fn.roleId = :ROLEID " - + "AND fn.appId = :APPID", EPUserApp.class) - .setParameter("USERID", userId) - .setParameter("ROLEID", ACCOUNT_ADMIN_ROLE_ID) - .setParameter("APPID", appId) - .getResultList(); + private List getAdminUserRoles(Long userId, Long appId) { + return fnUserRoleService.getAdminUserRoles(userId, ACCOUNT_ADMIN_ROLE_ID, appId); } private void applyOnboardingWidget(OnboardingWidget onboardingWidget, FieldsValidator fieldsValidator) { @@ -238,7 +232,7 @@ public class WidgetService { synchronized (syncRests) { FnWidget widget = fnWidgetDao.getOne(onboardingWidgetId); if (widget != null && widget.getAppId() != null) { // widget exists - if (!this.isUserAdminOfAppForWidget(adminRolesService.isSuperAdmin(user), user.getId(), + if (!this.isUserAdminOfAppForWidget(adminRolesService.isSuperAdmin(user), user.getUserId(), widget.getAppId())) { fieldsValidator.setHttpStatusCode((long) HttpServletResponse.SC_FORBIDDEN); } else { diff --git a/portal-BE/src/main/java/org/onap/portal/service/fn/FnUserRoleService.java b/portal-BE/src/main/java/org/onap/portal/service/fn/FnUserRoleService.java new file mode 100644 index 00000000..4b24f9f3 --- /dev/null +++ b/portal-BE/src/main/java/org/onap/portal/service/fn/FnUserRoleService.java @@ -0,0 +1,65 @@ +/* + * ============LICENSE_START========================================== + * ONAP Portal + * =================================================================== + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Modifications Copyright (c) 2019 Samsung + * =================================================================== + * + * Unless otherwise specified, all software contained herein is licensed + * under the Apache License, Version 2.0 (the "License"); + * you may not use this software 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. + * + * Unless otherwise specified, all documentation contained herein is licensed + * under the Creative Commons License, Attribution 4.0 Intl. (the "License"); + * you may not use this documentation except in compliance with the License. + * You may obtain a copy of the License at + * + * https://creativecommons.org/licenses/by/4.0/ + * + * Unless required by applicable law or agreed to in writing, documentation + * 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.portal.service.fn; + +import java.util.ArrayList; +import java.util.List; +import org.onap.portal.dao.fn.FnUserRoleDao; +import org.onap.portal.domain.db.fn.FnUserRole; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional +public class FnUserRoleService { + + private final FnUserRoleDao fnUserRoleDao; + + @Autowired + public FnUserRoleService(FnUserRoleDao fnUserRoleDao) { + this.fnUserRoleDao = fnUserRoleDao; + } + + public List getAdminUserRoles(final Long userId, final Long roleId, final Long appId) { + return fnUserRoleDao.getAdminUserRoles(userId, roleId, appId).orElse(new ArrayList<>()); + } +} diff --git a/portal-BE/src/test/java/org/onap/portal/controller/WidgetsControllerTest.java b/portal-BE/src/test/java/org/onap/portal/controller/WidgetsControllerTest.java index 0f277471..48035908 100644 --- a/portal-BE/src/test/java/org/onap/portal/controller/WidgetsControllerTest.java +++ b/portal-BE/src/test/java/org/onap/portal/controller/WidgetsControllerTest.java @@ -44,6 +44,7 @@ import static junit.framework.TestCase.assertEquals; import static junit.framework.TestCase.assertNull; import static org.mockito.Mockito.when; +import java.io.IOException; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; @@ -58,6 +59,7 @@ import org.onap.portal.domain.db.fn.FnUser; import org.onap.portal.domain.db.fn.FnWidget; import org.onap.portal.domain.dto.transport.FieldsValidator; import org.onap.portal.domain.dto.transport.OnboardingWidget; +import org.onap.portal.domain.dto.transport.WidgetCatalogPersonalization; import org.onap.portal.framework.MockitoTestSuite; import org.onap.portal.service.WidgetService; import org.springframework.beans.factory.annotation.Autowired; @@ -118,7 +120,8 @@ public class WidgetsControllerTest { @Test public void getOnboardingWidgetsUserTest() { - UsernamePasswordAuthenticationToken notQuestprincipal = new UsernamePasswordAuthenticationToken("notQuestUser", + UsernamePasswordAuthenticationToken notQuestprincipal = new UsernamePasswordAuthenticationToken( + "notQuestUser", "demo123"); fnUserDao.save(notQuestUser); List expected = new ArrayList<>(); @@ -133,7 +136,8 @@ public class WidgetsControllerTest { @Test public void getOnboardingWidgetsWrongHeaderTest() { - UsernamePasswordAuthenticationToken notQuestprincipal = new UsernamePasswordAuthenticationToken("notQuestUser", + UsernamePasswordAuthenticationToken notQuestprincipal = new UsernamePasswordAuthenticationToken( + "notQuestUser", "demo123"); fnUserDao.save(notQuestUser); when(request.getHeader("X-Widgets-Type")).thenReturn("test"); @@ -147,8 +151,6 @@ public class WidgetsControllerTest { @Test public void putOnboardingWidgetSameWidget() { //Given - UsernamePasswordAuthenticationToken notQuestprincipal = new UsernamePasswordAuthenticationToken("cs0008", - "demo123"); fnUserDao.save(notQuestUser); when(request.getHeader("X-Widgets-Type")).thenReturn("managed"); @@ -162,7 +164,6 @@ public class WidgetsControllerTest { .url("testurl") .build(); - FnWidget fnWidget = FnWidget.builder() .name("Application") .appId(453L) @@ -175,7 +176,8 @@ public class WidgetsControllerTest { FieldsValidator expected = new FieldsValidator(); //When - FieldsValidator actual = widgetsController.putOnboardingWidget(principal, fnWidget.getWidgetId(), onboardingWidget, response); + FieldsValidator actual = widgetsController + .putOnboardingWidget(principal, fnWidget.getWidgetId(), onboardingWidget, response); //Then assertEquals(expected.getErrorCode(), actual.getErrorCode()); assertEquals(expected.getHttpStatusCode(), actual.getHttpStatusCode()); @@ -185,8 +187,6 @@ public class WidgetsControllerTest { @Test public void putOnboardingWidgetAOP() { //Given - UsernamePasswordAuthenticationToken notQuestprincipal = new UsernamePasswordAuthenticationToken("cs0008", - "demo123"); fnUserDao.save(notQuestUser); when(request.getHeader("X-Widgets-Type")).thenReturn("managed"); @@ -200,7 +200,6 @@ public class WidgetsControllerTest { .url("testurl") .build(); - FnWidget fnWidget = FnWidget.builder() .name("Application") .appId(1421L) @@ -215,7 +214,8 @@ public class WidgetsControllerTest { expected.setHttpStatusCode(406L); expected.addProblematicFieldName("appName can't be blank, appId value must be higher than 1"); //When - FieldsValidator actual = widgetsController.putOnboardingWidget(principal, fnWidget.getWidgetId(), onboardingWidget, response); + FieldsValidator actual = widgetsController + .putOnboardingWidget(principal, fnWidget.getWidgetId(), onboardingWidget, response); //Then assertEquals(expected.getHttpStatusCode(), actual.getHttpStatusCode()); assertEquals(expected.getFields().size(), actual.getFields().size()); @@ -224,8 +224,6 @@ public class WidgetsControllerTest { @Test public void putOnboardingWidgetAOPXSSTest() { //Given - UsernamePasswordAuthenticationToken notQuestprincipal = new UsernamePasswordAuthenticationToken("cs0008", - "demo123"); fnUserDao.save(notQuestUser); when(request.getHeader("X-Widgets-Type")).thenReturn("managed"); @@ -241,9 +239,37 @@ public class WidgetsControllerTest { FieldsValidator expected = new FieldsValidator(); expected.setHttpStatusCode(406L); - expected.addProblematicFieldName("appName may have unsafe html content, name may have unsafe html content"); + expected.addProblematicFieldName( + "appName may have unsafe html content, name may have unsafe html content"); //When - FieldsValidator actual = widgetsController.putOnboardingWidget(principal, 15L, onboardingWidget, response); + FieldsValidator actual = widgetsController + .putOnboardingWidget(principal, 15L, onboardingWidget, response); + //Then + assertEquals(expected.getHttpStatusCode(), actual.getHttpStatusCode()); + assertEquals(expected.getFields().size(), actual.getFields().size()); + } + + @Test + public void postOnboardingWidgetXSS() { + //Given + fnUserDao.save(notQuestUser); + when(request.getHeader("X-Widgets-Type")).thenReturn("managed"); + + OnboardingWidget onboardingWidget = OnboardingWidget.builder() + .id(123L) + .name("\n") + .appId(34L) + .appName("") + .width(123) + .height(45) + .url("testurl") + .build(); + + FieldsValidator expected = new FieldsValidator(); + expected.setHttpStatusCode(406L); + expected.addProblematicFieldName("appName may have unse html content, name may have unsafe html content"); + //When + FieldsValidator actual = widgetsController.postOnboardingWidget(principal, response, onboardingWidget); //Then assertEquals(expected.getHttpStatusCode(), actual.getHttpStatusCode()); assertEquals(expected.getFields().size(), actual.getFields().size()); @@ -251,17 +277,84 @@ public class WidgetsControllerTest { @Test public void postOnboardingWidget() { + //Given + fnUserDao.save(notQuestUser); + when(request.getHeader("X-Widgets-Type")).thenReturn("managed"); + + OnboardingWidget onboardingWidget = OnboardingWidget.builder() + .id(123L) + .name("appname") + .appId(34L) + .appName("appname") + .width(123) + .height(45) + .url("testurl") + .build(); + + FieldsValidator expected = new FieldsValidator(); + expected.setHttpStatusCode(200L); + //When + FieldsValidator actual = widgetsController.postOnboardingWidget(principal, response, onboardingWidget); + //Then + assertEquals(expected.getHttpStatusCode(), actual.getHttpStatusCode()); + assertEquals(expected.getFields().size(), actual.getFields().size()); } @Test - public void deleteOnboardingWidget() { + public void deleteOnboardingWidgetSCFORBIDDEN() { + //Given + fnUserDao.save(notQuestUser); + when(request.getHeader("X-Widgets-Type")).thenReturn("managed"); + + OnboardingWidget onboardingWidget = OnboardingWidget.builder() + .id(123L) + .name("") + .appId(1L) + .appName("rtyrty") + .width(123) + .height(45) + .url("testurl") + .build(); + + FnWidget fnWidget = FnWidget.builder() + .name("Application") + .appId(1421L) + .width(123) + .height(45) + .url("testurl") + .build(); + + widgetService.saveOne(fnWidget); + + + + FieldsValidator expected = new FieldsValidator(); + expected.setHttpStatusCode(403L); + expected.addProblematicFieldName("appName can't be blank, appId value must be higher than 1"); + + //When + widgetsController.putOnboardingWidget(principal, fnWidget.getWidgetId(), onboardingWidget, response); + + FieldsValidator actual = widgetsController.deleteOnboardingWidget(principal, response, fnWidget.getWidgetId()); + //Then + assertEquals(expected.getHttpStatusCode(), actual.getHttpStatusCode()); } @Test - public void putWidgetCatalogSelection() { + public void putWidgetCatalogSelection() throws IOException { + //Give + WidgetCatalogPersonalization personalization = new WidgetCatalogPersonalization(7L, true); + + FieldsValidator expected = new FieldsValidator(); + expected.setHttpStatusCode(200L); + expected.addProblematicFieldName(""); + //When + FieldsValidator actual = widgetsController.putWidgetCatalogSelection(principal, personalization, response); + //Then + assertEquals(expected.getHttpStatusCode(), actual.getHttpStatusCode()); } - private FnUser getQuestUser(){ + private FnUser getQuestUser() { return FnUser.builder() .loginId("questUser") .loginPwd("demo123") @@ -275,7 +368,7 @@ public class WidgetsControllerTest { .build(); } - private FnUser getNotQuestUser(){ + private FnUser getNotQuestUser() { return FnUser.builder() .loginId("notQuestUser") .loginPwd("demo123") @@ -289,7 +382,7 @@ public class WidgetsControllerTest { .build(); } - private FnLanguage getFnLanguage(){ + private FnLanguage getFnLanguage() { return FnLanguage.builder().languageName("Polish").languageAlias("Pl").build(); } } \ No newline at end of file -- 2.16.6