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