1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portal.action;
24  
25  import com.liferay.portal.CookieNotSupportedException;
26  import com.liferay.portal.NoSuchUserException;
27  import com.liferay.portal.PasswordExpiredException;
28  import com.liferay.portal.PortalException;
29  import com.liferay.portal.SendPasswordException;
30  import com.liferay.portal.SystemException;
31  import com.liferay.portal.UserEmailAddressException;
32  import com.liferay.portal.UserIdException;
33  import com.liferay.portal.UserLockoutException;
34  import com.liferay.portal.UserPasswordException;
35  import com.liferay.portal.UserScreenNameException;
36  import com.liferay.portal.kernel.captcha.CaptchaTextException;
37  import com.liferay.portal.kernel.captcha.CaptchaUtil;
38  import com.liferay.portal.kernel.log.Log;
39  import com.liferay.portal.kernel.log.LogFactoryUtil;
40  import com.liferay.portal.kernel.servlet.HttpHeaders;
41  import com.liferay.portal.kernel.servlet.SessionErrors;
42  import com.liferay.portal.kernel.servlet.SessionMessages;
43  import com.liferay.portal.kernel.util.Constants;
44  import com.liferay.portal.kernel.util.GetterUtil;
45  import com.liferay.portal.kernel.util.HttpUtil;
46  import com.liferay.portal.kernel.util.ParamUtil;
47  import com.liferay.portal.kernel.util.StringPool;
48  import com.liferay.portal.kernel.util.Validator;
49  import com.liferay.portal.model.Company;
50  import com.liferay.portal.model.CompanyConstants;
51  import com.liferay.portal.model.User;
52  import com.liferay.portal.security.auth.AuthException;
53  import com.liferay.portal.security.auth.Authenticator;
54  import com.liferay.portal.service.UserLocalServiceUtil;
55  import com.liferay.portal.struts.LastPath;
56  import com.liferay.portal.theme.ThemeDisplay;
57  import com.liferay.portal.util.CookieKeys;
58  import com.liferay.portal.util.PortalUtil;
59  import com.liferay.portal.util.PropsValues;
60  import com.liferay.portal.util.WebKeys;
61  import com.liferay.util.Encryptor;
62  import com.liferay.util.servlet.SessionParameters;
63  
64  import java.util.ArrayList;
65  import java.util.Enumeration;
66  import java.util.HashMap;
67  import java.util.List;
68  import java.util.Map;
69  
70  import javax.servlet.http.Cookie;
71  import javax.servlet.http.HttpServletRequest;
72  import javax.servlet.http.HttpServletResponse;
73  import javax.servlet.http.HttpSession;
74  
75  import org.apache.struts.action.Action;
76  import org.apache.struts.action.ActionForm;
77  import org.apache.struts.action.ActionForward;
78  import org.apache.struts.action.ActionMapping;
79  
80  /**
81   * <a href="LoginAction.java.html"><b><i>View Source</i></b></a>
82   *
83   * @author Brian Wing Shun Chan
84   * @author Scott Lee
85   *
86   */
87  public class LoginAction extends Action {
88  
89      public static String getLogin(
90              HttpServletRequest request, String paramName, Company company)
91          throws PortalException, SystemException {
92  
93          String login = request.getParameter(paramName);
94  
95          if ((login == null) || (login.equals(StringPool.NULL))) {
96              login = GetterUtil.getString(
97                  CookieKeys.getCookie(request, CookieKeys.LOGIN));
98  
99              if (PropsValues.COMPANY_LOGIN_PREPOPULATE_DOMAIN &&
100                 Validator.isNull(login) &&
101                 company.getAuthType().equals(CompanyConstants.AUTH_TYPE_EA)) {
102 
103                 login = "@" + company.getMx();
104             }
105         }
106 
107         return login;
108     }
109 
110     public static void login(
111             HttpServletRequest request, HttpServletResponse response,
112             String login, String password, boolean rememberMe)
113         throws Exception {
114 
115         CookieKeys.validateSupportCookie(request);
116 
117         HttpSession session = request.getSession();
118 
119         long userId = GetterUtil.getLong(login);
120 
121         int authResult = Authenticator.FAILURE;
122 
123         Company company = PortalUtil.getCompany(request);
124 
125         Map<String, String[]> headerMap = new HashMap<String, String[]>();
126 
127         Enumeration<String> enu1 = request.getHeaderNames();
128 
129         while (enu1.hasMoreElements()) {
130             String name = enu1.nextElement();
131 
132             Enumeration<String> enu2 = request.getHeaders(name);
133 
134             List<String> headers = new ArrayList<String>();
135 
136             while (enu2.hasMoreElements()) {
137                 String value = enu2.nextElement();
138 
139                 headers.add(value);
140             }
141 
142             headerMap.put(name, headers.toArray(new String[headers.size()]));
143         }
144 
145         Map<String, String[]> parameterMap = request.getParameterMap();
146 
147         if (company.getAuthType().equals(CompanyConstants.AUTH_TYPE_EA)) {
148             authResult = UserLocalServiceUtil.authenticateByEmailAddress(
149                 company.getCompanyId(), login, password, headerMap,
150                 parameterMap);
151 
152             userId = UserLocalServiceUtil.getUserIdByEmailAddress(
153                 company.getCompanyId(), login);
154         }
155         else if (company.getAuthType().equals(CompanyConstants.AUTH_TYPE_SN)) {
156             authResult = UserLocalServiceUtil.authenticateByScreenName(
157                 company.getCompanyId(), login, password, headerMap,
158                 parameterMap);
159 
160             userId = UserLocalServiceUtil.getUserIdByScreenName(
161                 company.getCompanyId(), login);
162         }
163         else if (company.getAuthType().equals(CompanyConstants.AUTH_TYPE_ID)) {
164             authResult = UserLocalServiceUtil.authenticateByUserId(
165                 company.getCompanyId(), userId, password, headerMap,
166                 parameterMap);
167         }
168 
169         if (authResult == Authenticator.SUCCESS) {
170             if (PropsValues.SESSION_ENABLE_PHISHING_PROTECTION) {
171 
172                 // Invalidate the previous session to prevent phishing
173 
174                 Boolean httpsInitial = (Boolean)session.getAttribute(
175                     WebKeys.HTTPS_INITIAL);
176 
177                 LastPath lastPath = (LastPath)session.getAttribute(
178                     WebKeys.LAST_PATH);
179 
180                 try {
181                     session.invalidate();
182                 }
183                 catch (IllegalStateException ise) {
184 
185                     // This only happens in Geronimo
186 
187                     if (_log.isWarnEnabled()) {
188                         _log.warn(ise.getMessage());
189                     }
190                 }
191 
192                 session = request.getSession(true);
193 
194                 if (httpsInitial != null) {
195                     session.setAttribute(WebKeys.HTTPS_INITIAL, httpsInitial);
196                 }
197 
198                 if (lastPath != null) {
199                     session.setAttribute(WebKeys.LAST_PATH, lastPath);
200                 }
201             }
202 
203             // Set cookies
204 
205             String domain = CookieKeys.getDomain(request);
206 
207             User user = UserLocalServiceUtil.getUserById(userId);
208 
209             String userIdString = String.valueOf(userId);
210 
211             session.setAttribute("j_username", userIdString);
212             session.setAttribute("j_password", user.getPassword());
213             session.setAttribute("j_remoteuser", userIdString);
214 
215             session.setAttribute(WebKeys.USER_PASSWORD, password);
216 
217             Cookie companyIdCookie = new Cookie(
218                 CookieKeys.COMPANY_ID, String.valueOf(company.getCompanyId()));
219 
220             if (Validator.isNotNull(domain)) {
221                 companyIdCookie.setDomain(domain);
222             }
223 
224             companyIdCookie.setPath(StringPool.SLASH);
225 
226             Cookie idCookie = new Cookie(
227                 CookieKeys.ID,
228                 UserLocalServiceUtil.encryptUserId(userIdString));
229 
230             if (Validator.isNotNull(domain)) {
231                 idCookie.setDomain(domain);
232             }
233 
234             idCookie.setPath(StringPool.SLASH);
235 
236             Cookie passwordCookie = new Cookie(
237                 CookieKeys.PASSWORD,
238                 Encryptor.encrypt(company.getKeyObj(), password));
239 
240             if (Validator.isNotNull(domain)) {
241                 passwordCookie.setDomain(domain);
242             }
243 
244             passwordCookie.setPath(StringPool.SLASH);
245 
246             Cookie rememberMeCookie = new Cookie(
247                 CookieKeys.REMEMBER_ME, Boolean.TRUE.toString());
248 
249             if (Validator.isNotNull(domain)) {
250                 rememberMeCookie.setDomain(domain);
251             }
252 
253             rememberMeCookie.setPath(StringPool.SLASH);
254 
255             int loginMaxAge = PropsValues.COMPANY_SECURITY_AUTO_LOGIN_MAX_AGE;
256 
257             if (PropsValues.SESSION_DISABLED) {
258                 rememberMe = true;
259             }
260 
261             if (rememberMe) {
262                 companyIdCookie.setMaxAge(loginMaxAge);
263                 idCookie.setMaxAge(loginMaxAge);
264                 passwordCookie.setMaxAge(loginMaxAge);
265                 rememberMeCookie.setMaxAge(loginMaxAge);
266             }
267             else {
268 
269                 // This was explicitly changed from 0 to -1 so that the cookie
270                 // lasts as long as the browser. This allows an external servlet
271                 // wrapped in AutoLoginFilter to work throughout the client
272                 // connection. The cookies ARE removed on an actual logout, so
273                 // there is no security issue. See LEP-4678 and LEP-5177.
274 
275                 companyIdCookie.setMaxAge(-1);
276                 idCookie.setMaxAge(-1);
277                 passwordCookie.setMaxAge(-1);
278                 rememberMeCookie.setMaxAge(0);
279             }
280 
281             Cookie loginCookie = new Cookie(CookieKeys.LOGIN, login);
282 
283             if (Validator.isNotNull(domain)) {
284                 loginCookie.setDomain(domain);
285             }
286 
287             loginCookie.setMaxAge(loginMaxAge);
288             loginCookie.setPath(StringPool.SLASH);
289 
290             Cookie screenNameCookie = new Cookie(
291                 CookieKeys.SCREEN_NAME,
292                 Encryptor.encrypt(company.getKeyObj(), user.getScreenName()));
293 
294             if (Validator.isNotNull(domain)) {
295                 screenNameCookie.setDomain(domain);
296             }
297 
298             screenNameCookie.setMaxAge(loginMaxAge);
299             screenNameCookie.setPath(StringPool.SLASH);
300 
301             boolean secure = request.isSecure();
302 
303             if (secure) {
304                 Boolean httpsInitial = (Boolean)session.getAttribute(
305                     WebKeys.HTTPS_INITIAL);
306 
307                 if ((httpsInitial == null) || !httpsInitial.booleanValue()) {
308                     secure = false;
309                 }
310             }
311 
312             CookieKeys.addCookie(request, response, companyIdCookie, secure);
313             CookieKeys.addCookie(request, response, idCookie, secure);
314             CookieKeys.addCookie(request, response, passwordCookie, secure);
315             CookieKeys.addCookie(request, response, rememberMeCookie, secure);
316             CookieKeys.addCookie(request, response, loginCookie, secure);
317             CookieKeys.addCookie(request, response, screenNameCookie, secure);
318         }
319         else {
320             throw new AuthException();
321         }
322     }
323 
324     public static void sendPassword(HttpServletRequest request)
325         throws Exception {
326 
327         ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
328             WebKeys.THEME_DISPLAY);
329 
330         Company company = themeDisplay.getCompany();
331 
332         if (!company.isSendPassword()) {
333             return;
334         }
335 
336         String emailAddress = ParamUtil.getString(request, "emailAddress");
337 
338         String remoteAddr = request.getRemoteAddr();
339         String remoteHost = request.getRemoteHost();
340         String userAgent = request.getHeader(HttpHeaders.USER_AGENT);
341 
342         UserLocalServiceUtil.sendPassword(
343             PortalUtil.getCompanyId(request), emailAddress, remoteAddr,
344             remoteHost, userAgent);
345     }
346 
347     public ActionForward execute(
348             ActionMapping mapping, ActionForm form, HttpServletRequest request,
349             HttpServletResponse response)
350         throws Exception {
351 
352         if (PropsValues.COMPANY_SECURITY_AUTH_REQUIRES_HTTPS &&
353             !request.isSecure()) {
354 
355             ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
356                 WebKeys.THEME_DISPLAY);
357 
358             StringBuilder sb = new StringBuilder();
359 
360             sb.append(PortalUtil.getPortalURL(request, true));
361             sb.append(themeDisplay.getURLSignIn());
362 
363             response.sendRedirect(sb.toString());
364 
365             return null;
366         }
367 
368         HttpSession session = request.getSession();
369 
370         ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
371             WebKeys.THEME_DISPLAY);
372 
373         if (session.getAttribute("j_username") != null &&
374             session.getAttribute("j_password") != null) {
375 
376             if (PropsValues.PORTAL_JAAS_ENABLE) {
377                 return mapping.findForward("/portal/touch_protected.jsp");
378             }
379             else {
380                 response.sendRedirect(themeDisplay.getPathMain());
381 
382                 return null;
383             }
384         }
385 
386         String cmd = ParamUtil.getString(request, Constants.CMD);
387 
388         if (cmd.equals("already-registered")) {
389             try {
390                 login(request, response);
391 
392                 if (PropsValues.PORTAL_JAAS_ENABLE) {
393                     return mapping.findForward("/portal/touch_protected.jsp");
394                 }
395                 else {
396                     String redirect = ParamUtil.getString(request, "redirect");
397 
398                     if (Validator.isNotNull(redirect)) {
399                         response.sendRedirect(redirect);
400                     }
401                     else {
402                         response.sendRedirect(themeDisplay.getPathMain());
403                     }
404 
405                     return null;
406                 }
407             }
408             catch (Exception e) {
409                 if (e instanceof AuthException) {
410                     Throwable cause = e.getCause();
411 
412                     if (cause instanceof PasswordExpiredException ||
413                         cause instanceof UserLockoutException) {
414 
415                         SessionErrors.add(request, cause.getClass().getName());
416                     }
417                     else {
418                         SessionErrors.add(request, e.getClass().getName());
419                     }
420 
421                     return mapping.findForward("portal.login");
422                 }
423                 else if (e instanceof CookieNotSupportedException ||
424                          e instanceof NoSuchUserException ||
425                          e instanceof PasswordExpiredException ||
426                          e instanceof UserEmailAddressException ||
427                          e instanceof UserIdException ||
428                          e instanceof UserLockoutException ||
429                          e instanceof UserPasswordException ||
430                          e instanceof UserScreenNameException) {
431 
432                     SessionErrors.add(request, e.getClass().getName());
433 
434                     return mapping.findForward("portal.login");
435                 }
436                 else {
437                     PortalUtil.sendError(e, request, response);
438 
439                     return null;
440                 }
441             }
442         }
443         else if (cmd.equals("forgot-password")) {
444             try {
445                 if (PropsValues.CAPTCHA_CHECK_PORTAL_SEND_PASSWORD) {
446                     CaptchaUtil.check(request);
447                 }
448 
449                 sendPassword(request);
450 
451                 SessionMessages.add(request, "request_processed");
452 
453                 return mapping.findForward("portal.login");
454             }
455             catch (Exception e) {
456                 if (e instanceof CaptchaTextException ||
457                     e instanceof NoSuchUserException ||
458                     e instanceof SendPasswordException ||
459                     e instanceof UserEmailAddressException) {
460 
461                     SessionErrors.add(request, e.getClass().getName());
462 
463                     return mapping.findForward("portal.login");
464                 }
465                 else {
466                     PortalUtil.sendError(e, request, response);
467 
468                     return null;
469                 }
470             }
471         }
472         else {
473             String redirect = PortalUtil.getCommunityLoginURL(themeDisplay);
474 
475             if (Validator.isNull(redirect)) {
476                 redirect = PropsValues.AUTH_LOGIN_URL;
477             }
478 
479             String loginRedirect = ParamUtil.getString(request, "redirect");
480 
481             if (Validator.isNotNull(loginRedirect)) {
482                 String loginPortletNamespace = PortalUtil.getPortletNamespace(
483                     PropsValues.AUTH_LOGIN_PORTLET_NAME);
484 
485                 String loginRedirectParameter = loginPortletNamespace +
486                     "redirect";
487 
488                 redirect = HttpUtil.setParameter(
489                     redirect, "p_p_id", PropsValues.AUTH_LOGIN_PORTLET_NAME);
490                 redirect = HttpUtil.setParameter(
491                     redirect, "p_p_lifecycle", "0");
492                 redirect = HttpUtil.setParameter(
493                     redirect, loginRedirectParameter, loginRedirect);
494             }
495 
496             if (Validator.isNotNull(redirect)) {
497                 response.sendRedirect(redirect);
498 
499                 return null;
500             }
501             else {
502                 return mapping.findForward("portal.login");
503             }
504         }
505     }
506 
507     protected void login(
508             HttpServletRequest request, HttpServletResponse response)
509         throws Exception {
510 
511         String login = ParamUtil.getString(request, "login").toLowerCase();
512         String password = ParamUtil.getString(
513             request, SessionParameters.get(request, "password"));
514         boolean rememberMe = ParamUtil.getBoolean(request, "rememberMe");
515 
516         login(request, response, login, password, rememberMe);
517     }
518 
519     private static Log _log = LogFactoryUtil.getLog(LoginAction.class);
520 
521 }