001: /**
002: * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
003: *
004: * Permission is hereby granted, free of charge, to any person obtaining a copy
005: * of this software and associated documentation files (the "Software"), to deal
006: * in the Software without restriction, including without limitation the rights
007: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
008: * copies of the Software, and to permit persons to whom the Software is
009: * furnished to do so, subject to the following conditions:
010: *
011: * The above copyright notice and this permission notice shall be included in
012: * all copies or substantial portions of the Software.
013: *
014: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
015: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
016: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
017: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
018: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
019: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
020: * SOFTWARE.
021: */package com.liferay.portal.action;
022:
023: import com.liferay.portal.CookieNotSupportedException;
024: import com.liferay.portal.NoSuchUserException;
025: import com.liferay.portal.PasswordExpiredException;
026: import com.liferay.portal.PortalException;
027: import com.liferay.portal.SendPasswordException;
028: import com.liferay.portal.SystemException;
029: import com.liferay.portal.UserEmailAddressException;
030: import com.liferay.portal.UserIdException;
031: import com.liferay.portal.UserLockoutException;
032: import com.liferay.portal.UserPasswordException;
033: import com.liferay.portal.UserScreenNameException;
034: import com.liferay.portal.captcha.CaptchaTextException;
035: import com.liferay.portal.captcha.CaptchaUtil;
036: import com.liferay.portal.kernel.servlet.HttpHeaders;
037: import com.liferay.portal.kernel.util.Constants;
038: import com.liferay.portal.kernel.util.GetterUtil;
039: import com.liferay.portal.kernel.util.ParamUtil;
040: import com.liferay.portal.kernel.util.StringMaker;
041: import com.liferay.portal.kernel.util.StringPool;
042: import com.liferay.portal.kernel.util.Validator;
043: import com.liferay.portal.model.Company;
044: import com.liferay.portal.model.User;
045: import com.liferay.portal.model.impl.CompanyImpl;
046: import com.liferay.portal.security.auth.AuthException;
047: import com.liferay.portal.security.auth.Authenticator;
048: import com.liferay.portal.service.UserLocalServiceUtil;
049: import com.liferay.portal.struts.ActionConstants;
050: import com.liferay.portal.struts.LastPath;
051: import com.liferay.portal.theme.ThemeDisplay;
052: import com.liferay.portal.util.CookieKeys;
053: import com.liferay.portal.util.PortalUtil;
054: import com.liferay.portal.util.PropsValues;
055: import com.liferay.portal.util.WebKeys;
056: import com.liferay.util.Encryptor;
057: import com.liferay.util.servlet.SessionErrors;
058: import com.liferay.util.servlet.SessionMessages;
059: import com.liferay.util.servlet.SessionParameters;
060:
061: import java.util.ArrayList;
062: import java.util.Enumeration;
063: import java.util.HashMap;
064: import java.util.List;
065: import java.util.Map;
066:
067: import javax.servlet.http.Cookie;
068: import javax.servlet.http.HttpServletRequest;
069: import javax.servlet.http.HttpServletResponse;
070: import javax.servlet.http.HttpSession;
071: import javax.servlet.jsp.PageContext;
072:
073: import org.apache.commons.logging.Log;
074: import org.apache.commons.logging.LogFactory;
075: import org.apache.struts.action.Action;
076: import org.apache.struts.action.ActionForm;
077: import org.apache.struts.action.ActionForward;
078: import org.apache.struts.action.ActionMapping;
079:
080: /**
081: * <a href="LoginAction.java.html"><b><i>View Source</i></b></a>
082: *
083: * @author Brian Wing Shun Chan
084: * @author Scott Lee
085: *
086: */
087: public class LoginAction extends Action {
088:
089: public static String getLogin(HttpServletRequest req,
090: String paramName, Company company) throws PortalException,
091: SystemException {
092:
093: String login = req.getParameter(paramName);
094:
095: if ((login == null) || (login.equals(StringPool.NULL))) {
096: login = GetterUtil.getString(CookieKeys.getCookie(req,
097: CookieKeys.LOGIN));
098:
099: if (Validator.isNull(login)
100: && company.getAuthType().equals(
101: CompanyImpl.AUTH_TYPE_EA)) {
102:
103: login = "@" + company.getMx();
104: }
105: }
106:
107: return login;
108: }
109:
110: public static void login(HttpServletRequest req,
111: HttpServletResponse res, String login, String password,
112: boolean rememberMe) throws Exception {
113:
114: CookieKeys.validateSupportCookie(req);
115:
116: HttpSession ses = req.getSession();
117:
118: long userId = GetterUtil.getLong(login);
119:
120: int authResult = Authenticator.FAILURE;
121:
122: Company company = PortalUtil.getCompany(req);
123:
124: Map headerMap = new HashMap();
125:
126: Enumeration enu1 = req.getHeaderNames();
127:
128: while (enu1.hasMoreElements()) {
129: String name = (String) enu1.nextElement();
130:
131: Enumeration enu2 = req.getHeaders(name);
132:
133: List headers = new ArrayList();
134:
135: while (enu2.hasMoreElements()) {
136: String value = (String) enu2.nextElement();
137:
138: headers.add(value);
139: }
140:
141: headerMap.put(name, (String[]) headers
142: .toArray(new String[0]));
143: }
144:
145: Map parameterMap = req.getParameterMap();
146:
147: if (company.getAuthType().equals(CompanyImpl.AUTH_TYPE_EA)) {
148: authResult = UserLocalServiceUtil
149: .authenticateByEmailAddress(company.getCompanyId(),
150: login, password, headerMap, parameterMap);
151:
152: userId = UserLocalServiceUtil.getUserIdByEmailAddress(
153: company.getCompanyId(), login);
154: } else if (company.getAuthType().equals(
155: CompanyImpl.AUTH_TYPE_SN)) {
156: authResult = UserLocalServiceUtil.authenticateByScreenName(
157: company.getCompanyId(), login, password, headerMap,
158: parameterMap);
159:
160: userId = UserLocalServiceUtil.getUserIdByScreenName(company
161: .getCompanyId(), login);
162: } else if (company.getAuthType().equals(
163: CompanyImpl.AUTH_TYPE_ID)) {
164: authResult = UserLocalServiceUtil.authenticateByUserId(
165: company.getCompanyId(), userId, password,
166: headerMap, 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) ses
175: .getAttribute(WebKeys.HTTPS_INITIAL);
176:
177: LastPath lastPath = (LastPath) ses
178: .getAttribute(WebKeys.LAST_PATH);
179:
180: try {
181: ses.invalidate();
182: } catch (IllegalStateException ise) {
183:
184: // This only happens in Geronimo
185:
186: if (_log.isWarnEnabled()) {
187: _log.warn(ise.getMessage());
188: }
189: }
190:
191: ses = req.getSession(true);
192:
193: if (httpsInitial != null) {
194: ses.setAttribute(WebKeys.HTTPS_INITIAL,
195: httpsInitial);
196: }
197:
198: if (lastPath != null) {
199: ses.setAttribute(WebKeys.LAST_PATH, lastPath);
200: }
201: }
202:
203: // Set cookies
204:
205: String domain = CookieKeys.getDomain(req);
206:
207: User user = UserLocalServiceUtil.getUserById(userId);
208:
209: String userIdString = String.valueOf(userId);
210:
211: ses.setAttribute("j_username", userIdString);
212: ses.setAttribute("j_password", user.getPassword());
213: ses.setAttribute("j_remoteuser", userIdString);
214:
215: ses.setAttribute(WebKeys.USER_PASSWORD, password);
216:
217: Cookie companyIdCookie = new Cookie(CookieKeys.COMPANY_ID,
218: 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(CookieKeys.ID,
227: UserLocalServiceUtil.encryptUserId(userIdString));
228:
229: if (Validator.isNotNull(domain)) {
230: idCookie.setDomain(domain);
231: }
232:
233: idCookie.setPath(StringPool.SLASH);
234:
235: Cookie passwordCookie = new Cookie(CookieKeys.PASSWORD,
236: Encryptor.encrypt(company.getKeyObj(), password));
237:
238: if (Validator.isNotNull(domain)) {
239: passwordCookie.setDomain(domain);
240: }
241:
242: passwordCookie.setPath(StringPool.SLASH);
243:
244: Cookie rememberMeCookie = new Cookie(
245: CookieKeys.REMEMBER_ME, Boolean.TRUE.toString());
246:
247: if (Validator.isNotNull(domain)) {
248: rememberMeCookie.setDomain(domain);
249: }
250:
251: rememberMeCookie.setPath(StringPool.SLASH);
252:
253: int loginMaxAge = PropsValues.COMPANY_SECURITY_AUTO_LOGIN_MAX_AGE;
254:
255: if (PropsValues.SESSION_DISABLED) {
256: rememberMe = true;
257: }
258:
259: if (rememberMe) {
260: companyIdCookie.setMaxAge(loginMaxAge);
261: idCookie.setMaxAge(loginMaxAge);
262: passwordCookie.setMaxAge(loginMaxAge);
263: rememberMeCookie.setMaxAge(loginMaxAge);
264: } else {
265:
266: // This was explicitly changed from 0 to -1 so that the cookie
267: // lasts as long as the browser. This allows an external servlet
268: // wrapped in AutoLoginFilter to work throughout the client
269: // connection. The cookies ARE removed on an actual logout, so
270: // there is no security issue. See LEP-4678 and LEP-5177.
271:
272: companyIdCookie.setMaxAge(-1);
273: idCookie.setMaxAge(-1);
274: passwordCookie.setMaxAge(-1);
275: rememberMeCookie.setMaxAge(0);
276: }
277:
278: Cookie loginCookie = new Cookie(CookieKeys.LOGIN, login);
279:
280: if (Validator.isNotNull(domain)) {
281: loginCookie.setDomain(domain);
282: }
283:
284: loginCookie.setMaxAge(loginMaxAge);
285: loginCookie.setPath(StringPool.SLASH);
286:
287: Cookie screenNameCookie = new Cookie(
288: CookieKeys.SCREEN_NAME, Encryptor.encrypt(company
289: .getKeyObj(), user.getScreenName()));
290:
291: if (Validator.isNotNull(domain)) {
292: screenNameCookie.setDomain(domain);
293: }
294:
295: screenNameCookie.setMaxAge(loginMaxAge);
296: screenNameCookie.setPath(StringPool.SLASH);
297:
298: CookieKeys.addCookie(res, companyIdCookie);
299: CookieKeys.addCookie(res, idCookie);
300: CookieKeys.addCookie(res, passwordCookie);
301: CookieKeys.addCookie(res, loginCookie);
302: CookieKeys.addCookie(res, screenNameCookie);
303: } else {
304: throw new AuthException();
305: }
306: }
307:
308: public ActionForward execute(ActionMapping mapping,
309: ActionForm form, HttpServletRequest req,
310: HttpServletResponse res) throws Exception {
311:
312: if (PropsValues.COMPANY_SECURITY_AUTH_REQUIRES_HTTPS
313: && !req.isSecure()) {
314:
315: ThemeDisplay themeDisplay = (ThemeDisplay) req
316: .getAttribute(WebKeys.THEME_DISPLAY);
317:
318: StringMaker sm = new StringMaker();
319:
320: sm.append(PortalUtil.getPortalURL(req, true));
321: sm.append(themeDisplay.getURLSignIn());
322:
323: res.sendRedirect(sm.toString());
324:
325: return null;
326: }
327:
328: HttpSession ses = req.getSession();
329:
330: ThemeDisplay themeDisplay = (ThemeDisplay) req
331: .getAttribute(WebKeys.THEME_DISPLAY);
332:
333: if (ses.getAttribute("j_username") != null
334: && ses.getAttribute("j_password") != null) {
335:
336: if (PropsValues.PORTAL_JAAS_ENABLE) {
337: return mapping
338: .findForward("/portal/touch_protected.jsp");
339: } else {
340: res.sendRedirect(themeDisplay.getPathMain());
341:
342: return null;
343: }
344: }
345:
346: String cmd = ParamUtil.getString(req, Constants.CMD);
347:
348: if (cmd.equals("already-registered")) {
349: try {
350: login(req, res);
351:
352: if (PropsValues.PORTAL_JAAS_ENABLE) {
353: return mapping
354: .findForward("/portal/touch_protected.jsp");
355: } else {
356: String redirect = ParamUtil.getString(req,
357: "redirect");
358:
359: if (Validator.isNotNull(redirect)) {
360: res.sendRedirect(redirect);
361: } else {
362: res.sendRedirect(themeDisplay.getPathMain());
363: }
364:
365: return null;
366: }
367: } catch (Exception e) {
368: if (e instanceof AuthException) {
369: Throwable cause = e.getCause();
370:
371: if (cause instanceof PasswordExpiredException
372: || cause instanceof UserLockoutException) {
373:
374: SessionErrors.add(req, cause.getClass()
375: .getName());
376: } else {
377: SessionErrors.add(req, e.getClass().getName());
378: }
379:
380: return mapping.findForward("portal.login");
381: } else if (e instanceof CookieNotSupportedException
382: || e instanceof NoSuchUserException
383: || e instanceof PasswordExpiredException
384: || e instanceof UserEmailAddressException
385: || e instanceof UserIdException
386: || e instanceof UserLockoutException
387: || e instanceof UserPasswordException
388: || e instanceof UserScreenNameException) {
389:
390: SessionErrors.add(req, e.getClass().getName());
391:
392: return mapping.findForward("portal.login");
393: } else {
394: req.setAttribute(PageContext.EXCEPTION, e);
395:
396: return mapping
397: .findForward(ActionConstants.COMMON_ERROR);
398: }
399: }
400: } else if (cmd.equals("forgot-password")) {
401: try {
402: sendPassword(req);
403:
404: return mapping.findForward("portal.login");
405: } catch (Exception e) {
406: if (e instanceof CaptchaTextException
407: || e instanceof NoSuchUserException
408: || e instanceof SendPasswordException
409: || e instanceof UserEmailAddressException) {
410:
411: SessionErrors.add(req, e.getClass().getName());
412:
413: return mapping.findForward("portal.login");
414: } else {
415: req.setAttribute(PageContext.EXCEPTION, e);
416:
417: return mapping
418: .findForward(ActionConstants.COMMON_ERROR);
419: }
420: }
421: } else {
422: return mapping.findForward("portal.login");
423: }
424: }
425:
426: protected void login(HttpServletRequest req, HttpServletResponse res)
427: throws Exception {
428:
429: String login = ParamUtil.getString(req, "login").toLowerCase();
430: String password = ParamUtil.getString(req, SessionParameters
431: .get(req, "password"));
432: boolean rememberMe = ParamUtil.getBoolean(req, "rememberMe");
433:
434: login(req, res, login, password, rememberMe);
435: }
436:
437: protected void sendPassword(HttpServletRequest req)
438: throws Exception {
439: ThemeDisplay themeDisplay = (ThemeDisplay) req
440: .getAttribute(WebKeys.THEME_DISPLAY);
441:
442: Company company = themeDisplay.getCompany();
443:
444: if (!company.isSendPassword()) {
445: return;
446: }
447:
448: CaptchaUtil.check(req);
449:
450: String emailAddress = ParamUtil.getString(req, "emailAddress");
451:
452: String remoteAddr = req.getRemoteAddr();
453: String remoteHost = req.getRemoteHost();
454: String userAgent = req.getHeader(HttpHeaders.USER_AGENT);
455:
456: UserLocalServiceUtil.sendPassword(PortalUtil.getCompanyId(req),
457: emailAddress, remoteAddr, remoteHost, userAgent);
458:
459: SessionMessages.add(req, "request_processed", emailAddress);
460: }
461:
462: private static Log _log = LogFactory.getLog(LoginAction.class);
463:
464: }
|