Closed pat-lego closed 5 years ago
@pat-lego I tried to reproduce the issue but without success. Basically if (clientInput.trim().equals(AUTH_CANCEL_COMMAND))
is part of the smtp server library https://github.com/voodoodyne/subethasmtp which I used in this project.
I created a new branch with integration tests. Can you please provide more details how the servers are configured and also a bit more details about the client setup. A stacktrace or log would also be helpful.
I have the following in my Class:
@ClassRule public static FakeSmtpRule smtpServer = new FakeSmtpRule(ServerConfiguration.create().port(2525).charset("UTF-8").userName("someusername").password("somepassword"));
I use the javax.mail library in the OpenJDK 64 bit Java 11 to send emails to the fake SMTP server and when I try to send emails with that username and password I get a NullPointerError.
Let me know if you require more information to reproduce this error.
@pat-lego It would be great to get some more details about the FakeSmtpRule and the ServerConfiguration. What is it doing specifically? Can you maybe share some code snippets. This could help me to reproduce the issue.
Email Client:
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import org.apache.commons.io.IOUtils;
import com.outreach.core.enumerations.EncryptionType;
public class SendEmail
{
private Properties properties;
private Session session;
public SendEmail(String host, String port, String username, String password, EncryptionType e) {
this.properties = new Properties();
this.properties.put("mail.smtp.host", host);
this.properties.put("mail.smtp.port", port);
this.properties.put("mail.smtp.auth", "true");
if(e.equals(EncryptionType.TLS))
this.properties.put("mail.smtp.starttls.enable","true");
if(e.equals(EncryptionType.SSL)) {
this.properties.put("mail.smtp.socketFactory.port", port);
this.properties.put("mail.smtp.socketFactory.class",
"javax.net.ssl.SSLSocketFactory");
}
this.session = Session.getInstance(this.properties,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
}
/**
* Send an email to anyone in either HTML or plain text format
* @param from User to send the email
* @param recipient User(s) to receive the email
* @param subject The message to send
* @param body The content of the email
* @param html If the email is in HTML format or not
* @param encoding The type of character encoding to use for the message
* @param attachments documents to add to the email
* @throws AddressException Invalid address
* @throws MessagingException Invalid Message
*/
public void sendMessage(String from, String[] recipient, String subject, String body, Boolean html, String encoding, List<Attachment> attachments) throws AddressException, MessagingException {
Message message = new MimeMessage(this.session);
message.setFrom(new InternetAddress(from));
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse(String.join(",", recipient)));
message.setSubject(subject);
Multipart multipart;
if(attachments == null) {
multipart = this.setContent(html, new MimeBodyPart(), body, encoding);
}
else {
BodyPart messageBodyPart = new MimeBodyPart();
multipart = this.setContent(html, messageBodyPart, body, encoding);
for(int i = 0; i < attachments.size(); i++) {
SendEmail.addAttachment(multipart, attachments.get(i), attachments.get(i).getFileName());
}
}
message.setContent(multipart);
Transport.send(message);
}
SMTP Server:
private static SendEmail sendTLSEmail;
private static SendEmail sendSSLEmail;
private static String emailTemplate;
private static String pdf1;
private static String pdf2;
@ClassRule
public static FakeSmtpRule smtpServer = new FakeSmtpRule(ServerConfiguration.create().port(2525).charset("UTF-8").relayDomains("localhost").userName("uottawa.outreach@gmail.com").password("uottawaTestTest");
@BeforeClass
public static void static_init() throws IOException {
TestSendEmail.sendTLSEmail = new SendEmail("localhost", "2525", "uottawa.outreach@gmail.com", "uottawaTestTest", EncryptionType.TLS);
TestSendEmail.sendSSLEmail = new SendEmail("localhost", "2525", "uottawa.outreach.developers@gmail.com", "uottawa123", EncryptionType.SSL);
assertNotNull(TestSendEmail.sendTLSEmail);
assertNotNull(TestSendEmail.sendSSLEmail);
TestSendEmail.emailTemplate = IOUtils.toString(TestSendEmail.class.getResourceAsStream("/email-templates/template.html"), "UTF-8");
assertNotNull(TestSendEmail.emailTemplate);
TestSendEmail.pdf1 = IOUtils.toString(TestSendEmail.class.getResourceAsStream("/email-attachments/sample.pdf"), "UTF-8");
assertNotNull(TestSendEmail.pdf1);
TestSendEmail.pdf2 = IOUtils.toString(TestSendEmail.class.getResourceAsStream("/email-attachments/pdf-sample.pdf"), "UTF-8");
assertNotNull(TestSendEmail.pdf2);
}
@Test
public void assertRunning() {
assertTrue(smtpServer.isRunning());
}
@Test
public void sendEmailTLS() throws AddressException, MessagingException {
TestSendEmail.sendTLSEmail.sendMessage("patrique.legault@uottawa.ca", new String[] {"pat@aesstaff.ca"}, "Test", "Test 1,2,3", false, "UTF-8");
}
@Test
public void sendEmailTLSMultiReceipients() throws AddressException, MessagingException {
TestSendEmail.sendTLSEmail.sendMessage("patrique.legault@uottawa.ca", new String[] { "patrique.legault@gmail.com", "pat@aesstaff.ca"}, "Test", "Test 1,2,3", false, "UTF-8");
}
@Test
public void sendEmailSSL() throws AddressException, MessagingException {
TestSendEmail.sendSSLEmail.sendMessage("patrique.legault@uottawa.ca", new String[] {"pat@aesstaff.ca"}, "Test", "Test 1,2,3", false, "UTF-8");
}
@Test(expected = java.lang.NullPointerException.class)
public void sendEmailNoFrom() throws AddressException, MessagingException {
TestSendEmail.sendTLSEmail.sendMessage(null, new String[] {"pat@aesstaff.ca"}, "Test", "Test 1,2,3", false, "UTF-8");
}
Above is a snippet of the mail server and mail client that I wrote. Let me know if this helps with the current issue.
When trying to authenticate developers should start seeing errors appear in the tests saying that Authentication could be completed due to the fact that the clientInput
variable is null
.
@pat-lego I now extended the test cases with your implementation in SendEmail
. However I can still not reproduce the issue. You can compare this with the following class and test case:
I'm still wondering what this code is doing:
@ClassRule
public static FakeSmtpRule smtpServer = new FakeSmtpRule(ServerConfiguration.create().port(2525).charset("UTF-8").relayDomains("localhost").userName("uottawa.outreach@gmail.com").password("uottawaTestTest");
@gessnerfl
The following line of code is what creates the SMTP server that I then run my client against. I assume that this line creates an SMTP server with the following credentials (userName
: uottawa.outreach@gmail.com and password
: uottawaTestTest) required to send emails to it. As seen from the documentation here: https://github.com/sleroy/fakesmtp-junit-runner/blob/master/README.md
@ClassRule
public static FakeSmtpRule smtpServer = new FakeSmtpRule(ServerConfiguration.create().port(2525).charset("UTF-8").relayDomains("localhost").userName("uottawa.outreach@gmail.com").password("uottawaTestTest");
Just like in GMAIL in order to send an email you must authenticate yourself against the SMTP servers in order to get the server to send an email. In the code snippet that you have provided to me I did not see anywhere the client authenticating itself against the SMTP server.
I see that in the Mail Sender class that you have procided, it does not use the userName and password provided to the SMTP server and thus for that reason it does not truly perform authentication.
This is the error stack that I get from my code:
1 [main] INFO com.github.sleroy.junit.mail.server.MailServer - Configuration of the server. ServerConfiguration [port=2525, bindAddress=null, storageCharsetName=UTF-8, authentication=Authentication [userName=test, password=test]]
4605 [main] INFO org.subethamail.smtp.server.SMTPServer - SMTP server *:2525 starting
4621 [org.subethamail.smtp.server.ServerThread *:2525] INFO org.subethamail.smtp.server.ServerThread - SMTP server *:2525 started
4915 [org.subethamail.smtp.server.Session-/127.0.0.1:54217] ERROR org.subethamail.smtp.server.Session - Unexpected error in the SMTP handler thread
java.lang.NullPointerException
at org.subethamail.smtp.command.AuthCommand.execute(AuthCommand.java:88)
at org.subethamail.smtp.server.RequireTLSCommandWrapper.execute(RequireTLSCommandWrapper.java:30)
at org.subethamail.smtp.server.CommandHandler.handleCommand(CommandHandler.java:99)
at org.subethamail.smtp.server.Session.runCommandLoop(Session.java:244)
at org.subethamail.smtp.server.Session.run(Session.java:145)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
Exception in thread "pool-1-thread-1" java.lang.NullPointerException
at org.subethamail.smtp.command.AuthCommand.execute(AuthCommand.java:88)
at org.subethamail.smtp.server.RequireTLSCommandWrapper.execute(RequireTLSCommandWrapper.java:30)
at org.subethamail.smtp.server.CommandHandler.handleCommand(CommandHandler.java:99)
at org.subethamail.smtp.server.Session.runCommandLoop(Session.java:244)
at org.subethamail.smtp.server.Session.run(Session.java:145)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
4921 [main] INFO com.github.sleroy.junit.mail.server.MailServer - Stopping the server
4921 [main] INFO org.subethamail.smtp.server.SMTPServer - SMTP server *:2525 stopping
4922 [org.subethamail.smtp.server.ServerThread *:2525] INFO org.subethamail.smtp.server.ServerThread - SMTP server *:2525 stopped
@pat-lego I do use login. The MailSender provides both options. However I have the feeling that you mix the projects. I do not see how this project relates to the implementation in https://github.com/sleroy/fakesmtp-junit-runner. I think it is not even used there. The mentioned project also uses https://github.com/voodoodyne/subethasmtp natively. So I guess this is the right place for the issue. Or am I wrong?
You are correct I did mix up the projects but I am still able to get the error. Now that being said I am not too sure if it is the GitHub project that is not sending in the data correctly to the https://github.com/voodoodyne/subethasmtp project or if it is a bug within the core project.
My guess based off of your testing is that it's how the other project is communicating with the main library. I will log a ticket on the other github project.
I apologize for the mistake.
Thank you for all your help.
On Dec 12, 2018 2:04 AM, Florian Gessner notifications@github.com wrote:
@pat-legohttps://github.com/pat-lego I do use login. The MailSender provides both options. However I have the feeling that you mix the projects. I do not see how this project relates to the implementation in https://github.com/sleroy/fakesmtp-junit-runner. I think it is not even used there. The mentioned project also uses https://github.com/voodoodyne/subethasmtp natively. So I guess this is the right place for the issue. Or am I wrong?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHubhttps://github.com/gessnerfl/fake-smtp-server/issues/16#issuecomment-446484266, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AjOE1HBbko55431QVBg4rCqQSp6NAB_Dks5u4KqLgaJpZM4ZIuOv.
@pat-lego excuse me Patrique i have the same error in my code.
have you fix the problem ?
can you share with me some information about the solution ?
When users have .auth() or (.userName() and .password()) enabled on the @Rule for the SMTP server the authentication mechanism of the mock server throws a Null Pointer Error.
Debugged it and saw that the error occurs at the following line:
if (clientInput.trim().equals(AUTH_CANCEL_COMMAND))
in the AuthCommand class returns null instead of the an empty string.This is stopping users from properly testing the SMTP server with Authentication.