diff --git a/pom.xml b/pom.xml
index a1ab163..04b7800 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
org.example
Widerhall
- 1.0.0
+ 1.0.1
diff --git a/src/main/java/de/srsoftware/widerhall/Constants.java b/src/main/java/de/srsoftware/widerhall/Constants.java
index fb9396b..cd57c4a 100644
--- a/src/main/java/de/srsoftware/widerhall/Constants.java
+++ b/src/main/java/de/srsoftware/widerhall/Constants.java
@@ -18,6 +18,8 @@ public class Constants {
public static final String LIST = "list";
public static final String LOCATIONS = "locations";
public static final String NAME = "name";
+ public static final String MESSAGE_ID = "message_id";
+ public static final String MODERATOR = "moderator";
public static final String MONTH = "month";
public static final String NOTES = "notes";
public static final String PASSWORD = "password";
diff --git a/src/main/java/de/srsoftware/widerhall/data/Database.java b/src/main/java/de/srsoftware/widerhall/data/Database.java
index b094c95..ae90a9b 100644
--- a/src/main/java/de/srsoftware/widerhall/data/Database.java
+++ b/src/main/java/de/srsoftware/widerhall/data/Database.java
@@ -169,8 +169,6 @@ public class Database {
}
}
-
-
@Override
protected Request clone() {
Request clone = new Request(new StringBuilder(sql));
diff --git a/src/main/java/de/srsoftware/widerhall/data/MailingList.java b/src/main/java/de/srsoftware/widerhall/data/MailingList.java
index 3e72621..ffe7afb 100644
--- a/src/main/java/de/srsoftware/widerhall/data/MailingList.java
+++ b/src/main/java/de/srsoftware/widerhall/data/MailingList.java
@@ -187,7 +187,7 @@ public class MailingList implements MessageHandler, ProblemListener {
}
private void forward(Message message, Stream members) throws MessagingException {
- if (hasState(STATE_PUBLIC_ARCHIVE)) storeMessage(message);
+ if (hasPublicArchive()) storeMessage(message);
String newSender = !hasState(STATE_FORWARD_FROM) ? email() : null;
var receivers = members
.map(ListMember::user)
@@ -238,6 +238,10 @@ public class MailingList implements MessageHandler, ProblemListener {
return ml;
}
+ public boolean hasPublicArchive() {
+ return hasState(STATE_PUBLIC_ARCHIVE);
+ }
+
public boolean hasState(int test){
return (state & test) > 0;
}
@@ -327,6 +331,7 @@ public class MailingList implements MessageHandler, ProblemListener {
}
public boolean mayBeAlteredBy(User user) {
+ if (user == null) return false;
if (user.hashPermission(PERMISSION_ADMIN)) return true;
try {
if (ListMember.load(this,user).isModerator()) return true;
@@ -602,9 +607,9 @@ public class MailingList implements MessageHandler, ProblemListener {
if (hasState(STATE_FORWARD_ATTACHED)) map.put(t("forward_attached"),HIDDEN);
if (hasState(STATE_HIDE_RECEIVERS)) map.put(t("hide_receivers"),HIDDEN);
if (hasState(STATE_REPLY_TO_LIST)) map.put(t("reply_to_list"),HIDDEN);
- if (hasState(STATE_OPEN_FOR_GUESTS)) map.put(t("open_for_guests"),HIDDEN);
- if (hasState(STATE_OPEN_FOR_SUBSCRIBERS)) map.put(t("open_for_subscribers"),HIDDEN);
- if (hasState(STATE_PUBLIC_ARCHIVE)) map.put(t("archive"),VISIBLE);
+ if (isOpenForGuests()) map.put(t("open_for_guests"),HIDDEN);
+ if (isOpenForSubscribers()) map.put(t("open_for_subscribers"),HIDDEN);
+ if (hasPublicArchive()) map.put(t("archive"),VISIBLE);
return map;
}
diff --git a/src/main/java/de/srsoftware/widerhall/data/Post.java b/src/main/java/de/srsoftware/widerhall/data/Post.java
index deee9eb..282ac49 100644
--- a/src/main/java/de/srsoftware/widerhall/data/Post.java
+++ b/src/main/java/de/srsoftware/widerhall/data/Post.java
@@ -96,7 +96,7 @@ public class Post {
return new File(filename);
}
- public static ArrayList find(MailingList list, String month, List allowedSenders) throws SQLException {
+ public static ArrayList find(MailingList list, String month, List allowedSenders) throws SQLException {
var query = Database.open()
.select(TABLE_NAME,"*","strftime('%Y-%m',date/1000,'unixepoch') as month")
.where(LIST,list.email())
@@ -140,6 +140,10 @@ public class Post {
return id;
}
+ public MailingList list() {
+ return list;
+ }
+
public static Post load(String id) throws SQLException {
var rs = Database.open().select(TABLE_NAME).where(ID,id).compile().exec();
try {
@@ -160,6 +164,11 @@ public class Post {
FILE,filename);
}
+ public void remove() throws SQLException {
+ Database.open().deleteFrom(TABLE_NAME).where(ID,id).compile().run();
+ file().delete();
+ }
+
public Map safeMap() {
return Map.of(ID,id,
LIST,list.name(),
@@ -188,5 +197,4 @@ public class Post {
public long timestamp(){
return timestamp;
}
-
}
diff --git a/src/main/java/de/srsoftware/widerhall/web/Rest.java b/src/main/java/de/srsoftware/widerhall/web/Rest.java
index b406a40..72bc6d4 100644
--- a/src/main/java/de/srsoftware/widerhall/web/Rest.java
+++ b/src/main/java/de/srsoftware/widerhall/web/Rest.java
@@ -13,6 +13,7 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.NotAllowedException;
import java.io.IOException;
import java.sql.SQLException;
import java.time.Month;
@@ -40,6 +41,7 @@ public class Rest extends HttpServlet {
private static final String LIST_SHOW = "list/show";
private static final String LIST_TEST = "list/test";
private static final String LIST_SUBSCRIBABLE = "list/subscribable";
+ private static final String MAIL_DROP = "mail/drop";
private static final String USER_ADD_PERMISSION = "user/addpermission";
private static final String USER_DROP_PERMISSION = "user/droppermission";
private static final String USER_LIST = "user/list";
@@ -62,28 +64,30 @@ public class Rest extends HttpServlet {
return Map.of(SUCCESS,"Nutzer-Berechtigungen aktualisiert");
}
- private Map archive(MailingList list, String month, User requestingUser){
- if (list != null){
- try {
- var allEmails = requestingUser != null || list.hasState(STATE_OPEN_FOR_SUBSCRIBERS) || list.hasState(STATE_OPEN_FOR_GUESTS);
- var limitedSenders = allEmails ? null : list.moderators().map(ListMember::user).map(User::email).toList();
- if (month == null || month.isBlank()) {
- return Map.of(LIST,list.email(),"summary",Post.summarize(list,limitedSenders));
- } else {
- return Map.of(LIST,list.email(),"posts",Post.find(list,month,limitedSenders).stream().map(Post::safeMap).toList());
- }
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- LOG.debug("list: {}",list.email());
- return Map.of();
+ private Map archive(HttpServletRequest req, User user) throws SQLException {
+ var list = Util.getMailingList(req);
+ if (list == null) throw new IllegalArgumentException(t("You are trying to access a non-existing list!"));
+ var allowed = list.hasPublicArchive() || list.mayBeAlteredBy(user);
+ if (!allowed) throw new IllegalAccessError(t("You are not allowed to access the archive of this list!"));
+
+ var allEmails = user != null || list.hasState(STATE_OPEN_FOR_SUBSCRIBERS) || list.hasState(STATE_OPEN_FOR_GUESTS);
+ var limitedSenders = allEmails ? null : list.moderators().map(ListMember::user).map(User::email).toList();
+
+ boolean userIsMod = list.mayBeAlteredBy(user);
+ String month = req.getParameter(MONTH);
+ if (month == null || month.isBlank()) return Map.of(LIST,list.email(),MODERATOR,userIsMod,"summary",Post.summarize(list,limitedSenders));
+ return Map.of(LIST,list.email(),MODERATOR,userIsMod,"posts",Post.find(list,month,limitedSenders).stream().map(Post::safeMap).toList());
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- String error = handleGet(req, resp);
+ String error;
+ try {
+ error = handleGet(req, resp);
+ } catch (SQLException e) {
+ error = e.getMessage();
+ }
if (error != null) resp.sendError(400,error);
}
@@ -120,6 +124,21 @@ public class Rest extends HttpServlet {
if (error != null) resp.sendError(400,error);
}
+ private Map dropMail(String messageId,User user){
+ try {
+ var message = Post.load(messageId);
+ if (message == null) return Map.of(ERROR,t("Cannot remove: unknown message id"));
+ var allowed = message.list().mayBeAlteredBy(user);
+ if (allowed){
+ message.remove();
+ return Map.of(SUCCESS,t("Message deleted"));
+ }
+ return Map.of(ERROR,t("You are not allowed to remove messages from this list!"));
+ } catch (SQLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
private Map dropPermission(String userEmail, String permissions) {
if (userEmail == null || userEmail.isBlank()) return Map.of(ERROR,"Nutzer-Emailadresse fehlt!");
try {
@@ -148,7 +167,7 @@ public class Rest extends HttpServlet {
}
}
- public String handleGet(HttpServletRequest req, HttpServletResponse resp){
+ public String handleGet(HttpServletRequest req, HttpServletResponse resp) throws SQLException {
var user = Util.getUser(req);
var path = Util.getPath(req);
@@ -158,14 +177,7 @@ public class Rest extends HttpServlet {
json.put(USER,user.safeMap());
switch (path) {
case LIST_ARCHIVE:
- var list = Util.getMailingList(req);
- try {
- var allowed = list.hasState(STATE_PUBLIC_ARCHIVE) || list.moderators().map(ListMember::user).anyMatch(mod -> user.equals(mod));
- if (!allowed) return t("Sie sind nicht berechtigt, das Archiv dieser Liste einzusehen!");
- json.put("archive",archive(list,req.getParameter(MONTH),user));
- } catch (SQLException sqle){
- return sqle.getMessage();
- }
+ json.put("archive",archive(req,user));
break;
case USER_LIST:
try {
@@ -188,10 +200,7 @@ public class Rest extends HttpServlet {
} else {
switch (path) {
case LIST_ARCHIVE:
- var list = Util.getMailingList(req);
- var allowed = list.hasState(STATE_PUBLIC_ARCHIVE);
- if (!allowed) return t("Diese Liste hat kein öffentliches Archiv!");
- json.put("archive",archive(list,req.getParameter(MONTH),null));
+ json.put("archive",archive(req,null));
break;
case LIST_SUBSCRIBABLE:
json.put("lists", MailingList.subscribable().stream().map(MailingList::minimalMap).toList());
@@ -257,6 +266,10 @@ public class Rest extends HttpServlet {
case LIST_TEST:
json.putAll(testList(list,user));
break;
+ case MAIL_DROP:
+ var messageId = req.getParameter(MESSAGE_ID);
+ json.putAll(dropMail(messageId,user));
+ break;
case USER_ADD_PERMISSION:
if (user.hashPermission(User.PERMISSION_ADMIN)){
json.putAll(addPermission(userEmail,permissions));
@@ -319,7 +332,7 @@ public class Rest extends HttpServlet {
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);
+ if (list.hasPublicArchive()) map.put(KEY_ARCHIVE,true);
if (list.hasState(STATE_MODS_CAN_EDIT_MODS)) map.put(KEY_MODS_CAN_EDIT_MODS,true);
if (list.holdTime() != null) map.put(KEY_DELETE_MESSAGES,list.holdTime());
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 2835f43..f6d9ec6 100644
--- a/src/main/java/de/srsoftware/widerhall/web/Web.java
+++ b/src/main/java/de/srsoftware/widerhall/web/Web.java
@@ -134,13 +134,20 @@ public class Web extends TemplateServlet {
}
}
- private String archive(HttpServletRequest req, HttpServletResponse resp) {
+ private String archive(MailingList list, User user, HttpServletRequest req, HttpServletResponse resp) {
+ if (list == null) return t("The mailing list you are trying to view does not exist!");
+
+ var allowed = list.hasPublicArchive() || list.mayBeAlteredBy(user);
+ if (!allowed) return t("You are not allowed to access the archive of this list");
+
var map = new HashMap();
- var list = Util.getMailingList(req);
map.put(LIST,list.email());
var month = req.getParameter(MONTH);
- if (month != null && !month.isBlank())map.put(MONTH,month);
+ if (month != null && !month.isBlank()){
+ map.put(MONTH,month);
+ map.put(MODERATOR,list.mayBeAlteredBy(user));
+ }
return loadTemplate(ARCHIVE,map,resp);
}
@@ -279,10 +286,9 @@ public class Web extends TemplateServlet {
if (user != null) data.put(USER,user.safeMap());
if (list != null) data.put(LIST,list.minimalMap());
- String notes = null;
switch (path){
case ARCHIVE:
- return archive(req,resp);
+ return archive(list,user,req,resp);
case CONFIRM:
return confirm(req,resp);
case POST:
diff --git a/static/templates/archive.st b/static/templates/archive.st
index 7949e9e..66f5fc6 100644
--- a/static/templates/archive.st
+++ b/static/templates/archive.st
@@ -18,6 +18,9 @@
Datum |
Absender |
Betreff |
+ «if (data.moderator)»
+ Aktionen |
+ «endif»