Fix for NullPointerException in ecomp-portal-BE-common
[portal.git] / ecomp-portal-BE-common / src / main / java / org / onap / portalapp / portal / controller / AppsControllerExternalRequest.java
1 /*-
2  * ============LICENSE_START==========================================
3  * ONAP Portal
4  * ===================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ===================================================================
7  *
8  * Unless otherwise specified, all software contained herein is licensed
9  * under the Apache License, Version 2.0 (the "License");
10  * you may not use this software except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *             http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  * Unless otherwise specified, all documentation contained herein is licensed
22  * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
23  * you may not use this documentation except in compliance with the License.
24  * You may obtain a copy of the License at
25  *
26  *             https://creativecommons.org/licenses/by/4.0/
27  *
28  * Unless required by applicable law or agreed to in writing, documentation
29  * distributed under the License is distributed on an "AS IS" BASIS,
30  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31  * See the License for the specific language governing permissions and
32  * limitations under the License.
33  *
34  * ============LICENSE_END============================================
35  *
36  * 
37  */
38 package org.onap.portalapp.portal.controller;
39
40 import java.util.List;
41
42 import java.util.Set;
43 import javax.servlet.http.HttpServletRequest;
44 import javax.servlet.http.HttpServletResponse;
45
46 import javax.validation.ConstraintViolation;
47 import javax.validation.Valid;
48 import javax.validation.Validation;
49 import javax.validation.Validator;
50 import javax.validation.ValidatorFactory;
51 import org.onap.portalapp.portal.domain.EPApp;
52 import org.onap.portalapp.portal.domain.EPUser;
53 import org.onap.portalapp.portal.ecomp.model.PortalRestResponse;
54 import org.onap.portalapp.portal.ecomp.model.PortalRestStatusEnum;
55 import org.onap.portalapp.portal.logging.aop.EPAuditLog;
56 import org.onap.portalapp.portal.service.AdminRolesService;
57 import org.onap.portalapp.portal.service.EPAppService;
58 import org.onap.portalapp.portal.service.PortalAdminService;
59 import org.onap.portalapp.portal.service.UserService;
60 import org.onap.portalapp.portal.transport.FieldsValidator;
61 import org.onap.portalapp.portal.transport.OnboardingApp;
62 import org.onap.portalapp.portal.utils.EPCommonSystemProperties;
63 import org.onap.portalapp.portal.utils.EcompPortalUtils;
64 import org.onap.portalapp.portal.utils.PortalConstants;
65 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
66 import org.springframework.beans.factory.annotation.Autowired;
67 import org.springframework.context.annotation.Configuration;
68 import org.springframework.context.annotation.EnableAspectJAutoProxy;
69 import org.springframework.web.bind.annotation.PathVariable;
70 import org.springframework.web.bind.annotation.RequestBody;
71 import org.springframework.web.bind.annotation.RequestMapping;
72 import org.springframework.web.bind.annotation.RequestMethod;
73 import org.springframework.web.bind.annotation.ResponseBody;
74 import org.springframework.web.bind.annotation.RestController;
75
76 import io.swagger.annotations.ApiOperation;
77
78 /**
79  * Processes requests from external systems (i.e., not the front-end web UI).
80  * First use case is ONAP Controller, which has to create an admin and onboard
81  * itself upon launch of a fresh Portal.
82  * 
83  * Listens on the "auxapi" path prefix. Provides alternate implementations of
84  * methods in several existing controllers because an EPUser object is not
85  * available in the session for these requests.
86  * 
87  * Checks credentials sent via HTTP Basic Authentication. The Portal's basic
88  * HTTP authentication system requires that the user names and endpoints are
89  * registered together.
90  */
91 @RestController
92 @RequestMapping(PortalConstants.REST_AUX_API)
93 @Configuration
94 @EnableAspectJAutoProxy
95 @EPAuditLog
96 public class AppsControllerExternalRequest implements BasicAuthenticationController {
97         private static final ValidatorFactory VALIDATOR_FACTORY = Validation.buildDefaultValidatorFactory();
98
99         private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(AppsControllerExternalRequest.class);
100
101         private static final String ONBOARD_APP = "/onboardApp";
102
103         /**
104          * For testing whether a user is a superadmin.
105          */
106         @Autowired
107         private AdminRolesService adminRolesService;
108
109         /**
110          * For onboarding or updating an app
111          */
112         @Autowired
113         private EPAppService appService;
114
115         /**
116          * For promoting a user to Portal admin
117          */
118         @Autowired
119         private PortalAdminService portalAdminService;
120
121         /**
122          * For creating a new user
123          */
124         @Autowired
125         private UserService userService;
126
127         /**
128          * Creates a new user as a Portal administrator.
129          * 
130          * <PRE>
131          { 
132                 "loginId" : "abc123",
133                 "loginPwd": "",
134                 "email":"ecomp@controller" 
135          }
136          * </PRE>
137          * 
138          * @param request
139          *            HttpServletRequest
140          * @param epUser
141          *            User details; the email and orgUserId fields are mandatory
142          * @param response
143          *            HttpServletResponse
144          * @return PortalRestResponse with success or failure
145          */
146         @ApiOperation(value = "Creates a new user as a Portal administrator.", response = PortalRestResponse.class)
147         @RequestMapping(value = "/portalAdmin", method = RequestMethod.POST, produces = "application/json")
148         @ResponseBody
149         public PortalRestResponse<String> postPortalAdmin(HttpServletRequest request, HttpServletResponse response,
150                         @Valid @RequestBody EPUser epUser) {
151                 EcompPortalUtils.logAndSerializeObject(logger, "postPortalAdmin", "request", epUser);
152                 PortalRestResponse<String> portalResponse = new PortalRestResponse<>();
153
154         if (epUser != null) {
155             Validator validator = VALIDATOR_FACTORY.getValidator();
156             Set<ConstraintViolation<EPUser>> constraintViolations = validator.validate(epUser);
157             if (!constraintViolations.isEmpty()) {
158                 portalResponse.setStatus(PortalRestStatusEnum.ERROR);
159                 portalResponse.setMessage("Data is not valid");
160                 return portalResponse;
161             }
162         }
163
164         // Check mandatory fields.
165         if (epUser != null && (epUser.getEmail() == null || epUser.getEmail().trim().length() == 0 //
166                 || epUser.getLoginId() == null || epUser.getLoginId().trim().length() == 0 //
167                 || epUser.getLoginPwd() == null)) {
168             portalResponse.setStatus(PortalRestStatusEnum.ERROR);
169             portalResponse.setMessage("Missing required field: email, loginId, or loginPwd");
170             return portalResponse;
171         }
172
173                 try {
174             // Check for existing user; create if not found.
175             List<EPUser> userList = null;
176             if (epUser != null) {
177                 userList = userService.getUserByUserId(epUser.getOrgUserId());
178             }
179
180                         if (userList == null || userList.isEmpty()) {
181                                 // Create user with first, last names etc.; do check for
182                                 // duplicates.
183                                 String userCreateResult = userService.saveNewUser(epUser, "Yes");
184                                 if (!"success".equals(userCreateResult)) {
185                                         portalResponse.setStatus(PortalRestStatusEnum.ERROR);
186                                         portalResponse.setMessage(userCreateResult);
187                                         return portalResponse;
188                                 }
189                         }
190
191                         // Check for Portal admin status; promote if not.
192             if (adminRolesService.isSuperAdmin(epUser)) {
193                 portalResponse.setStatus(PortalRestStatusEnum.OK);
194             } else {
195                 FieldsValidator fv = null;
196                 if (epUser != null) {
197                     fv = portalAdminService.createPortalAdmin(epUser.getOrgUserId());
198                 }
199                 if (fv != null && fv.httpStatusCode.intValue() == HttpServletResponse.SC_OK) {
200                     portalResponse.setStatus(PortalRestStatusEnum.OK);
201                 } else {
202                     portalResponse.setStatus(PortalRestStatusEnum.ERROR);
203                     if (fv != null) {
204                         portalResponse.setMessage(fv.toString());
205                     }
206                 }
207             }
208                 } catch (Exception ex) {
209                         // Uncaught exceptions yield 404 and an empty error page
210                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
211                         portalResponse.setStatus(PortalRestStatusEnum.ERROR);
212                         portalResponse.setMessage(ex.toString());
213                 }
214
215                 EcompPortalUtils.logAndSerializeObject(logger, "postPortalAdmin", "response", portalResponse);
216                 return portalResponse;
217         }
218
219         /**
220          * Gets the specified application that is on-boarded in Portal.
221          * 
222          * @param request
223          *            HttpServletRequest
224          * @param appId
225          *            Application ID to get
226          * @param response
227          *            httpServletResponse
228          * @return OnboardingApp objects
229          */
230         @ApiOperation(value = "Gets the specified application that is on-boarded in Portal.", response = OnboardingApp.class)
231         @RequestMapping(value = { ONBOARD_APP + "/{appId}" }, method = RequestMethod.GET, produces = "application/json")
232         @ResponseBody
233         public OnboardingApp getOnboardAppExternal(HttpServletRequest request, HttpServletResponse response,
234                         @PathVariable("appId") Long appId) {
235                 EPApp epApp = appService.getApp(appId);
236                 OnboardingApp obApp = new OnboardingApp();
237                 epApp.setAppPassword(EPCommonSystemProperties.APP_DISPLAY_PASSWORD); //to hide password from get request
238                 appService.createOnboardingFromApp(epApp, obApp);
239                 EcompPortalUtils.logAndSerializeObject(logger, "getOnboardAppExternal", "response", obApp);
240                 return obApp;
241         }
242
243         /**
244          * Adds a new application to Portal. The My Logins App Owner in the request
245          * must be the organization user ID of a person who is a Portal
246          * administrator.
247          * 
248          * <pre>
249          * { 
250                 "myLoginsAppOwner" : "abc123",
251                 "name": "dashboard",
252                 "url": "http://k8s/something",
253                 "restUrl" : "http://targeturl.com",
254                 "restrictedApp" : true,
255                 "isOpen" : true,
256                 "isEnabled": false
257                 }
258          * </pre>
259          * 
260          * @param request
261          *            HttpServletRequest
262          * @param response
263          *            httpServletResponse
264          * @param newOnboardApp
265          *            Message with details about the app to add
266          * @return PortalRestResponse
267          */
268         @ApiOperation(value = "Adds a new application to Portal.", response = PortalRestResponse.class)
269         @RequestMapping(value = { ONBOARD_APP }, method = RequestMethod.POST, produces = "application/json")
270         @ResponseBody
271         public PortalRestResponse<String> postOnboardAppExternal(HttpServletRequest request, HttpServletResponse response,
272                         @Valid @RequestBody OnboardingApp newOnboardApp) {
273                 EcompPortalUtils.logAndSerializeObject(logger, "postOnboardAppExternal", "request", newOnboardApp);
274                 PortalRestResponse<String> portalResponse = new PortalRestResponse<>();
275                 if (newOnboardApp != null){
276                         Validator validator = VALIDATOR_FACTORY.getValidator();
277                         Set<ConstraintViolation<OnboardingApp>> constraintViolations = validator.validate(newOnboardApp);
278                         if (!constraintViolations.isEmpty()){
279                                 portalResponse.setStatus(PortalRestStatusEnum.ERROR);
280                                 portalResponse.setMessage("Data is not valid");
281                                 return portalResponse;
282                         }
283                 }
284                 // Validate fields
285                 if (newOnboardApp != null && newOnboardApp.id != null) {
286                         portalResponse.setStatus(PortalRestStatusEnum.ERROR);
287                         portalResponse.setMessage("Unexpected field: id");
288                         return portalResponse;
289                 }
290         if (newOnboardApp != null && (newOnboardApp.name == null || newOnboardApp.name.trim().length() == 0 //
291                 || newOnboardApp.url == null || newOnboardApp.url.trim().length() == 0 //
292                 || newOnboardApp.restUrl == null || newOnboardApp.restUrl.trim().length() == 0
293                 || newOnboardApp.myLoginsAppOwner == null || newOnboardApp.myLoginsAppOwner.trim().length() == 0
294                 || newOnboardApp.restrictedApp == null //
295                 || newOnboardApp.isOpen == null //
296                 || newOnboardApp.isEnabled == null)) {
297             portalResponse.setStatus(PortalRestStatusEnum.ERROR);
298             portalResponse.setMessage(
299                     "Missing required field: name, url, restUrl, restrictedApp, isOpen, isEnabled, myLoginsAppOwner");
300             return portalResponse;
301         }
302
303                 try {
304                     List<EPUser> userList = null;
305             if (newOnboardApp != null) {
306                 userList = userService.getUserByUserId(newOnboardApp.myLoginsAppOwner);
307             }
308             if (userList == null || userList.size() != 1) {
309                 portalResponse.setStatus(PortalRestStatusEnum.ERROR);
310                 if (newOnboardApp != null) {
311                     portalResponse.setMessage("Failed to find user: " + newOnboardApp.myLoginsAppOwner);
312                 } else {
313                     portalResponse.setMessage("Failed to find user");
314                 }
315
316                                 return portalResponse;
317                         }
318
319                         EPUser epUser = userList.get(0);
320                         // Check for Portal admin status
321                         if (! adminRolesService.isSuperAdmin(epUser)) {
322                                 portalResponse.setStatus(PortalRestStatusEnum.ERROR);
323                                 portalResponse.setMessage("User lacks Portal admin role: " + epUser.getLoginId());
324                                 return portalResponse;                          
325                         }
326                                 
327                         newOnboardApp.normalize();
328                         FieldsValidator fv = appService.addOnboardingApp(newOnboardApp, epUser);
329                         if (fv.httpStatusCode.intValue() == HttpServletResponse.SC_OK) {
330                                 portalResponse.setStatus(PortalRestStatusEnum.OK);
331                         } else {
332                                 portalResponse.setStatus(PortalRestStatusEnum.ERROR);
333                                 portalResponse.setMessage(fv.toString());
334                         }
335                 } catch (Exception ex) {
336                         // Uncaught exceptions yield 404 and an empty error page
337                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
338                         portalResponse.setStatus(PortalRestStatusEnum.ERROR);
339                         portalResponse.setMessage(ex.toString());
340                 }
341                 EcompPortalUtils.logAndSerializeObject(logger, "postOnboardAppExternal", "response", portalResponse);
342                 return portalResponse;
343         }
344
345         /**
346          * Updates information about an on-boarded application in Portal. The My
347          * Logins App Owner in the request must be the organization user ID of a
348          * person who is a Portal administrator.
349          * <pre>
350            { 
351                 "id" : 123,
352                 "myLoginsAppOwner" : "abc123",
353                 "name": "dashboard",
354                 "url": "http://k8s/something",
355                 "restUrl" : "http://targeturl.com",
356                 "restrictedApp" : true,
357                 "isOpen" : true,
358                 "isEnabled": false
359                 }
360                 </pre>
361          * @param request
362          *            HttpServletRequest
363          * @param response
364          *            httpServletResponse
365          * @param appId
366          *            application id
367          * @param oldOnboardApp
368          *            Message with details about the app to add
369          * @return PortalRestResponse
370          */
371         @ApiOperation(value = "Updates information about an on-boarded application in Portal.", response = PortalRestResponse.class)
372         @RequestMapping(value = { ONBOARD_APP + "/{appId}" }, method = RequestMethod.PUT, produces = "application/json")
373         @ResponseBody
374         public PortalRestResponse<String> putOnboardAppExternal(HttpServletRequest request, HttpServletResponse response,
375                         @PathVariable("appId") Long appId, @Valid @RequestBody OnboardingApp oldOnboardApp) {
376                 EcompPortalUtils.logAndSerializeObject(logger, "putOnboardAppExternal", "request", oldOnboardApp);
377                 PortalRestResponse<String> portalResponse = new PortalRestResponse<>();
378
379                 if (oldOnboardApp != null){
380                         Validator validator = VALIDATOR_FACTORY.getValidator();
381                         Set<ConstraintViolation<OnboardingApp>> constraintViolations = validator.validate(oldOnboardApp);
382                         if (!constraintViolations.isEmpty()){
383                                 portalResponse.setStatus(PortalRestStatusEnum.ERROR);
384                                 portalResponse.setMessage("Data is not valid");
385                                 return portalResponse;
386                         }
387                 }
388
389                 // Validate fields.
390                 if (oldOnboardApp !=null && (oldOnboardApp.id == null || !appId.equals(oldOnboardApp.id))) {
391                         portalResponse.setStatus(PortalRestStatusEnum.ERROR);
392                         portalResponse.setMessage("Unexpected value for field: id");
393                         return portalResponse;
394                 }
395                 if (oldOnboardApp !=null && (oldOnboardApp.name == null || oldOnboardApp.name.trim().length() == 0 //
396                                 || oldOnboardApp.url == null || oldOnboardApp.url.trim().length() == 0 //
397                                 || oldOnboardApp.restUrl == null || oldOnboardApp.restUrl.trim().length() == 0
398                                 || oldOnboardApp.myLoginsAppOwner == null || oldOnboardApp.myLoginsAppOwner.trim().length() == 0
399                                 || oldOnboardApp.restrictedApp == null //
400                                 || oldOnboardApp.isOpen == null //
401                                 || oldOnboardApp.isEnabled == null)) {
402                         portalResponse.setStatus(PortalRestStatusEnum.ERROR);
403                         portalResponse.setMessage(
404                                         "Missing required field: name, url, restUrl, restrictedApp, isOpen, isEnabled, myLoginsAppOwner");
405                         return portalResponse;
406                 }
407
408                 try {
409             List<EPUser> userList = null;
410             if (oldOnboardApp != null) {
411                 userList = userService.getUserByUserId(oldOnboardApp.myLoginsAppOwner);
412             }
413             if (userList == null || userList.size() != 1) {
414                 portalResponse.setStatus(PortalRestStatusEnum.ERROR);
415                 if (oldOnboardApp != null) {
416                     portalResponse.setMessage("Failed to find user: " + oldOnboardApp.myLoginsAppOwner);
417                 } else {
418                     portalResponse.setMessage("Failed to find user");
419                 }
420
421                 return portalResponse;
422             }
423
424                         EPUser epUser = userList.get(0);
425                         // Check for Portal admin status
426                         if (! adminRolesService.isSuperAdmin(epUser)) {
427                                 portalResponse.setStatus(PortalRestStatusEnum.ERROR);
428                                 portalResponse.setMessage("User lacks Portal admin role: " + epUser.getLoginId());
429                                 return portalResponse;                          
430                         }
431
432                         oldOnboardApp.normalize();
433                         FieldsValidator fv = appService.modifyOnboardingApp(oldOnboardApp, epUser);
434                         if (fv.httpStatusCode.intValue() == HttpServletResponse.SC_OK) {
435                                 portalResponse.setStatus(PortalRestStatusEnum.OK);
436                         } else {
437                                 portalResponse.setStatus(PortalRestStatusEnum.ERROR);
438                                 portalResponse.setMessage(fv.toString());
439                         }
440                 } catch (Exception ex) {
441                         // Uncaught exceptions yield 404 and an empty error page
442                         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
443                         portalResponse.setStatus(PortalRestStatusEnum.ERROR);
444                         portalResponse.setMessage(ex.toString());
445                 }
446                 EcompPortalUtils.logAndSerializeObject(logger, "putOnboardAppExternal", "response", portalResponse);
447                 return portalResponse;
448         }
449
450 }