implemented transfer of list ownership. this resolves #4
Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
@@ -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<MailingList> listActive() {
|
||||
try {
|
||||
var list = new ArrayList<MailingList>();
|
||||
@@ -505,10 +516,6 @@ public class MailingList implements MessageHandler, ProblemListener {
|
||||
return list;
|
||||
}
|
||||
|
||||
public Stream<ListMember> 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()
|
||||
|
||||
@@ -326,4 +326,9 @@ public class User {
|
||||
public String token() {
|
||||
return token;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name == null ? email : name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 = $('<tr/>');
|
||||
@@ -218,11 +223,17 @@ function showMembers(data){
|
||||
$('<td/>').text(member.email).appendTo(row);
|
||||
$('<td/>').text(member.state).appendTo(row);
|
||||
let col = $('<td/>');
|
||||
console.log("data",data);
|
||||
if (member.state.includes("moderator")) {
|
||||
if (!member.state.includes("owner")) $('<button/>',{onclick:'dropMod("'+member.email+'","'+list_mail+'")'}).text("- moderator").appendTo(col);
|
||||
} else $('<button/>',{onclick:'addMod("'+member.email+'","'+list_mail+'")'}).text("+ moderator").appendTo(col);
|
||||
if (!member.state.includes("owner")) $('<button/>',{onclick:'dropMember("'+member.email+'","'+list_mail+'")'}).text("remove").appendTo(col);
|
||||
if (member.email != owner){
|
||||
$('<button/>',{onclick:'dropMod("'+member.email+'","'+list_mail+'")'}).text("- moderator").appendTo(col);
|
||||
if (data.user.email == owner) $('<button/>',{onclick:'transfer("'+member.email+'","'+list_mail+'")'}).text("transfer ownership").appendTo(col);
|
||||
}
|
||||
} else {
|
||||
$('<button/>',{onclick:'addMod("'+member.email+'","'+list_mail+'")'}).text("+ moderator").appendTo(col);
|
||||
}
|
||||
if (!member.state.includes("owner")) {
|
||||
$('<button/>',{onclick:'dropMember("'+member.email+'","'+list_mail+'")'}).text("remove").appendTo(col);
|
||||
}
|
||||
col.appendTo(row);
|
||||
|
||||
row.appendTo('#memberlist');
|
||||
@@ -273,6 +284,12 @@ function testList(listEmail){
|
||||
$.post('/api/list/test',{list:listEmail},showListResult,'json');
|
||||
}
|
||||
|
||||
function transfer(newOwner,listEmail){
|
||||
if (confirm("Really transfer "+listEmail+" to "+newOwner+"?")){
|
||||
$.post('/api/list/transfer',{email:newOwner,list:listEmail},reload,'json');
|
||||
}
|
||||
}
|
||||
|
||||
function unsubscribeFrom(listEmail){
|
||||
window.location.href='unsubscribe?list='+listEmail;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user