/*!
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* Copyright (c) 2002-2016 Pentaho Corporation.. All rights reserved.
*/
package org.pentaho.platform.scheduler2.email;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.platform.api.email.IEmailService;
import org.pentaho.platform.engine.core.system.PentahoSessionHolder;
import org.pentaho.platform.engine.core.system.PentahoSystem;
import org.pentaho.platform.scheduler2.messsages.Messages;
import org.pentaho.platform.util.messages.LocaleHelper;
import javax.activation.DataHandler;
import javax.mail.AuthenticationFailedException;
import javax.mail.Authenticator;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.SendFailedException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;
import javax.mail.util.ByteArrayDataSource;
import java.io.InputStream;
import java.util.Date;
import java.util.Properties;
public class Emailer {
private static final Log logger = LogFactory.getLog( Emailer.class );
private static final String MAILER = "smtpsend"; //$NON-NLS-1$
private static final String EMBEDDED_HTML = "mime-message/text/html";
private Properties props = new Properties();
private InputStream attachment = null;
private String attachmentName = null;
private String attachmentMimeType = null;
private Authenticator authenticator = null;
public Emailer() {
}
public void setTo( String to ) {
to = to.replaceAll( ";", "," );
if ( to != null && !"".equals( to ) ) {
props.put( "to", to );
}
}
public void setCc( String cc ) {
cc = cc.replaceAll( ";", "," );
if ( cc != null && !"".equals( cc ) ) {
props.put( "cc", cc );
}
}
public void setBcc( String bcc ) {
bcc = bcc.replaceAll( ";", "," );
if ( bcc != null && !"".equals( bcc ) ) {
props.put( "bcc", bcc );
}
}
public void setSubject( String subject ) {
props.put( "subject", cleanEmailField( subject ) );
}
public String getSubject() {
return props.getProperty( "subject" );
}
public void setFrom( String from ) {
props.put( "mail.from.default", from );
}
public void setFromName( String fromName ) {
props.put( "mail.from.name", fromName );
}
public void setUseAuthentication( boolean useAuthentication ) {
props.put( "mail.smtp.auth", ObjectUtils.toString( useAuthentication ) );
}
public void setSmtpHost( String smtpHost ) {
props.put( "mail.smtp.host", smtpHost );
}
public void setSmtpPort( int port ) {
props.put( "mail.smtp.port", ObjectUtils.toString( port ) );
}
public void setTransportProtocol( String protocol ) {
props.put( "mail.transport.protocol", protocol );
}
public void setUseSSL( boolean useSSL ) {
props.put( "mail.smtp.ssl", ObjectUtils.toString( useSSL ) );
}
public void setStartTLS( boolean startTLS ) {
props.put( "mail.smtp.starttls.enable", ObjectUtils.toString( startTLS ) );
}
public void setQuitWait( boolean quitWait ) {
props.put( "mail.smtp.quitwait", ObjectUtils.toString( quitWait ) );
}
public void setAttachment( InputStream attachment ) {
this.attachment = attachment;
}
public void setAttachmentName( String attachmentName ) {
this.attachmentName = attachmentName;
}
public String getAttachmentName() {
return attachmentName;
}
public void setAttachmentMimeType( String mimeType ) {
this.attachmentMimeType = mimeType;
}
public Authenticator getAuthenticator() {
return authenticator;
}
public void setAuthenticator( Authenticator authenticator ) {
this.authenticator = authenticator;
}
public void setBody( String body ) {
props.put( "body", body );
}
public boolean setup() {
try {
final IEmailService service =
PentahoSystem.get( IEmailService.class, "IEmailService", PentahoSessionHolder.getSession() );
props.put( "mail.smtp.host", service.getEmailConfig().getSmtpHost() );
props.put( "mail.smtp.port", ObjectUtils.toString( service.getEmailConfig().getSmtpPort() ) );
props.put( "mail.transport.protocol", service.getEmailConfig().getSmtpProtocol() );
props.put( "mail.smtp.starttls.enable", ObjectUtils.toString( service.getEmailConfig().isUseStartTls() ) );
props.put( "mail.smtp.auth", ObjectUtils.toString( service.getEmailConfig().isAuthenticate() ) );
props.put( "mail.smtp.ssl", ObjectUtils.toString( service.getEmailConfig().isUseSsl() ) );
props.put( "mail.smtp.quitwait", ObjectUtils.toString( service.getEmailConfig().isSmtpQuitWait() ) );
props.put( "mail.from.default", service.getEmailConfig().getDefaultFrom() );
String fromName = service.getEmailConfig().getFromName();
if ( StringUtils.isEmpty( fromName ) ) {
fromName = Messages.getInstance().getString( "schedulerEmailFromName" );
}
props.put( "mail.from.name", fromName );
props.put( "mail.debug", ObjectUtils.toString( service.getEmailConfig().isDebug() ) );
if ( service.getEmailConfig().isAuthenticate() ) {
props.put( "mail.userid", service.getEmailConfig().getUserId() );
props.put( "mail.password", service.getEmailConfig().getPassword() );
setAuthenticator( new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication( service.getEmailConfig().getUserId(), service.getEmailConfig()
.getPassword() );
}
} );
}
return true;
} catch ( Exception e ) {
logger.error( "Email.ERROR_0013_CONFIG_FILE_INVALID", e ); //$NON-NLS-1$
}
return false;
}
private String cleanEmailField( String emailField ) {
if ( emailField != null ) {
// Remove CR symbols - email header injection
emailField = emailField.replaceAll( "\r", "" );
return emailField.replaceAll( "\n", "" );
} else {
return null;
}
}
public boolean send() {
String from = props.getProperty( "mail.from.default" );
String fromName = props.getProperty( "mail.from.name" );
String to = props.getProperty( "to" );
String cc = props.getProperty( "cc" );
String bcc = props.getProperty( "bcc" );
boolean authenticate = "true".equalsIgnoreCase( props.getProperty( "mail.smtp.auth" ) );
String subject = props.getProperty( "subject" );
String body = props.getProperty( "body" );
logger.info( "Going to send an email to " + to + " from " + from + " with the subject '" + subject
+ "' and the body " + body );
try {
// Get a Session object
Session session;
if ( authenticate ) {
session = Session.getInstance( props, authenticator );
} else {
session = Session.getInstance( props );
}
// if debugging is not set in the email config file, then default to false
if ( !props.containsKey( "mail.debug" ) ) { //$NON-NLS-1$
session.setDebug( false );
}
final MimeMessage msg;
if ( EMBEDDED_HTML.equals( attachmentMimeType ) ) {
//Message is ready
msg = new MimeMessage( session, attachment );
if ( body != null ) {
//We need to add message to the top of the email body
final MimeMultipart oldMultipart = (MimeMultipart) msg.getContent();
final MimeMultipart newMultipart = new MimeMultipart( "related" );
for ( int i = 0; i < oldMultipart.getCount(); i++ ) {
BodyPart bodyPart = oldMultipart.getBodyPart( i );
final Object content = bodyPart.getContent();
//Main HTML body
if ( content instanceof String ) {
final String newContent = body + "<br/><br/>" + content;
final MimeBodyPart part = new MimeBodyPart();
part.setText( newContent, "UTF-8", "html" );
newMultipart.addBodyPart( part );
} else {
//CID attachments
newMultipart.addBodyPart( bodyPart );
}
}
msg.setContent( newMultipart );
}
} else {
// construct the message
msg = new MimeMessage( session );
Multipart multipart = new MimeMultipart();
if ( attachment == null ) {
logger.error( "Email.ERROR_0015_ATTACHMENT_FAILED" ); //$NON-NLS-1$
return false;
}
ByteArrayDataSource dataSource = new ByteArrayDataSource( attachment, attachmentMimeType );
if ( body != null ) {
MimeBodyPart bodyMessagePart = new MimeBodyPart();
bodyMessagePart.setText( body, LocaleHelper.getSystemEncoding() );
multipart.addBodyPart( bodyMessagePart );
}
// attach the file to the message
MimeBodyPart attachmentBodyPart = new MimeBodyPart();
attachmentBodyPart.setDataHandler( new DataHandler( dataSource ) );
attachmentBodyPart.setFileName( MimeUtility.encodeText( attachmentName, "UTF-8", null ) );
multipart.addBodyPart( attachmentBodyPart );
// add the Multipart to the message
msg.setContent( multipart );
}
if ( from != null ) {
msg.setFrom( new InternetAddress( from, fromName ) );
} else {
// There should be no way to get here
logger.error( "Email.ERROR_0012_FROM_NOT_DEFINED" ); //$NON-NLS-1$
}
if ( ( to != null ) && ( to.trim().length() > 0 ) ) {
msg.setRecipients( Message.RecipientType.TO, InternetAddress.parse( to, false ) );
}
if ( ( cc != null ) && ( cc.trim().length() > 0 ) ) {
msg.setRecipients( Message.RecipientType.CC, InternetAddress.parse( cc, false ) );
}
if ( ( bcc != null ) && ( bcc.trim().length() > 0 ) ) {
msg.setRecipients( Message.RecipientType.BCC, InternetAddress.parse( bcc, false ) );
}
if ( subject != null ) {
msg.setSubject( subject, LocaleHelper.getSystemEncoding() );
}
msg.setHeader( "X-Mailer", Emailer.MAILER ); //$NON-NLS-1$
msg.setSentDate( new Date() );
Transport.send( msg );
return true;
} catch ( SendFailedException e ) {
logger.error( "Email.ERROR_0011_SEND_FAILED -" + to, e ); //$NON-NLS-1$
} catch ( AuthenticationFailedException e ) {
logger.error( "Email.ERROR_0014_AUTHENTICATION_FAILED - " + to, e ); //$NON-NLS-1$
} catch ( Throwable e ) {
logger.error( "Email.ERROR_0011_SEND_FAILED - " + to, e ); //$NON-NLS-1$
}
return false;
}
}