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; package de.fswiai.klausurenmodul.controller;
import de.fswiai.klausurenmodul.model.Email; 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.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; 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; import java.util.concurrent.atomic.AtomicLong;
@RestController @RestController
public class MailController { public class MailController {
//DEPRECATED
private static final String template = "Hello %s! This is a test mail from the Fachschaft WIAI."; 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 private final AtomicLong counter = new AtomicLong(); //from the tutorial... deprc
@GetMapping("/mail") @GetMapping("/mail")
public Email showDefaultMail(@RequestParam(value="recipientName", defaultValue = "Student") String recipientName){ 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") @PostMapping("/mail")
public Email sendMail( public Email sendMail(
@RequestParam(value = "recipientName", defaultValue = "") String recipientName, @RequestParam(value = "recipientName", defaultValue = "") String recipientName,
@RequestParam(value = "toMail", defaultValue = "") String toMail, @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()){ if(toMail.isEmpty() || fromMail.isEmpty()){
System.out.println("Abort Mail sending"); System.out.println("Abort Mail sending");
return new Email(-1, "", "", ""); return new Email(-1, "", "", "", "");
} }
try {
Message message = new MimeMessage(session); Email mail = new Email(counter.incrementAndGet(), toMail, fromMail, body, subject);
message.setFrom(new InternetAddress(mail.getSourceAddress())); // TODO add all the exam file stuff via another service, i.e. WatermarkingService
// ...
// Stupid array. How is there not a method to only parse one address? TODO fix // TODO Mail Validate
message.setRecipient(Message.RecipientType.TO, InternetAddress.parse(mail.getDestinationAddress())[0]); if(mail.validateFields()){
message.setSubject("Altklausuren-Anfrage"); try {
// TODO load the mail config file dep. on the given name in mailConfig and load that config.
final String body = mail.getBody(); MailService mailService = new MailService();
//For now...
MimeBodyPart mimeBodyPart = new MimeBodyPart(); mailService.loadDevelopmentDefault();
mimeBodyPart.setContent(body,"text/html"); //mailService.loadFromConfig();
Multipart multipart = new MimeMultipart(); // Send the mail via the mailService
multipart.addBodyPart(mimeBodyPart); boolean sendResult = mailService.sendMail(mail);
//TODO add the watermarked exams here //TODO Properly handle return value from sendMail
//MimeBodyPart attachmentBodyPart = new MimeBodyPart(); if(sendResult){
//attachmentBodyPart.attachFile(new File("path/to/file")); System.out.println("Mail was sent successfully.");
//multipart.addBodyPart(attachmentBodyPart); }
return mail;
message.setContent(multipart); } catch (javax.mail.internet.AddressException jMailException) {
Transport.send(message); System.err.println("Address Exception whilst sending the mail");
System.out.println("- Mail Sent Successfully"); jMailException.printStackTrace();
return new Email(-1, "", "", "", "");
return mail; } catch (javax.mail.MessagingException jMailException) {
} catch (javax.mail.internet.AddressException jMailException) { System.err.println("Messaging Exception whilst sending the mail");
System.err.println("Address Exception whilst sending the mail"); jMailException.printStackTrace();
jMailException.printStackTrace(); return new Email(-1, "", "", "", "");
return new Email(-1, "", "", ""); }
} else {
} catch (javax.mail.MessagingException jMailException) { System.err.println("Mail is not valid.");
System.err.println("Messaging Exception whilst sending the mail"); return new Email(-1, "", "", "", "");
jMailException.printStackTrace();
return new Email(-1, "", "", "");
} }
} }
} }

View File

@ -1,24 +1,44 @@
package de.fswiai.klausurenmodul.model; package de.fswiai.klausurenmodul.model;
import java.io.File;
import java.util.List;
public class Email { public class Email {
private final long id; private final long id;
private String destinationAddress; private String destinationAddress;
private String sourceAddress; private String sourceAddress;
private String body; private String body;
// Appended documents? private String subject;
// bool 'sent'? 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.id = id;
this.destinationAddress = destinationAddress; this.destinationAddress = destinationAddress;
this.sourceAddress = sourceAddress; this.sourceAddress = sourceAddress;
this.body = body; 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() { public long getId() {
return id; return id;
} }
public boolean hasFiles() {
if(fileList == null){
return false;
} else return (!fileList.isEmpty());
}
public String getDestinationAddress() { public String getDestinationAddress() {
return destinationAddress; return destinationAddress;
} }
@ -42,4 +62,29 @@ public class Email {
public void setBody(String body) { public void setBody(String body) {
this.body = 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; package de.fswiai.klausurenmodul.service;
import javax.mail.Authenticator; import de.fswiai.klausurenmodul.model.Email;
import javax.mail.PasswordAuthentication;
import javax.mail.Session; 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.File;
import java.io.IOException;
import java.util.List;
import java.util.Properties; import java.util.Properties;
public class MailService { public class MailService {
@ -14,6 +20,9 @@ public class MailService {
private String tlsVersion = "TLSv1.2"; //maybe already use 1.3? private String tlsVersion = "TLSv1.2"; //maybe already use 1.3?
private boolean useSTARTTLS = true; private boolean useSTARTTLS = true;
public MailService() {
}
public MailService(String username, String password, int smtpPort, String smtpHost, String tlsVersion, boolean useSTARTTLS) { public MailService(String username, String password, int smtpPort, String smtpHost, String tlsVersion, boolean useSTARTTLS) {
this.username = username; this.username = username;
this.password = password; this.password = password;
@ -23,35 +32,96 @@ public class MailService {
this.useSTARTTLS = useSTARTTLS; this.useSTARTTLS = useSTARTTLS;
} }
//TODO switch boolean to some result class public void loadFromConfig(String configJSON){
public boolean sendSimpleMail(String subject, String body) //TODO First Idea for how we handle mail accounts/configurations.
throws javax.mail.internet.AddressException, javax.mail.MessagingException { // -> 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 //TODO switch boolean to some result class
public boolean sendMailWithAttachments(String subject, String body, File[] files) //TODO switch to a proper logging framework
throws javax.mail.internet.AddressException, javax.mail.MessagingException { 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(); Properties prop = new Properties();
prop.put("mail.smtp.auth", true); prop.put("mail.smtp.auth", true);
if(this.useSTARTTLS){ prop.put("mail.smtp.starttls.enable", this.useSTARTTLS ? "true" : "false");
prop.put("mail.smtp.starttls.enable", "true"); prop.put("mail.smtp.starttls.required", this.useSTARTTLS ? "true" : "false");
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.host", this.smtpHost); prop.put("mail.smtp.host", this.smtpHost);
prop.put("mail.smtp.port", this.smtpPort); prop.put("mail.smtp.port", this.smtpPort);
prop.put("mail.smtp.ssl.protocols", this.tlsVersion); 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() { Session session = Session.getInstance(prop, new Authenticator() {
@Override @Override
protected PasswordAuthentication getPasswordAuthentication() { protected PasswordAuthentication getPasswordAuthentication() {