Browse Source

Merge branch 'main' into lang_de

lang_de
Stephan Richter 2 years ago
parent
commit
0e7ef745c4
  1. 2
      pom.xml
  2. 131
      src/main/java/de/srsoftware/widerhall/data/MailingList.java
  3. 8
      src/main/java/de/srsoftware/widerhall/mail/SmtpClient.java
  4. 14
      src/main/java/de/srsoftware/widerhall/web/Rest.java

2
pom.xml

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

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

@ -164,24 +164,22 @@ public class MailingList implements MessageHandler, ProblemListener {
return this; return this;
} }
private void forward(Message message) throws MessagingException { private void forward(Message message, Stream<ListMember> members) throws MessagingException {
try { if (hasState(STATE_PUBLIC_ARCHIVE)) storeMessage(message);
String newSender = !hasState(STATE_FORWARD_FROM) ? email() : null; String newSender = !hasState(STATE_FORWARD_FROM) ? email() : null;
var receivers = members() var receivers = members
.stream() .map(ListMember::user)
.map(ListMember::user) .map(User::email)
.map(User::email) .toList();
.toList(); var subject = message.getSubject();
var subject = message.getSubject();
if (!subject.contains(stamp())) subject = stamp()+" "+subject; if (!subject.contains(stamp())) subject = stamp()+" "+subject;
var replyTo = (newSender == null && hasState(STATE_REPLY_TO_LIST)) ? email() : null; 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); 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);
}
} }
public MailingList forwardAttached(boolean forward) throws SQLException { public MailingList forwardAttached(boolean forward) throws SQLException {
return setFlag(STATE_FORWARD_ATTACHED,forward); return setFlag(STATE_FORWARD_ATTACHED,forward);
} }
@ -217,16 +215,6 @@ public class MailingList implements MessageHandler, ProblemListener {
return ml; 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){ public boolean hasState(int test){
return (state & test) > 0; return (state & test) > 0;
} }
@ -239,20 +227,6 @@ public class MailingList implements MessageHandler, ProblemListener {
return setFlag(STATE_HIDE_RECEIVERS,hide); 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 * test, whether the current ML is subscribable by a given user
* @param user * @param user
@ -344,8 +318,8 @@ public class MailingList implements MessageHandler, ProblemListener {
return false; return false;
} }
public Set<ListMember> members() throws SQLException { public Stream<ListMember> members() throws SQLException {
return ListMember.of(this); return ListMember.of(this).stream();
} }
public boolean membersMayBeListedBy(User user) { public boolean membersMayBeListedBy(User user) {
@ -387,6 +361,10 @@ public class MailingList implements MessageHandler, ProblemListener {
} }
public Stream<ListMember> moderators() throws SQLException {
return members().filter(ListMember::isModerator);
}
public boolean modsMayEditMods(){ public boolean modsMayEditMods(){
return hasState(STATE_MODS_CAN_EDIT_MODS); return hasState(STATE_MODS_CAN_EDIT_MODS);
} }
@ -413,27 +391,52 @@ public class MailingList implements MessageHandler, ProblemListener {
public void onMessageReceived(Message message) throws MessagingException { public void onMessageReceived(Message message) throws MessagingException {
LOG.info("Nachricht empfangen: {}",message.getFrom()); LOG.info("Nachricht empfangen: {}",message.getFrom());
String subject = message.getSubject(); 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]; try {
if (from instanceof InternetAddress internetAddress){ if (subject.toLowerCase().contains("undelivered")){
var senderEmail = ((InternetAddress) from).getAddress(); forward(message,moderators());
if (!isAllowedSender(senderEmail)) {
retainMessage(message);
sentRetentionNotification(senderEmail);
return; 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 { public MailingList openForGuests(boolean open) throws SQLException {
@ -464,6 +467,10 @@ public class MailingList implements MessageHandler, ProblemListener {
return list; return list;
} }
public Stream<ListMember> owners() throws SQLException {
return members().filter(ListMember::isOwner);
}
public MailingList replyToList(boolean on) throws SQLException { public MailingList replyToList(boolean on) throws SQLException {
return setFlag(STATE_REPLY_TO_LIST,on); return setFlag(STATE_REPLY_TO_LIST,on);
} }
@ -537,9 +544,7 @@ public class MailingList implements MessageHandler, ProblemListener {
private void sentRetentionNotification(String senderEmail) { private void sentRetentionNotification(String senderEmail) {
try { try {
var receivers = members() var receivers = moderators()
.stream()
.filter(ListMember::isOwner)
.map(ListMember::user) .map(ListMember::user)
.map(User::email) .map(User::email)
.collect(Collectors.joining(", ")); .collect(Collectors.joining(", "));
@ -620,6 +625,10 @@ public class MailingList implements MessageHandler, ProblemListener {
} }
} }
private Stream<ListMember> subscribers() throws SQLException {
return members().filter(ListMember::isSubscriber);
}
/** /**
* Request list subscription for the given user. * 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. * Usually creates a ListMember entry with AWAITING_CONFIRMATION state is created and a confirmation request email is sent.

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

@ -37,15 +37,15 @@ public class SmtpClient {
MimeMessage forward = new MimeMessage(session); MimeMessage forward = new MimeMessage(session);
var oldSender = message.getFrom()[0].toString(); var oldSender = message.getFrom()[0].toString();
if (newSender != null){ if (newSender != null){
var pos = subject.indexOf(" (from "); var pos = subject.indexOf(" (von ");
while (pos > 0){ while (pos > 0){
var end = subject.indexOf(')',pos); var end = subject.indexOf(')',pos);
if (end < pos) break; if (end < pos) break;
subject = (subject.substring(0,pos)+subject.substring(end+1)).trim(); subject = (subject.substring(0,pos)+subject.substring(end+1)).trim();
pos = subject.indexOf(" (from "); pos = subject.indexOf(" (von ");
} }
forward.setFrom(newSender); forward.setFrom(newSender);
forward.setSubject(subject+" (from "+oldSender+")"); forward.setSubject(subject+" (von "+oldSender+")");
} else { } else {
forward.setFrom(oldSender); forward.setFrom(oldSender);
forward.setSubject(subject); forward.setSubject(subject);
@ -57,7 +57,7 @@ public class SmtpClient {
MimeMultipart multipart = new MimeMultipart(); MimeMultipart multipart = new MimeMultipart();
if (forwardAsAttachment){ if (forwardAsAttachment){
MimeBodyPart bodyPart = new MimeBodyPart(); 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); multipart.addBodyPart(bodyPart);
// create another body part to contain the message to be forwarded // create another body part to contain the message to be forwarded

14
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!"); if (!allowed) return Map.of(ERROR,"Es ist dir nicht gestattet, diese Liste zu löschen!");
try { try {
list.hide(true).enable(false).openForGuests(false).openForSubscribers(false); list.hide(true).enable(false).openForGuests(false).openForSubscribers(false);
for (ListMember member : list.members()) { // drop all list members except for owner list.members().forEach(listMember -> {
if (!member.isOwner()) member.unsubscribe(); try {
} listMember.unsubscribe();
} catch (SQLException e) { } catch (SQLException e) {
throw new RuntimeException(e);
}
});
} catch (Exception e) {
LOG.debug("Disabling and hiding of {} failed",list.email(),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())); 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())); if (!list.membersMayBeListedBy(user)) Map.of(ERROR,t("Es ist dir nicht gestattet, die Mitglieder von '{}' aufzulisten",list.email()));
try { try {
var members = list.members() var members = list.members()
.stream()
.map(ListMember::safeMap) .map(ListMember::safeMap)
.toList(); .toList();
return Map.of(MEMBERS,members,LIST,list.minimalMap()); return Map.of(MEMBERS,members,LIST,list.minimalMap());

Loading…
Cancel
Save