PersUserWidgetServiceAOP and tests up
[portal.git] / portal-BE / src / main / java / org / onap / portal / service / widget / WidgetService.java
1 /*
2  * ============LICENSE_START==========================================
3  * ONAP Portal
4  * ===================================================================
5  * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
6  * ===================================================================
7  * Modifications Copyright (c) 2019 Samsung
8  * ===================================================================
9  *
10  * Unless otherwise specified, all software contained herein is licensed
11  * under the Apache License, Version 2.0 (the "License");
12  * you may not use this software except in compliance with the License.
13  * You may obtain a copy of the License at
14  *
15  *             http://www.apache.org/licenses/LICENSE-2.0
16  *
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  *
23  * Unless otherwise specified, all documentation contained herein is licensed
24  * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
25  * you may not use this documentation except in compliance with the License.
26  * You may obtain a copy of the License at
27  *
28  *             https://creativecommons.org/licenses/by/4.0/
29  *
30  * Unless required by applicable law or agreed to in writing, documentation
31  * distributed under the License is distributed on an "AS IS" BASIS,
32  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
33  * See the License for the specific language governing permissions and
34  * limitations under the License.
35  *
36  * ============LICENSE_END============================================
37  *
38  *
39  */
40
41 package org.onap.portal.service.widget;
42
43 import java.util.ArrayList;
44 import java.util.List;
45 import java.util.Optional;
46 import javax.persistence.EntityManager;
47 import javax.servlet.http.HttpServletResponse;
48
49 import org.onap.portal.domain.db.fn.FnUser;
50 import org.onap.portal.domain.db.fn.FnUserRole;
51 import org.onap.portal.domain.db.fn.FnWidget;
52 import org.onap.portal.domain.dto.transport.FieldsValidator;
53 import org.onap.portal.domain.dto.transport.OnboardingWidget;
54 import org.onap.portal.service.AdminRolesService;
55 import org.onap.portal.service.user.FnUserService;
56 import org.onap.portal.service.userRole.FnUserRoleService;
57 import org.onap.portal.utils.EPCommonSystemProperties;
58 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
59 import org.springframework.beans.factory.annotation.Autowired;
60 import org.springframework.context.annotation.EnableAspectJAutoProxy;
61 import org.springframework.security.access.prepost.PreAuthorize;
62 import org.springframework.stereotype.Service;
63 import org.springframework.transaction.annotation.Transactional;
64
65 @Service
66 @Transactional
67 @EnableAspectJAutoProxy
68 public class WidgetService {
69
70        private static final EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(WidgetService.class);
71        private static final Long ACCOUNT_ADMIN_ROLE_ID = 999L;
72
73        private static final String baseSqlToken =
74            " new org.onap.portal.domain.dto.transport.OnboardingWidget("
75                + "widget.WIDGET_ID,widget.WDG_NAME,widget.APP_ID,"
76                + "app.APP_NAME,widget.WDG_WIDTH,widget.WDG_HEIGHT,"
77                + "widget.WDG_URL, widget.WIDGET_ID,widget.WDG_NAME,widget.APP_ID,app.APP_NAME,widget.WDG_WIDTH,widget.WDG_HEIGHT,widget.WDG_URL) from FN_WIDGET widget join FN_APP app ON widget.APP_ID = app.APP_ID";
78
79        private static final String sqlWidgetsForAllApps = "SELECT" + baseSqlToken;
80
81        private static final String sqlWidgetsForAllAppsWhereUserIsAdmin =
82               "SELECT" + baseSqlToken
83                   + " join FN_USER_ROLE ON FN_USER_ROLE.APP_ID = app.APP_ID where FN_USER_ROLE.USER_ID = :USERID AND FN_USER_ROLE.ROLE_ID = "
84                   + ACCOUNT_ADMIN_ROLE_ID;
85
86        private static final String sqlWidgetsForAllAppsWhereUserHasAnyRole =
87               "SELECT DISTINCT" + baseSqlToken
88                   + " join FN_USER_ROLE ON FN_USER_ROLE.APP_ID = app.APP_ID where FN_USER_ROLE.USER_ID = "
89                   + ":USERID";
90
91        private static final String urlField = "url";
92        private static final Long DUBLICATED_FIELD_VALUE_ECOMP_ERROR = Long
93            .valueOf(EPCommonSystemProperties.DUBLICATED_FIELD_VALUE_ECOMP_ERROR);
94        private static final String nameField = "name";
95        private final AdminRolesService adminRolesService;
96        private final EntityManager entityManager;
97        private final FnWidgetDao fnWidgetDao;
98        private final FnUserService fnUserService;
99        private final FnUserRoleService fnUserRoleService;
100
101        private static final Object syncRests = new Object();
102
103        @Autowired
104        public WidgetService(final AdminRolesService adminRolesService, final EntityManager entityManager,
105            final FnWidgetDao fnWidgetDao, FnUserService fnUserService,
106            FnUserRoleService fnUserRoleService) {
107               this.adminRolesService = adminRolesService;
108               this.entityManager = entityManager;
109               this.fnWidgetDao = fnWidgetDao;
110               this.fnUserService = fnUserService;
111               this.fnUserRoleService = fnUserRoleService;
112        }
113
114        @PreAuthorize("hasRole('System_Administrator')")
115        public FieldsValidator setOnboardingWidget(final Long userId, final OnboardingWidget onboardingWidget) {
116               return this.updateOrSaveWidget(true, userId, onboardingWidget);
117        }
118
119        public List<OnboardingWidget> getOnboardingWidgets(final String orgUserId, final long userId,  final boolean managed) {
120               FnUser user = fnUserService.getUser(userId).get();
121               if (adminRolesService.isSuperAdmin(orgUserId)){
122                      return entityManager.createQuery(sqlWidgetsForAllApps, OnboardingWidget.class).getResultList();
123               } else if (managed) {
124                      if (adminRolesService.isAccountAdmin(user.getId(), user.getOrgUserId(), user.getUserApps())) {
125                             return entityManager
126                                 .createQuery(sqlWidgetsForAllAppsWhereUserIsAdmin, OnboardingWidget.class)
127                                 .setParameter("USERID", userId).getResultList();
128                      }
129               } else if (adminRolesService.isAccountAdmin(user.getId(), user.getOrgUserId(), user.getUserApps()) || adminRolesService.isUser(userId)) {
130                      return entityManager
131                          .createQuery(sqlWidgetsForAllAppsWhereUserHasAnyRole, OnboardingWidget.class)
132                          .setParameter("USERID", userId).getResultList();
133               }
134               return new ArrayList<>();
135        }
136
137        public FnWidget saveOne(final FnWidget widget) {
138               return fnWidgetDao.saveAndFlush(widget);
139        }
140
141        @PreAuthorize("hasRole('System_Administrator')")
142        public FieldsValidator deleteOnboardingWidget(final String orgUserId, final long userId, final long onboardingWidgetId) {
143               FieldsValidator fieldsValidator = new FieldsValidator();
144               synchronized (syncRests) {
145                      Optional<FnWidget> widget = this.getOne(onboardingWidgetId);
146                      if (widget.isPresent() && widget.get().getAppId() != null) { // widget exists
147                             if (!this.isUserAdminOfAppForWidget(adminRolesService.isSuperAdmin(orgUserId), userId,
148                                 widget.get().getAppId())) {
149                                    fieldsValidator.setHttpStatusCode((long) HttpServletResponse.SC_FORBIDDEN);
150                             } else {
151                                    fnWidgetDao.deleteById(onboardingWidgetId);
152                                    fieldsValidator.setHttpStatusCode(
153                                        (long) HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
154                             }
155                      }
156               }
157               return fieldsValidator;
158        }
159
160        public Optional<FnWidget> getOne(final long id) {
161               return Optional.of(fnWidgetDao.getOne(id));
162        }
163
164        private FieldsValidator updateOrSaveWidget(final boolean superAdmin, final long userId, final OnboardingWidget onboardingWidget) {
165               FieldsValidator fieldsValidator = new FieldsValidator();
166               if (!this.isUserAdminOfAppForWidget(superAdmin, userId, onboardingWidget.getAppId())) {
167                      fieldsValidator.setHttpStatusCode((long) HttpServletResponse.SC_FORBIDDEN);
168                      return fieldsValidator;
169               }
170               synchronized (syncRests) {
171                      if (onboardingWidget.getId() == null) {
172                             this.validateOnboardingWidget(onboardingWidget, fieldsValidator);
173                      } else {
174                             Optional<FnWidget> widget = this.getOne(onboardingWidget.getId());
175                             if (!widget.isPresent() || widget.get().getAppId() == null) {
176                                    fieldsValidator.setHttpStatusCode((long) HttpServletResponse.SC_NOT_FOUND);
177                                    return fieldsValidator;
178                             }
179                             this.validateOnboardingWidget(onboardingWidget, fieldsValidator);
180                      }
181                      if (fieldsValidator.getHttpStatusCode() == HttpServletResponse.SC_OK) {
182                             this.applyOnboardingWidget(onboardingWidget, fieldsValidator);
183                      }
184               }
185               return fieldsValidator;
186        }
187
188        private boolean isUserAdminOfAppForWidget(final boolean superAdmin, final Long userId, final Long appId) {
189               if (!superAdmin) {
190                      List<FnUserRole> userRoles = fnUserRoleService.getAdminUserRoles(userId, ACCOUNT_ADMIN_ROLE_ID, appId);
191                      return (userRoles.size() > 0);
192               }
193               return true;
194        }
195
196        private void applyOnboardingWidget(final OnboardingWidget onboardingWidget, final FieldsValidator fieldsValidator) {
197               boolean result;
198               FnWidget widget;
199               if (onboardingWidget.getId() == null) {
200                      widget = new FnWidget();
201               } else {
202                      widget = fnWidgetDao.getOne(onboardingWidget.getId());
203               }
204               widget.setAppId(onboardingWidget.getAppId());
205               widget.setName(onboardingWidget.getName());
206               widget.setWidth(onboardingWidget.getWidth());
207               widget.setHeight(onboardingWidget.getHeight());
208               widget.setUrl(onboardingWidget.getUrl());
209               result = widget.equals(fnWidgetDao.saveAndFlush(widget));
210               if (!result) {
211                      fieldsValidator.setHttpStatusCode((long) HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
212               }
213        }
214
215        private void validateOnboardingWidget(final OnboardingWidget onboardingWidget,
216            final FieldsValidator fieldsValidator) {
217               List<FnWidget> widgets = getWidgets(onboardingWidget);
218               boolean duplicatedUrl = false;
219               boolean duplicatedName = false;
220               for (FnWidget widget : widgets) {
221                      if (onboardingWidget.getId() != null && onboardingWidget.getId().equals(widget.getWidgetId())) {
222                             // widget should not be compared with itself
223                             continue;
224                      }
225                      if (!duplicatedUrl && widget.getUrl().equals(onboardingWidget.getUrl())) {
226                             duplicatedUrl = true;
227                             if (duplicatedName) {
228                                    break;
229                             }
230                      }
231                      if (!duplicatedName && widget.getName().equalsIgnoreCase(onboardingWidget.getName()) && widget
232                          .getAppId().equals(onboardingWidget.getAppId())) {
233                             duplicatedName = true;
234                             if (duplicatedUrl) {
235                                    break;
236                             }
237                      }
238               }
239               if (duplicatedUrl || duplicatedName) {
240                      if (duplicatedUrl) {
241                             fieldsValidator.addProblematicFieldName(urlField);
242                      }
243                      if (duplicatedName) {
244                             fieldsValidator.addProblematicFieldName(nameField);
245                      }
246                      fieldsValidator.setHttpStatusCode((long) HttpServletResponse.SC_CONFLICT);
247                      fieldsValidator.setErrorCode(DUBLICATED_FIELD_VALUE_ECOMP_ERROR);
248               }
249        }
250
251        private List<FnWidget> getWidgets(final OnboardingWidget onboardingWidget) {
252               return fnWidgetDao
253                   .getForUrlNameAndAppId(onboardingWidget.getUrl(), onboardingWidget.getName(), onboardingWidget.getAppId())
254                   .orElse(new ArrayList<>());
255        }
256 }