Transfer of mailing execution to actual mailservice

This commit is contained in:
Luedtke 2021-07-09 17:13:51 +02:00
parent 4f1725251c
commit 6fb7824d8a
3 changed files with 183 additions and 95 deletions

View File

@ -1,101 +1,74 @@
package de.fswiai.klausurenmodul.controller;
import de.fswiai.klausurenmodul.model.Email;
import de.fswiai.klausurenmodul.service.MailService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicLong;
@RestController
public class MailController {
//DEPRECATED
private static final String template = "Hello %s! This is a test mail from the Fachschaft WIAI.";
private static final String user = "";
private static final String pw = "";
//TODO controllers should be stateless. This certainly is not. Solve differently.
private final AtomicLong counter = new AtomicLong(); //from the tutorial... deprc
@GetMapping("/mail")
public Email showDefaultMail(@RequestParam(value="recipientName", defaultValue = "Student") String recipientName){
return new Email(counter.incrementAndGet(),"defaultMailDestination", "defaultMailSource", String.format(template, recipientName));
return new Email(counter.incrementAndGet(),"defaultMailDestination", "defaultMailSource", String.format(template, recipientName), "defaultSubject");
}
//void for now only
//TODO Return datatype does not make sense yet -> Ask the frontend people
@PostMapping("/mail")
public Email sendMail(
@RequestParam(value = "recipientName", defaultValue = "") String recipientName,
@RequestParam(value = "toMail", defaultValue = "") String toMail,
@RequestParam(value = "fromMail", defaultValue = "") String fromMail)
@RequestParam(value = "fromMail", defaultValue = "") String fromMail,
@RequestParam(value = "subject", defaultValue = "") String subject,
@RequestParam(value = "body", defaultValue = "") String body,
@RequestParam(value = "mailConfig", defaultValue = "") String mailConfig)
{
Email mail = new Email(counter.incrementAndGet(), toMail, fromMail, String.format(template, recipientName));
Properties prop = new Properties();
prop.put("mail.smtp.auth", true);
prop.put("mail.smtp.starttls.enable", "true");
prop.put("mail.smtp.starttls.required", "true");
prop.put("mail.smtp.host", "exhub.uni-bamberg.de");
prop.put("mail.smtp.port", "587");
prop.put("mail.smtp.ssl.protocols", "TLSv1.2");
prop.put("mail.smtp.ssl.trust", "exhub.uni-bamberg.de");
Session session = Session.getInstance(prop, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user, pw);
}
});
System.out.println("- Attempting to send Mail:");
System.out.println(" Recipient Name: " + recipientName);
System.out.println(" ToMail: " + toMail);
System.out.println(" FromMail: " + fromMail);
if(toMail.isEmpty() || fromMail.isEmpty()){
System.out.println("Abort Mail sending");
return new Email(-1, "", "", "");
return new Email(-1, "", "", "", "");
}
try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(mail.getSourceAddress()));
// Stupid array. How is there not a method to only parse one address? TODO fix
message.setRecipient(Message.RecipientType.TO, InternetAddress.parse(mail.getDestinationAddress())[0]);
message.setSubject("Altklausuren-Anfrage");
Email mail = new Email(counter.incrementAndGet(), toMail, fromMail, body, subject);
// TODO add all the exam file stuff via another service, i.e. WatermarkingService
// ...
// TODO Mail Validate
if(mail.validateFields()){
try {
// TODO load the mail config file dep. on the given name in mailConfig and load that config.
MailService mailService = new MailService();
//For now...
mailService.loadDevelopmentDefault();
//mailService.loadFromConfig();
final String body = mail.getBody();
MimeBodyPart mimeBodyPart = new MimeBodyPart();
mimeBodyPart.setContent(body,"text/html");
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(mimeBodyPart);
//TODO add the watermarked exams here
//MimeBodyPart attachmentBodyPart = new MimeBodyPart();
//attachmentBodyPart.attachFile(new File("path/to/file"));
//multipart.addBodyPart(attachmentBodyPart);
message.setContent(multipart);
Transport.send(message);
System.out.println("- Mail Sent Successfully");
return mail;
} catch (javax.mail.internet.AddressException jMailException) {
System.err.println("Address Exception whilst sending the mail");
jMailException.printStackTrace();
return new Email(-1, "", "", "");
} catch (javax.mail.MessagingException jMailException) {
System.err.println("Messaging Exception whilst sending the mail");
jMailException.printStackTrace();
return new Email(-1, "", "", "");
// Send the mail via the mailService
boolean sendResult = mailService.sendMail(mail);
//TODO Properly handle return value from sendMail
if(sendResult){
System.out.println("Mail was sent successfully.");
}
return mail;
} catch (javax.mail.internet.AddressException jMailException) {
System.err.println("Address Exception whilst sending the mail");
jMailException.printStackTrace();
return new Email(-1, "", "", "", "");
} catch (javax.mail.MessagingException jMailException) {
System.err.println("Messaging Exception whilst sending the mail");
jMailException.printStackTrace();
return new Email(-1, "", "", "", "");
}
} else {
System.err.println("Mail is not valid.");
return new Email(-1, "", "", "", "");
}
}
}

View File

