/**
* Copyright (c) 2009--2015 Red Hat, Inc.
*
* This software is licensed to you under the GNU General Public License,
* version 2 (GPLv2). There is NO WARRANTY for this software, express or
* implied, including the implied warranties of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
* along with this software; if not, see
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
*
* Red Hat trademarks are not licensed under GPLv2. No permission is
* granted to use or replicate Red Hat trademarks that are incorporated
* in this software or its documentation.
*/
package com.redhat.rhn.frontend.action.help;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.log4j.Logger;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.action.DynaActionForm;
import com.redhat.rhn.common.conf.Config;
import com.redhat.rhn.common.conf.ConfigDefaults;
import com.redhat.rhn.common.db.ResetPasswordFactory;
import com.redhat.rhn.common.hibernate.LookupException;
import com.redhat.rhn.common.localization.LocalizationService;
import com.redhat.rhn.common.messaging.Mail;
import com.redhat.rhn.common.messaging.SmtpMail;
import com.redhat.rhn.domain.common.ResetPassword;
import com.redhat.rhn.domain.user.User;
import com.redhat.rhn.domain.user.UserFactory;
import com.redhat.rhn.frontend.struts.RequestContext;
import com.redhat.rhn.frontend.struts.RhnAction;
import com.redhat.rhn.frontend.struts.RhnHelper;
/**
* ForgotCredentialsAction
* @version $Rev$
*/
public class ForgotCredentialsAction extends RhnAction {
private static Logger log = Logger.getLogger(ForgotCredentialsAction.class);
private static final long PASSWORD_REQUEST_TIMEOUT = 60;
private static final long LOGINS_REQUEST_TIMEOUT = 300;
/** {@inheritDoc} */
@Override
public ActionForward execute(ActionMapping mapping, ActionForm formIn,
HttpServletRequest request, HttpServletResponse response) {
DynaActionForm form = (DynaActionForm)formIn;
if (!isSubmitted(form)) {
return getStrutsDelegate().forwardParams(
mapping.findForward(RhnHelper.DEFAULT_FORWARD),
request.getParameterMap());
}
ActionMessages msgs = new ActionMessages();
ActionErrors errors = new ActionErrors();
RequestContext ctx = new RequestContext(request);
Map forwardParams = makeParamMap(request);
// For saving previous request times
HttpSession session = request.getSession();
String email = form.getString("email");
String login = form.getString("username");
if (ctx.hasParam("password_button")) {
newPassword(login, email, errors, msgs, session);
}
else if (ctx.hasParam("login_button")) {
lookupLogins(email, errors, msgs, session);
}
if (!errors.isEmpty()) {
addErrors(request, errors);
return getStrutsDelegate().forwardParams(
mapping.findForward(RhnHelper.DEFAULT_FORWARD),
forwardParams);
}
saveMessages(request, msgs);
return getStrutsDelegate().forwardParams(
mapping.findForward("success"),
forwardParams);
}
private void newPassword(String login, String email,
ActionErrors errors, ActionMessages msgs, HttpSession session) {
// Check if time elapsed from last request
if (!hasTimeElapsed(session, "password", login, PASSWORD_REQUEST_TIMEOUT)) {
errors.add(ActionMessages.GLOBAL_MESSAGE,
new ActionMessage("help.credentials.rerequest",
PASSWORD_REQUEST_TIMEOUT));
return;
}
try {
User foundUser = UserFactory.lookupByLogin(login);
// Check if email and login agrees
if (foundUser.getEmail().toUpperCase().equals(
email.toUpperCase())) {
ResetPassword rp = ResetPasswordFactory.createNewEntryFor(foundUser);
String link = ResetPasswordFactory.generateLink(rp);
String emailBody = setupEmailBody("email.forgotten.password",
email, link, login);
sendEmail(email, LocalizationService.getInstance().
getMessage("help.credentials.jsp.passwordreset"), emailBody);
// Save time and login to session
saveRequestTime(session, "password", login);
msgs.add(ActionMessages.GLOBAL_MESSAGE,
new ActionMessage("help.credentials.passwordsent", email));
}
else {
errors.add(ActionMessages.GLOBAL_MESSAGE,
new ActionMessage("help.credentials.invalidemail"));
}
}
catch (LookupException e) {
errors.add(ActionMessages.GLOBAL_MESSAGE,
new ActionMessage("help.credentials.invalidlogin"));
}
}
private void lookupLogins(String email,
ActionErrors errors, ActionMessages msgs, HttpSession session) {
// Check if time elapsed from last request
if (!hasTimeElapsed(session, "logins", email, LOGINS_REQUEST_TIMEOUT)) {
errors.add(ActionMessages.GLOBAL_MESSAGE,
new ActionMessage("help.credentials.rerequest",
LOGINS_REQUEST_TIMEOUT));
return;
}
List<User> users = UserFactory.lookupByEmail(email);
if (!users.isEmpty()) {
StringBuilder logins = new StringBuilder();
for (User usr : users) {
logins.append(usr.getLogin() + "\n");
}
String emailBody = setupEmailBody("email.forgotten.logins",
email, logins.toString(), ConfigDefaults.get().getHostname());
sendEmail(email, LocalizationService.getInstance().
getMessage("help.credentials.jsp.logininfo"), emailBody);
// Save time and email to session
saveRequestTime(session, "logins", email);
msgs.add(ActionMessages.GLOBAL_MESSAGE,
new ActionMessage("help.credentials.loginssent", email));
}
else {
errors.add(ActionMessages.GLOBAL_MESSAGE,
new ActionMessage("help.credentials.nologins"));
}
}
private void sendEmail(String recipient,
String subject, String body) {
Mail mail = new SmtpMail();
mail.setHeader("X-RHN-Info",
"Requested " + subject + " for " + recipient);
mail.setRecipient(recipient);
mail.setSubject(Config.get().getString("web.product_name") +
" " + subject);
mail.setBody(body);
log.debug("Sending mail message:\n" + mail.toString());
try {
mail.send();
}
catch (Exception e) {
log.error("Exception while sending email: ");
log.error(e.getMessage(), e);
}
}
/**
* Get template, enter args there and return result.
* @param template name of template
* @param args args to be in template
* @return complete body, args in template
*/
private String setupEmailBody(String template, Object... args) {
// Build email body from template
LocalizationService ls = LocalizationService.getInstance();
String body = ls.getMessage(template, args);
return body;
}
/**
* Method for simple checking if time from last request has elapsed.
* Like it was in old perl page.
* @param session http session
* @param type string to name record in session
* @param user identification of last request author
* @param timeout time in seconds
* @return if time has elapsed
*/
private boolean hasTimeElapsed(HttpSession session, String type,
String user, long timeout) {
// Save time and request author/login
Long prevRequest = (Long) session.getAttribute(
"previous_" + type + "_request");
String prevRequestUser = (String) session.getAttribute(
"previous_" + type + "_request_user");
Long now = new Date().getTime();
// Time has not elapsed for last user
if (prevRequest != null &&
((now - prevRequest) < timeout * 1000) &&
(user.toUpperCase().equals(prevRequestUser))) {
log.debug("Unsuccesful try to request email for " + user);
return false;
}
return true;
}
/**
* Actualize record of time and user in session.
* @param session http session
* @param type string to name record in session
* @param user identification of last request author
*/
private void saveRequestTime(HttpSession session, String type,
String user) {
session.setAttribute("previous_" + type + "_request",
new Date().getTime());
session.setAttribute("previous_" + type + "_request_user",
user.toUpperCase());
}
}