package com.sixsq.slipstream.util; /* * +=================================================================+ * SlipStream Server (WAR) * ===== * Copyright (C) 2013 SixSq Sarl (sixsq.com) * ===== * Licensed 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. * -=================================================================- */ import com.sixsq.slipstream.exceptions.SlipStreamInternalException; import com.sixsq.slipstream.exceptions.SlipStreamRuntimeException; import com.sixsq.slipstream.persistence.ServiceConfiguration; import com.sixsq.slipstream.persistence.ServiceConfiguration.RequiredParameters; import com.sixsq.slipstream.persistence.ServiceConfigurationParameter; import javax.mail.*; import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import java.util.Date; import java.util.Properties; import java.util.logging.Logger; public class Notifier { private static Logger logger = Logger.getLogger("org.restlet"); private Notifier() { } public static boolean sendHTMLNotification(String email, String message) throws SlipStreamRuntimeException { ServiceConfiguration cfg = ServiceConfiguration.load(); try { InternetAddress address = new InternetAddress(email); return sendNotification(cfg, address, message, true); } catch (AddressException e) { throw new SlipStreamRuntimeException(e.getMessage()); } } public static boolean sendNotification(String email, String message) throws SlipStreamRuntimeException { ServiceConfiguration cfg = ServiceConfiguration.load(); return sendNotification(cfg, email, message); } public static boolean sendNotification(ServiceConfiguration cfg, String email, String message) throws SlipStreamRuntimeException { try { InternetAddress address = new InternetAddress(email); return sendNotification(cfg, address, message); } catch (AddressException e) { throw new SlipStreamRuntimeException(e.getMessage()); } } public static boolean sendNotification(ServiceConfiguration cfg, InternetAddress email, String message) { return sendNotification(cfg, email, message, false); } private static void logEmailDetails(InternetAddress email, boolean isHTML, String message) { String notificationType = isHTML ? "HTML " : ""; logger.info(String.format("sending %snotification to %s", notificationType, email)); if(!isHTML) { logger.info("Message:"); logger.info(message); } } private static boolean sendNotification(ServiceConfiguration cfg, InternetAddress email, String message, boolean isHTML) { boolean sendOk = true; try { InternetAddress admin = getRegistrationEmail(cfg); Session session = createSmtpSession(cfg); String password = getMailPassword(cfg); logEmailDetails(email, isHTML, message); Message msg = new MimeMessage(session); msg.setFrom(admin); Address[] recipients = new Address[] { email }; msg.setRecipients(Message.RecipientType.TO, recipients); msg.setSubject("SlipStream Message"); if(isHTML) { msg.setContent(message, "text/html; charset=utf-8"); } else { msg.setText(message); } msg.setHeader("X-Mailer", "javamail"); msg.setSentDate(new Date()); msg.saveChanges(); // send the thing off try { Transport t = session.getTransport(); t.connect(null, password); t.sendMessage(msg, msg.getAllRecipients()); logger.info("mail was successfully sent"); } catch (AuthenticationFailedException afe) { String m = String.format("authentication failure%n%s%n", afe.getMessage()); logger.severe(m); sendOk = false; } catch (MessagingException me) { String m = String.format("error sending message to %s%n%s%n", email, me.getMessage()); logger.severe(m); sendOk = false; } } catch (RuntimeException re) { String m = String.format("error sending message to %s%n%s%n", email, re.getMessage()); logger.severe(m); sendOk = false; } catch (Exception e) { String m = String.format("error sending message to %s%n%s%n", email, e.getMessage()); logger.severe(m); sendOk = false; } return sendOk; } private static InternetAddress getRegistrationEmail(ServiceConfiguration cfg) { try { String key = RequiredParameters.SLIPSTREAM_REGISTRATION_EMAIL.getName(); ServiceConfigurationParameter parameter = cfg.getParameter(key); String adminEmail = parameter.getValue(); return new InternetAddress(adminEmail); } catch (NullPointerException e) { throw new SlipStreamInternalException( "administrator email undefined or invalid", e); } catch (AddressException e) { throw new SlipStreamInternalException( "administrator email undefined or invalid", e); } } private static String getMailPassword(ServiceConfiguration cfg) { String key = RequiredParameters.SLIPSTREAM_MAIL_PASSWORD.getName(); ServiceConfigurationParameter parameter = cfg.getParameter(key); if (parameter != null) { return parameter.getValue(); } else { return ""; } } private static Session createSmtpSession(ServiceConfiguration cfg) { try { // Retrieve a copy of the system properties as a baseline for // setting the mail properties. Properties props = System.getProperties(); // Force authentication for the SMTP server to be used. props.put("mail.smtp.auth", "true"); // Turn on the use of TLS if it is available. props.put("mail.smtp.starttls.enable", "true"); // Determine whether or not to use SSL. By default, SSL is not used // when contacting the SMTP server. String key = RequiredParameters.SLIPSTREAM_MAIL_SSL.getName(); ServiceConfigurationParameter parameter = cfg.getParameter(key); boolean useSSL = false; if ("true".equals(parameter.getValue())) { useSSL = true; } String protocol = useSSL ? "smtps" : "smtp"; props.put("mail.transport.protocol", protocol); // Set the SMTP server parameters. The host name is required; the // port is optional. key = RequiredParameters.SLIPSTREAM_MAIL_HOST.getName(); parameter = cfg.getParameter(key); String mailHost = parameter.getValue(); props.put("mail." + protocol + ".host", mailHost); key = RequiredParameters.SLIPSTREAM_MAIL_PORT.getName(); parameter = cfg.getParameter(key); if (parameter != null) { String mailPort = parameter.getValue(); props.put("mail." + protocol + ".port", mailPort); } // Set the name of the user on the SMTP server. This must be // specified. key = RequiredParameters.SLIPSTREAM_MAIL_USERNAME.getName(); parameter = cfg.getParameter(key); String mailUser = parameter.getValue(); props.put("mail." + protocol + ".user", mailUser); // Determine whether or not the debugging should be enabled for java // mail. If the option isn't given, then debugging will be off. key = RequiredParameters.SLIPSTREAM_MAIL_DEBUG.getName(); parameter = cfg.getParameter(key); if (parameter != null) { String mailDebug = parameter.getValue(); props.put("mail.debug", Boolean.parseBoolean(mailDebug)); } // Create the session object for later use. Session session = Session.getInstance(props); session.setDebug(true); return session; } catch (NullPointerException e) { throw new SlipStreamInternalException( "required mail parameter is not specified", e); } } }