001    /**
002     * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
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.service.UserLocalServiceUtil;
033    import com.liferay.portal.struts.PortletAction;
034    import com.liferay.portal.theme.ThemeDisplay;
035    import com.liferay.portal.util.PortalUtil;
036    import com.liferay.portal.util.PropsValues;
037    import com.liferay.portal.util.WebKeys;
038    import com.liferay.portlet.login.util.LoginUtil;
039    
040    import javax.portlet.ActionRequest;
041    import javax.portlet.ActionResponse;
042    import javax.portlet.PortletConfig;
043    import javax.portlet.PortletPreferences;
044    import javax.portlet.PortletSession;
045    import javax.portlet.RenderRequest;
046    import javax.portlet.RenderResponse;
047    
048    import org.apache.struts.action.ActionForm;
049    import org.apache.struts.action.ActionForward;
050    import org.apache.struts.action.ActionMapping;
051    
052    /**
053     * @author Brian Wing Shun Chan
054     * @author Tibor Kovacs
055     */
056    public class ForgotPasswordAction extends PortletAction {
057    
058            @Override
059            public void processAction(
060                            ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
061                            ActionRequest actionRequest, ActionResponse actionResponse)
062                    throws Exception {
063    
064                    try {
065                            if (PropsValues.USERS_REMINDER_QUERIES_ENABLED) {
066                                    checkReminderQueries(actionRequest, actionResponse);
067                            }
068                            else {
069                                    checkCaptcha(actionRequest);
070    
071                                    sendPassword(actionRequest, actionResponse);
072                            }
073                    }
074                    catch (Exception e) {
075                            if (e instanceof CaptchaTextException ||
076                                    e instanceof NoSuchUserException ||
077                                    e instanceof RequiredReminderQueryException ||
078                                    e instanceof SendPasswordException ||
079                                    e instanceof UserActiveException ||
080                                    e instanceof UserEmailAddressException ||
081                                    e instanceof UserReminderQueryException) {
082    
083                                    SessionErrors.add(actionRequest, e.getClass().getName());
084                            }
085                            else {
086                                    PortalUtil.sendError(e, actionRequest, actionResponse);
087                            }
088                    }
089            }
090    
091            @Override
092            public ActionForward render(
093                            ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
094                            RenderRequest renderRequest, RenderResponse renderResponse)
095                    throws Exception {
096    
097                    ThemeDisplay themeDisplay = (ThemeDisplay)renderRequest.getAttribute(
098                            WebKeys.THEME_DISPLAY);
099    
100                    renderResponse.setTitle(themeDisplay.translate("forgot-password"));
101    
102                    return mapping.findForward("portlet.login.forgot_password");
103            }
104    
105            protected void checkCaptcha(ActionRequest actionRequest)
106                    throws CaptchaException {
107    
108                    if (PropsValues.CAPTCHA_CHECK_PORTAL_SEND_PASSWORD) {
109                            CaptchaUtil.check(actionRequest);
110                    }
111            }
112    
113            protected void checkReminderQueries(
114                            ActionRequest actionRequest, ActionResponse actionResponse)
115                    throws Exception {
116    
117                    PortletSession portletSession = actionRequest.getPortletSession();
118    
119                    int step = ParamUtil.getInteger(actionRequest, "step");
120    
121                    if (step == 1) {
122                            checkCaptcha(actionRequest);
123    
124                            portletSession.removeAttribute(
125                                    WebKeys.FORGOT_PASSWORD_REMINDER_ATTEMPTS);
126                            portletSession.removeAttribute(
127                                    WebKeys.FORGOT_PASSWORD_REMINDER_USER_EMAIL_ADDRESS);
128                    }
129    
130                    User user = getUser(actionRequest);
131    
132                    portletSession.setAttribute(
133                            WebKeys.FORGOT_PASSWORD_REMINDER_USER_EMAIL_ADDRESS,
134                            user.getEmailAddress());
135    
136                    actionRequest.setAttribute(WebKeys.FORGOT_PASSWORD_REMINDER_USER, user);
137    
138                    if (step == 2) {
139                            Integer reminderAttempts =
140                                    (Integer)portletSession.getAttribute(
141                                            WebKeys.FORGOT_PASSWORD_REMINDER_ATTEMPTS);
142    
143                            if (reminderAttempts == null) {
144                                    reminderAttempts = 0;
145                            }
146                            else if (reminderAttempts > 2) {
147                                    checkCaptcha(actionRequest);
148                            }
149    
150                            reminderAttempts++;
151    
152                            portletSession.setAttribute(
153                                    WebKeys.FORGOT_PASSWORD_REMINDER_ATTEMPTS, reminderAttempts);
154    
155                            sendPassword(actionRequest, actionResponse);
156                    }
157            }
158    
159            protected User getUser(ActionRequest actionRequest)
160                    throws Exception {
161    
162                    PortletSession portletSession = actionRequest.getPortletSession();
163    
164                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
165                            WebKeys.THEME_DISPLAY);
166    
167                    String sessionEmailAddress = (String)portletSession.getAttribute(
168                            WebKeys.FORGOT_PASSWORD_REMINDER_USER_EMAIL_ADDRESS);
169    
170                    User user = null;
171    
172                    if (Validator.isNotNull(sessionEmailAddress)) {
173                            user = UserLocalServiceUtil.getUserByEmailAddress(
174                                    themeDisplay.getCompanyId(), sessionEmailAddress);
175                    }
176                    else {
177                            long userId = ParamUtil.getLong(actionRequest, "userId");
178                            String screenName = ParamUtil.getString(
179                                    actionRequest, "screenName");
180                            String emailAddress = ParamUtil.getString(
181                                    actionRequest, "emailAddress");
182    
183                            if (Validator.isNotNull(emailAddress)) {
184                                    user = UserLocalServiceUtil.getUserByEmailAddress(
185                                            themeDisplay.getCompanyId(), emailAddress);
186                            }
187                            else if (Validator.isNotNull(screenName)) {
188                                    user = UserLocalServiceUtil.getUserByScreenName(
189                                            themeDisplay.getCompanyId(), screenName);
190                            }
191                            else if (userId > 0) {
192                                    user = UserLocalServiceUtil.getUserById(userId);
193                            }
194                            else {
195                                    throw new NoSuchUserException();
196                            }
197                    }
198    
199                    if (!user.isActive()) {
200                            throw new UserActiveException();
201                    }
202    
203                    return user;
204            }
205    
206            @Override
207            protected boolean isCheckMethodOnProcessAction() {
208                    return _CHECK_METHOD_ON_PROCESS_ACTION;
209            }
210    
211            protected void sendPassword(
212                            ActionRequest actionRequest, ActionResponse actionResponse)
213                    throws Exception {
214    
215                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
216                            WebKeys.THEME_DISPLAY);
217    
218                    Company company = themeDisplay.getCompany();
219    
220                    User user = getUser(actionRequest);
221    
222                    if (PropsValues.USERS_REMINDER_QUERIES_ENABLED) {
223                            if (PropsValues.USERS_REMINDER_QUERIES_REQUIRED &&
224                                    !user.hasReminderQuery()) {
225    
226                                    throw new RequiredReminderQueryException(
227                                            "No reminder query or answer is defined for user " +
228                                                    user.getUserId());
229                            }
230    
231                            String answer = ParamUtil.getString(actionRequest, "answer");
232    
233                            if (!user.getReminderQueryAnswer().equals(answer)) {
234                                    throw new UserReminderQueryException();
235                            }
236                    }
237    
238                    PortletPreferences preferences = actionRequest.getPreferences();
239    
240                    String languageId = LanguageUtil.getLanguageId(actionRequest);
241    
242                    String emailFromName = preferences.getValue("emailFromName", null);
243                    String emailFromAddress = preferences.getValue(
244                            "emailFromAddress", null);
245                    String emailToAddress = user.getEmailAddress();
246    
247                    String emailParam = "emailPasswordSent";
248    
249                    if (company.isSendPasswordResetLink()) {
250                            emailParam = "emailPasswordReset";
251                    }
252    
253                    String subject = preferences.getValue(
254                            emailParam + "Subject_" + languageId, null);
255                    String body = preferences.getValue(
256                            emailParam + "Body_" + languageId, null);
257    
258                    LoginUtil.sendPassword(
259                            actionRequest, emailFromName, emailFromAddress, emailToAddress,
260                            subject, body);
261    
262                    sendRedirect(actionRequest, actionResponse);
263            }
264    
265            private static final boolean _CHECK_METHOD_ON_PROCESS_ACTION = false;
266    
267    }