Commit f63971d2 authored by Liang Ding's avatar Liang Ding

Fix #12578

parent de87b240
......@@ -75,7 +75,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<org.b3log.latke.version>2.4.29</org.b3log.latke.version>
<org.b3log.latke.version>2.4.30-SNAPSHOT</org.b3log.latke.version>
<servlet.version>3.1.0</servlet.version>
<slf4j.version>1.7.5</slf4j.version>
......
......@@ -26,10 +26,9 @@ import org.b3log.latke.ioc.BeanManager;
import org.b3log.latke.ioc.Singleton;
import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger;
import org.b3log.latke.mail.MailService;
import org.b3log.latke.mail.MailService.Message;
import org.b3log.latke.mail.MailServiceFactory;
import org.b3log.latke.util.Strings;
import org.b3log.solo.mail.MailService;
import org.b3log.solo.mail.MailServiceFactory;
import org.b3log.solo.model.Article;
import org.b3log.solo.model.Comment;
import org.b3log.solo.model.Option;
......@@ -111,7 +110,7 @@ public class ArticleCommentReplyNotifier extends AbstractEventListener<JSONObjec
final String commentContent = comment.getString(Comment.COMMENT_CONTENT);
final String commentSharpURL = comment.getString(Comment.COMMENT_SHARP_URL);
final Message message = new Message();
final MailService.Message message = new MailService.Message();
message.setFrom(adminEmail);
message.addRecipient(originalCommentEmail);
......
......@@ -26,10 +26,9 @@ import org.b3log.latke.ioc.BeanManager;
import org.b3log.latke.ioc.Singleton;
import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger;
import org.b3log.latke.mail.MailService;
import org.b3log.latke.mail.MailService.Message;
import org.b3log.latke.mail.MailServiceFactory;
import org.b3log.latke.util.Strings;
import org.b3log.solo.mail.MailService;
import org.b3log.solo.mail.MailServiceFactory;
import org.b3log.solo.model.Comment;
import org.b3log.solo.model.Option;
import org.b3log.solo.model.Page;
......@@ -106,7 +105,7 @@ public class PageCommentReplyNotifier extends AbstractEventListener<JSONObject>
final String commentContent = comment.getString(Comment.COMMENT_CONTENT);
final String commentSharpURL = comment.getString(Comment.COMMENT_SHARP_URL);
final Message message = new Message();
final MailService.Message message = new MailService.Message();
message.setFrom(adminEmail);
message.addRecipient(originalCommentEmail);
......
/*
* Solo - A small and beautiful blogging system written in Java.
* Copyright (c) 2010-2018, b3log.org & hacpai.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.b3log.solo.mail;
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
/**
* Mail service.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.0, Aug 8, 2011
*/
public interface MailService {
/**
* Sends the specified message as a mail asynchronously.
*
* @param message the specified message
* @throws IOException if internal errors
*/
void send(final Message message) throws IOException;
/**
* Mail message.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.0, Aug 8, 2011
*/
class Message {
/**
* From.
*/
private String from;
/**
* Recipients.
*/
private Set<String> recipients = new HashSet<>();
/**
* HTML body.
*/
private String htmlBody;
/**
* Subject.
*/
private String subject;
/**
* Gets the recipients.
*
* @return recipients
*/
public Set<String> getRecipients() {
return Collections.unmodifiableSet(recipients);
}
/**
* Adds the specified recipient.
*
* @param recipient the specified recipient
*/
public void addRecipient(final String recipient) {
recipients.add(recipient);
}
/**
* Gets the HTML body.
*
* @return HTML body
*/
public String getHtmlBody() {
return htmlBody;
}
/**
* Sets the HTML body with the specified HTML body.
*
* @param htmlBody the specified HTML body
*/
public void setHtmlBody(final String htmlBody) {
this.htmlBody = htmlBody;
}
/**
* Gets the from.
*
* @return from
*/
public String getFrom() {
return from;
}
/**
* Sets the from with the specified from.
*
* @param from the specified from
*/
public void setFrom(final String from) {
this.from = from;
}
/**
* Gets the subject.
*
* @return subject
*/
public String getSubject() {
return subject;
}
/**
* Sets the subject with the specified subject.
*
* @param subject the specified subject
*/
public void setSubject(final String subject) {
this.subject = subject;
}
}
}
/*
* Solo - A small and beautiful blogging system written in Java.
* Copyright (c) 2010-2018, b3log.org & hacpai.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.b3log.solo.mail;
import org.b3log.latke.logging.Logger;
/**
* Mail service factory.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 2.0.1.2, Jul 5, 2017
*/
public final class MailServiceFactory {
/**
* Logger.
*/
private static final Logger LOGGER = Logger.getLogger(MailServiceFactory.class);
/**
* Mail service.
*/
private static final MailService MAIL_SERVICE;
static {
LOGGER.info("Constructing mail service....");
try {
final Class<MailService> mailServiceClass = (Class<MailService>) Class.forName(
"org.b3log.solo.mail.local.LocalMailService");
MAIL_SERVICE = mailServiceClass.newInstance();
} catch (final Exception e) {
throw new RuntimeException("Can not initialize mail service!", e);
}
LOGGER.info("Constructed mail service");
}
/**
* Private constructor.
*/
private MailServiceFactory() {
}
/**
* Gets mail service.
*
* @return mail service
*/
public static MailService getMailService() {
return MAIL_SERVICE;
}
}
/*
* Solo - A small and beautiful blogging system written in Java.
* Copyright (c) 2010-2018, b3log.org & hacpai.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.b3log.solo.mail.local;
import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger;
import org.b3log.solo.mail.MailService;
/**
* Implementation of the {@link MailService} interface.
*
* @author <a href="https://hacpai.com/member/jiangzezhou">zezhou jiang</a>
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.4, Dec 2, 2018
*/
public final class LocalMailService implements MailService {
@Override
public void send(final Message message) {
new Thread(() -> {
try {
new MailSender().sendMail(message);
} catch (final Exception e) {
Logger.getLogger(LocalMailService.class).log(Level.ERROR, "Sends mail failed", e);
}
}).start();
}
}
/*
* Solo - A small and beautiful blogging system written in Java.
* Copyright (c) 2010-2018, b3log.org & hacpai.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.b3log.solo.mail.local;
import org.apache.commons.lang.StringUtils;
import org.b3log.solo.mail.MailService.Message;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMessage.RecipientType;
import javax.mail.internet.MimeUtility;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.Set;
/**
* Email sender.
*
* @author <a href="https://hacpai.com/member/jiangzezhou">zezhou jiang</a>
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.2.4, Feb 25, 2015
*/
final class MailSender {
/**
* Mail configurations.
*
* <ul>
* <li>mail.user</li>
* <li>mail.password</li>
* <li>mail.smtp.host</li>
* <li>mail.smtp.auth</li>
* <li>mail.smtp.port</li>
* <li>mail.smtp.starttls.enable</li>
* <li>mail.debug</li>
* <li>mail.smtp.socketFactory.class</li>
* <li>mail.smtp.socketFactory.fallback</li>
* <li>mail.smtp.socketFactory.port</li>
* </ul>
*/
private final ResourceBundle mailProperties = ResourceBundle.getBundle("mail");
/**
* Create session based on the mail properties.
*
* @return session session from mail properties
*/
private Session getSession() {
final Properties props = new Properties();
props.setProperty("mail.smtp.host", mailProperties.getString("mail.smtp.host"));
String auth = "true";
if (mailProperties.containsKey("mail.smtp.auth")) {
auth = mailProperties.getString("mail.smtp.auth");
}
props.setProperty("mail.smtp.auth", auth);
props.setProperty("mail.smtp.port", mailProperties.getString("mail.smtp.port"));
String starttls = "true";
if (mailProperties.containsKey("mail.smtp.starttls.enable")) {
starttls = mailProperties.getString("mail.smtp.starttls.enable");
}
props.put("mail.smtp.starttls.enable", starttls);
props.put("mail.debug", mailProperties.getString("mail.debug"));
props.put("mail.smtp.socketFactory.class", mailProperties.getString("mail.smtp.socketFactory.class"));
props.put("mail.smtp.socketFactory.fallback", mailProperties.getString("mail.smtp.socketFactory.fallback"));
props.put("mail.smtp.socketFactory.port", mailProperties.getString("mail.smtp.socketFactory.port"));
return Session.getInstance(props, new SMTPAuthenticator());
}
/**
* Converts the specified message into a {@link javax.mail.Message
* javax.mail.Message}.
*
* @param message the specified message
* @return a {@link javax.mail.internet.MimeMessage}
* @throws Exception if converts error
*/
public javax.mail.Message convert2JavaMailMsg(final Message message) throws Exception {
if (null == message) {
return null;
}
if (StringUtils.isBlank(message.getFrom())) {
throw new MessagingException("Null from");
}
if (null == message.getRecipients() || message.getRecipients().isEmpty()) {
throw new MessagingException("Null recipients");
}
final MimeMessage ret = new MimeMessage(getSession());
ret.setFrom(new InternetAddress(message.getFrom()));
final String subject = message.getSubject();
ret.setSubject(MimeUtility.encodeText(subject != null ? subject : "", "UTF-8", "B"));
final String htmlBody = message.getHtmlBody();
ret.setContent(htmlBody != null ? htmlBody : "", "text/html;charset=UTF-8");
ret.addRecipients(RecipientType.TO, transformRecipients(message.getRecipients()));
return ret;
}
/**
* Transport recipients to InternetAddress array.
*
* @param recipients the set of all recipients
* @return InternetAddress array of all recipients internetAddress
* @throws MessagingException messagingException from javax.mail
*/
private InternetAddress[] transformRecipients(final Set<String> recipients) throws MessagingException {
if (recipients.isEmpty()) {
throw new MessagingException("recipients of mail should not be empty");
}
final InternetAddress[] ret = new InternetAddress[recipients.size()];
int i = 0;
for (String recipient : recipients) {
ret[i] = new InternetAddress(recipient);
i++;
}
return ret;
}
/**
* Sends email.
*
* @param message the specified message
* @throws Exception message exception
*/
void sendMail(final Message message) throws Exception {
final javax.mail.Message msg = convert2JavaMailMsg(message);
Transport.send(msg);
}
/**
* Inner class for Authenticator.
*/
private class SMTPAuthenticator extends Authenticator {
@Override
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(mailProperties.getString("mail.user"), mailProperties.getString("mail.password"));
}
}
}
/**
* Provides mail service (via <a href="http://www.oracle.com/technetwork/java/javamail/index.html">
* JavaMail</a>) on local (standard Servlet container).
*/
package org.b3log.solo.mail.local;
/**
* Main service.
*/
package org.b3log.solo.mail;
......@@ -25,8 +25,6 @@ import org.b3log.latke.Latkes;
import org.b3log.latke.ioc.Inject;
import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger;
import org.b3log.latke.mail.MailService;
import org.b3log.latke.mail.MailServiceFactory;
import org.b3log.latke.model.Role;
import org.b3log.latke.model.User;
import org.b3log.latke.repository.RepositoryException;
......@@ -41,9 +39,10 @@ import org.b3log.latke.servlet.renderer.AbstractFreeMarkerRenderer;
import org.b3log.latke.servlet.renderer.JSONRenderer;
import org.b3log.latke.util.Requests;
import org.b3log.solo.SoloServletListener;
import org.b3log.solo.mail.MailService;
import org.b3log.solo.mail.MailServiceFactory;
import org.b3log.solo.model.Common;
import org.b3log.solo.model.Option;
import org.b3log.solo.processor.console.ConsoleRenderer;
import org.b3log.solo.repository.OptionRepository;
import org.b3log.solo.service.*;
import org.b3log.solo.util.Solos;
......
......@@ -22,9 +22,6 @@ import org.b3log.latke.ioc.BeanManager;
import org.b3log.latke.ioc.Inject;
import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger;
import org.b3log.latke.mail.MailService;
import org.b3log.latke.mail.MailService.Message;
import org.b3log.latke.mail.MailServiceFactory;
import org.b3log.latke.repository.Query;
import org.b3log.latke.repository.annotation.Transactional;
import org.b3log.latke.servlet.HTTPRequestContext;
......@@ -33,6 +30,8 @@ import org.b3log.latke.servlet.annotation.Before;
import org.b3log.latke.servlet.annotation.RequestProcessing;
import org.b3log.latke.servlet.annotation.RequestProcessor;
import org.b3log.latke.servlet.renderer.TextHTMLRenderer;
import org.b3log.solo.mail.MailService;
import org.b3log.solo.mail.MailServiceFactory;
import org.b3log.solo.model.Article;
import org.b3log.solo.model.Option;
import org.b3log.solo.model.Tag;
......@@ -142,7 +141,7 @@ public class RepairConsole {
return;
}
final Message msg = new MailService.Message();
final MailService.Message msg = new MailService.Message();
msg.setFrom(preference.getString(Option.ID_C_ADMIN_EMAIL));
msg.addRecipient("d@b3log.org");
msg.setSubject("Restore signs");
......
......@@ -27,8 +27,6 @@ import org.b3log.latke.event.EventManager;
import org.b3log.latke.ioc.Inject;
import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger;
import org.b3log.latke.mail.MailService;
import org.b3log.latke.mail.MailServiceFactory;
import org.b3log.latke.repository.RepositoryException;
import org.b3log.latke.repository.Transaction;
import org.b3log.latke.service.LangPropsService;
......@@ -37,6 +35,8 @@ import org.b3log.latke.service.annotation.Service;
import org.b3log.latke.util.Ids;
import org.b3log.latke.util.Strings;
import org.b3log.solo.event.EventTypes;
import org.b3log.solo.mail.MailService;
import org.b3log.solo.mail.MailServiceFactory;
import org.b3log.solo.model.*;
import org.b3log.solo.repository.ArticleRepository;
import org.b3log.solo.repository.CommentRepository;
......
......@@ -23,8 +23,6 @@ import org.b3log.latke.Latkes;
import org.b3log.latke.ioc.Inject;
import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger;
import org.b3log.latke.mail.MailService;
import org.b3log.latke.mail.MailServiceFactory;
import org.b3log.latke.model.User;
import org.b3log.latke.repository.Query;
import org.b3log.latke.repository.Transaction;
......@@ -34,6 +32,8 @@ import org.b3log.latke.service.annotation.Service;
import org.b3log.solo.SoloServletListener;
import org.b3log.solo.cache.ArticleCache;
import org.b3log.solo.cache.CommentCache;
import org.b3log.solo.mail.MailService;
import org.b3log.solo.mail.MailServiceFactory;
import org.b3log.solo.model.Article;
import org.b3log.solo.model.Comment;
import org.b3log.solo.model.Option;
......
/*
* Copyright (c) 2009-2018, b3log.org & hacpai.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 org.b3log.solo.mail;
import org.b3log.latke.Latkes;
import org.b3log.solo.mail.MailService.Message;
import org.testng.annotations.Test;
/**
* {@link MailService} test case.
*
* @author <a href="https://hacpai.com/member/jiangzezhou">zezhou jiang</a>
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.4, Dec 2, 2018
*/
public final class MailServiceTestCase {
static {
Latkes.init();
}
/**
* Tests mail sending.
*
* @throws Exception exception
*/
@Test
public void testSendMail() throws Exception {
System.out.println("testSendMail");
final MailService mailService = MailServiceFactory.getMailService();
final Message message = new Message();
message.setFrom("b3log.solo@gmail.com");
message.setSubject("Latke Mail Service[local] Test");
message.setHtmlBody("<htmL><body>测试</body><html>");
message.addRecipient("d@b3log.org");
mailService.send(message);
Thread.sleep(10000); // Waiting for sending....
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment