2 * ============LICENSE_START==========================================
4 * ===================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ===================================================================
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
13 * http://www.apache.org/licenses/LICENSE-2.0
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.
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
26 * https://creativecommons.org/licenses/by/4.0/
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.
34 * ============LICENSE_END============================================
38 package org.onap.portalapp.controller;
40 import static com.att.eelf.configuration.Configuration.MDC_KEY_REQUEST_ID;
42 import java.io.IOException;
43 import java.net.MalformedURLException;
45 import java.net.URLDecoder;
46 import java.util.Enumeration;
47 import java.util.HashMap;
48 import java.util.List;
50 import java.util.UUID;
52 import javax.servlet.http.Cookie;
53 import javax.servlet.http.HttpServletRequest;
54 import javax.servlet.http.HttpServletResponse;
56 import org.apache.commons.lang.StringUtils;
57 import org.json.JSONObject;
58 import org.onap.portalapp.command.EPLoginBean;
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.ExternalAccessRolesService;
63 import org.onap.portalapp.portal.service.SharedContextService;
64 import org.onap.portalapp.portal.utils.EPCommonSystemProperties;
65 import org.onap.portalapp.portal.utils.EPSystemProperties;
66 import org.onap.portalapp.portal.utils.EcompPortalUtils;
67 import org.onap.portalapp.util.EPUserUtils;
68 import org.onap.portalapp.util.SessionCookieUtil;
69 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
70 import org.onap.portalsdk.core.menu.MenuProperties;
71 import org.onap.portalsdk.core.util.SystemProperties;
73 import org.springframework.beans.factory.annotation.Autowired;
74 import org.springframework.http.HttpStatus;
75 import org.springframework.stereotype.Controller;
76 import org.springframework.util.StopWatch;
77 import org.springframework.web.bind.annotation.ExceptionHandler;
78 import org.springframework.web.bind.annotation.RequestMapping;
79 import org.springframework.web.bind.annotation.GetMapping;
80 import org.springframework.web.bind.annotation.PostMapping;
81 import org.springframework.web.bind.annotation.RequestMethod;
82 import org.springframework.web.bind.annotation.ResponseBody;
83 import org.springframework.web.servlet.ModelAndView;
84 import org.springframework.web.util.WebUtils;
86 import com.fasterxml.jackson.databind.DeserializationFeature;
87 import com.fasterxml.jackson.databind.JsonNode;
88 import com.fasterxml.jackson.databind.ObjectMapper;
92 public class LoginController extends EPUnRestrictedBaseController implements LoginService {
94 private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(LoginController.class);
96 public static final String DEFAULT_SUCCESS_VIEW = "applicationsHome";
97 public static final String DEFAULT_FAILURE_VIEW = "login";
98 public static final String ERROR_MESSAGE_KEY = "error";
99 public static final String REDIRECT_URL = "redirectUrl";
100 public static final String REDIRECT_COLON = "redirect:";
103 private EPLoginService loginService;
105 private SharedContextService sharedContextService;
107 private EPRoleFunctionService ePRoleFunctionService;
109 private ExternalAccessRolesService externalAccessRolesService ;
111 private String viewName = "login";
113 private String welcomeView;
115 @GetMapping(value = { "/login.htm" })
116 public ModelAndView login(HttpServletRequest request) {
117 Map<String, Object> model = new HashMap<String, Object>();
118 String authentication = SystemProperties.getProperty(SystemProperties.AUTHENTICATION_MECHANISM);
120 if (authentication == null || "".equals(authentication) || "OICD".equals(authentication.trim()))
121 loginPage = "openIdLogin";
123 loginPage = getViewName();
124 return new ModelAndView(loginPage, "model", model);
127 @SuppressWarnings("rawtypes")
128 @PostMapping(value = { "/open_source/login" })
130 public String loginValidate(HttpServletRequest request, HttpServletResponse response) throws Exception {
132 String orgUserId = "";
133 ObjectMapper mapper = new ObjectMapper();
134 mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
135 JsonNode root = mapper.readTree(request.getReader());
137 EPLoginBean commandBean = new EPLoginBean();
138 String loginId = root.get("loginId").textValue();
139 String password = root.get("password").textValue();
140 commandBean.setLoginId(loginId);
141 commandBean.setLoginPwd(password);
143 HashMap additionalParamsMap = new HashMap();
144 StringBuilder sbAdditionalInfo = new StringBuilder();
146 commandBean = getLoginService().findUser(commandBean,
147 (String) request.getAttribute(MenuProperties.MENU_PROPERTIES_FILENAME_KEY), additionalParamsMap);
148 String fullURL = getFullURL(request);
149 if (commandBean.getUser() == null) {
150 String loginErrorMessage = (commandBean.getLoginErrorMessage() != null) ? commandBean.getLoginErrorMessage()
151 : "login.error.external.invalid";
152 logger.info(EELFLoggerDelegate.debugLogger, "loginId {} does not exist in the the DB.", loginId);
153 sbAdditionalInfo.append(String.format("But the Login-Id: %s doesn't exist in the Database. Request-URL: %s",
155 return loginErrorMessage;
157 // store the currently logged in user's information in the session
158 EPUserUtils.setUserSession(request, commandBean.getUser(), commandBean.getMenu(),
159 commandBean.getBusinessDirectMenu(), ePRoleFunctionService);
162 logger.info(EELFLoggerDelegate.debugLogger, "loginValidate: store user info into share context begins");
163 String sessionId = request.getSession().getId();
164 List<SharedContext> existingSC = getSharedContextService().getSharedContexts(sessionId);
165 if (existingSC == null || existingSC.isEmpty()) {
166 getSharedContextService().addSharedContext(sessionId, EPSystemProperties.USER_FIRST_NAME,
167 commandBean.getUser().getFirstName());
168 getSharedContextService().addSharedContext(sessionId, EPSystemProperties.USER_LAST_NAME,
169 commandBean.getUser().getLastName());
170 getSharedContextService().addSharedContext(sessionId, EPSystemProperties.USER_EMAIL,
171 commandBean.getUser().getEmail());
172 getSharedContextService().addSharedContext(sessionId, EPSystemProperties.USER_ORG_USERID,
173 commandBean.getLoginId());
176 } catch (Exception e) {
177 logger.info(EELFLoggerDelegate.errorLogger, "loginValidate: failed the shared context adding process ",
180 logger.info(EELFLoggerDelegate.debugLogger,
181 "loginValidate: PresetUp the EP service cookie and intial sessionManagement");
183 SessionCookieUtil.preSetUp(request, response);
184 SessionCookieUtil.setUpUserIdCookie(request, response, loginId);
186 JSONObject j = new JSONObject("{success: success}");
189 //if app is centralized then sync user roles from the external auth system
190 orgUserId = commandBean.getUser().getOrgUserId();
191 if(EcompPortalUtils.checkIfRemoteCentralAccessAllowed()) {
192 externalAccessRolesService.syncApplicationUserRolesFromExtAuthSystem(orgUserId);
193 logger.info(EELFLoggerDelegate.errorLogger, "Sync: Sync Application UserRoles From ExtAuthSystem is done..");
195 } catch (Exception e) {
196 logger.info(EELFLoggerDelegate.errorLogger, "Sync: Sync Application UserRoles From ExtAuthSystem Faild..",
205 * Work around a bug in ecompsdkos version 1.1.0 which hard-codes this endpoint.
207 @RequestMapping(value = { "/process_csp" }, method = RequestMethod.GET)
208 public ModelAndView processCsp(HttpServletRequest request, HttpServletResponse response) throws Exception {
209 return processSingleSignOn(request, response);
212 * Remove this method after epsdk-app-common/.../SingleSignOnController.java is
216 @GetMapping(value = { "/processSingleSignOn" })
217 public ModelAndView processSingleSignOn(HttpServletRequest request, HttpServletResponse response) throws Exception {
219 Map<Object, Object> model = new HashMap<Object, Object>();
220 HashMap<Object, Object> additionalParamsMap = new HashMap<Object, Object>();
221 EPLoginBean commandBean = new EPLoginBean();
222 MDC.put(MDC_KEY_REQUEST_ID, (getRequestId(request)==null || getRequestId(request).isEmpty()) ? UUID.randomUUID().toString():getRequestId(request));
223 // get userId from cookie
224 String orgUserId = SessionCookieUtil.getUserIdFromCookie(request, response);
225 logger.info(EELFLoggerDelegate.debugLogger, "processSingleSignOn: begins with orgUserId {}", orgUserId);
227 StringBuilder sbAdditionalInfo = new StringBuilder();
228 validateDomain(request);
229 if (orgUserId == null || orgUserId.length() == 0) {
230 model.put(ERROR_MESSAGE_KEY, SystemProperties.MESSAGE_KEY_LOGIN_ERROR_COOKIE_EMPTY);
231 if (request.getParameter(REDIRECT_URL) != null && request.getParameter(REDIRECT_URL).length() != 0) {
232 return new ModelAndView(REDIRECT_COLON + DEFAULT_FAILURE_VIEW + ".htm" + "?redirectUrl="
233 + request.getParameter(REDIRECT_URL));
235 return new ModelAndView(REDIRECT_COLON + DEFAULT_FAILURE_VIEW + ".htm");
239 StopWatch stopWatch = new StopWatch("LoginController.Login");
243 logger.info(EELFLoggerDelegate.debugLogger,
244 "Operation findUser is started to locate user {} in the database.", orgUserId);
245 commandBean.setLoginId(orgUserId);
246 commandBean.setOrgUserId(orgUserId);
247 commandBean = getLoginService().findUser(commandBean,
248 (String) request.getAttribute(MenuProperties.MENU_PROPERTIES_FILENAME_KEY),
249 additionalParamsMap);
252 MDC.put(EPSystemProperties.MDC_TIMER, String.valueOf(stopWatch.getTotalTimeMillis()));
253 logger.info(EELFLoggerDelegate.debugLogger, "Operation findUser is completed.");
254 } catch (Exception e) {
256 MDC.put(EPSystemProperties.MDC_TIMER, String.valueOf(stopWatch.getTotalTimeMillis()));
257 logger.info(EELFLoggerDelegate.errorLogger, "processSingleSignOn failed on user " + orgUserId, e);
259 MDC.remove(EPSystemProperties.MDC_TIMER);
262 sbAdditionalInfo.append("Login attempt is succeeded. ");
263 String fullURL = getFullURL(request);
264 if (commandBean.getUser() == null) {
265 logger.info(EELFLoggerDelegate.debugLogger,
266 "processSingleSignOn: loginId {} does not exist in the the DB.", orgUserId);
268 sbAdditionalInfo.append(String.format(
269 "But the Login-Id: %s doesn't exist in the Database. Created a Guest Session. Request-URL: %s",
270 orgUserId, fullURL));
271 validateDomain(request);
272 if (request.getParameter(REDIRECT_URL) != null && request.getParameter(REDIRECT_URL).length() != 0) {
273 return new ModelAndView(REDIRECT_COLON + DEFAULT_FAILURE_VIEW + ".htm" + "?redirectUrl="
274 + request.getParameter(REDIRECT_URL));
276 return new ModelAndView(REDIRECT_COLON + DEFAULT_FAILURE_VIEW + ".htm");
280 sbAdditionalInfo.append(
281 String.format("Login-Id: %s, Login-Method: %s, Request-URL: %s", orgUserId, "", fullURL));
282 logger.info(EELFLoggerDelegate.debugLogger, "processSingleSignOn: now set up user session for {}",
285 EPUserUtils.setUserSession(request, commandBean.getUser(), commandBean.getMenu(),
286 commandBean.getBusinessDirectMenu(), ePRoleFunctionService);
287 logger.info(EELFLoggerDelegate.debugLogger,
288 "processSingleSignOn: now set up user session for {} finished", orgUserId);
290 // Store user's information into share context
292 logger.info(EELFLoggerDelegate.debugLogger,
293 "processSingleSignOn: store user info into share context begins");
294 String sessionId = request.getSession().getId();
295 List<SharedContext> existingSC = getSharedContextService().getSharedContexts(sessionId);
296 if (existingSC == null || existingSC.isEmpty()) {
297 getSharedContextService().addSharedContext(sessionId, EPSystemProperties.USER_FIRST_NAME,
298 commandBean.getUser().getFirstName());
299 getSharedContextService().addSharedContext(sessionId, EPSystemProperties.USER_LAST_NAME,
300 commandBean.getUser().getLastName());
301 getSharedContextService().addSharedContext(sessionId, EPSystemProperties.USER_EMAIL,
302 commandBean.getUser().getEmail());
303 getSharedContextService().addSharedContext(sessionId, EPSystemProperties.USER_ORG_USERID,
304 commandBean.getLoginId());
306 } catch (Exception e) {
307 logger.info(EELFLoggerDelegate.errorLogger,
308 "processSingleSignOn: failed the shared context adding process", e);
311 logger.info(EELFLoggerDelegate.debugLogger,
312 "processSingleSignOn: PresetUp the EP service cookie and intial sessionManagement");
313 SessionCookieUtil.preSetUp(request, response);
314 SessionCookieUtil.setUpUserIdCookie(request, response, orgUserId);
315 logger.info(EELFLoggerDelegate.debugLogger,
316 "processSingleSignOn: PresetUp the EP service cookie and intial sessionManagement completed");
317 logger.info(EELFLoggerDelegate.debugLogger,
318 commandBean.getUser().getOrgUserId() + " exists in the the system.");
320 // get redirectUrl from URL parameter
321 validateDomain(request);
322 if (request.getParameter(REDIRECT_URL) != null && request.getParameter(REDIRECT_URL).length() != 0) {
323 String forwardUrl = URLDecoder.decode(request.getParameter(REDIRECT_URL), "UTF-8");
325 Cookie cookie2 = new Cookie(REDIRECT_URL, "");
326 // ONAP does not use https
327 cookie2.setSecure(false);
328 cookie2.setMaxAge(0);
329 cookie2.setDomain(EPSystemProperties.getProperty(EPSystemProperties.COOKIE_DOMAIN));
330 cookie2.setPath("/");
331 response.addCookie(cookie2);
332 return new ModelAndView(REDIRECT_COLON + forwardUrl);
335 // first check if redirectUrl exists or not
336 if (WebUtils.getCookie(request, REDIRECT_URL) != null) {
337 String forwardUrl = WebUtils.getCookie(request, REDIRECT_URL).getValue();
339 Cookie cookie2 = new Cookie(REDIRECT_URL, "");
340 // ONAP does not use https
341 cookie2.setSecure(false);
342 cookie2.setMaxAge(0);
343 cookie2.setDomain(EPSystemProperties.getProperty(EPSystemProperties.COOKIE_DOMAIN));
344 cookie2.setPath("/");
345 response.addCookie(cookie2);
347 return new ModelAndView(REDIRECT_COLON + forwardUrl);
352 // if user has been authenticated, now take them to the welcome page.
353 logger.info(EELFLoggerDelegate.debugLogger, "processSingleSignOn: Now return to application home page");
354 return new ModelAndView(REDIRECT_COLON + SystemProperties.getProperty(EPSystemProperties.FE_URL));
357 private void validateDomain(HttpServletRequest request) throws MalformedURLException {
358 final String returnToAppUrl = request.getParameter(REDIRECT_URL);
359 if (StringUtils.isNotBlank(returnToAppUrl)) {
360 String hostName = new URL(returnToAppUrl).getHost();
361 if (StringUtils.isNotBlank(hostName)
362 && !hostName.endsWith(EPSystemProperties.getProperty(EPCommonSystemProperties.COOKIE_DOMAIN))) {
363 logger.debug(EELFLoggerDelegate.debugLogger,
364 "processSingleSignOn () accessing Unauthorized url :" + hostName);
365 throw new SecurityException("accessing Unauthorized url : " + hostName);
370 private String getFullURL(HttpServletRequest request) {
371 if (request != null) {
372 String requestURL = request.getRequestURL().toString();
373 String queryString = request.getQueryString();
374 if (queryString == null) {
377 return requestURL + "?" + queryString;
383 private String getRequestId(HttpServletRequest request) {
384 Enumeration<String> headerNames = request.getHeaderNames();
385 String requestId = "";
386 while (headerNames.hasMoreElements()) {
387 String headerName = headerNames.nextElement();
388 logger.debug(EELFLoggerDelegate.debugLogger, "getRequestId: header {} has value {}", headerName,
389 request.getHeader(headerName));
390 if (headerName.equalsIgnoreCase(SystemProperties.ECOMP_REQUEST_ID)) {
391 requestId = request.getHeader(headerName);
395 return requestId.isEmpty() ? UUID.randomUUID().toString() : requestId;
398 public String getWelcomeView() {
402 public void setWelcomeView(String welcomeView) {
403 this.welcomeView = welcomeView;
407 public String getViewName() {
412 public void setViewName(String viewName) {
413 this.viewName = viewName;
416 public EPLoginService getLoginService() {
420 public void setLoginService(EPLoginService loginService) {
421 this.loginService = loginService;
424 public SharedContextService getSharedContextService() {
425 return sharedContextService;
428 public void setSharedContextService(SharedContextService sharedContextService) {
429 this.sharedContextService = sharedContextService;
432 @ExceptionHandler(Exception.class)
433 protected void handleBadRequests(Exception e, HttpServletResponse response) throws IOException {
434 logger.warn(EELFLoggerDelegate.errorLogger, "Handling bad request", e);
435 response.sendError(HttpStatus.BAD_REQUEST.value());