@ -7,6 +7,8 @@ import de.srsoftware.widerhall.mail.SmtpClient;
@@ -7,6 +7,8 @@ import de.srsoftware.widerhall.mail.SmtpClient;
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
import javax.mail.Address ;
import javax.mail.Flags ;
import javax.mail.Message ;
import javax.mail.MessagingException ;
import javax.mail.internet.AddressException ;
@ -15,6 +17,7 @@ import java.io.UnsupportedEncodingException;
@@ -15,6 +17,7 @@ import java.io.UnsupportedEncodingException;
import java.sql.ResultSet ;
import java.sql.SQLException ;
import java.util.* ;
import java.util.stream.Collectors ;
import java.util.stream.Stream ;
import static de.srsoftware.widerhall.Constants.* ;
@ -46,6 +49,7 @@ public class MailingList implements MessageHandler {
@@ -46,6 +49,7 @@ public class MailingList implements MessageHandler {
private static final int VISIBLE = 1 ;
private static final int HIDDEN = 0 ;
private static final int DEFAULT_STATE = STATE_PENDING | STATE_HIDE_RECEIVERS ;
private static final String RETAINED_FOLDER = "retained" ;
private final String name ;
private final String email ;
private int state ;
@ -136,13 +140,9 @@ public class MailingList implements MessageHandler {
@@ -136,13 +140,9 @@ public class MailingList implements MessageHandler {
public MailingList enable ( boolean enable ) throws SQLException {
if ( ! enable ) imap . stop ( ) ;
setFlag ( STATE_ENABLED , enable ) ;
if ( enable ) {
imap . start ( ) . addListener ( this ) ;
} else {
imap . stop ( ) ;
}
if ( enable ) imap . start ( ) . addListener ( this ) ;
return this ;
}
@ -217,7 +217,7 @@ public class MailingList implements MessageHandler {
@@ -217,7 +217,7 @@ public class MailingList implements MessageHandler {
* @return
* /
public boolean isOpenFor ( User user ) {
if ( ( state & STATE_PUBLIC ) > 0 ) return true ; // all users may subscribe public mailing lists
if ( hasState ( STATE_PUBLIC ) ) return true ; // all users may subscribe public mailing lists
if ( user = = null ) return false ;
try {
var member = ListMember . load ( this , user ) ;
@ -312,10 +312,33 @@ public class MailingList implements MessageHandler {
@@ -312,10 +312,33 @@ public class MailingList implements MessageHandler {
} catch ( SQLException e ) {
LOG . error ( "Was not able to load members of {}; Non-Delivery notification dropped!" , this . email ( ) , e ) ;
}
} else {
storeMessage ( message ) ;
forward ( message ) ;
return ;
}
Address from = message . getFrom ( ) [ 0 ] ;
if ( from instanceof InternetAddress internetAddress ) {
var senderEmail = ( ( InternetAddress ) from ) . getAddress ( ) ;
if ( ! hasState ( STATE_OPEN ) & & ! this . hashMember ( senderEmail ) ) {
retainMessage ( message ) ;
sentRetentionNotification ( senderEmail ) ;
return ;
}
}
storeMessage ( message ) ;
forward ( message ) ;
}
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() failded for {}" , email ( ) , e ) ;
}
return false ;
}
public MailingList open ( boolean open ) throws SQLException {
@ -346,7 +369,29 @@ public class MailingList implements MessageHandler {
@@ -346,7 +369,29 @@ public class MailingList implements MessageHandler {
return setFlag ( STATE_REPLY_TO_LIST , on ) ;
}
private void retainMessage ( Message message ) {
String subject = "unknown mail" ;
try {
subject = message . getSubject ( ) ;
imap . move ( message , RETAINED_FOLDER ) ;
return ;
} catch ( MessagingException e ) {
LOG . warn ( "Retaining message {} failed!" , subject , e ) ;
}
try {
message . setFlag ( Flags . Flag . SEEN , true ) ;
return ;
} catch ( MessagingException e ) {
LOG . warn ( "Failed to flag message {} as SEEN!" , subject , e ) ;
}
try {
LOG . error ( "Retaining message {} failed. To avoid dead loop, the MailingList '{}' will be stopped!" , subject , email ( ) ) ;
enable ( false ) ;
} catch ( SQLException sqle ) {
LOG . debug ( "Failed to update list state in database:" , sqle ) ;
}
}
/ * *
* creates a map of the current ML containing all fields but passwords .
* @return
@ -402,7 +447,30 @@ public class MailingList implements MessageHandler {
@@ -402,7 +447,30 @@ public class MailingList implements MessageHandler {
var config = Configuration . instance ( ) ;
var url = new StringBuilder ( config . baseUrl ( ) ) . append ( "/confirm?token=" ) . append ( token ) ;
var text = t ( "Please go to {} in order to complete your list subscription!" , url ) ;
smtp . login ( ) . send ( email ( ) , name ( ) , user . email ( ) , subject , text ) ;
smtp . send ( email ( ) , name ( ) , user . email ( ) , subject , text ) ;
}
private void sentRetentionNotification ( String senderEmail ) {
try {
var receivers = members ( )
. stream ( )
. filter ( ListMember : : isOwner )
. map ( ListMember : : user )
. map ( User : : email )
. collect ( Collectors . joining ( ", " ) ) ;
var subject = t ( "List '{}' requires attention!" , name ( ) ) ;
var text = t ( "This list received an email from {}, who is not member of the list.\nThe email has been moved to the '{}' folder.\nYou may manually forward this message or drop it." , senderEmail , RETAINED_FOLDER ) ;
smtp . send ( email ( ) , name ( ) , receivers , subject , text ) ;
subject = t ( "Your message to {} was rejected!" , email ( ) ) ;
text = t ( "You have tried to send a message to the list '{}', which failed. This is because you are not a member of this list.\n" , name ( ) ) ;
if ( hasState ( STATE_PUBLIC ) ) text + = t ( "You may go to {} and subscribe to the list, then try again." , Configuration . instance ( ) . baseUrl ( ) ) ;
smtp . send ( email ( ) , name ( ) , senderEmail , subject , text ) ;
} catch ( SQLException e ) {
LOG . error ( "Failed to load list of owners of mailing list. Retention notification was not sent to owners of {}" , email ( ) , e ) ;
} catch ( MessagingException | UnsupportedEncodingException e ) {
LOG . error ( "Failed to send retention notification to owners of {}" , email ( ) , e ) ;
}
}
private MailingList setFlag ( int flag , boolean on ) throws SQLException {
@ -416,6 +484,10 @@ public class MailingList implements MessageHandler {
@@ -416,6 +484,10 @@ public class MailingList implements MessageHandler {
if ( hasState ( STATE_ENABLED ) ) map . put ( "enabled" , VISIBLE ) ;
if ( hasState ( STATE_PUBLIC ) ) map . put ( "public" , VISIBLE ) ;
if ( hasState ( STATE_FORWARD_FROM ) ) map . put ( "original_from" , HIDDEN ) ;
if ( hasState ( STATE_FORWARD_ATTACHED ) ) map . put ( "forward_attached" , HIDDEN ) ;
if ( hasState ( STATE_HIDE_RECEIVERS ) ) map . put ( "hide_receivers" , HIDDEN ) ;
if ( hasState ( STATE_REPLY_TO_LIST ) ) map . put ( "reply_to_list" , HIDDEN ) ;
if ( hasState ( STATE_OPEN ) ) map . put ( "open" , VISIBLE ) ;
return map ;
}