diff --git a/config/logback.xml b/config/logback.xml deleted file mode 100644 index 49a6adb..0000000 --- a/config/logback.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{5}: %msg%n - - - - - - - - - - - diff --git a/pom.xml b/pom.xml index f1c8a40..acbbd78 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.example Widerhall - 0.2.13 + 0.2.14 diff --git a/src/main/java/de/srsoftware/widerhall/data/MailingList.java b/src/main/java/de/srsoftware/widerhall/data/MailingList.java index b4ed0d4..a8cd967 100644 --- a/src/main/java/de/srsoftware/widerhall/data/MailingList.java +++ b/src/main/java/de/srsoftware/widerhall/data/MailingList.java @@ -28,6 +28,13 @@ import static de.srsoftware.widerhall.data.User.PERMISSION_ADMIN; * this class encapsulates a MailingList db object */ public class MailingList implements MessageHandler { + public static final String KEY_FORWARD_FROM = "forward_from"; + public static final String KEY_FORWARD_ATTACHED = "forward_attached"; + public static final String KEY_HIDE_RECEIVERS = "hide_receivers"; + public static final String KEY_REPLY_TO_LIST = "reply_to_list"; + public static final String KEY_OPEN_FOR_GUESTS = "open_for_guests"; + public static final String KEY_OPEN_FOR_SUBSCRIBERS = "open_for_subscribers"; + public static final String KEY_ARCHIVE = "archive"; private static final Logger LOG = LoggerFactory.getLogger(MailingList.class); private static final String IMAP_HOST = "imap_host"; private static final String IMAP_PORT = "imap_port"; @@ -47,10 +54,11 @@ public class MailingList implements MessageHandler { public static final int STATE_REPLY_TO_LIST = 32; // set REPLY TO field to list address? public static final int STATE_OPEN_FOR_GUESTS = 64; // allow anyone to send via this list? public static final int STATE_PUBLIC_ARCHIVE = 128; // save received messages in archive? - public static final int STATE_OPEN_FOR_MODS = 256; // allow mods to send via this list? + public static final int STATE_OPEN_FOR_SUBSCRIBERS = 256; // allow mods to send via this list? + public static final int STATE_MODS_CAN_CREATE_MODS = 512; // allow mods to make subscribers to mods? private static final int VISIBLE = 1; private static final int HIDDEN = 0; - private static final int DEFAULT_STATE = STATE_PENDING|STATE_HIDE_RECEIVERS|STATE_PUBLIC_ARCHIVE|STATE_OPEN_FOR_MODS; + private static final int DEFAULT_STATE = STATE_PENDING|STATE_HIDE_RECEIVERS|STATE_PUBLIC_ARCHIVE; private static final String RETAINED_FOLDER = "retained"; private final String name; private final String email; @@ -227,6 +235,20 @@ public class MailingList implements MessageHandler { 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("Failed to load User for {}",senderEmail,e); + } + return this.isOpenForGuests(); + } /** * test, whether the current ML is subscribable by a given user * @param user @@ -244,6 +266,14 @@ public class MailingList implements MessageHandler { } } + public boolean isOpenForGuests(){ + return hasState(STATE_OPEN_FOR_GUESTS); + } + + public boolean isOpenForSubscribers(){ + return hasState(STATE_OPEN_FOR_GUESTS|STATE_OPEN_FOR_SUBSCRIBERS); + } + /** * Load a ML object by it's identifying email address. * This is a cached method: if the ML has been loaded before, the already-loaded object will be returned. @@ -334,7 +364,7 @@ public class MailingList implements MessageHandler { Address from = message.getFrom()[0]; if (from instanceof InternetAddress internetAddress){ var senderEmail = ((InternetAddress) from).getAddress(); - if (!hasState(STATE_OPEN_FOR_GUESTS) && !this.hashMember(senderEmail)){ + if (!isAllowedSender(senderEmail)) { retainMessage(message); sentRetentionNotification(senderEmail); return; @@ -344,10 +374,14 @@ public class MailingList implements MessageHandler { forward(message); } - public MailingList open(boolean open) throws SQLException { + public MailingList openForGuests(boolean open) throws SQLException { return setFlag(STATE_OPEN_FOR_GUESTS,open); } + public MailingList openForSubscribers(boolean open) throws SQLException { + return setFlag(STATE_OPEN_FOR_SUBSCRIBERS,open); + } + /** * provide the set of mailing lists that are publicy open to subscriptions * @return @@ -490,7 +524,8 @@ public class MailingList implements MessageHandler { 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_FOR_GUESTS)) map.put("open",VISIBLE); + if (hasState(STATE_OPEN_FOR_GUESTS)) map.put("open_for_guests",HIDDEN); + if (hasState(STATE_OPEN_FOR_SUBSCRIBERS)) map.put("open_for_subscribers",HIDDEN); if (hasState(STATE_PUBLIC_ARCHIVE)) map.put("archive",VISIBLE); return map; } diff --git a/src/main/java/de/srsoftware/widerhall/web/Rest.java b/src/main/java/de/srsoftware/widerhall/web/Rest.java index 30c81ce..311c83e 100644 --- a/src/main/java/de/srsoftware/widerhall/web/Rest.java +++ b/src/main/java/de/srsoftware/widerhall/web/Rest.java @@ -21,6 +21,7 @@ import java.util.Map; import static de.srsoftware.widerhall.Constants.*; import static de.srsoftware.widerhall.Util.t; +import static de.srsoftware.widerhall.data.MailingList.*; public class Rest extends HttpServlet { private static final Logger LOG = LoggerFactory.getLogger(Rest.class); @@ -56,6 +57,19 @@ public class Rest extends HttpServlet { return Map.of(SUCCESS,"Updated user permissions"); } + private List archive(HttpServletRequest req) { + var list = Util.getMailingList(req); + if (list != null){ + try { + return Post.find(list).stream().map(Post::safeMap).toList(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + LOG.debug("list: {}",list.email()); + return List.of(); + } + @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String error = handleGet(req, resp); @@ -144,18 +158,7 @@ public class Rest extends HttpServlet { } } - private List archive(HttpServletRequest req) { - var list = Util.getMailingList(req); - if (list != null){ - try { - return Post.find(list).stream().map(Post::safeMap).toList(); - } catch (SQLException e) { - e.printStackTrace(); - } - } - LOG.debug("list: {}",list.email()); - return List.of(); - } + public String handlePost(HttpServletRequest req, HttpServletResponse resp){ @@ -232,12 +235,13 @@ public class Rest extends HttpServlet { private Map listDetail(MailingList list, User user) { if (list == null) return Map.of(ERROR,"no list email provided!"); var map = new HashMap<>(); - 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_HIDE_RECEIVERS)) map.put("hide_receivers",true); - if (list.hasState(MailingList.STATE_REPLY_TO_LIST)) map.put("reply_to_list",true); - if (list.hasState(MailingList.STATE_OPEN_FOR_GUESTS)) map.put("open",true); - if (list.hasState(MailingList.STATE_PUBLIC_ARCHIVE)) map.put("archive",true); + if (list.hasState(MailingList.STATE_FORWARD_FROM)) map.put(KEY_FORWARD_FROM,true); + if (list.hasState(MailingList.STATE_FORWARD_ATTACHED)) map.put(KEY_FORWARD_ATTACHED,true); + if (list.hasState(MailingList.STATE_HIDE_RECEIVERS)) map.put(KEY_HIDE_RECEIVERS,true); + if (list.hasState(MailingList.STATE_REPLY_TO_LIST)) map.put(KEY_REPLY_TO_LIST,true); + if (list.isOpenForGuests()) map.put(KEY_OPEN_FOR_GUESTS,true); + if (list.isOpenForSubscribers()) map.put(KEY_OPEN_FOR_SUBSCRIBERS,true); + if (list.hasState(MailingList.STATE_PUBLIC_ARCHIVE)) map.put(KEY_ARCHIVE,true); return map; } diff --git a/src/main/java/de/srsoftware/widerhall/web/Web.java b/src/main/java/de/srsoftware/widerhall/web/Web.java index 9b01702..721a4db 100644 --- a/src/main/java/de/srsoftware/widerhall/web/Web.java +++ b/src/main/java/de/srsoftware/widerhall/web/Web.java @@ -21,6 +21,7 @@ import java.util.Map; import static de.srsoftware.widerhall.Constants.*; import static de.srsoftware.widerhall.Util.t; +import static de.srsoftware.widerhall.data.MailingList.*; public class Web extends TemplateServlet { public static final String WEB_ROOT = "/web"; @@ -300,12 +301,13 @@ public class Web extends TemplateServlet { if (!error){ try { - list.forwardFrom(Util.getCheckbox(req, "forward_from")) - .forwardAttached(Util.getCheckbox(req, "forward_attached")) - .hideReceivers(Util.getCheckbox(req, "hide_receivers")) - .replyToList(Util.getCheckbox(req, "reply_to_list")) - .open(Util.getCheckbox(req,"open")) - .archive(Util.getCheckbox(req,"archive")); + list.forwardFrom(Util.getCheckbox(req, KEY_FORWARD_FROM)) + .forwardAttached(Util.getCheckbox(req, KEY_FORWARD_ATTACHED)) + .hideReceivers(Util.getCheckbox(req, KEY_HIDE_RECEIVERS)) + .replyToList(Util.getCheckbox(req, KEY_REPLY_TO_LIST)) + .openForGuests(Util.getCheckbox(req,KEY_OPEN_FOR_GUESTS)) + .openForSubscribers(Util.getCheckbox(req,KEY_OPEN_FOR_SUBSCRIBERS)) + .archive(Util.getCheckbox(req,KEY_ARCHIVE)); data.put(NOTES,t("Sucessfully updated MailingList!")); } catch (SQLException e){ LOG.warn("Failed to update MailingList:",e); diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml index 38483ff..a57f20a 100644 --- a/src/main/resources/logback.xml +++ b/src/main/resources/logback.xml @@ -11,6 +11,6 @@ - + diff --git a/static/templates/inspect.st b/static/templates/inspect.st index 5162fbf..3650777 100644 --- a/static/templates/inspect.st +++ b/static/templates/inspect.st @@ -11,37 +11,54 @@ «userinfo()» «messages()»

Widerhall '«data.list»' Details

- «listmembers()»
- Options for «data.list» - - - - - - + Settings +
+ Forward permissions +

+ Who is allowed to distribute mails via «data.list»? +

+ ✓ Oweners and Moderators + + +
+
+ Forward options + + + + +
+
+ Archive options + +
+ «listmembers()» diff --git a/static/templates/js.st b/static/templates/js.st index cc06e1d..fc29db7 100644 --- a/static/templates/js.st +++ b/static/templates/js.st @@ -74,12 +74,11 @@ function showListArchive(data){ } function showListDetail(data){ - if (data.forward_from) $('input[name="forward_from"]').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); - if (data.open) $('input[name="open"]').prop('checked',true); - if (data.archive) $('input[name="archive"]').prop('checked',true); + var options = ['forward_from','forward_attached','hide_receivers','reply_to_list','open_for_guests','open_for_subscribers','archive']; + options.forEach(function(option,index,array){ + console.log(option,'→',data[option]); + if (data[option]) $('input[name="'+option+'"]').prop('checked',true); + }); } function showListOfEditableLists(data){