Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* SonarQube
* Copyright (C) 2009-2018 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.server.notification.email;
import java.net.MalformedURLException;
import java.net.URL;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.SimpleEmail;
import org.sonar.api.config.EmailSettings;
import org.sonar.api.notifications.Notification;
import org.sonar.api.notifications.NotificationChannel;
import org.sonar.api.user.User;
import org.sonar.api.user.UserFinder;
import org.sonar.api.utils.SonarException;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.plugins.emailnotifications.api.EmailMessage;
import org.sonar.plugins.emailnotifications.api.EmailTemplate;
/**
* References:
*
*
* @since 2.10
*/
public class EmailNotificationChannel extends NotificationChannel {
private static final Logger LOG = Loggers.get(EmailNotificationChannel.class);
/**
* @see org.apache.commons.mail.Email#setSocketConnectionTimeout(int)
* @see org.apache.commons.mail.Email#setSocketTimeout(int)
*/
private static final int SOCKET_TIMEOUT = 30_000;
/**
* Email Header Field: "List-ID".
* Value of this field should contain mailing list identifier as specified in RFC 2919.
*/
private static final String LIST_ID_HEADER = "List-ID";
/**
* Email Header Field: "List-Archive".
* Value of this field should contain URL of mailing list archive as specified in RFC 2369.
*/
private static final String LIST_ARCHIVE_HEADER = "List-Archive";
/**
* Email Header Field: "In-Reply-To".
* Value of this field should contain related message identifier as specified in RFC 2822.
*/
private static final String IN_REPLY_TO_HEADER = "In-Reply-To";
/**
* Email Header Field: "References".
* Value of this field should contain related message identifier as specified in RFC 2822
*/
private static final String REFERENCES_HEADER = "References";
private static final String SUBJECT_DEFAULT = "Notification";
private EmailSettings configuration;
private EmailTemplate[] templates;
private UserFinder userFinder;
public EmailNotificationChannel(EmailSettings configuration, EmailTemplate[] templates, UserFinder userFinder) {
this.configuration = configuration;
this.templates = templates;
this.userFinder = userFinder;
}
@Override
public void deliver(Notification notification, String username) {
User user = userFinder.findByLogin(username);
if (user == null || StringUtils.isBlank(user.email())) {
LOG.debug("User does not exist or has no email: {}", username);
return;
}
EmailMessage emailMessage = format(notification);
if (emailMessage != null) {
emailMessage.setTo(user.email());
deliver(emailMessage);
}
}
private EmailMessage format(Notification notification) {
for (EmailTemplate template : templates) {
EmailMessage email = template.format(notification);
if (email != null) {
return email;
}
}
LOG.warn("Email template not found for notification: {}", notification);
return null;
}
/**
* Visibility has been relaxed for tests.
*/
void deliver(EmailMessage emailMessage) {
if (StringUtils.isBlank(configuration.getSmtpHost())) {
LOG.debug("SMTP host was not configured - email will not be sent");
return;
}
try {
send(emailMessage);
} catch (EmailException e) {
LOG.error("Unable to send email", e);
}
}
private void send(EmailMessage emailMessage) throws EmailException {
// Trick to correctly initialize javax.mail library
ClassLoader classloader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
try {
LOG.debug("Sending email: {}", emailMessage);
String host = null;
try {
host = new URL(configuration.getServerBaseURL()).getHost();
} catch (MalformedURLException e) {
// ignore
}
SimpleEmail email = new SimpleEmail();
if (StringUtils.isNotBlank(host)) {
/*
* Set headers for proper threading: GMail will not group messages, even if they have same subject, but don't have "In-Reply-To" and
* "References" headers. TODO investigate threading in other clients like KMail, Thunderbird, Outlook
*/
if (StringUtils.isNotEmpty(emailMessage.getMessageId())) {
String messageId = "<" + emailMessage.getMessageId() + "@" + host + ">";
email.addHeader(IN_REPLY_TO_HEADER, messageId);
email.addHeader(REFERENCES_HEADER, messageId);
}
// Set headers for proper filtering
email.addHeader(LIST_ID_HEADER, "SonarQube ");
email.addHeader(LIST_ARCHIVE_HEADER, configuration.getServerBaseURL());
}
// Set general information
email.setCharset("UTF-8");
String fromName = configuration.getFromName();
String from = StringUtils.isBlank(emailMessage.getFrom()) ? fromName : (emailMessage.getFrom() + " (" + fromName + ")");
email.setFrom(configuration.getFrom(), from);
email.addTo(emailMessage.getTo(), " ");
String subject = StringUtils.defaultIfBlank(StringUtils.trimToEmpty(configuration.getPrefix()) + " ", "")
+ StringUtils.defaultString(emailMessage.getSubject(), SUBJECT_DEFAULT);
email.setSubject(subject);
email.setMsg(emailMessage.getMessage());
// Send
email.setHostName(configuration.getSmtpHost());
configureSecureConnection(email);
if (StringUtils.isNotBlank(configuration.getSmtpUsername()) || StringUtils.isNotBlank(configuration.getSmtpPassword())) {
email.setAuthentication(configuration.getSmtpUsername(), configuration.getSmtpPassword());
}
email.setSocketConnectionTimeout(SOCKET_TIMEOUT);
email.setSocketTimeout(SOCKET_TIMEOUT);
email.send();
} finally {
Thread.currentThread().setContextClassLoader(classloader);
}
}
private void configureSecureConnection(SimpleEmail email) {
if (StringUtils.equalsIgnoreCase(configuration.getSecureConnection(), "ssl")) {
email.setSSLOnConnect(true);
email.setSslSmtpPort(String.valueOf(configuration.getSmtpPort()));
// this port is not used except in EmailException message, that's why it's set with the same value than SSL port.
// It prevents from getting bad message.
email.setSmtpPort(configuration.getSmtpPort());
} else if (StringUtils.equalsIgnoreCase(configuration.getSecureConnection(), "starttls")) {
email.setStartTLSEnabled(true);
email.setStartTLSRequired(true);
email.setSmtpPort(configuration.getSmtpPort());
} else if (StringUtils.isBlank(configuration.getSecureConnection())) {
email.setSmtpPort(configuration.getSmtpPort());
} else {
throw new SonarException("Unknown type of SMTP secure connection: " + configuration.getSecureConnection());
}
}
/**
* Send test email.
*
* @throws EmailException when unable to send
*/
public void sendTestEmail(String toAddress, String subject, String message) throws EmailException {
try {
EmailMessage emailMessage = new EmailMessage();
emailMessage.setTo(toAddress);
emailMessage.setSubject(subject);
emailMessage.setMessage(message);
send(emailMessage);
} catch (EmailException e) {
LOG.debug("Fail to send test email to {}: {}", toAddress, e);
throw e;
}
}
}