working on permissions
This commit is contained in:
@@ -127,6 +127,53 @@ public class Database {
|
|||||||
return sql.toString();
|
return sql.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuffer sql = new StringBuffer(this.sql);
|
||||||
|
|
||||||
|
if (!setValues.isEmpty()){
|
||||||
|
var keys = new ArrayList<String>();
|
||||||
|
var expressions = new ArrayList<String>();
|
||||||
|
for (var entry : setValues.entrySet()) expressions.add(entry.getKey()+" = entry.getValue()");
|
||||||
|
sql.append(" SET ").append(String.join(", ",expressions));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!values.isEmpty()){
|
||||||
|
var keys = new ArrayList<String>();
|
||||||
|
var vals = new ArrayList<String>();
|
||||||
|
for (var entry : values.entrySet()) {
|
||||||
|
keys.add(entry.getKey());
|
||||||
|
vals.add(entry.getValue().toString());
|
||||||
|
}
|
||||||
|
sql.append("(")
|
||||||
|
.append(String.join(", ",keys))
|
||||||
|
.append(")")
|
||||||
|
.append(" VALUES ")
|
||||||
|
.append("(")
|
||||||
|
.append(String.join(",",vals))
|
||||||
|
.append(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!where.isEmpty()){
|
||||||
|
var clauses = new ArrayList<String>();
|
||||||
|
sql.append(" WHERE ");
|
||||||
|
|
||||||
|
for (var entry : where.entrySet()) clauses.add("("+entry.getKey()+" IN ("+String.join(", ",entry.getValue().stream().map(Object::toString).toList())+"))");
|
||||||
|
sql.append(String.join(" AND ",clauses));
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Request{" + "sql=" + sql + '}';
|
||||||
|
}
|
||||||
|
|
||||||
|
public Request values(Map<String,Object> newValues) {
|
||||||
|
values.putAll(newValues);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Request values(String key, Object value) {
|
||||||
|
values.put(key,value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Request where(String key, Object ... values) {
|
public Request where(String key, Object ... values) {
|
||||||
for (var val : values) where(key,val);
|
for (var val : values) where(key,val);
|
||||||
@@ -145,15 +192,6 @@ public class Database {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Request values(Map<String,Object> newValues) {
|
|
||||||
values.putAll(newValues);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Request values(String key, Object value) {
|
|
||||||
values.put(key,value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Database(Connection connection) {
|
public Database(Connection connection) {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.stringtemplate.v4.ST;
|
import org.stringtemplate.v4.ST;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -73,10 +74,9 @@ public class ListMember {
|
|||||||
public static Set<String> listsOwnedBy(User user) {
|
public static Set<String> listsOwnedBy(User user) {
|
||||||
var list = new HashSet<String>();
|
var list = new HashSet<String>();
|
||||||
try {
|
try {
|
||||||
var rs = Database.open().select(TABLE_NAME,LIST_EMAIL)
|
var request = Database.open().select(TABLE_NAME, LIST_EMAIL, STATE+" & "+STATE_OWNER+" as "+STATE);
|
||||||
.where(USER_EMAIL,user.email())
|
if (!user.is(ADMIN)) request = request.where(USER_EMAIL, user.email()).where(STATE, STATE_OWNER);
|
||||||
.where(STATE,STATE_OWNER)
|
var rs = request.exec();
|
||||||
.exec();
|
|
||||||
while (rs.next()) list.add(rs.getString(LIST_EMAIL));
|
while (rs.next()) list.add(rs.getString(LIST_EMAIL));
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
LOG.warn("Listing memberships lists failed: ",e);
|
LOG.warn("Listing memberships lists failed: ",e);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
|
|
||||||
import javax.mail.MessagingException;
|
import javax.mail.MessagingException;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -92,14 +93,28 @@ public class MailingList {
|
|||||||
return openLists().stream().filter(ml -> ml.email.equals(list)).count() > 0;
|
return openLists().stream().filter(ml -> ml.email.equals(list)).count() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Set<MailingList> listsOf(User user) {
|
public static Set<MailingList> editableBy(User user) {
|
||||||
var list = openLists();
|
var list = new HashSet<MailingList>();
|
||||||
Set<String> keys = (user.is(ADMIN)) ? null : ListMember.listsOwnedBy(user);
|
for (String key : ListMember.listsOwnedBy(user)) list.add(load(key));
|
||||||
if (keys == null || keys.isEmpty()) return list;
|
|
||||||
for (String key : keys) list.add(load(key));
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static MailingList from(ResultSet rs) throws SQLException {
|
||||||
|
String email = rs.getString(EMAIL);
|
||||||
|
var ml = lists.get(email);
|
||||||
|
if (ml == null) lists.put(email,ml = new MailingList(rs.getString(EMAIL),
|
||||||
|
rs.getString(NAME),
|
||||||
|
rs.getString(IMAP_HOST),
|
||||||
|
rs.getInt(IMAP_PORT),
|
||||||
|
rs.getString(IMAP_USER),
|
||||||
|
rs.getString(IMAP_PASS),
|
||||||
|
rs.getString(SMTP_HOST),
|
||||||
|
rs.getInt(SMTP_PORT),
|
||||||
|
rs.getString(SMTP_USER),
|
||||||
|
rs.getString(SMTP_PASS),
|
||||||
|
rs.getInt(STATE)));
|
||||||
|
return ml;
|
||||||
|
}
|
||||||
|
|
||||||
public static MailingList load(String listEmail) {
|
public static MailingList load(String listEmail) {
|
||||||
var ml = lists.get(listEmail);
|
var ml = lists.get(listEmail);
|
||||||
@@ -108,26 +123,22 @@ public class MailingList {
|
|||||||
.select(TABLE_NAME)
|
.select(TABLE_NAME)
|
||||||
.where(EMAIL,listEmail)
|
.where(EMAIL,listEmail)
|
||||||
.exec();
|
.exec();
|
||||||
if (rs.next()){
|
if (rs.next()) lists.put(listEmail,ml = MailingList.from(rs));
|
||||||
ml = new MailingList(rs.getString(EMAIL),
|
|
||||||
rs.getString(NAME),
|
|
||||||
rs.getString(IMAP_HOST),
|
|
||||||
rs.getInt(IMAP_PORT),
|
|
||||||
rs.getString(IMAP_USER),
|
|
||||||
rs.getString(IMAP_PASS),
|
|
||||||
rs.getString(SMTP_HOST),
|
|
||||||
rs.getInt(SMTP_PORT),
|
|
||||||
rs.getString(SMTP_USER),
|
|
||||||
rs.getString(SMTP_PASS),
|
|
||||||
rs.getInt(STATE));
|
|
||||||
lists.put(listEmail,ml);
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
LOG.debug("Failed to load MailingList: ",e);
|
LOG.debug("Failed to load MailingList: ",e);
|
||||||
}
|
}
|
||||||
return ml;
|
return ml;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public HashMap<String, Object> minimalMap() {
|
||||||
|
var map = new HashMap<String,Object>();
|
||||||
|
String[] parts = email.split("@", 2);
|
||||||
|
map.put(EMAIL,Map.of(PREFIX,parts[0],DOMAIN,parts[1]));
|
||||||
|
map.put(NAME, name);
|
||||||
|
map.put(STATE, stateString(state));
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
public String name(){
|
public String name(){
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
@@ -151,17 +162,13 @@ public class MailingList {
|
|||||||
|
|
||||||
|
|
||||||
public Map<String, Object> safeMap() {
|
public Map<String, Object> safeMap() {
|
||||||
var map = new HashMap<String,Object>();
|
var map = minimalMap();
|
||||||
String[] parts = email.split("@", 2);
|
|
||||||
map.put(EMAIL,Map.of(PREFIX,parts[0],DOMAIN,parts[1]));
|
|
||||||
map.put(NAME, name);
|
|
||||||
if (imapHost != null) map.put(IMAP_HOST, imapHost);
|
if (imapHost != null) map.put(IMAP_HOST, imapHost);
|
||||||
if (imapPort != 0) map.put(IMAP_PORT, imapPort);
|
if (imapPort != 0) map.put(IMAP_PORT, imapPort);
|
||||||
if (imapUser != null) map.put(IMAP_USER, imapUser);
|
if (imapUser != null) map.put(IMAP_USER, imapUser);
|
||||||
if (smtp.host() != null) map.put(SMTP_HOST, smtp.host());
|
if (smtp.host() != null) map.put(SMTP_HOST, smtp.host());
|
||||||
if (smtp.port() != 0) map.put(SMTP_PORT, smtp.port());
|
if (smtp.port() != 0) map.put(SMTP_PORT, smtp.port());
|
||||||
if (smtp.username() != null) map.put(SMTP_USER, smtp.username());
|
if (smtp.username() != null) map.put(SMTP_USER, smtp.username());
|
||||||
map.put(STATE, stateString(state));
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,6 +207,32 @@ public class MailingList {
|
|||||||
return String.join(", ", states);
|
return String.join(", ", states);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Set<MailingList> subscribable() {
|
||||||
|
return subscribable(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Set<MailingList> subscribable(User user) {
|
||||||
|
try {
|
||||||
|
if (user == null) return openLists();
|
||||||
|
if (user.is(ADMIN)) {
|
||||||
|
var rs = Database.open().select(TABLE_NAME).exec();
|
||||||
|
var result = new HashSet<MailingList>();
|
||||||
|
while (rs.next()) result.add(MailingList.from(rs));
|
||||||
|
rs.close();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
var listEmails = ListMember.listsOwnedBy(user);
|
||||||
|
var rs = Database.open().select(TABLE_NAME).where(EMAIL, listEmails).exec();
|
||||||
|
var result = openLists();
|
||||||
|
while (rs.next()) result.add(MailingList.from(rs));
|
||||||
|
rs.close();
|
||||||
|
return result;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
LOG.warn("Failed to read subscribable mailinglists for {}",user,e);
|
||||||
|
return Set.of();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void requestSubscription(User user, boolean skipConfirmation) throws SQLException, MessagingException {
|
public void requestSubscription(User user, boolean skipConfirmation) throws SQLException, MessagingException {
|
||||||
var state = skipConfirmation ? ListMember.STATE_SUBSCRIBER : ListMember.STATE_AWAITING_CONFIRMATION;
|
var state = skipConfirmation ? ListMember.STATE_SUBSCRIBER : ListMember.STATE_AWAITING_CONFIRMATION;
|
||||||
var member = ListMember.create(this,user,state);
|
var member = ListMember.create(this,user,state);
|
||||||
@@ -218,4 +251,6 @@ public class MailingList {
|
|||||||
var text = t("If you received this mail, the SMTP settings of your mailing list are correct.");
|
var text = t("If you received this mail, the SMTP settings of your mailing list are correct.");
|
||||||
smtp.login().send(email(),name(),user.email(),subject,text);
|
smtp.login().send(email(),name(),user.email(),subject,text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,13 +25,14 @@ import static de.srsoftware.widerhall.Util.t;
|
|||||||
|
|
||||||
public class Rest extends HttpServlet {
|
public class Rest extends HttpServlet {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(Rest.class);
|
private static final Logger LOG = LoggerFactory.getLogger(Rest.class);
|
||||||
private static final String LIST_LIST = "list/list";
|
|
||||||
private static final String LIST_DISABLE = "list/disable";
|
private static final String LIST_DISABLE = "list/disable";
|
||||||
|
private static final String LIST_EDITABLE = "list/editable";
|
||||||
private static final String LIST_ENABLE = "list/enable";
|
private static final String LIST_ENABLE = "list/enable";
|
||||||
private static final String LIST_HIDE = "list/hide";
|
private static final String LIST_HIDE = "list/hide";
|
||||||
private static final String LIST_MEMBERS = "list/members";
|
private static final String LIST_MEMBERS = "list/members";
|
||||||
private static final String LIST_SHOW = "list/show";
|
private static final String LIST_SHOW = "list/show";
|
||||||
private static final String LIST_TEST = "list/test";
|
private static final String LIST_TEST = "list/test";
|
||||||
|
private static final String LIST_SUBSCRIBABLE = "list/subscribable";
|
||||||
private static final String USER_LIST = "user/list";
|
private static final String USER_LIST = "user/list";
|
||||||
private static final String MEMBERS = "members";
|
private static final String MEMBERS = "members";
|
||||||
private static final String SUCCESS = "success";
|
private static final String SUCCESS = "success";
|
||||||
@@ -64,17 +65,19 @@ public class Rest extends HttpServlet {
|
|||||||
json.put(ERROR,"failed to load user list");
|
json.put(ERROR,"failed to load user list");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LIST_LIST:
|
case LIST_EDITABLE:
|
||||||
json.put("lists", MailingList.listsOf(user).stream().map(MailingList::safeMap).toList());
|
json.put("lists", MailingList.editableBy(user).stream().map(MailingList::safeMap).toList());
|
||||||
break;
|
break;
|
||||||
|
case LIST_SUBSCRIBABLE:
|
||||||
|
json.put("lists", MailingList.subscribable(user).stream().map(MailingList::minimalMap).toList());
|
||||||
default:
|
default:
|
||||||
json.put(ERROR,t("No handler for path '{}'!",path));
|
json.put(ERROR,t("No handler for path '{}'!",path));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch (path) {
|
switch (path) {
|
||||||
case LIST_LIST:
|
case LIST_SUBSCRIBABLE:
|
||||||
json.put("lists", MailingList.openLists().stream().map(MailingList::safeMap).toList());
|
json.put("lists", MailingList.subscribable().stream().map(MailingList::minimalMap).toList());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
json.put(ERROR,"Not logged in!");
|
json.put(ERROR,"Not logged in!");
|
||||||
|
|||||||
@@ -90,6 +90,11 @@ public class Web extends HttpServlet {
|
|||||||
return loadTemplate(ADD_LIST,data,resp);
|
return loadTemplate(ADD_LIST,data,resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!Util.isEmail(email)){
|
||||||
|
data.put(ERROR,t("List email ({}) is not a valid email address!",email));
|
||||||
|
return loadTemplate(ADD_LIST,data,resp);
|
||||||
|
}
|
||||||
|
|
||||||
if (imapHost == null || imapHost.isBlank() || imapUser == null || imapUser.isBlank() || imapPass == null || imapPass.isBlank()) {
|
if (imapHost == null || imapHost.isBlank() || imapUser == null || imapUser.isBlank() || imapPass == null || imapPass.isBlank()) {
|
||||||
data.put(ERROR,"IMAP credentials are required!");
|
data.put(ERROR,"IMAP credentials are required!");
|
||||||
return loadTemplate(ADD_LIST,data,resp);
|
return loadTemplate(ADD_LIST,data,resp);
|
||||||
|
|||||||
@@ -14,12 +14,12 @@ function hideList(listEmail){
|
|||||||
$.post('/api/list/hide',{list:listEmail},showListResult,'json');
|
$.post('/api/list/hide',{list:listEmail},showListResult,'json');
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadListAdminList(){
|
function loadListOfEditableLists(){
|
||||||
$.getJSON('/api/list/list', showListAdminList);
|
$.getJSON('/api/list/editable', showListOfEditableLists);
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadListList(){
|
function loadListOfSubscribableLists(){
|
||||||
$.getJSON('/api/list/list', showListList);
|
$.getJSON('/api/list/subscribable', showListList);
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadMembers(listEmail){
|
function loadMembers(listEmail){
|
||||||
@@ -38,7 +38,7 @@ function showList(listEmail){
|
|||||||
$.post('/api/list/show',{list:listEmail},showListResult,'json');
|
$.post('/api/list/show',{list:listEmail},showListResult,'json');
|
||||||
}
|
}
|
||||||
|
|
||||||
function showListAdminList(data){
|
function showListOfEditableLists(data){
|
||||||
for (let i in data.lists){
|
for (let i in data.lists){
|
||||||
let list = data.lists[i];
|
let list = data.lists[i];
|
||||||
let row = $('<tr/>');
|
let row = $('<tr/>');
|
||||||
|
|||||||
@@ -21,6 +21,6 @@
|
|||||||
</table>
|
</table>
|
||||||
<a href="add_list">Add new mailing list</a>
|
<a href="add_list">Add new mailing list</a>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
loadListAdminList();
|
loadListOfEditableLists();
|
||||||
</script>
|
</script>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
@@ -9,6 +9,6 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
loadListList();
|
loadListOfSubscribableLists();
|
||||||
</script>
|
</script>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
Reference in New Issue
Block a user