/**
* Licensed to Apereo under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright ownership. Apereo
* licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use
* this file except in compliance with the License. You may obtain a copy of the License at the
* following location:
*
* <p>http://www.apache.org/licenses/LICENSE-2.0
*
* <p>Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apereo.portal.portlets.account;
import java.net.URL;
import java.util.Arrays;
import java.util.Locale;
import javax.annotation.Resource;
import javax.mail.internet.MimeMessage;
import org.apache.commons.lang3.StringUtils;
import org.apereo.portal.persondir.ILocalAccountPerson;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import org.stringtemplate.v4.ST;
import org.stringtemplate.v4.STGroup;
import org.stringtemplate.v4.STGroupDir;
@Component("emailPasswordResetNotificationImpl")
public class EmailPasswordResetNotificationImpl implements IPasswordResetNotification {
protected final Logger log = LoggerFactory.getLogger(getClass());
private String subjectMessageKey = "reset.your.password";
private JavaMailSender mailSender;
private MessageSource messageSource;
private String portalEmailAddress;
private String templateDir = "properties/templates";
private String templateName = "passwordReset";
/**
* Set the subject string. Note that this is the i18n key, not a raw text string. eg.
* reset.your.password
*
* @param subjectMessageKey the message key to use as a subject line. Defaults to
* "reset.your.password"
*/
public void setSubjectMessageKey(final String subjectMessageKey) {
this.subjectMessageKey = subjectMessageKey;
}
@Autowired
public void setMailSender(final JavaMailSenderImpl mailSender) {
this.mailSender = mailSender;
}
@Autowired
public void setMessageSource(final MessageSource messageSource) {
this.messageSource = messageSource;
}
@Resource(name = "portalEmailAddress")
public void setPortalEmailAddress(final String portalEmailAddress) {
this.portalEmailAddress = portalEmailAddress;
}
public void setTemplateDir(final String templateDir) {
this.templateDir = templateDir;
}
public void setTemplateName(final String templateName) {
this.templateName = templateName;
}
@Override
public void sendNotification(URL resetUrl, ILocalAccountPerson account, Locale locale) {
log.debug("Sending password reset instructions to user with url {}", resetUrl.toString());
try {
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true);
String email = (String) account.getAttributeValue(ILocalAccountPerson.ATTR_MAIL);
String subject = messageSource.getMessage(subjectMessageKey, new Object[] {}, locale);
String body = formatBody(resetUrl, account, locale);
helper.addTo(email);
helper.setText(body, true);
helper.setSubject(subject);
helper.setFrom(
portalEmailAddress,
messageSource.getMessage("portal.name", new Object[] {}, locale));
log.debug(
"Sending message to {} from {} subject {}",
email,
Arrays.toString(message.getFrom()),
message.getSubject());
this.mailSender.send(helper.getMimeMessage());
} catch (Exception e) {
log.error("Unable to send password reset email", e);
}
}
/**
* Get the body content of the email.
*
* @param resetUrl the password reset URL
* @param account the user account that has had its password reset
* @param locale the locale of the user who reset the password
* @return The message body as a string.
*/
private String formatBody(URL resetUrl, ILocalAccountPerson account, Locale locale) {
final STGroup group = new STGroupDir(templateDir, '$', '$');
final ST template = group.getInstanceOf(templateName);
String name = findDisplayNameFromLocalAccountPerson(account);
template.add("displayName", name);
template.add("url", resetUrl.toString());
return template.render();
}
/**
* Determine the name to use in the password reset email that identifies the users whose
* password has been reset.
*
* @param person the account that has had its password reset
* @return the account holders name
*/
protected String findDisplayNameFromLocalAccountPerson(ILocalAccountPerson person) {
Object name = person.getAttributeValue(ILocalAccountPerson.ATTR_DISPLAY_NAME);
if ((name instanceof String) && !StringUtils.isEmpty((String) name)) {
return (String) name;
}
// if display name is not set, just return username.
return person.getName();
}
}