edu.wisc.bnsemail.dao.SmtpBusinessEmailUpdateNotifier.java Source code

Java tutorial

Introduction

Here is the source code for edu.wisc.bnsemail.dao.SmtpBusinessEmailUpdateNotifier.java

Source

/**
 * Licensed to Jasig under one or more contributor license
 * agreements. See the NOTICE file distributed with this work
 * for additional information regarding copyright ownership.
 * Jasig 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:
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * 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 edu.wisc.bnsemail.dao;

import java.io.InputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.Security;
import java.security.cert.CertStore;
import java.security.cert.Certificate;
import java.security.cert.CollectionCertStoreParameters;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import javax.mail.Address;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMessage.RecipientType;
import javax.mail.internet.MimeMultipart;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.mail.smime.SMIMESignedGenerator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

import edu.wisc.hr.dao.bnsemail.BusinessEmailUpdateNotifier;

/**
 * 
 * @author Eric Dalquist
 * @version $Revision: 1.1 $
 */
@Service("businessEmailUpdateNotifier")
public class SmtpBusinessEmailUpdateNotifier implements InitializingBean, BusinessEmailUpdateNotifier {
    protected final Logger logger = LoggerFactory.getLogger(getClass());

    private SMIMESignedGenerator smimeSignedGenerator;

    private JavaMailSender javaMailSender;
    private Resource keystore;
    private String keystorePassword;
    private String certificateAlias;

    public void setKeystore(Resource keystore) {
        this.keystore = keystore;
    }

    public void setKeystorePassword(String keystorePassword) {
        this.keystorePassword = keystorePassword;
    }

    public void setCertificateAlias(String certificateAlias) {
        this.certificateAlias = certificateAlias;
    }

    @Autowired
    public void setJavaMailSender(JavaMailSender javaMailSender) {
        this.javaMailSender = javaMailSender;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        if (this.keystore == null) {
            this.logger.warn("No S/MIME KeyStore configured. Email update notifications will NOT be signed");
        } else {
            Security.addProvider(new BouncyCastleProvider());

            final KeyStore signingKeyStore = KeyStore.getInstance("JKS");

            final InputStream keyStoreStream = this.keystore.getInputStream();
            try {
                signingKeyStore.load(keyStoreStream, this.keystorePassword.toCharArray());
            } finally {
                IOUtils.closeQuietly(keyStoreStream);
            }

            final List<Certificate> certList = new ArrayList<Certificate>(1);
            for (final Enumeration<String> aliasesEnum = signingKeyStore.aliases(); aliasesEnum
                    .hasMoreElements();) {
                final String alias = aliasesEnum.nextElement();
                final Certificate cert = signingKeyStore.getCertificate(alias);
                if (cert != null) {
                    certList.add(cert);
                }
            }

            final PrivateKey signingKey = (PrivateKey) signingKeyStore.getKey(this.certificateAlias,
                    this.keystorePassword.toCharArray());
            final X509Certificate signingCert = (X509Certificate) signingKeyStore
                    .getCertificate(this.certificateAlias);

            // create a CertStore containing the certificates we want carried
            // in the signature
            final CertStore certsAndcrls = CertStore.getInstance("Collection",
                    new CollectionCertStoreParameters(certList), "BC");

            // create the generator for creating an smime/signed message
            smimeSignedGenerator = new SMIMESignedGenerator();

            // add a signer to the generator - this specifies we are using SHA1 and
            // adding the smime attributes above to the signed attributes that
            // will be generated as part of the signature. The encryption algorithm
            // used is taken from the key - in this RSA with PKCS1Padding
            smimeSignedGenerator.addSigner(signingKey, signingCert, SMIMESignedGenerator.DIGEST_SHA1);

            // add our pool of certs and cerls (if any) to go with the signature
            smimeSignedGenerator.addCertificatesAndCRLs(certsAndcrls);
        }
    }

    /* (non-Javadoc)
     * @see edu.wisc.bnsemail.dao.BusinessEmailUpdateNotifier#notifyEmailUpdated(java.lang.String, java.lang.String)
     */
    @Override
    public void notifyEmailUpdated(String oldAddress, String newAddress) {
        try {
            //Create the message body
            final MimeBodyPart msg = new MimeBodyPart();
            msg.setContent(
                    "Your Business Email Address has changed\n" + "\n" + "Old Email Address: " + oldAddress + "\n"
                            + "New Email Address: " + newAddress + "\n" + "\n"
                            + "If you have any questions, please contact your Human Resources department.",
                    "text/plain");

            final MimeMessage message = this.javaMailSender.createMimeMessage();
            final Address[] recipients;
            if (StringUtils.isNotEmpty(oldAddress)) {
                recipients = new Address[] { new InternetAddress(oldAddress), new InternetAddress(newAddress) };
            } else {
                recipients = new Address[] { new InternetAddress(newAddress) };
            }
            message.setRecipients(RecipientType.TO, recipients);
            message.setFrom(new InternetAddress("payroll@ohr.wisc.edu"));
            message.setSubject("Business Email Address Change");

            // sign the message body
            if (this.smimeSignedGenerator != null) {
                final MimeMultipart mm = this.smimeSignedGenerator.generate(msg, "BC");
                message.setContent(mm, mm.getContentType());
            }
            // no signing keystore configured, send the message unsigned
            else {
                message.setContent(msg.getContent(), msg.getContentType());
            }

            message.saveChanges();

            this.javaMailSender.send(message);

            this.logger.info("Sent notification of email address change from {} to {}", oldAddress, newAddress);
        } catch (Exception e) {
            this.logger.error(
                    "Failed to send notification email for change from " + oldAddress + " to " + newAddress, e);
        }
    }
}