001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.login.action;
016    
017    import com.liferay.portal.NoSuchUserException;
018    import com.liferay.portal.RequiredReminderQueryException;
019    import com.liferay.portal.SendPasswordException;
020    import com.liferay.portal.UserActiveException;
021    import com.liferay.portal.UserEmailAddressException;
022    import com.liferay.portal.UserReminderQueryException;
023    import com.liferay.portal.kernel.captcha.CaptchaException;
024    import com.liferay.portal.kernel.captcha.CaptchaTextException;
025    import com.liferay.portal.kernel.captcha.CaptchaUtil;
026    import com.liferay.portal.kernel.language.LanguageUtil;
027    import com.liferay.portal.kernel.servlet.SessionErrors;
028    import com.liferay.portal.kernel.util.ParamUtil;
029    import com.liferay.portal.kernel.util.Validator;
030    import com.liferay.portal.model.Company;
031    import com.liferay.portal.model.User;
032    import com.liferay.portal.security.auth.PrincipalException;
033    import com.liferay.portal.service.UserLocalServiceUtil;
034    import com.liferay.portal.struts.PortletAction;
035    import com.liferay.portal.theme.ThemeDisplay;
036    import com.liferay.portal.util.PortalUtil;
037    import com.liferay.portal.util.PropsValues;
038    import com.liferay.portal.util.WebKeys;
039    import com.liferay.portlet.login.util.LoginUtil;
040    
041    import javax.portlet.ActionRequest;
042    import javax.portlet.ActionResponse;
043    import javax.portlet.PortletConfig;
044    import javax.portlet.PortletPreferences;
045    import javax.portlet.PortletSession;
046    import javax.portlet.RenderRequest;
047    import javax.portlet.RenderResponse;
048    
049    import org.apache.struts.action.ActionForm;
050    import org.apache.struts.action.ActionForward;
051    import org.apache.struts.action.ActionMapping;
052    
053    /**
054     * @author Brian Wing Shun Chan
055     * @author Tibor Kovacs
056     */
057    public class ForgotPasswordAction extends PortletAction {
058    
059            @Override
060            public void processAction(
061                            ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
062                            ActionRequest actionRequest, ActionResponse actionResponse)
063                    throws Exception {
064    
065                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
066                            WebKeys.THEME_DISPLAY);
067    
068                    Company company = themeDisplay.getCompany();
069    
070                    if (!company.isSendPassword() && !company.isSendPasswordResetLink()) {
071                            throw new PrincipalException();
072                    }
073    
074                    try {
075                            if (PropsValues.USERS_REMINDER_QUERIES_ENABLED) {
076                                    checkReminderQueries(actionRequest, actionResponse);
077                            }
078                            else {
079                                    checkCaptcha(actionRequest);
080    
081                                    sendPassword(actionRequest, actionResponse);
082                            }
083                    }
084                    catch (Exception e) {
085                            if (e instanceof CaptchaTextException ||
086                                    e instanceof NoSuchUserException ||
087                                    e instanceof RequiredReminderQueryException ||
088                                    e instanceof SendPasswordException ||
089                                    e instanceof UserActiveException ||
090                                    e instanceof UserEmailAddressException ||
091                                    e instanceof UserReminderQueryException) {
092    
093                                    SessionErrors.add(actionRequest, e.getClass().getName());
094                            }
095                            else {
096                                    PortalUtil.sendError(e, actionRequest, actionResponse);
097                            }
098                    }
099            }
100    
101            @Override
102            public ActionForward render(
103                            ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
104                            RenderRequest renderRequest, RenderResponse renderResponse)
105                    throws Exception {
106    
107                    ThemeDisplay themeDisplay = (ThemeDisplay)renderRequest.getAttribute(
108                            WebKeys.THEME_DISPLAY);
109    
110                    Company company = themeDisplay.getCompany();
111    
112                    if (!company.isSendPassword() && !company.isSendPasswordResetLink()) {
113                            return mapping.findForward("portlet.login.login");
114                    }
115    
116                    renderResponse.setTitle(themeDisplay.translate("forgot-password"));
117    
118                    return mapping.findForward("portlet.login.forgot_password");
119            }
120    
121            protected void checkCaptcha(ActionRequest actionRequest)
122                    throws CaptchaException {
123    
124                    if (PropsValues.CAPTCHA_CHECK_PORTAL_SEND_PASSWORD) {
125                            CaptchaUtil.check(actionRequest);
126                    }
127            }
128    
129            protected void checkReminderQueries(
130                            ActionRequest actionRequest, ActionResponse actionResponse)
131                    throws Exception {
132    
133                    PortletSession portletSession = actionRequest.getPortletSession();
134    
135                    int step = ParamUtil.getInteger(actionRequest, "step");
136    
137                    if (step == 1) {
138                            checkCaptcha(actionRequest);
139    
140                            portletSession.removeAttribute(
141                                    WebKeys.FORGOT_PASSWORD_REMINDER_ATTEMPTS);
142                            portletSession.removeAttribute(
143                                    WebKeys.FORGOT_PASSWORD_REMINDER_USER_EMAIL_ADDRESS);
144                    }
145    
146                    User user = getUser(actionRequest);
147    
148                    portletSession.setAttribute(
149                            WebKeys.FORGOT_PASSWORD_REMINDER_USER_EMAIL_ADDRESS,
150                            user.getEmailAddress());
151    
152                    actionRequest.setAttribute(WebKeys.FORGOT_PASSWORD_REMINDER_USER, user);
153    
154                    if (step == 2) {
155                            Integer reminderAttempts =
156                                    (Integer)portletSession.getAttribute(
157                                            WebKeys.FORGOT_PASSWORD_REMINDER_ATTEMPTS);
158    
159                            if (reminderAttempts == null) {
160                                    reminderAttempts = 0;
161                            }
162                            else if (reminderAttempts > 2) {
163                                    checkCaptcha(actionRequest);
164                            }
165    
166                            reminderAttempts++;
167    
168                            portletSession.setAttribute(
169                                    WebKeys.FORGOT_PASSWORD_REMINDER_ATTEMPTS, reminderAttempts);
170    
171                            sendPassword(actionRequest, actionResponse);
172                    }
173            }
174    
175            protected User getUser(ActionRequest actionRequest)
176                    throws Exception {
177    
178                    PortletSession portletSession = actionRequest.getPortletSession();
179    
180                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
181                            WebKeys.THEME_DISPLAY);
182    
183                    String sessionEmailAddress = (String)portletSession.getAttribute(
184                            WebKeys.FORGOT_PASSWORD_REMINDER_USER_EMAIL_ADDRESS);
185    
186                    User user = null;
187    
188                    if (Validator.isNotNull(sessionEmailAddress)) {
189                            user = UserLocalServiceUtil.getUserByEmailAddress(
190                                    themeDisplay.getCompanyId(), sessionEmailAddress);
191                    }
192                    else {
193                            long userId = ParamUtil.getLong(actionRequest, "userId");
194                            String screenName = ParamUtil.getString(
195                                    actionRequest, "screenName");
196                            String emailAddress = ParamUtil.getString(
197                                    actionRequest, "emailAddress");
198    
199                            if (Validator.isNotNull(emailAddress)) {
200                                    user = UserLocalServiceUtil.getUserByEmailAddress(
201                                            themeDisplay.getCompanyId(), emailAddress);
202                            }
203                            else if (Validator.isNotNull(screenName)) {
204                                    user = UserLocalServiceUtil.getUserByScreenName(
205                                            themeDisplay.getCompanyId(), screenName);
206                            }
207                            else if (userId > 0) {
208                                    user = UserLocalServiceUtil.getUserById(userId);
209                            }
210                            else {
211                                    throw new NoSuchUserException();
212                            }
213                    }
214    
215                    if (!user.isActive()) {
216                            throw new UserActiveException();
217                    }
218    
219                    return user;
220            }
221    
222            @Override
223            protected boolean isCheckMethodOnProcessAction() {
224                    return _CHECK_METHOD_ON_PROCESS_ACTION;
225            }
226    
227            protected void sendPassword(
228                            ActionRequest actionRequest, ActionResponse actionResponse)
229                    throws Exception {
230    
231                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
232                            WebKeys.THEME_DISPLAY);
233    
234                    Company company = themeDisplay.getCompany();
235    
236                    User user = getUser(actionRequest);
237    
238                    if (PropsValues.USERS_REMINDER_QUERIES_ENABLED) {
239                            if (PropsValues.USERS_REMINDER_QUERIES_REQUIRED &&
240                                    !user.hasReminderQuery()) {
241    
242                                    throw new RequiredReminderQueryException(
243                                            "No reminder query or answer is defined for user " +
244                                                    user.getUserId());
245                            }
246    
247                            String answer = ParamUtil.getString(actionRequest, "answer");
248    
249                            if (!user.getReminderQueryAnswer().equals(answer)) {
250                                    throw new UserReminderQueryException();
251                            }
252                    }
253    
254                    PortletPreferences preferences = actionRequest.getPreferences();
255    
256                    String languageId = LanguageUtil.getLanguageId(actionRequest);
257    
258                    String emailFromName = preferences.getValue("emailFromName", null);
259                    String emailFromAddress = preferences.getValue(
260                            "emailFromAddress", null);
261                    String emailToAddress = user.getEmailAddress();
262    
263                    String emailParam = "emailPasswordSent";
264    
265                    if (company.isSendPasswordResetLink()) {
266                            emailParam = "emailPasswordReset";
267                    }
268    
269                    String subject = preferences.getValue(
270                            emailParam + "Subject_" + languageId, null);
271                    String body = preferences.getValue(
272                            emailParam + "Body_" + languageId, null);
273    
274                    LoginUtil.sendPassword(
275                            actionRequest, emailFromName, emailFromAddress, emailToAddress,
276                            subject, body);
277    
278                    sendRedirect(actionRequest, actionResponse);
279            }
280    
281            private static final boolean _CHECK_METHOD_ON_PROCESS_ACTION = false;
282    
283    }