From fa265f14b2d29b3176f99e1ad6c0086941529272 Mon Sep 17 00:00:00 2001 From: Stephan Richter Date: Fri, 7 Jun 2024 14:06:27 +0200 Subject: [PATCH] implemented transfer of list ownership. this resolves #4 Signed-off-by: Stephan Richter --- .../widerhall/data/MailingList.java | 45 ++++++++++++++++--- .../de/srsoftware/widerhall/data/User.java | 5 +++ .../de/srsoftware/widerhall/web/Rest.java | 8 ++++ static/templates/js.st | 25 +++++++++-- 4 files changed, 73 insertions(+), 10 deletions(-) diff --git a/src/main/java/de/srsoftware/widerhall/data/MailingList.java b/src/main/java/de/srsoftware/widerhall/data/MailingList.java index f622d84..fb61eb6 100644 --- a/src/main/java/de/srsoftware/widerhall/data/MailingList.java +++ b/src/main/java/de/srsoftware/widerhall/data/MailingList.java @@ -22,6 +22,7 @@ import java.util.stream.Stream; import static de.srsoftware.widerhall.Constants.*; import static de.srsoftware.widerhall.Util.t; +import static de.srsoftware.widerhall.data.ListMember.*; import static de.srsoftware.widerhall.data.User.PERMISSION_ADMIN; /** @@ -268,7 +269,7 @@ public class MailingList implements MessageHandler, ProblemListener { if (user == null) return false; try { var member = ListMember.load(this,user); - return member.hasState(ListMember.STATE_OWNER|ListMember.STATE_SUBSCRIBER); // owners may subscribe their own mailing lists + return member.hasState(STATE_OWNER|STATE_SUBSCRIBER); // owners may subscribe their own mailing lists } catch (SQLException e) { LOG.warn("Was not able to load ListMember:",e); return false; @@ -283,6 +284,16 @@ public class MailingList implements MessageHandler, ProblemListener { return hasState(STATE_OPEN_FOR_GUESTS|STATE_OPEN_FOR_SUBSCRIBERS); } + public boolean isOwnedBy(User user) { + if (user == null) return false; + try { + if (ListMember.load(this,user).isOwner()) return true; + } catch (SQLException e) { + LOG.debug("Error loading list member for ({}, {})",user.email(),email()); + } + return false; + } + public static List listActive() { try { var list = new ArrayList(); @@ -505,10 +516,6 @@ public class MailingList implements MessageHandler, ProblemListener { return list; } - public Stream owners() throws SQLException { - return members().filter(ListMember::isOwner); - } - public MailingList replyToList(boolean on) throws SQLException { return setFlag(STATE_REPLY_TO_LIST,on); } @@ -678,7 +685,7 @@ public class MailingList implements MessageHandler, ProblemListener { * @throws MessagingException */ public void requestSubscription(User user, boolean skipConfirmation, ST template) throws SQLException, MessagingException { - var state = skipConfirmation ? ListMember.STATE_SUBSCRIBER : ListMember.STATE_AWAITING_CONFIRMATION; + var state = skipConfirmation ? STATE_SUBSCRIBER : STATE_AWAITING_CONFIRMATION; var member = ListMember.create(this,user,state); if (skipConfirmation) return; try { @@ -742,6 +749,32 @@ public class MailingList implements MessageHandler, ProblemListener { } } + public String transfer(User owner, String newOwnerMail) { + User newOwner; + try { + newOwner = User.load(newOwnerMail); + } catch (SQLException e) { + return t("Failed to load user for address {}",newOwnerMail); + } + ListMember member; + try { + member = ListMember.load(this,newOwner); + } catch (SQLException e) { + return t("{} is not a member of {}",newOwner); + } + try { + member.setState(STATE_OWNER); + } catch (SQLException e) { + return t("Failed to transfer list ownership to {}",newOwner); + } + try { + ListMember.load(this,owner).setState(STATE_MODERATOR); + } catch (SQLException e) { + return t("Failed to withdraw ownership from {}",owner); + } + return null; + } + public void update(String name, String email, String imapHost, Integer imapPort, String imapUser, String imapPass, String inbox, String smtpHost, Integer smtpPort, String smtpUser, String smtpPass) throws SQLException { imap.stop(); Database.open() diff --git a/src/main/java/de/srsoftware/widerhall/data/User.java b/src/main/java/de/srsoftware/widerhall/data/User.java index 4b1d558..2af3590 100644 --- a/src/main/java/de/srsoftware/widerhall/data/User.java +++ b/src/main/java/de/srsoftware/widerhall/data/User.java @@ -326,4 +326,9 @@ public class User { public String token() { return token; } + + @Override + public String toString() { + return name == null ? email : name; + } } diff --git a/src/main/java/de/srsoftware/widerhall/web/Rest.java b/src/main/java/de/srsoftware/widerhall/web/Rest.java index 60f0e14..86733af 100644 --- a/src/main/java/de/srsoftware/widerhall/web/Rest.java +++ b/src/main/java/de/srsoftware/widerhall/web/Rest.java @@ -18,6 +18,7 @@ import java.sql.SQLException; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import static de.srsoftware.widerhall.Constants.*; import static de.srsoftware.widerhall.Util.t; @@ -40,6 +41,7 @@ public class Rest extends HttpServlet { 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 TRANSFER = "list/transfer"; 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"; @@ -267,6 +269,11 @@ public class Rest extends HttpServlet { var messageId = req.getParameter(MESSAGE_ID); json.putAll(dropMail(messageId,user)); break; + case TRANSFER: + if (list.isOwnedBy(user)){ + Optional.ofNullable(list.transfer(user,userEmail)).ifPresent(err -> json.put(ERROR,err)); + } else json.put(ERROR,t("As you don't own this list, you may not transfer its ownership!")); + break; case USER_ADD_PERMISSION: if (user.hashPermission(User.PERMISSION_ADMIN)){ json.putAll(addPermission(userEmail,permissions)); @@ -286,6 +293,7 @@ public class Rest extends HttpServlet { } try { resp.setContentType("application/json"); + if (json.containsKey(ERROR)) resp.setStatus(404); resp.getWriter().println(json.toJSONString()); return null; } catch (IOException e) { diff --git a/static/templates/js.st b/static/templates/js.st index d030805..3b01759 100644 --- a/static/templates/js.st +++ b/static/templates/js.st @@ -211,6 +211,11 @@ function showListResult(result){ function showMembers(data){ var list_mail = data.list.email.prefix+'@'+data.list.email.domain; + console.log("data",data); + var owner = false; + for (let member of data.members){ + if (member.email == data.user.email && member.state.includes("owner")) owner = member.email; + } for (let i in data.members){ let member = data.members[i]; let row = $(''); @@ -218,11 +223,17 @@ function showMembers(data){ $('').text(member.email).appendTo(row); $('').text(member.state).appendTo(row); let col = $(''); - console.log("data",data); if (member.state.includes("moderator")) { - if (!member.state.includes("owner")) $('