implemented un-subscribe
This commit is contained in:
@@ -30,82 +30,12 @@ public class Database {
|
||||
private final String sql;
|
||||
private final HashMap<String, List<Object>> where = new HashMap<>();
|
||||
private final HashMap<String,Object> values = new HashMap<>();
|
||||
private final HashMap<String,Object> setValues = new HashMap<>();
|
||||
|
||||
public Request(String sql) {
|
||||
this.sql = sql;
|
||||
}
|
||||
|
||||
public Request where(String key, Object ... values) {
|
||||
for (var val : values) where(key,val);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Request where(String key, Collection<? extends Object> values) {
|
||||
for (var val : values) where(key,val);
|
||||
return this;
|
||||
}
|
||||
|
||||
private Request where(String key, Object value) {
|
||||
var list = where.get(key);
|
||||
if (list == null) where.put(key,list = new ArrayList<>());
|
||||
list.add(value);
|
||||
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 void run() throws SQLException {
|
||||
var sb = new StringBuilder(sql);
|
||||
var args = new ArrayList<>();
|
||||
if (!values.isEmpty()){
|
||||
var keys = new ArrayList<String>();
|
||||
for (var entry : values.entrySet()) {
|
||||
keys.add(entry.getKey());
|
||||
args.add(entry.getValue());
|
||||
}
|
||||
sb.append("(")
|
||||
.append(String.join(", ",keys))
|
||||
.append(")")
|
||||
.append(" VALUES ");
|
||||
var arr = new String[args.size()];
|
||||
Arrays.fill(arr,"?");
|
||||
var marks = String.join(", ",arr);
|
||||
sb.append("(").append(marks).append(")");
|
||||
}
|
||||
if (!where.isEmpty()){
|
||||
var clauses = new ArrayList<String>();
|
||||
sb.append(" WHERE ");
|
||||
|
||||
for (var entry : where.entrySet()){
|
||||
var arr = new String[entry.getValue().size()];
|
||||
Arrays.fill(arr,"?");
|
||||
var marks = String.join(", ",arr);
|
||||
clauses.add("("+entry.getKey()+" IN ("+marks+"))");
|
||||
args.addAll(entry.getValue());
|
||||
}
|
||||
sb.append(String.join(" AND ",clauses));
|
||||
|
||||
}
|
||||
var sql = sb.toString();
|
||||
LOG.debug(sql);
|
||||
try {
|
||||
var stmt = conn.prepareStatement(sql);
|
||||
if (!args.isEmpty()) {
|
||||
for (int i = 0; i < args.size(); i++) stmt.setObject(i+1, args.get(i));
|
||||
}
|
||||
stmt.execute();
|
||||
} catch (SQLException sqle) {
|
||||
throw new SQLException(t("Query '{}' failed:",sql),sqle);
|
||||
}
|
||||
}
|
||||
|
||||
public ResultSet exec() throws SQLException {
|
||||
var sb = new StringBuilder(sql);
|
||||
@@ -136,12 +66,109 @@ public class Database {
|
||||
throw new SQLException(t("Query '{}' failed:",sql),sqle);
|
||||
}
|
||||
}
|
||||
|
||||
public void run() throws SQLException {
|
||||
var sb = new StringBuilder(sql);
|
||||
var args = new ArrayList<>();
|
||||
|
||||
if (!setValues.isEmpty()){
|
||||
var keys = new ArrayList<String>();
|
||||
var expressions = new ArrayList<String>();
|
||||
for (var entry : setValues.entrySet()) {
|
||||
expressions.add(" SET "+entry.getKey()+" = ?");
|
||||
args.add(entry.getValue());
|
||||
}
|
||||
sb.append(String.join(", ",expressions));
|
||||
}
|
||||
|
||||
if (!values.isEmpty()){
|
||||
var keys = new ArrayList<String>();
|
||||
for (var entry : values.entrySet()) {
|
||||
keys.add(entry.getKey());
|
||||
args.add(entry.getValue());
|
||||
}
|
||||
sb.append("(")
|
||||
.append(String.join(", ",keys))
|
||||
.append(")")
|
||||
.append(" VALUES ");
|
||||
var arr = new String[args.size()];
|
||||
Arrays.fill(arr,"?");
|
||||
var marks = String.join(", ",arr);
|
||||
sb.append("(").append(marks).append(")");
|
||||
}
|
||||
|
||||
if (!where.isEmpty()){
|
||||
var clauses = new ArrayList<String>();
|
||||
sb.append(" WHERE ");
|
||||
|
||||
for (var entry : where.entrySet()){
|
||||
var arr = new String[entry.getValue().size()];
|
||||
Arrays.fill(arr,"?");
|
||||
var marks = String.join(", ",arr);
|
||||
clauses.add("("+entry.getKey()+" IN ("+marks+"))");
|
||||
args.addAll(entry.getValue());
|
||||
}
|
||||
sb.append(String.join(" AND ",clauses));
|
||||
|
||||
}
|
||||
var sql = sb.toString();
|
||||
LOG.debug(sql);
|
||||
try {
|
||||
var stmt = conn.prepareStatement(sql);
|
||||
if (!args.isEmpty()) {
|
||||
for (int i = 0; i < args.size(); i++) stmt.setObject(i+1, args.get(i));
|
||||
}
|
||||
stmt.execute();
|
||||
} catch (SQLException sqle) {
|
||||
throw new SQLException(t("Query '{}' failed:",sql),sqle);
|
||||
}
|
||||
}
|
||||
|
||||
public Request set(String key, Object value) {
|
||||
setValues.put(key,value);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Request where(String key, Object ... values) {
|
||||
for (var val : values) where(key,val);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Request where(String key, Collection<? extends Object> values) {
|
||||
for (var val : values) where(key,val);
|
||||
return this;
|
||||
}
|
||||
|
||||
private Request where(String key, Object value) {
|
||||
var list = where.get(key);
|
||||
if (list == null) where.put(key,list = new ArrayList<>());
|
||||
list.add(value);
|
||||
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) {
|
||||
this.conn = connection;
|
||||
}
|
||||
|
||||
private Database assertTables() throws SQLException {
|
||||
if (!tableExists(User.TABLE_NAME)) User.createTable();
|
||||
if (!tableExists(MailingList.TABLE_NAME)) MailingList.createTable();
|
||||
if (!tableExists(ListMember.TABLE_NAME)) ListMember.createTable();
|
||||
return this;
|
||||
}
|
||||
|
||||
public static Database open() {
|
||||
if (singleton == null){
|
||||
Configuration config = Configuration.instance();
|
||||
@@ -159,15 +186,10 @@ public class Database {
|
||||
return singleton;
|
||||
}
|
||||
|
||||
private Database assertTables() throws SQLException {
|
||||
if (!tableExists(User.TABLE_NAME)) User.createTable();
|
||||
if (!tableExists(MailingList.TABLE_NAME)) MailingList.createTable();
|
||||
if (!tableExists(ListMember.TABLE_NAME)) ListMember.createTable();
|
||||
return this;
|
||||
public Request query(String sql) {
|
||||
return new Request(sql);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private boolean tableExists(String tbName) throws SQLException {
|
||||
try {
|
||||
ResultSet rs = query("SELECT EXISTS (SELECT name FROM sqlite_schema WHERE type='table' AND name='" + tbName + "')").exec();
|
||||
@@ -179,8 +201,4 @@ public class Database {
|
||||
throw new SQLException(t("Was not able to check existence of table {}!",tbName),e);
|
||||
}
|
||||
}
|
||||
|
||||
public Request query(String sql) {
|
||||
return new Request(sql);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package de.srsoftware.widerhall.data;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.xml.crypto.Data;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@@ -90,4 +91,27 @@ public class ListMember {
|
||||
.run();
|
||||
return this;
|
||||
}
|
||||
|
||||
public static void unsubscribe(String listEmail, User user) throws SQLException {
|
||||
var db = Database.open();
|
||||
var rs = db.query("SELECT * FROM "+TABLE_NAME)
|
||||
.where(LIST_EMAIL,listEmail)
|
||||
.where(USER_EMAIL,user.email())
|
||||
.exec();
|
||||
while (rs.next()){
|
||||
int state = rs.getInt(STATE) ^ STATE_SUBSCRIBER;
|
||||
if (state < 1) { // drop entry
|
||||
db.query("DELETE FROM "+TABLE_NAME)
|
||||
.where(LIST_EMAIL,listEmail)
|
||||
.where(USER_EMAIL,user.email())
|
||||
.run();
|
||||
} else { // update entry: whitdraw subscription
|
||||
db.query("UPDATE "+TABLE_NAME)
|
||||
.set(STATE,state)
|
||||
.where(LIST_EMAIL,listEmail)
|
||||
.where(USER_EMAIL,user.email())
|
||||
.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,8 +32,8 @@ public class Web extends HttpServlet {
|
||||
private static final String LOGOUT = "logout";
|
||||
private static final String REGISTER = "register";
|
||||
private static final String SUBSCRIBE = "subscribe";
|
||||
private static final String UNSUBSCRIBE = "unsubscribe";
|
||||
private static final String RELOAD = "reload";
|
||||
private static final String INSPECT = "inspect";
|
||||
private static final String IMAP_HOST = "imap_host";
|
||||
private static final String IMAP_PORT = "imap_port";
|
||||
private static final String IMAP_USER = "imap_user";
|
||||
@@ -140,6 +140,15 @@ public class Web extends HttpServlet {
|
||||
if (error != null) resp.sendError(400,error);
|
||||
}
|
||||
|
||||
private SQLException getCausingException(SQLException sqle) {
|
||||
Throwable cause = sqle.getCause();
|
||||
while (cause instanceof SQLException){
|
||||
sqle = (SQLException) cause;
|
||||
cause = sqle.getCause();
|
||||
}
|
||||
return sqle;
|
||||
}
|
||||
|
||||
private String handleGet(HttpServletRequest req, HttpServletResponse resp) {
|
||||
var o = req.getSession().getAttribute("user");
|
||||
User user = o instanceof User ? (User) o : null;
|
||||
@@ -148,6 +157,8 @@ public class Web extends HttpServlet {
|
||||
var path = req.getPathInfo();
|
||||
path = (path == null || path.equals("/")) ? INDEX : path.substring(1);
|
||||
String notes = null;
|
||||
var list = req.getParameter(LIST);
|
||||
if (list != null && !list.isBlank()) data.put(LIST,list);
|
||||
switch (path){
|
||||
case RELOAD:
|
||||
loadTemplates();
|
||||
@@ -155,9 +166,9 @@ public class Web extends HttpServlet {
|
||||
path = INDEX;
|
||||
case "css":
|
||||
case INDEX:
|
||||
case UNSUBSCRIBE:
|
||||
return loadTemplate(path,data,resp);
|
||||
case SUBSCRIBE:
|
||||
var list = req.getParameter(LIST);
|
||||
// TODO check permission
|
||||
if (MailingList.isOpen(list)) {
|
||||
data.put(LIST, list);
|
||||
@@ -183,9 +194,8 @@ public class Web extends HttpServlet {
|
||||
}
|
||||
|
||||
if (user != null){
|
||||
var list = req.getParameter(LIST);
|
||||
if (list != null) data.put(LIST,req.getParameter(LIST));
|
||||
data.put(NOTES,notes);
|
||||
//data.put(NOTES,notes);
|
||||
return loadTemplate(path,data,resp);
|
||||
}
|
||||
return redirectTo(LOGIN,resp);
|
||||
@@ -225,6 +235,8 @@ public class Web extends HttpServlet {
|
||||
return registerUser(req,resp);
|
||||
case SUBSCRIBE:
|
||||
return subscribe(req,resp);
|
||||
case UNSUBSCRIBE:
|
||||
return unsubscribe(req,resp);
|
||||
}
|
||||
|
||||
return t("No handler for path {}!",path);
|
||||
@@ -357,12 +369,52 @@ public class Web extends HttpServlet {
|
||||
}
|
||||
}
|
||||
|
||||
private SQLException getCausingException(SQLException sqle) {
|
||||
Throwable cause = sqle.getCause();
|
||||
while (cause instanceof SQLException){
|
||||
sqle = (SQLException) cause;
|
||||
cause = sqle.getCause();
|
||||
|
||||
|
||||
private String unsubscribe(HttpServletRequest req, HttpServletResponse resp) {
|
||||
var data = new HashMap<String,Object>();
|
||||
var user = getSessionUser(req);
|
||||
var email = req.getParameter(EMAIL);
|
||||
var pass = req.getParameter(PASSWORD);
|
||||
var list = req.getParameter(LIST);
|
||||
data.put(EMAIL,email);
|
||||
data.put(LIST,list);
|
||||
if (user != null) data.put(USER,user.safeMap());
|
||||
if (list == null || list.isBlank()){
|
||||
data.put(ERROR,"No list provided by form data!");
|
||||
return loadTemplate(UNSUBSCRIBE,data,resp);
|
||||
|
||||
}
|
||||
return sqle;
|
||||
if (user == null) {
|
||||
if (email == null || email.isBlank()) {
|
||||
data.put(ERROR, "Email is required for list un-subscription!");
|
||||
return loadTemplate(UNSUBSCRIBE, data, resp);
|
||||
}
|
||||
if (pass != null && pass.isBlank()) pass = null;
|
||||
|
||||
try {
|
||||
user = User.load(email,pass);
|
||||
req.getSession().setAttribute(USER,user);
|
||||
data.put(USER,user.safeMap());
|
||||
} catch (InvalidKeyException | SQLException e) {
|
||||
data.put(ERROR,"Invalid email/password combination!");
|
||||
return loadTemplate(UNSUBSCRIBE,data,resp);
|
||||
}
|
||||
}
|
||||
// if we get here, we should have a valid user
|
||||
try {
|
||||
ListMember.unsubscribe(list,user);
|
||||
data.put(NOTES,t("Sucessfully un-subscribed from '{}'.",list));
|
||||
return loadTemplate(INDEX,data,resp);
|
||||
} catch (SQLException e) {
|
||||
LOG.warn("Problem during unscubsription of {} from {}:",user.email(),list,e);
|
||||
data.put(ERROR,"Failed to unsubscribe!");
|
||||
return loadTemplate(UNSUBSCRIBE,data,resp);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private User getSessionUser(HttpServletRequest req) {
|
||||
return req.getSession().getAttribute(USER) instanceof User user ? user : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,5 +145,9 @@ function subscribeTo(domain,prefix){
|
||||
window.location.href='subscribe?list='+prefix+'@'+domain;
|
||||
}
|
||||
|
||||
function unsubscribeFrom(domain,prefix){
|
||||
window.location.href='unsubscribe?list='+prefix+'@'+domain;
|
||||
}
|
||||
|
||||
|
||||
$(start); // document.on ready
|
||||
@@ -16,11 +16,11 @@
|
||||
<fieldset>
|
||||
<legend>Suscribe to "«data.list»"</legend>
|
||||
<label>
|
||||
<input type="text" name="name" value="«if(data.user)»«data.user.name»«else»«data.name»«endif»">
|
||||
<input type="text" name="name" value="«if(data.name)»«data.name»«else»«data.user.name»«endif»">
|
||||
Name
|
||||
</label>
|
||||
<label>
|
||||
<input type="text" name="email" value="«if(data.user)»«data.user.email»«else»«data.email»«endif»">
|
||||
<input type="text" name="email" value="«if(data.email)»«data.email»«else»«data.user.email»«endif»">
|
||||
Email
|
||||
</label>
|
||||
<label>
|
||||
|
||||
30
static/templates/unsubscribe.st
Normal file
30
static/templates/unsubscribe.st
Normal file
@@ -0,0 +1,30 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<script src="jquery"></script>
|
||||
<script src="js"></script>
|
||||
<link rel="stylesheet" href="css" />
|
||||
</head>
|
||||
<body id="login">
|
||||
«navigation()»
|
||||
«userinfo()»
|
||||
«messages()»
|
||||
<h1>Widerhall Subscription</h1>
|
||||
<form method="POST">
|
||||
<input type="hidden" name="list" value="«data.list»" />
|
||||
<fieldset>
|
||||
<legend>Un-subscribe from "«data.list»"</legend>
|
||||
<label>
|
||||
<input type="text" name="email" value="«if(data.email)»«data.email»«else»«data.user.email»«endif»">
|
||||
Email
|
||||
</label>
|
||||
<label>
|
||||
<input type="password" name="password">
|
||||
Password (optional)
|
||||
</label>
|
||||
<button type="submit">Un-subscribe</button>
|
||||
</fieldset>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user