import com.gitblit.manager.RuntimeManager;\r
import com.gitblit.manager.UserManager;\r
import com.gitblit.models.FederationModel;\r
+import com.gitblit.models.Mailing;\r
import com.gitblit.service.FederationPullService;\r
import com.gitblit.utils.FederationUtils;\r
import com.gitblit.utils.StringUtils;\r
public void sendMail(String subject, String message, Collection<String> toAddresses) {\r
}\r
\r
- @Override\r
- public void sendMail(String subject, String message, String... toAddresses) {\r
- }\r
-\r
@Override\r
public void sendHtmlMail(String subject, String message, Collection<String> toAddresses) {\r
}\r
\r
@Override\r
- public void sendHtmlMail(String subject, String message, String... toAddresses) {\r
- }\r
-\r
- @Override\r
- public void sendHtmlMail(String from, String subject, String message, Collection<String> toAddresses) {\r
- }\r
-\r
- @Override\r
- public void sendHtmlMail(String from, String subject, String message, String... toAddresses) {\r
+ public void send(Mailing mailing) {\r
}\r
}\r
}\r
import java.security.cert.X509Certificate;\r
import java.text.MessageFormat;\r
import java.util.ArrayList;\r
-import java.util.Arrays;\r
import java.util.Calendar;\r
import java.util.Collections;\r
import java.util.Date;\r
import java.util.List;\r
import java.util.Map;\r
\r
-import javax.activation.DataHandler;\r
-import javax.activation.FileDataSource;\r
import javax.mail.Message;\r
-import javax.mail.Multipart;\r
-import javax.mail.internet.MimeBodyPart;\r
-import javax.mail.internet.MimeMultipart;\r
import javax.swing.ImageIcon;\r
import javax.swing.InputVerifier;\r
import javax.swing.JButton;\r
import com.gitblit.Keys;\r
import com.gitblit.client.HeaderPanel;\r
import com.gitblit.client.Translation;\r
+import com.gitblit.models.Mailing;\r
import com.gitblit.models.UserModel;\r
import com.gitblit.service.MailService;\r
import com.gitblit.utils.ArrayUtils;\r
// send email\r
try {\r
if (mail.isReady()) {\r
- Message message = mail.createMessage(Arrays.asList(user.emailAddress));\r
- message.setSubject("Your Gitblit client certificate for " + metadata.serverHostname);\r
-\r
- // body of email\r
+ Mailing mailing = Mailing.newPlain();\r
+ mailing.subject = "Your Gitblit client certificate for " + metadata.serverHostname;\r
+ mailing.setRecipients(user.emailAddress);\r
String body = X509Utils.processTemplate(new File(folder, X509Utils.CERTS + File.separator + "mail.tmpl"), metadata);\r
if (StringUtils.isEmpty(body)) {\r
body = MessageFormat.format("Hi {0}\n\nHere is your client certificate bundle.\nInside the zip file are installation instructions.", user.getDisplayName());\r
}\r
- Multipart mp = new MimeMultipart();\r
- MimeBodyPart messagePart = new MimeBodyPart();\r
- messagePart.setText(body);\r
- mp.addBodyPart(messagePart);\r
-\r
- // attach zip\r
- MimeBodyPart filePart = new MimeBodyPart();\r
- FileDataSource fds = new FileDataSource(zip);\r
- filePart.setDataHandler(new DataHandler(fds));\r
- filePart.setFileName(fds.getName());\r
- mp.addBodyPart(filePart);\r
-\r
- message.setContent(mp);\r
+ mailing.content = body;\r
+ mailing.addAttachment(zip);\r
+\r
+ Message message = mail.createMessage(mailing);\r
\r
mail.sendNow(message);\r
return true;\r
import com.gitblit.models.FederationSet;
import com.gitblit.models.ForkModel;
import com.gitblit.models.GitClientApplication;
+import com.gitblit.models.Mailing;
import com.gitblit.models.Metric;
import com.gitblit.models.ProjectModel;
import com.gitblit.models.RegistrantAccessPermission;
notificationManager.sendMail(subject, message, toAddresses);
}
- @Override
- public void sendMail(String subject, String message, String... toAddresses) {
- notificationManager.sendMail(subject, message, toAddresses);
- }
-
@Override
public void sendHtmlMail(String subject, String message, Collection<String> toAddresses) {
notificationManager.sendHtmlMail(subject, message, toAddresses);
}
@Override
- public void sendHtmlMail(String subject, String message, String... toAddresses) {
- notificationManager.sendHtmlMail(subject, message, toAddresses);
- }
-
- @Override
- public void sendHtmlMail(String from, String subject, String message, Collection<String> toAddresses) {
- notificationManager.sendHtmlMail(from, subject, message, toAddresses);
- }
-
- @Override
- public void sendHtmlMail(String from, String subject, String message, String... toAddresses) {
- notificationManager.sendHtmlMail(from, subject, message, toAddresses);
+ public void send(Mailing mail) {
+ notificationManager.send(mail);
}
/*
import java.util.Collection;
+import com.gitblit.models.Mailing;
+
public interface INotificationManager extends IManager {
/**
*/
void sendMail(String subject, String message, Collection<String> toAddresses);
- /**
- * Notify users by email of something.
- *
- * @param subject
- * @param message
- * @param toAddresses
- */
- void sendMail(String subject, String message, String... toAddresses);
-
/**
* Notify users by email of something.
*
/**
* Notify users by email of something.
*
- * @param subject
- * @param message
- * @param toAddresses
- */
- void sendHtmlMail(String subject, String message, String... toAddresses);
-
- /**
- * Notify users by email of something.
- *
- * @param from
- * @param subject
- * @param message
- * @param toAddresses
- */
- void sendHtmlMail(String from, String subject, String message, Collection<String> toAddresses);
-
- /**
- * Notify users by email of something.
- *
- * @param from
- * @param subject
- * @param message
- * @param toAddresses
+ * @param mailing
+ * @return the mail message object
*/
- void sendHtmlMail(String from, String subject, String message, String... toAddresses);
+ void send(Mailing mailing);
}
\ No newline at end of file
*/
package com.gitblit.manager;
-import java.text.MessageFormat;
import java.util.Collection;
-import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.mail.Message;
-import javax.mail.MessagingException;
-import javax.mail.internet.MimeBodyPart;
-import javax.mail.internet.MimeMultipart;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.gitblit.IStoredSettings;
import com.gitblit.Keys;
+import com.gitblit.models.Mailing;
import com.gitblit.service.MailService;
/**
private final IStoredSettings settings;
- private final MailService mailExecutor;
+ private final MailService mailService;
public NotificationManager(IStoredSettings settings) {
this.settings = settings;
- this.mailExecutor = new MailService(settings);
+ this.mailService = new MailService(settings);
}
@Override
public NotificationManager start() {
- if (mailExecutor.isReady()) {
+ if (mailService.isReady()) {
int period = 2;
logger.info("Mail service will process the queue every {} minutes.", period);
- scheduledExecutor.scheduleAtFixedRate(mailExecutor, 1, period, TimeUnit.MINUTES);
+ scheduledExecutor.scheduleAtFixedRate(mailService, 1, period, TimeUnit.MINUTES);
} else {
logger.warn("Mail service disabled.");
}
*/
@Override
public void sendMailToAdministrators(String subject, String message) {
- List<String> toAddresses = settings.getStrings(Keys.mail.adminAddresses);
- sendMail(subject, message, toAddresses);
+ Mailing mail = Mailing.newPlain();
+ mail.subject = subject;
+ mail.content = message;
+ mail.setRecipients(settings.getStrings(Keys.mail.adminAddresses));
+ send(mail);
}
/**
*/
@Override
public void sendMail(String subject, String message, Collection<String> toAddresses) {
- this.sendMail(subject, message, toAddresses.toArray(new String[0]));
- }
-
- /**
- * Notify users by email of something.
- *
- * @param subject
- * @param message
- * @param toAddresses
- */
- @Override
- public void sendMail(String subject, String message, String... toAddresses) {
- if (toAddresses == null || toAddresses.length == 0) {
- logger.debug(MessageFormat.format("Dropping message {0} because there are no recipients", subject));
- return;
- }
- try {
- Message mail = mailExecutor.createMessage(toAddresses);
- if (mail != null) {
- mail.setSubject(subject);
-
- MimeBodyPart messagePart = new MimeBodyPart();
- messagePart.setText(message, "utf-8");
- messagePart.setHeader("Content-Type", "text/plain; charset=\"utf-8\"");
- messagePart.setHeader("Content-Transfer-Encoding", "quoted-printable");
-
- MimeMultipart multiPart = new MimeMultipart();
- multiPart.addBodyPart(messagePart);
- mail.setContent(multiPart);
-
- mailExecutor.queue(mail);
- }
- } catch (MessagingException e) {
- logger.error("Messaging error", e);
- }
+ Mailing mail = Mailing.newPlain();
+ mail.subject = subject;
+ mail.content = message;
+ mail.setRecipients(toAddresses);
+ send(mail);
}
/**
*/
@Override
public void sendHtmlMail(String subject, String message, Collection<String> toAddresses) {
- this.sendHtmlMail(null, subject, message, toAddresses.toArray(new String[0]));
- }
-
- /**
- * Notify users by email of something.
- *
- * @param from
- * @param subject
- * @param message
- * @param toAddresses
- */
- @Override
- public void sendHtmlMail(String from, String subject, String message, Collection<String> toAddresses) {
- this.sendHtmlMail(from, subject, message, toAddresses.toArray(new String[0]));
- }
-
- /**
- * Notify users by email of something.
- *
- * @param subject
- * @param message
- * @param toAddresses
- */
- @Override
- public void sendHtmlMail(String subject, String message, String... toAddresses) {
- this.sendHtmlMail(null, message, toAddresses);
+ Mailing mail = Mailing.newHtml();
+ mail.content = message;
+ mail.setRecipients(toAddresses);
+ send(mail);
}
/**
* Notify users by email of something.
*
- * @param from
- * @param subject
- * @param message
- * @param toAddresses
+ * @param mailing
*/
@Override
- public void sendHtmlMail(String from, String subject, String message, String... toAddresses) {
- if (toAddresses == null || toAddresses.length == 0) {
- logger.debug("Dropping message {} because there are no recipients", subject);
+ public void send(Mailing mailing) {
+ if (!mailing.hasRecipients()) {
+ logger.debug("Dropping message {} because there are no recipients", mailing.subject);
return;
}
- try {
- Message mail = mailExecutor.createMessage(from, toAddresses);
- if (mail != null) {
- mail.setSubject(subject);
-
- MimeBodyPart messagePart = new MimeBodyPart();
- messagePart.setText(message, "utf-8");
- messagePart.setHeader("Content-Type", "text/html; charset=\"utf-8\"");
- messagePart.setHeader("Content-Transfer-Encoding", "quoted-printable");
-
- MimeMultipart multiPart = new MimeMultipart();
- multiPart.addBodyPart(messagePart);
- mail.setContent(multiPart);
-
- mailExecutor.queue(mail);
- }
- } catch (MessagingException e) {
- logger.error("Messaging error", e);
+ Message msg = mailService.createMessage(mailing);
+ if (msg != null) {
+ mailService.queue(msg);
}
}
--- /dev/null
+/*
+ * Copyright 2014 gitblit.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.
+ */
+package com.gitblit.models;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * Encapsulates an email notification.
+ *
+ * @author James Moger
+ *
+ */
+public class Mailing {
+
+ public enum Type {
+ plain, html
+ }
+
+ public final Type type;
+ public final Set<String> toAddresses;
+ public final Set<String> ccAddresses;
+ public final List<File> attachments;
+
+ public String from;
+ public String subject;
+ public String content;
+ public String id;
+
+ public static Mailing newHtml() {
+ return new Mailing(Type.html);
+ }
+
+ public static Mailing newPlain() {
+ return new Mailing(Type.plain);
+ }
+
+ private Mailing(Type type) {
+ this.type = type;
+ this.toAddresses = new TreeSet<String>();
+ this.ccAddresses = new TreeSet<String>();
+ this.attachments = new ArrayList<File>();
+ }
+
+ public boolean hasRecipients() {
+ return toAddresses.size() > 0;
+ }
+
+ public void setRecipients(String... addrs) {
+ setRecipients(Arrays.asList(addrs));
+ }
+
+ public void setRecipients(Collection<String> addrs) {
+ toAddresses.clear();
+ for (String addr : addrs) {
+ toAddresses.add(addr.toLowerCase());
+ }
+ cleanup();
+ }
+
+ public boolean hasCCs() {
+ return ccAddresses.size() > 0;
+ }
+
+ public void setCCs(String... addrs) {
+ setCCs(Arrays.asList(addrs));
+ }
+
+ public void setCCs(Collection<String> addrs) {
+ ccAddresses.clear();
+ for (String addr : addrs) {
+ ccAddresses.add(addr.toLowerCase());
+ }
+ cleanup();
+ }
+
+ private void cleanup() {
+ ccAddresses.removeAll(toAddresses);
+ }
+
+ public boolean hasAttachments() {
+ return attachments.size() > 0;
+ }
+
+ public void addAttachment(File file) {
+ attachments.add(file);
+ }
+
+ @Override
+ public String toString() {
+ return subject + "\n\n" + content;
+ }
+}
\ No newline at end of file
*/\r
package com.gitblit.service;\r
\r
+import java.io.File;\r
import java.util.ArrayList;\r
-import java.util.Arrays;\r
import java.util.Date;\r
-import java.util.HashSet;\r
import java.util.List;\r
import java.util.Properties;\r
import java.util.Queue;\r
-import java.util.Set;\r
+import java.util.UUID;\r
import java.util.concurrent.ConcurrentLinkedQueue;\r
import java.util.regex.Pattern;\r
\r
+import javax.activation.DataHandler;\r
+import javax.activation.FileDataSource;\r
import javax.mail.Authenticator;\r
import javax.mail.Message;\r
+import javax.mail.MessagingException;\r
import javax.mail.PasswordAuthentication;\r
import javax.mail.Session;\r
import javax.mail.Transport;\r
import javax.mail.internet.InternetAddress;\r
+import javax.mail.internet.MimeBodyPart;\r
import javax.mail.internet.MimeMessage;\r
+import javax.mail.internet.MimeMultipart;\r
\r
import org.slf4j.Logger;\r
import org.slf4j.LoggerFactory;\r
\r
import com.gitblit.IStoredSettings;\r
import com.gitblit.Keys;\r
+import com.gitblit.models.Mailing;\r
import com.gitblit.utils.StringUtils;\r
\r
/**\r
/**\r
* Create a message.\r
*\r
- * @param toAddresses\r
+ * @param mailing\r
* @return a message\r
*/\r
- public Message createMessage(String... toAddresses) {\r
- return createMessage(null, Arrays.asList(toAddresses));\r
- }\r
-\r
- /**\r
- * Create a message.\r
- *\r
- * @param toAddresses\r
- * @return a message\r
- */\r
- public Message createMessage(List<String> toAddresses) {\r
- return createMessage(null, toAddresses);\r
- }\r
+ public Message createMessage(Mailing mailing) {\r
+ if (mailing.subject == null) {\r
+ mailing.subject = "";\r
+ }\r
\r
- /**\r
- * Create a message.\r
- *\r
- * @param fromDisplayName\r
- * @param toAddresses\r
- * @return a message\r
- */\r
- public Message createMessage(String fromDisplayName, String... toAddresses) {\r
- return createMessage(fromDisplayName, Arrays.asList(toAddresses));\r
- }\r
+ if (mailing.content == null) {\r
+ mailing.content = "";\r
+ }\r
\r
- /**\r
- * Create a message.\r
- *\r
- * @param fromDisplayName\r
- * @param toAddresses\r
- * @return a message\r
- */\r
- public Message createMessage(String fromDisplayName, List<String> toAddresses) {\r
- MimeMessage message = new MimeMessage(session);\r
+ Message message = new MailMessageImpl(session, mailing.id);\r
try {\r
String fromAddress = settings.getString(Keys.mail.fromAddress, null);\r
if (StringUtils.isEmpty(fromAddress)) {\r
fromAddress = "gitblit@gitblit.com";\r
}\r
- InternetAddress from = new InternetAddress(fromAddress, fromDisplayName == null ? "Gitblit" : fromDisplayName);\r
+ InternetAddress from = new InternetAddress(fromAddress, mailing.from == null ? "Gitblit" : mailing.from);\r
message.setFrom(from);\r
\r
- // determine unique set of addresses\r
- Set<String> uniques = new HashSet<String>();\r
- for (String address : toAddresses) {\r
- uniques.add(address.toLowerCase());\r
- }\r
-\r
Pattern validEmail = Pattern\r
.compile("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$");\r
- List<InternetAddress> tos = new ArrayList<InternetAddress>();\r
- for (String address : uniques) {\r
+\r
+ // validate & add TO recipients\r
+ List<InternetAddress> to = new ArrayList<InternetAddress>();\r
+ for (String address : mailing.toAddresses) {\r
if (StringUtils.isEmpty(address)) {\r
continue;\r
}\r
if (validEmail.matcher(address).find()) {\r
try {\r
- tos.add(new InternetAddress(address));\r
+ to.add(new InternetAddress(address));\r
} catch (Throwable t) {\r
}\r
}\r
}\r
- message.setRecipients(Message.RecipientType.BCC,\r
- tos.toArray(new InternetAddress[tos.size()]));\r
+\r
+ // validate & add CC recipients\r
+ List<InternetAddress> cc = new ArrayList<InternetAddress>();\r
+ for (String address : mailing.ccAddresses) {\r
+ if (StringUtils.isEmpty(address)) {\r
+ continue;\r
+ }\r
+ if (validEmail.matcher(address).find()) {\r
+ try {\r
+ cc.add(new InternetAddress(address));\r
+ } catch (Throwable t) {\r
+ }\r
+ }\r
+ }\r
+\r
+ if (settings.getBoolean(Keys.web.showEmailAddresses, true)) {\r
+ // full disclosure of recipients\r
+ if (to.size() > 0) {\r
+ message.setRecipients(Message.RecipientType.TO,\r
+ to.toArray(new InternetAddress[to.size()]));\r
+ }\r
+ if (cc.size() > 0) {\r
+ message.setRecipients(Message.RecipientType.CC,\r
+ cc.toArray(new InternetAddress[cc.size()]));\r
+ }\r
+ } else {\r
+ // everyone is bcc'd\r
+ List<InternetAddress> bcc = new ArrayList<InternetAddress>();\r
+ bcc.addAll(to);\r
+ bcc.addAll(cc);\r
+ message.setRecipients(Message.RecipientType.BCC,\r
+ bcc.toArray(new InternetAddress[bcc.size()]));\r
+ }\r
+\r
message.setSentDate(new Date());\r
+ message.setSubject(mailing.subject);\r
+\r
+ MimeBodyPart messagePart = new MimeBodyPart();\r
+ messagePart.setText(mailing.content, "utf-8");\r
+ //messagePart.setHeader("Content-Transfer-Encoding", "quoted-printable");\r
+\r
+ if (Mailing.Type.html == mailing.type) {\r
+ messagePart.setHeader("Content-Type", "text/html; charset=\"utf-8\"");\r
+ } else {\r
+ messagePart.setHeader("Content-Type", "text/plain; charset=\"utf-8\"");\r
+ }\r
+\r
+ MimeMultipart multiPart = new MimeMultipart();\r
+ multiPart.addBodyPart(messagePart);\r
+\r
+ // handle attachments\r
+ if (mailing.hasAttachments()) {\r
+ for (File file : mailing.attachments) {\r
+ if (file.exists()) {\r
+ MimeBodyPart filePart = new MimeBodyPart();\r
+ FileDataSource fds = new FileDataSource(file);\r
+ filePart.setDataHandler(new DataHandler(fds));\r
+ filePart.setFileName(fds.getName());\r
+ multiPart.addBodyPart(filePart);\r
+ }\r
+ }\r
+ }\r
+\r
+ message.setContent(multiPart);\r
+\r
} catch (Exception e) {\r
logger.error("Failed to properly create message", e);\r
}\r
public void sendNow(Message message) throws Exception {\r
Transport.send(message);\r
}\r
+\r
+ private static class MailMessageImpl extends MimeMessage {\r
+\r
+ final String id;\r
+\r
+ MailMessageImpl(Session session, String id) {\r
+ super(session);\r
+ this.id = id;\r
+ }\r
+\r
+ @Override\r
+ protected void updateMessageID() throws MessagingException {\r
+ if (!StringUtils.isEmpty(id)) {\r
+ String hostname = "gitblit.com";\r
+ String refid = "<" + id + "@" + hostname + ">";\r
+ String mid = "<" + UUID.randomUUID().toString() + "@" + hostname + ">";\r
+ setHeader("References", refid);\r
+ setHeader("In-Reply-To", refid);\r
+ setHeader("Message-Id", mid);\r
+ }\r
+ }\r
+ }\r
}\r
\r
import com.gitblit.FileSettings;\r
import com.gitblit.Keys;\r
+import com.gitblit.models.Mailing;\r
import com.gitblit.service.MailService;\r
\r
public class MailTest extends GitblitUnitTest {\r
public void testSendMail() throws Exception {\r
FileSettings settings = new FileSettings("mailtest.properties");\r
MailService mail = new MailService(settings);\r
- Message message = mail.createMessage(settings.getStrings(Keys.mail.adminAddresses));\r
+ Mailing mailing = Mailing.newPlain();\r
+ mailing.setRecipients(settings.getStrings(Keys.mail.adminAddresses));\r
+ Message message = mail.createMessage(mailing);\r
message.setSubject("Test");\r
message.setText("Lägger till andra stycket i ny fil. UTF-8 encoded");\r
mail.queue(message);\r