diff --git a/pom.xml b/pom.xml index 5157743..a1ab163 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.example Widerhall - 0.2.61 + 1.0.0 diff --git a/src/main/java/de/srsoftware/widerhall/data/Database.java b/src/main/java/de/srsoftware/widerhall/data/Database.java index ea706cd..b094c95 100644 --- a/src/main/java/de/srsoftware/widerhall/data/Database.java +++ b/src/main/java/de/srsoftware/widerhall/data/Database.java @@ -91,6 +91,7 @@ public class Database { */ public class Request{ + private String groupBy = null; private final StringBuilder sql; // buffer the sql to be built private final HashMap> where = new HashMap<>(); // buffer condition statements for select private final HashMap values = new HashMap<>(); // buffer values for insert/update statements @@ -128,31 +129,12 @@ public class Database { } } - private void applySorting(){ - if (!sortFields.isEmpty()) sql.append(" ORDER BY ").append(String.join(", ",sortFields)); - } - - @Override - protected Request clone() { - Request clone = new Request(new StringBuilder(sql)); - clone.where.putAll(where); - clone.values.putAll(values); - return clone; + private void applyGrouping(){ + if (groupBy != null && !groupBy.isBlank()) sql.append(" GROUP BY ").append(groupBy.trim()); } - /** - * finalize sql, save sql and arguments as compiled request - * @return - */ - public CompiledRequest compile(Object ...additionalArgs){ - var args = new ArrayList<>(); - applyValues(args); - applyConditions(args); - applySorting(); - if (additionalArgs != null) { - for (Object arg : additionalArgs) args.add(arg); - } - return new CompiledRequest(sql.toString(),args); + private void applySorting(){ + if (!sortFields.isEmpty()) sql.append(" ORDER BY ").append(String.join(", ",sortFields)); } /** @@ -188,6 +170,38 @@ public class Database { } + + @Override + protected Request clone() { + Request clone = new Request(new StringBuilder(sql)); + clone.where.putAll(where); + clone.values.putAll(values); + return clone; + } + + /** + * finalize sql, save sql and arguments as compiled request + * @return + */ + public CompiledRequest compile(Object ...additionalArgs){ + var args = new ArrayList<>(); + applyValues(args); + applyConditions(args); + applyGrouping(); + applySorting(); + if (additionalArgs != null) { + for (Object arg : additionalArgs) args.add(arg); + } + return new CompiledRequest(sql.toString(),args); + } + + + + public Request groupBy(String column) { + groupBy = column; + return this; + } + public void run() throws SQLException { compile().run(); } diff --git a/src/main/java/de/srsoftware/widerhall/data/Post.java b/src/main/java/de/srsoftware/widerhall/data/Post.java index b9b897a..deee9eb 100644 --- a/src/main/java/de/srsoftware/widerhall/data/Post.java +++ b/src/main/java/de/srsoftware/widerhall/data/Post.java @@ -15,10 +15,7 @@ import java.nio.file.Files; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; -import java.util.TreeMap; +import java.util.*; import static de.srsoftware.widerhall.Constants.*; import static de.srsoftware.widerhall.Constants.VARCHAR; @@ -26,12 +23,13 @@ import static de.srsoftware.widerhall.Constants.VARCHAR; public class Post { public static final Logger LOG = LoggerFactory.getLogger(Post.class); public static final String TABLE_NAME = "Posts"; + + private static final String DATE = "date"; + private static final String FILE = "file"; private static final String FROM_ADDR = "from_addr"; private static final String FROM_NAME = "from_name"; - private static final String PARENT = "parent"; private static final String LONG = "LONG"; - private static final String DATE = "date"; - private static final String FILE = "file"; + private static final String PARENT = "parent"; private static HashMap cache = new HashMap<>(); private String id, fromAddr, fromName, subject, filename; @@ -98,12 +96,13 @@ public class Post { return new File(filename); } - public static ArrayList find(MailingList list, String month) throws SQLException { - var rs = Database.open() + 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()) - .where(MONTH,month) - .sort(DATE) + .where(MONTH,month); + if (allowedSenders != null) query = query.where(FROM_ADDR,allowedSenders); + var rs = query.sort(DATE) .compile() .exec(); try { @@ -174,10 +173,13 @@ public class Post { return this; } - public static Map summarize(MailingList list) throws SQLException { - var sql = new StringBuilder("SELECT count(*) as count,strftime('%Y-%m',date/1000,'unixepoch') as month FROM Posts WHERE list = ? GROUP BY month ORDER BY month;"); + public static Map summarize(MailingList list,List limitedUsers) throws SQLException { + var sql = new StringBuilder("SELECT count(*) as count,strftime('%Y-%m',date/1000,'unixepoch') as month FROM Posts"); + var query = Database.open().query(sql).where(LIST,list.email()).groupBy(MONTH).sort(MONTH); + if (limitedUsers != null) query.where(FROM_ADDR,limitedUsers); + var rs = query.compile().exec(); + var map = new TreeMap(); - var rs = Database.open().query(sql).compile(list.email()).exec(); while (rs.next()) map.put(rs.getString("month"),rs.getInt("count")); rs.close(); 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 f7b1753..b406a40 100644 --- a/src/main/java/de/srsoftware/widerhall/web/Rest.java +++ b/src/main/java/de/srsoftware/widerhall/web/Rest.java @@ -15,6 +15,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.sql.SQLException; +import java.time.Month; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -61,15 +62,16 @@ public class Rest extends HttpServlet { return Map.of(SUCCESS,"Nutzer-Berechtigungen aktualisiert"); } - private Map archive(HttpServletRequest req) { - var list = Util.getMailingList(req); + private Map archive(MailingList list, String month, User requestingUser){ if (list != null){ try { - var month = req.getParameter(MONTH); + 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)); + return Map.of(LIST,list.email(),"summary",Post.summarize(list,limitedSenders)); } else { - return Map.of(LIST,list.email(),"posts",Post.find(list,month).stream().map(Post::safeMap).toList()); + return Map.of(LIST,list.email(),"posts",Post.find(list,month,limitedSenders).stream().map(Post::safeMap).toList()); } } catch (SQLException e) { e.printStackTrace(); @@ -156,7 +158,14 @@ public class Rest extends HttpServlet { json.put(USER,user.safeMap()); switch (path) { case LIST_ARCHIVE: - json.put("archive",archive(req)); + 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(); + } break; case USER_LIST: try { @@ -179,7 +188,10 @@ public class Rest extends HttpServlet { } else { switch (path) { case LIST_ARCHIVE: - json.put("archive",archive(req)); + 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)); break; case LIST_SUBSCRIBABLE: json.put("lists", MailingList.subscribable().stream().map(MailingList::minimalMap).toList()); diff --git a/static/templates/footer.st b/static/templates/footer.st index 4caef9f..bd89db6 100644 --- a/static/templates/footer.st +++ b/static/templates/footer.st @@ -1,3 +1,3 @@ diff --git a/static/templates/inspect.st b/static/templates/inspect.st index d23f690..1f78fbb 100644 --- a/static/templates/inspect.st +++ b/static/templates/inspect.st @@ -9,7 +9,7 @@
Einstellungen - Diese Seite zeigt Konfigurations-Optionen für die Mailingliste. Um Login-Daten zu ändern, gehe zu Listenbarebeitung. + Diese Seite zeigt Konfigurations-Optionen für die Mailingliste. Um Login-Daten zu ändern, gehe zu Listenbearbeitung.
Weiterleitungs-Rechte