@ -1,24 +1,44 @@
package de.fswiai.klausurenmodul.model;
import java.io.File;
import java.util.List;
public class Email {
private final long id;
private String destinationAddress;
private String sourceAddress;
private String body;
// Appended documents?
// bool 'sent'?
private String subject;
private List<File> fileList;
public Email(long id, String destinationAddress, String sourceAddress, String body){
public Email(long id, String destinationAddress, String sourceAddress, String body, String subject, List<File> fileList) {
this.id = id;
this.destinationAddress = destinationAddress;
this.sourceAddress = sourceAddress;
this.body = body;
this.subject = subject;
this.fileList = fileList;
}
public Email(long id, String destinationAddress, String sourceAddress, String body, String subject) {
this.id = id;
this.destinationAddress = destinationAddress;
this.sourceAddress = sourceAddress;
this.body = body;
this.subject = subject;
fileList = null;
}
public long getId() {
return id;
}
public boolean hasFiles() {
if(fileList == null){
return false;
} else return (!fileList.isEmpty());
}
public String getDestinationAddress() {
return destinationAddress;
}
@ -42,4 +62,29 @@ public class Email {
public void setBody(String body) {
this.body = body;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public List<File> getFileList() {
return fileList;
}
public void setFileList(List<File> fileList) {
this.fileList = fileList;
}
public boolean validateFields(){
if(sourceAddress.isEmpty() || destinationAddress.isEmpty() || subject.isEmpty() || body.isEmpty()){
System.err.println("attribute(s) in mail are missing.");
return false;
} else {
return true;
}
}
}

View File

@ -1,9 +1,15 @@
package de.fswiai.klausurenmodul.service;
import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import de.fswiai.klausurenmodul.model.Email;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Properties;
public class MailService {
@ -14,6 +20,9 @@ public class MailService {
private String tlsVersion = "TLSv1.2"; //maybe already use 1.3?
private boolean useSTARTTLS = true;
public MailService() {
}
public MailService(String username, String password, int smtpPort, String smtpHost, String tlsVersion, boolean useSTARTTLS) {
this.username = username;
this.password = password;
@ -23,35 +32,96 @@ public class MailService {
this.useSTARTTLS = useSTARTTLS;
}
//TODO switch boolean to some result class
public boolean sendSimpleMail(String subject, String body)
throws javax.mail.internet.AddressException, javax.mail.MessagingException {
public void loadFromConfig(String configJSON){
//TODO First Idea for how we handle mail accounts/configurations.
// -> Build some parser for a JSON schema (or something else, idc) that will set username, password and so on.
}
return true;
public void loadDevelopmentDefault(){
this.username = "ex311199c";
this.password = "";
this.smtpPort = 587;
this.smtpHost = "exhub.uni-bamberg.de";
this.tlsVersion = "TLSv1.2";
this.useSTARTTLS = true;
}
//TODO switch boolean to some result class
public boolean sendMailWithAttachments(String subject, String body, File[] files)
throws javax.mail.internet.AddressException, javax.mail.MessagingException {
//TODO switch to a proper logging framework
public boolean sendMail(Email mail)
throws javax.mail.internet.AddressException, javax.mail.MessagingException
{
System.out.println("- Attempting to send Mail:");
System.out.println(" From: " + mail.getSourceAddress());
System.out.println(" To: " + mail.getDestinationAddress());
return true;
// Open the session and generate the basic message
Session session = getNewSession();
Message message = generateBaseMessage(session, mail);
if(message != null){
// Add the message body as a mime body part.
MimeBodyPart mimeBodyPart = new MimeBodyPart();
mimeBodyPart.setContent(mail.getBody(),"text/html");
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(mimeBodyPart);
// If the Email Object contains files to append, then append them.
if(mail.hasFiles()){
// Add the files to append
mail.getFileList().forEach(file -> {
try {
MimeBodyPart attachmentBodyPart = new MimeBodyPart();
attachmentBodyPart.attachFile(file);
multipart.addBodyPart(attachmentBodyPart);
} catch (IOException e) {
System.err.println("File Attachment IO Exception");
e.printStackTrace();
} catch (MessagingException e) {
System.err.println("File Attachment Message Exception");
e.printStackTrace();
}
});
}
// Set the prepared Mime Multipart as the message content
message.setContent(multipart);
// Send the message
Transport.send(message);
return true;
} else {
System.err.println("Unable to send a mail (mail message creation failed).");
return false;
}
}
private Session configureSession(){
private Message generateBaseMessage(Session session, Email mail){
try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(mail.getSourceAddress()));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(mail.getDestinationAddress()));
message.setSubject(mail.getSubject());
return message;
} catch (javax.mail.internet.AddressException jMailException) {
System.err.println("Address Exception whilst generating the mail message");
} catch (javax.mail.MessagingException jMailException) {
System.err.println("Messaging Exception whilst generating the mail message");
}
return null;
}
private Session getNewSession(){
Properties prop = new Properties();
prop.put("mail.smtp.auth", true);
if(this.useSTARTTLS){
prop.put("mail.smtp.starttls.enable", "true");
prop.put("mail.smtp.starttls.required", "true");
} else {
prop.put("mail.smtp.starttls.enable", "false");
prop.put("mail.smtp.starttls.required", "false");
}
prop.put("mail.smtp.starttls.enable", this.useSTARTTLS ? "true" : "false");
prop.put("mail.smtp.starttls.required", this.useSTARTTLS ? "true" : "false");
prop.put("mail.smtp.host", this.smtpHost);
prop.put("mail.smtp.port", this.smtpPort);
prop.put("mail.smtp.ssl.protocols", this.tlsVersion);
prop.put("mail.smtp.ssl.trust", "exhub.uni-bamberg.de");
prop.put("mail.smtp.ssl.trust", this.smtpHost);
Session session = Session.getInstance(prop, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {