diff --git a/pom.xml b/pom.xml
index ec48e0b..20f4b79 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
org.example
Widerhall
- 0.2.33
+ 0.2.35
diff --git a/src/main/java/de/srsoftware/widerhall/data/MailingList.java b/src/main/java/de/srsoftware/widerhall/data/MailingList.java
index 80d45e4..064eac6 100644
--- a/src/main/java/de/srsoftware/widerhall/data/MailingList.java
+++ b/src/main/java/de/srsoftware/widerhall/data/MailingList.java
@@ -164,24 +164,22 @@ public class MailingList implements MessageHandler, ProblemListener {
return this;
}
- private void forward(Message message) throws MessagingException {
- try {
- String newSender = !hasState(STATE_FORWARD_FROM) ? email() : null;
- var receivers = members()
- .stream()
- .map(ListMember::user)
- .map(User::email)
- .toList();
- var subject = message.getSubject();
+ private void forward(Message message, Stream members) throws MessagingException {
+ if (hasState(STATE_PUBLIC_ARCHIVE)) storeMessage(message);
+ String newSender = !hasState(STATE_FORWARD_FROM) ? email() : null;
+ var receivers = members
+ .map(ListMember::user)
+ .map(User::email)
+ .toList();
+ var subject = message.getSubject();
- 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) {
- LOG.error("Laden der Listen-Mitglieder von {} fehlgeschlagen. Nachricht kann nicht weitergeleitet werden!",email(),e);
- }
+ 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);
}
+
+
public MailingList forwardAttached(boolean forward) throws SQLException {
return setFlag(STATE_FORWARD_ATTACHED,forward);
}
@@ -217,16 +215,6 @@ public class MailingList implements MessageHandler, ProblemListener {
return ml;
}
- private boolean hashMember(String senderEmail) {
- if (senderEmail == null) return false;
- try {
- return members().stream().map(ListMember::user).map(User::email).anyMatch(senderEmail::equals);
- } catch (SQLException e) {
- LOG.warn("hasMember() fehlgeschlagen für {}",email(),e);
- }
- return false;
- }
-
public boolean hasState(int test){
return (state & test) > 0;
}
@@ -239,20 +227,6 @@ public class MailingList implements MessageHandler, ProblemListener {
return setFlag(STATE_HIDE_RECEIVERS,hide);
}
- public boolean isAllowedSender(String senderEmail){
- if (senderEmail == null || senderEmail.isBlank()) return false;
- try {
- var user = User.load(senderEmail);
- if (user == null) return this.isOpenForGuests();
- var member = ListMember.load(this,user);
- if (member == null) return this.isOpenForGuests();
- if (member.isModerator()) return true;
- if (member.isSubscriber()) return this.isOpenForSubscribers();
- } catch (SQLException e) {
- LOG.warn("Laden des Nutzers zu {} fehlgeschlagen",senderEmail,e);
- }
- return this.isOpenForGuests();
- }
/**
* test, whether the current ML is subscribable by a given user
* @param user
@@ -344,8 +318,8 @@ public class MailingList implements MessageHandler, ProblemListener {
return false;
}
- public Set members() throws SQLException {
- return ListMember.of(this);
+ public Stream members() throws SQLException {
+ return ListMember.of(this).stream();
}
public boolean membersMayBeListedBy(User user) {
@@ -387,6 +361,10 @@ public class MailingList implements MessageHandler, ProblemListener {
}
+ public Stream moderators() throws SQLException {
+ return members().filter(ListMember::isModerator);
+ }
+
public boolean modsMayEditMods(){
return hasState(STATE_MODS_CAN_EDIT_MODS);
}
@@ -413,27 +391,52 @@ public class MailingList implements MessageHandler, ProblemListener {
public void onMessageReceived(Message message) throws MessagingException {
LOG.info("Nachricht empfangen: {}",message.getFrom());
String subject = message.getSubject();
- 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);
- }
- return;
- }
- Address from = message.getFrom()[0];
- if (from instanceof InternetAddress internetAddress){
- var senderEmail = ((InternetAddress) from).getAddress();
- if (!isAllowedSender(senderEmail)) {
- retainMessage(message);
- sentRetentionNotification(senderEmail);
+ try {
+ if (subject.toLowerCase().contains("undelivered")){
+ forward(message,moderators());
return;
}
+
+ Address from = message.getFrom()[0];
+ if (from instanceof InternetAddress internetAddress) {
+ var senderEmail = internetAddress.getAddress();
+
+ var user = User.load(senderEmail);
+ if (user == null) { // no subscription
+ if (this.isOpenForGuests()) {
+ forward(message,subscribers());
+ } else {
+ retainMessage(message);
+ sentRetentionNotification(senderEmail);
+
+ }
+ return;
+ }
+
+ var member = ListMember.load(this, user);
+ if (member == null || member.isAwaiting()) { // no subscription
+ if (this.isOpenForGuests()) {
+ forward(message,subscribers());
+ } else {
+ retainMessage(message);
+ sentRetentionNotification(senderEmail);
+ }
+ return;
+ }
+
+ // at this point the member is at least a subscriber!
+
+ if (member.isModerator() || this.isOpenForSubscribers()) {
+ forward(message,subscribers());
+ } else {
+ forward(message,moderators());
+ }
+ }
+ } catch (SQLException e){
+ LOG.warn("Failed to process message '{}'",subject,e);
}
- if (hasState(STATE_PUBLIC_ARCHIVE)) storeMessage(message);
- forward(message);
+
}
public MailingList openForGuests(boolean open) throws SQLException {
@@ -464,6 +467,10 @@ public class MailingList implements MessageHandler, ProblemListener {
return list;
}
+ public Stream owners() throws SQLException {
+ return members().filter(ListMember::isOwner);
+ }
+
public MailingList replyToList(boolean on) throws SQLException {
return setFlag(STATE_REPLY_TO_LIST,on);
}
@@ -537,9 +544,7 @@ public class MailingList implements MessageHandler, ProblemListener {
private void sentRetentionNotification(String senderEmail) {
try {
- var receivers = members()
- .stream()
- .filter(ListMember::isOwner)
+ var receivers = moderators()
.map(ListMember::user)
.map(User::email)
.collect(Collectors.joining(", "));
@@ -620,6 +625,10 @@ public class MailingList implements MessageHandler, ProblemListener {
}
}
+ private Stream subscribers() throws SQLException {
+ return members().filter(ListMember::isSubscriber);
+ }
+
/**
* Request list subscription for the given user.
* Usually creates a ListMember entry with AWAITING_CONFIRMATION state is created and a confirmation request email is sent.
diff --git a/src/main/java/de/srsoftware/widerhall/mail/SmtpClient.java b/src/main/java/de/srsoftware/widerhall/mail/SmtpClient.java
index 0922005..1a7c3eb 100644
--- a/src/main/java/de/srsoftware/widerhall/mail/SmtpClient.java
+++ b/src/main/java/de/srsoftware/widerhall/mail/SmtpClient.java
@@ -37,15 +37,15 @@ public class SmtpClient {
MimeMessage forward = new MimeMessage(session);
var oldSender = message.getFrom()[0].toString();
if (newSender != null){
- var pos = subject.indexOf(" (from ");
+ var pos = subject.indexOf(" (von ");
while (pos > 0){
var end = subject.indexOf(')',pos);
if (end < pos) break;
subject = (subject.substring(0,pos)+subject.substring(end+1)).trim();
- pos = subject.indexOf(" (from ");
+ pos = subject.indexOf(" (von ");
}
forward.setFrom(newSender);
- forward.setSubject(subject+" (from "+oldSender+")");
+ forward.setSubject(subject+" (von "+oldSender+")");
} else {
forward.setFrom(oldSender);
forward.setSubject(subject);
@@ -57,7 +57,7 @@ public class SmtpClient {
MimeMultipart multipart = new MimeMultipart();
if (forwardAsAttachment){
MimeBodyPart bodyPart = new MimeBodyPart();
- bodyPart.setText("Find the forwarded message in the attachment(s)!\n");
+ bodyPart.setText("Die weitergeleitete Nachricht findest du im Anhang dieser E-Mail!\n");
multipart.addBodyPart(bodyPart);
// create another body part to contain the message to be forwarded
diff --git a/src/main/java/de/srsoftware/widerhall/web/Rest.java b/src/main/java/de/srsoftware/widerhall/web/Rest.java
index 225e817..c9779bc 100644
--- a/src/main/java/de/srsoftware/widerhall/web/Rest.java
+++ b/src/main/java/de/srsoftware/widerhall/web/Rest.java
@@ -94,10 +94,15 @@ public class Rest extends HttpServlet {
if (!allowed) return Map.of(ERROR,"Es ist dir nicht gestattet, diese Liste zu löschen!");
try {
list.hide(true).enable(false).openForGuests(false).openForSubscribers(false);
- for (ListMember member : list.members()) { // drop all list members except for owner
- if (!member.isOwner()) member.unsubscribe();
- }
- } catch (SQLException e) {
+ list.members().forEach(listMember -> {
+ try {
+ listMember.unsubscribe();
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ });
+
+ } catch (Exception e) {
LOG.debug("Disabling and hiding of {} failed",list.email(),e);
}
return Map.of(SUCCESS,t("Liste {} deaktiviert, Abonnement gesperrt, Liste de-publiziert. Mitglieder wurden entfernt.",list.email()));
@@ -338,7 +343,6 @@ public class Rest extends HttpServlet {
if (!list.membersMayBeListedBy(user)) Map.of(ERROR,t("Es ist dir nicht gestattet, die Mitglieder von '{}' aufzulisten",list.email()));
try {
var members = list.members()
- .stream()
.map(ListMember::safeMap)
.toList();
return Map.of(MEMBERS,members,LIST,list.minimalMap());