Browse Source

first working version

drop_old_mail
Stephan Richter 3 years ago
parent
commit
523e2fc432
  1. 2
      pom.xml
  2. 4
      src/main/java/de/srsoftware/widerhall/data/ListMember.java
  3. 52
      src/main/java/de/srsoftware/widerhall/data/MailingList.java
  4. 41
      src/main/java/de/srsoftware/widerhall/mail/SmtpClient.java
  5. 2
      src/main/java/de/srsoftware/widerhall/web/Rest.java
  6. 2
      src/main/java/de/srsoftware/widerhall/web/Web.java
  7. 8
      static/templates/inspect.st
  8. 2
      static/templates/js.st

2
pom.xml

@ -6,7 +6,7 @@
<groupId>org.example</groupId> <groupId>org.example</groupId>
<artifactId>Widerhall</artifactId> <artifactId>Widerhall</artifactId>
<version>0.0.21</version> <version>0.1.1</version>
<build> <build>
<plugins> <plugins>
<plugin> <plugin>

4
src/main/java/de/srsoftware/widerhall/data/ListMember.java

@ -136,6 +136,10 @@ public class ListMember {
} }
public boolean isOwner(){
return hasState(STATE_OWNER);
}
/** /**
* return a set of list emails of MailingLists owned by the given user * return a set of list emails of MailingLists owned by the given user
* @param user * @param user

52
src/main/java/de/srsoftware/widerhall/data/MailingList.java

@ -40,8 +40,11 @@ public class MailingList implements MessageHandler {
private static final int STATE_PUBLIC = 2; private static final int STATE_PUBLIC = 2;
public static final int STATE_FORWARD_FROM = 4; public static final int STATE_FORWARD_FROM = 4;
public static final int STATE_FORWARD_ATTACHED = 8; public static final int STATE_FORWARD_ATTACHED = 8;
public static final int STATE_HIDE_RECEIVERS = 16;
public static final int STATE_REPLY_TO_LIST = 32;
private static final int VISIBLE = 1; private static final int VISIBLE = 1;
private static final int HIDDEN = 0; private static final int HIDDEN = 0;
private static final int DEFAULT_STATE = STATE_PENDING|STATE_HIDE_RECEIVERS;
private final String name; private final String name;
private final String email; private final String email;
private int state; private int state;
@ -88,7 +91,7 @@ public class MailingList implements MessageHandler {
* @throws SQLException * @throws SQLException
*/ */
public static MailingList create(String email, String name, String imapHost, int imapPort, String imapUser, String imapPass, String inbox, String smtpHost, int smtpPort, String smtpUser, String smtpPass) throws SQLException { public static MailingList create(String email, String name, String imapHost, int imapPort, String imapUser, String imapPass, String inbox, String smtpHost, int smtpPort, String smtpUser, String smtpPass) throws SQLException {
return new MailingList(email, name, imapHost, imapPort, imapUser, imapPass, inbox, smtpHost, smtpPort, smtpUser, smtpPass, STATE_PENDING).save(); return new MailingList(email, name, imapHost, imapPort, imapUser, imapPass, inbox, smtpHost, smtpPort, smtpUser, smtpPass, DEFAULT_STATE).save();
} }
/** /**
@ -143,9 +146,17 @@ public class MailingList implements MessageHandler {
private void forward(Message message) throws MessagingException { private void forward(Message message) throws MessagingException {
try { try {
var emails = members().stream().map(ListMember::user).map(User::email).toList(); String newSender = !hasState(STATE_FORWARD_FROM) ? email() : null;
String sender = (state & STATE_FORWARD_FROM) > 0 ? message.getFrom()[0].toString() : email(); var receivers = members()
smtp.bccForward(sender,message,emails); .stream()
.map(ListMember::user)
.map(User::email)
.toList();
var subject = message.getSubject();
// TODO: remove '(from …)' from subject
if (!subject.contains(stamp())) subject = stamp()+" "+subject;
var replyTo = (newSender == null && hasState(STATE_REPLY_TO_LIST)) ? email() : null;
smtp.forward(newSender,receivers,message,subject,hasState(STATE_FORWARD_ATTACHED),hasState(STATE_HIDE_RECEIVERS),replyTo);
} catch (SQLException e) { } catch (SQLException e) {
LOG.error("Failed to read list members of {} from database. Cannot forward message!",email(),e); LOG.error("Failed to read list members of {} from database. Cannot forward message!",email(),e);
} }
@ -194,6 +205,10 @@ public class MailingList implements MessageHandler {
setFlag(STATE_PUBLIC,!hide); setFlag(STATE_PUBLIC,!hide);
} }
public void hideReceivers(boolean hide) throws SQLException {
setFlag(STATE_HIDE_RECEIVERS,hide);
}
/** /**
* test, whether the current ML is subscribable by a given user * test, whether the current ML is subscribable by a given user
* @param user * @param user
@ -235,7 +250,7 @@ public class MailingList implements MessageHandler {
public boolean mayBeAlteredBy(User user) { public boolean mayBeAlteredBy(User user) {
if (user.hashPermission(PERMISSION_ADMIN)) return true; if (user.hashPermission(PERMISSION_ADMIN)) return true;
try { try {
if (ListMember.load(this,user).hasState(ListMember.STATE_OWNER)) return true; if (ListMember.load(this,user).isOwner()) return true;
} catch (SQLException e) { } catch (SQLException e) {
LOG.debug("Error loading list member for ({}, {})",user.email(),email()); LOG.debug("Error loading list member for ({}, {})",user.email(),email());
} }
@ -245,7 +260,7 @@ public class MailingList implements MessageHandler {
public boolean mayBeTestedBy(User user) { public boolean mayBeTestedBy(User user) {
if (user.hashPermission(PERMISSION_ADMIN)) return true; if (user.hashPermission(PERMISSION_ADMIN)) return true;
try { try {
if (ListMember.load(this,user).hasState(ListMember.STATE_OWNER)) return true; if (ListMember.load(this,user).isOwner()) return true;
} catch (SQLException e) { } catch (SQLException e) {
LOG.debug("Error loading list member for ({}, {})",user.email(),email()); LOG.debug("Error loading list member for ({}, {})",user.email(),email());
} }
@ -259,7 +274,7 @@ public class MailingList implements MessageHandler {
public boolean membersMayBeListedBy(User user) { public boolean membersMayBeListedBy(User user) {
if (user.hashPermission(PERMISSION_ADMIN)) return true; if (user.hashPermission(PERMISSION_ADMIN)) return true;
try { try {
if (ListMember.load(this,user).hasState(ListMember.STATE_OWNER)) return true; if (ListMember.load(this,user).isOwner()) return true;
} catch (SQLException e) { } catch (SQLException e) {
LOG.debug("Error loading list member for ({}, {})",user.email(),email()); LOG.debug("Error loading list member for ({}, {})",user.email(),email());
} }
@ -287,8 +302,18 @@ public class MailingList implements MessageHandler {
@Override @Override
public void onMessageReceived(Message message) throws MessagingException { public void onMessageReceived(Message message) throws MessagingException {
LOG.debug("Message received: {}",message.getFrom()); LOG.debug("Message received: {}",message.getFrom());
storeMessage(message); String subject = message.getSubject();
forward(message); if (subject.toLowerCase().contains("undelivered")){
try {
var receivers = members().stream().filter(ListMember::isOwner).map(ListMember::user).map(User::email).toList();
smtp.forward(email(), receivers, message, message.getSubject(), false,false,null);
} catch (SQLException e){
LOG.error("Was not able to load members of {}; Non-Delivery notification dropped!",this.email(),e);
}
} else {
storeMessage(message);
forward(message);
}
} }
/** /**
@ -311,6 +336,10 @@ public class MailingList implements MessageHandler {
return list; return list;
} }
public void replyToList(boolean on) throws SQLException {
setFlag(STATE_REPLY_TO_LIST,on);
}
/** /**
* creates a map of the current ML containing all fields but passwords. * creates a map of the current ML containing all fields but passwords.
@ -441,6 +470,11 @@ public class MailingList implements MessageHandler {
} }
} }
private String stamp() {
return "["+name+"]";
}
private void storeMessage(Message message){ private void storeMessage(Message message){
// TODO: implement // TODO: implement
} }

41
src/main/java/de/srsoftware/widerhall/mail/SmtpClient.java

@ -30,21 +30,42 @@ public class SmtpClient {
this.port = port; this.port = port;
} }
public void bccForward(String from, Message message, List<String> emails) throws MessagingException {
public void forward(String newSender, List<String> receivers, Message message, String subject, boolean forwardAsAttachment, boolean bcc, String replyTo) throws MessagingException {
if (session == null) login(); if (session == null) login();
MimeMessage forward = new MimeMessage(session); MimeMessage forward = new MimeMessage(session);
forward.setFrom(from); var oldSender = message.getFrom()[0].toString();
forward.setRecipients(Message.RecipientType.BCC,InternetAddress.parse(String.join(", ",emails))); if (newSender != null){
forward.setSubject(message.getSubject()); forward.setFrom(newSender);
forward.setSubject(subject+" (from "+oldSender+")");
} else {
forward.setFrom(oldSender);
forward.setSubject(subject);
}
if (replyTo != null) forward.setReplyTo(InternetAddress.parse(replyTo));
var recipientType = bcc ? Message.RecipientType.BCC : Message.RecipientType.TO;
forward.setRecipients(recipientType,InternetAddress.parse(String.join(", ",receivers)));
MimeMultipart multipart = new MimeMultipart(); MimeMultipart multipart = new MimeMultipart();
MimeBodyPart messageBodyPart = new MimeBodyPart(); if (forwardAsAttachment){
MimeBodyPart bodyPart = new MimeBodyPart();
messageBodyPart.setDataHandler(message.getDataHandler()); bodyPart.setText("Find the forwarded message in the attachment(s)!\n");
multipart.addBodyPart(messageBodyPart); multipart.addBodyPart(bodyPart);
// create another body part to contain the message to be forwarded
bodyPart = new MimeBodyPart();
// forwardedMsg is the MimeMessage object you want to forward as an attachment
bodyPart.setContent(message, "message/rfc822");
bodyPart.setDisposition(Part.ATTACHMENT);
multipart.addBodyPart(bodyPart);
} else {
MimeBodyPart bodyPart = new MimeBodyPart();
bodyPart.setDataHandler(message.getDataHandler());
multipart.addBodyPart(bodyPart);
}
forward.setContent(multipart); forward.setContent(multipart);
send(forward); send(forward);
} }

2
src/main/java/de/srsoftware/widerhall/web/Rest.java

@ -220,6 +220,8 @@ public class Rest extends HttpServlet {
var map = new HashMap<>(); var map = new HashMap<>();
if (list.hasState(MailingList.STATE_FORWARD_FROM)) map.put("forward_from",true); if (list.hasState(MailingList.STATE_FORWARD_FROM)) map.put("forward_from",true);
if (list.hasState(MailingList.STATE_FORWARD_ATTACHED)) map.put("forward_attached",true); if (list.hasState(MailingList.STATE_FORWARD_ATTACHED)) map.put("forward_attached",true);
if (list.hasState(MailingList.STATE_HIDE_RECEIVERS)) map.put("hide_receivers",true);
if (list.hasState(MailingList.STATE_REPLY_TO_LIST)) map.put("reply_to_list",true);
return map; return map;
} }

2
src/main/java/de/srsoftware/widerhall/web/Web.java

@ -291,6 +291,8 @@ public class Web extends TemplateServlet {
try { try {
list.forwardFrom(Util.getCheckbox(req, "forward_from")); list.forwardFrom(Util.getCheckbox(req, "forward_from"));
list.forwardAttached(Util.getCheckbox(req, "forward_attached")); list.forwardAttached(Util.getCheckbox(req, "forward_attached"));
list.hideReceivers(Util.getCheckbox(req, "hide_receivers"));
list.replyToList(Util.getCheckbox(req, "reply_to_list"));
data.put(NOTES,t("Sucessfully updated MailingList!")); data.put(NOTES,t("Sucessfully updated MailingList!"));
} catch (SQLException e){ } catch (SQLException e){
LOG.warn("Failed to update MailingList:",e); LOG.warn("Failed to update MailingList:",e);

8
static/templates/inspect.st

@ -19,10 +19,18 @@
<input type="checkbox" name="forward_from"> <input type="checkbox" name="forward_from">
Forward using original sender Forward using original sender
</label> </label>
<label>
<input type="checkbox" name="reply_to_list">
Set list adddress in "ReplyTo" header
</label>
<label> <label>
<input type="checkbox" name="forward_attached"> <input type="checkbox" name="forward_attached">
Append original message as attachment Append original message as attachment
</label> </label>
<label>
<input type="checkbox" name="hide_receivers">
Hide receivers (using BCC)
</label>
<button type="submit">Save</button> <button type="submit">Save</button>
</fieldset> </fieldset>
</form> </form>

2
static/templates/js.st

@ -59,6 +59,8 @@ function showListDetail(data){
console.log(data); console.log(data);
if (data.forward_from) $('input[name="forward_from"]').prop('checked',true); if (data.forward_from) $('input[name="forward_from"]').prop('checked',true);
if (data.forward_attached) $('input[name="forward_attached"]').prop('checked',true); if (data.forward_attached) $('input[name="forward_attached"]').prop('checked',true);
if (data.hide_receivers) $('input[name="hide_receivers"]').prop('checked',true);
if (data.reply_to_list) $('input[name="reply_to_list"]').prop('checked',true);
} }
function showListOfEditableLists(data){ function showListOfEditableLists(data){

Loading…
Cancel
Save