Added Junits
[portal.git] / ecomp-portal-BE-os / src / main / java / org / onap / portalapp / controller / LoginController.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  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
37  */
38 package org.onap.portalapp.controller;
39
40 import static com.att.eelf.configuration.Configuration.MDC_KEY_REQUEST_ID;
41
42 import java.net.MalformedURLException;
43 import java.net.URL;
44 import java.net.URLDecoder;
45 import java.util.Enumeration;
46 import java.util.HashMap;
47 import java.util.List;
48 import java.util.Map;
49 import java.util.UUID;
50
51 import javax.servlet.http.Cookie;
52 import javax.servlet.http.HttpServletRequest;
53 import javax.servlet.http.HttpServletResponse;
54
55 import org.apache.commons.lang.StringUtils;
56 import org.json.JSONObject;
57 import org.onap.portalapp.command.EPLoginBean;
58 import org.onap.portalapp.controller.EPUnRestrictedBaseController;
59 import org.onap.portalapp.portal.domain.SharedContext;
60 import org.onap.portalapp.portal.service.EPLoginService;
61 import org.onap.portalapp.portal.service.EPRoleFunctionService;
62 import org.onap.portalapp.portal.service.SharedContextService;
63 import org.onap.portalapp.portal.utils.EPCommonSystemProperties;
64 import org.onap.portalapp.portal.utils.EPSystemProperties;
65 import org.onap.portalapp.util.EPUserUtils;
66 import org.onap.portalapp.util.SessionCookieUtil;
67 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
68 import org.onap.portalsdk.core.menu.MenuProperties;
69 import org.onap.portalsdk.core.onboarding.util.CipherUtil;
70 import org.onap.portalsdk.core.util.SystemProperties;
71 import org.slf4j.MDC;
72 import org.springframework.beans.factory.annotation.Autowired;
73 import org.springframework.stereotype.Controller;
74 import org.springframework.util.StopWatch;
75 import org.springframework.web.bind.annotation.RequestMapping;
76 import org.springframework.web.bind.annotation.RequestMethod;
77 import org.springframework.web.bind.annotation.ResponseBody;
78 import org.springframework.web.servlet.ModelAndView;
79 import org.springframework.web.util.WebUtils;
80
81 import com.fasterxml.jackson.databind.DeserializationFeature;
82 import com.fasterxml.jackson.databind.JsonNode;
83 import com.fasterxml.jackson.databind.ObjectMapper;
84
85 @Controller
86 @RequestMapping("/")
87 public class LoginController extends EPUnRestrictedBaseController implements LoginService {
88
89         private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(LoginController.class);
90
91         public static final String DEFAULT_SUCCESS_VIEW = "applicationsHome";
92         public static final String DEFAULT_FAILURE_VIEW = "login";
93         public static final String ERROR_MESSAGE_KEY = "error";
94         public static final String REDIRECT_URL = "redirectUrl";
95         public static final String REDIRECT_COLON = "redirect:";
96
97         @Autowired
98         private EPLoginService loginService;
99         @Autowired
100         private SharedContextService sharedContextService;
101         @Autowired
102         private EPRoleFunctionService ePRoleFunctionService;
103
104         private String viewName = "login";
105
106         private String welcomeView;
107
108         @RequestMapping(value = { "/login.htm" }, method = RequestMethod.GET)
109         public ModelAndView login(HttpServletRequest request) {
110                 Map<String, Object> model = new HashMap<String, Object>();
111                 String authentication = SystemProperties.getProperty(SystemProperties.AUTHENTICATION_MECHANISM);
112                 String loginPage;
113                 if (authentication == null || "".equals(authentication) || "OICD".equals(authentication.trim()))
114                         loginPage = "openIdLogin";
115                 else
116                         loginPage = getViewName();
117                 return new ModelAndView(loginPage, "model", model);
118         }
119
120         @SuppressWarnings("rawtypes")
121         @RequestMapping(value = { "/open_source/login" }, method = RequestMethod.POST)
122         @ResponseBody
123         public String loginValidate(HttpServletRequest request, HttpServletResponse response) throws Exception {
124
125                 ObjectMapper mapper = new ObjectMapper();
126                 mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
127                 JsonNode root = mapper.readTree(request.getReader());
128
129                 EPLoginBean commandBean = new EPLoginBean();
130                 String loginId = root.get("loginId").textValue();
131                 String password = root.get("password").textValue();
132                 commandBean.setLoginId(loginId);
133                 commandBean.setLoginPwd(CipherUtil.encryptPKC(password));
134                 
135                 HashMap additionalParamsMap = new HashMap();
136                 StringBuilder sbAdditionalInfo = new StringBuilder();
137
138                 commandBean = getLoginService().findUser(commandBean,
139                                 (String) request.getAttribute(MenuProperties.MENU_PROPERTIES_FILENAME_KEY), additionalParamsMap);
140                 String fullURL = getFullURL(request);
141                 if (commandBean.getUser() == null) {
142                         String loginErrorMessage = (commandBean.getLoginErrorMessage() != null) ? commandBean.getLoginErrorMessage()
143                                         : "login.error.external.invalid";
144                         logger.info(EELFLoggerDelegate.debugLogger, "loginId {} does not exist in the the DB.", loginId);
145                         sbAdditionalInfo.append(String.format("But the Login-Id: %s doesn't exist in the Database. Request-URL: %s",
146                                         loginId, fullURL));
147                         return loginErrorMessage;
148                 } else {
149                         // store the currently logged in user's information in the session
150                         EPUserUtils.setUserSession(request, commandBean.getUser(), commandBean.getMenu(),
151                                         commandBean.getBusinessDirectMenu(),
152                                         SystemProperties.getProperty(SystemProperties.AUTHENTICATION_MECHANISM), ePRoleFunctionService);
153
154                         try {
155                                 logger.info(EELFLoggerDelegate.debugLogger, "loginValidate: store user info into share context begins");
156                                 String sessionId = request.getSession().getId();
157                                 List<SharedContext> existingSC = getSharedContextService().getSharedContexts(sessionId);
158                                 if (existingSC == null || existingSC.isEmpty()) {
159                                         getSharedContextService().addSharedContext(sessionId, EPSystemProperties.USER_FIRST_NAME,
160                                                         commandBean.getUser().getFirstName());
161                                         getSharedContextService().addSharedContext(sessionId, EPSystemProperties.USER_LAST_NAME,
162                                                         commandBean.getUser().getLastName());
163                                         getSharedContextService().addSharedContext(sessionId, EPSystemProperties.USER_EMAIL,
164                                                         commandBean.getUser().getEmail());
165                                         getSharedContextService().addSharedContext(sessionId, EPSystemProperties.USER_ORG_USERID,
166                                                         commandBean.getLoginId());
167                                 }
168
169                         } catch (Exception e) {
170                                 logger.info(EELFLoggerDelegate.errorLogger, "loginValidate: failed the shared context adding process ",
171                                                 e);
172                         }
173                         logger.info(EELFLoggerDelegate.debugLogger,
174                                         "loginValidate: PresetUp the EP service cookie and intial sessionManagement");
175
176                         SessionCookieUtil.preSetUp(request, response);
177                         SessionCookieUtil.setUpUserIdCookie(request, response, loginId);
178
179                         JSONObject j = new JSONObject("{success: success}");
180
181                         return j.toString();
182                 }
183         }
184
185         /*
186          * Work around a bug in ecompsdkos version 1.1.0 which hard-codes this endpoint.
187          */
188         @RequestMapping(value = { "/process_csp" }, method = RequestMethod.GET)
189         public ModelAndView processCsp(HttpServletRequest request, HttpServletResponse response) throws Exception {
190                 return processSingleSignOn(request, response);
191         }
192         /*
193          * Remove this method after epsdk-app-common/.../SingleSignOnController.java is
194          * repaired.
195          */
196
197         @RequestMapping(value = { "/processSingleSignOn" }, method = RequestMethod.GET)
198         public ModelAndView processSingleSignOn(HttpServletRequest request, HttpServletResponse response) throws Exception {
199
200                 Map<Object, Object> model = new HashMap<Object, Object>();
201                 HashMap<Object, Object> additionalParamsMap = new HashMap<Object, Object>();
202                 EPLoginBean commandBean = new EPLoginBean();
203                 MDC.put(MDC_KEY_REQUEST_ID, getRequestId(request));
204                 // get userId from cookie
205                 String orgUserId = SessionCookieUtil.getUserIdFromCookie(request, response);
206                 logger.info(EELFLoggerDelegate.debugLogger, "processSingleSignOn: begins with orgUserId {}", orgUserId);
207
208                 StringBuilder sbAdditionalInfo = new StringBuilder();
209                 validateDomain(request);
210                 if (orgUserId == null || orgUserId.length() == 0) {
211                         model.put(ERROR_MESSAGE_KEY, SystemProperties.MESSAGE_KEY_LOGIN_ERROR_COOKIE_EMPTY);
212                         if (request.getParameter(REDIRECT_URL) != null && request.getParameter(REDIRECT_URL).length() != 0) {
213                                 return new ModelAndView(REDIRECT_COLON + DEFAULT_FAILURE_VIEW + ".htm" + "?redirectUrl="
214                                                 + request.getParameter(REDIRECT_URL));
215                         } else {
216                                 return new ModelAndView(REDIRECT_COLON + DEFAULT_FAILURE_VIEW + ".htm");
217                         }
218                 } else {
219
220                         StopWatch stopWatch = new StopWatch("LoginController.Login");
221                         stopWatch.start();
222
223                         try {
224                                 logger.info(EELFLoggerDelegate.debugLogger,
225                                                 "Operation findUser is started to locate user {}  in the database.", orgUserId);
226                                 commandBean.setLoginId(orgUserId);
227                                 commandBean.setOrgUserId(orgUserId);
228                                 commandBean = getLoginService().findUser(commandBean,
229                                                 (String) request.getAttribute(MenuProperties.MENU_PROPERTIES_FILENAME_KEY),
230                                                 additionalParamsMap);
231
232                                 stopWatch.stop();
233                                 MDC.put(EPSystemProperties.MDC_TIMER, stopWatch.getTotalTimeMillis() + "ms");
234                                 logger.info(EELFLoggerDelegate.debugLogger, "Operation findUser is completed.");
235                         } catch (Exception e) {
236                                 stopWatch.stop();
237                                 MDC.put(EPSystemProperties.MDC_TIMER, stopWatch.getTotalTimeMillis() + "ms");
238                                 logger.info(EELFLoggerDelegate.errorLogger, "processSingleSignOn failed on user " + orgUserId, e);
239                         } finally {
240                                 MDC.remove(EPSystemProperties.MDC_TIMER);
241                         }
242
243                         sbAdditionalInfo.append("Login attempt is succeeded. ");
244                         String fullURL = getFullURL(request);
245                         if (commandBean.getUser() == null) {
246                                 logger.info(EELFLoggerDelegate.debugLogger,
247                                                 "processSingleSignOn: loginId {} does not exist in the the DB.", orgUserId);
248
249                                 sbAdditionalInfo.append(String.format(
250                                                 "But the Login-Id: %s doesn't exist in the Database. Created a Guest Session. Request-URL: %s",
251                                                 orgUserId, fullURL));
252                                 validateDomain(request);
253                                 if (request.getParameter(REDIRECT_URL) != null && request.getParameter(REDIRECT_URL).length() != 0) {
254                                         return new ModelAndView(REDIRECT_COLON + DEFAULT_FAILURE_VIEW + ".htm" + "?redirectUrl="
255                                                         + request.getParameter(REDIRECT_URL));
256                                 } else {
257                                         return new ModelAndView(REDIRECT_COLON + DEFAULT_FAILURE_VIEW + ".htm");
258                                 }
259                         } else {
260
261                                 sbAdditionalInfo.append(
262                                                 String.format("Login-Id: %s, Login-Method: %s, Request-URL: %s", orgUserId, "", fullURL));
263                                 logger.info(EELFLoggerDelegate.debugLogger, "processSingleSignOn: now set up user session for {}",
264                                                 orgUserId);
265
266                                 EPUserUtils.setUserSession(request, commandBean.getUser(), commandBean.getMenu(),
267                                                 commandBean.getBusinessDirectMenu(),
268                                                 SystemProperties.getProperty(SystemProperties.AUTHENTICATION_MECHANISM), ePRoleFunctionService);
269                                 logger.info(EELFLoggerDelegate.debugLogger,
270                                                 "processSingleSignOn: now set up user session for {} finished", orgUserId);
271
272                                 // Store user's information into share context
273                                 try {
274                                         logger.info(EELFLoggerDelegate.debugLogger,
275                                                         "processSingleSignOn: store user info into share context begins");
276                                         String sessionId = request.getSession().getId();
277                                         List<SharedContext> existingSC = getSharedContextService().getSharedContexts(sessionId);
278                                         if (existingSC == null || existingSC.isEmpty()) {
279                                                 getSharedContextService().addSharedContext(sessionId, EPSystemProperties.USER_FIRST_NAME,
280                                                                 commandBean.getUser().getFirstName());
281                                                 getSharedContextService().addSharedContext(sessionId, EPSystemProperties.USER_LAST_NAME,
282                                                                 commandBean.getUser().getLastName());
283                                                 getSharedContextService().addSharedContext(sessionId, EPSystemProperties.USER_EMAIL,
284                                                                 commandBean.getUser().getEmail());
285                                                 getSharedContextService().addSharedContext(sessionId, EPSystemProperties.USER_ORG_USERID,
286                                                                 commandBean.getLoginId());
287                                         }
288                                 } catch (Exception e) {
289                                         logger.info(EELFLoggerDelegate.errorLogger,
290                                                         "processSingleSignOn: failed the shared context adding process", e);
291                                 }
292
293                                 logger.info(EELFLoggerDelegate.debugLogger,
294                                                 "processSingleSignOn: PresetUp the EP service cookie and intial sessionManagement");
295                                 SessionCookieUtil.preSetUp(request, response);
296                                 SessionCookieUtil.setUpUserIdCookie(request, response, orgUserId);
297                                 logger.info(EELFLoggerDelegate.debugLogger,
298                                                 "processSingleSignOn: PresetUp the EP service cookie and intial sessionManagement completed");
299                                 logger.info(EELFLoggerDelegate.debugLogger,
300                                                 commandBean.getUser().getOrgUserId() + " exists in the the system.");
301
302                                 // get redirectUrl from URL parameter
303                                 validateDomain(request);
304                                 if (request.getParameter(REDIRECT_URL) != null && request.getParameter(REDIRECT_URL).length() != 0) {
305                                         String forwardUrl = URLDecoder.decode(request.getParameter(REDIRECT_URL), "UTF-8");
306                                         // clean cookie
307                                         Cookie cookie2 = new Cookie(REDIRECT_URL, "");
308                                         // ONAP does not use https
309                                         cookie2.setSecure(false);
310                                         cookie2.setMaxAge(0);
311                                         cookie2.setDomain(EPSystemProperties.getProperty(EPSystemProperties.COOKIE_DOMAIN));
312                                         cookie2.setPath("/");
313                                         response.addCookie(cookie2);
314                                         return new ModelAndView(REDIRECT_COLON + forwardUrl);
315                                 }
316
317                                 // first check if redirectUrl exists or not
318                                 if (WebUtils.getCookie(request, REDIRECT_URL) != null) {
319                                         String forwardUrl = WebUtils.getCookie(request, REDIRECT_URL).getValue();
320                                         // clean cookie
321                                         Cookie cookie2 = new Cookie(REDIRECT_URL, "");
322                                         // ONAP does not use https
323                                         cookie2.setSecure(false);
324                                         cookie2.setMaxAge(0);
325                                         cookie2.setDomain(EPSystemProperties.getProperty(EPSystemProperties.COOKIE_DOMAIN));
326                                         cookie2.setPath("/");
327                                         response.addCookie(cookie2);
328
329                                         return new ModelAndView(REDIRECT_COLON + forwardUrl);
330                                 }
331                         }
332                 }
333
334                 // if user has been authenticated, now take them to the welcome page.
335                 logger.info(EELFLoggerDelegate.debugLogger, "processSingleSignOn: Now return to application home page");
336                 return new ModelAndView(REDIRECT_COLON + SystemProperties.getProperty(EPSystemProperties.FE_URL));
337         }
338
339         private void validateDomain(HttpServletRequest request) throws MalformedURLException {
340                 final String returnToAppUrl = request.getParameter(REDIRECT_URL);
341                 if (StringUtils.isNotBlank(returnToAppUrl)) {
342                         String hostName = new URL(returnToAppUrl).getHost();
343                         if (StringUtils.isNotBlank(hostName)
344                                         && !hostName.endsWith(EPSystemProperties.getProperty(EPCommonSystemProperties.COOKIE_DOMAIN))) {
345                                 logger.debug(EELFLoggerDelegate.debugLogger,
346                                                 "processSingleSignOn ()  accessing Unauthorized url  :" + hostName);
347                                 throw new SecurityException("accessing Unauthorized url : " + hostName);
348                         }
349                 }
350         }
351
352         private String getFullURL(HttpServletRequest request) {
353                 if (request != null) {
354                         String requestURL = request.getRequestURL().toString();
355                         String queryString = request.getQueryString();
356                         if (queryString == null) {
357                                 return requestURL;
358                         } else {
359                                 return requestURL + "?" + queryString;
360                         }
361                 }
362                 return "";
363         }
364
365         private String getRequestId(HttpServletRequest request) {
366                 Enumeration<String> headerNames = request.getHeaderNames();
367                 String requestId = "";
368                 while (headerNames.hasMoreElements()) {
369                         String headerName = headerNames.nextElement();
370                         logger.debug(EELFLoggerDelegate.debugLogger, "getRequestId: header {} has value {}", headerName,
371                                         request.getHeader(headerName));
372                         if (headerName.equalsIgnoreCase(SystemProperties.ECOMP_REQUEST_ID)) {
373                                 requestId = request.getHeader(headerName);
374                                 break;
375                         }
376                 }
377                 return requestId.isEmpty() ? UUID.randomUUID().toString() : requestId;
378         }
379
380         public String getWelcomeView() {
381                 return welcomeView;
382         }
383
384         public void setWelcomeView(String welcomeView) {
385                 this.welcomeView = welcomeView;
386         }
387
388         @Override
389         public String getViewName() {
390                 return viewName;
391         }
392
393         @Override
394         public void setViewName(String viewName) {
395                 this.viewName = viewName;
396         }
397
398         public EPLoginService getLoginService() {
399                 return loginService;
400         }
401
402         public void setLoginService(EPLoginService loginService) {
403                 this.loginService = loginService;
404         }
405
406         public SharedContextService getSharedContextService() {
407                 return sharedContextService;
408         }
409
410         public void setSharedContextService(SharedContextService sharedContextService) {
411                 this.sharedContextService = sharedContextService;
412         }
413
414 }