diff --git a/doc/data structure.dia b/doc/data structure.dia index 4a37bce..ec54437 100644 --- a/doc/data structure.dia +++ b/doc/data structure.dia @@ -267,13 +267,13 @@ - + - + - + @@ -299,7 +299,7 @@ - + @@ -312,13 +312,13 @@ - + - + - + @@ -344,7 +344,7 @@ - + @@ -357,13 +357,13 @@ - + - + - + @@ -389,7 +389,7 @@ - + @@ -537,13 +537,13 @@ - + - + - + @@ -569,7 +569,7 @@ - + @@ -656,13 +656,13 @@ - + - - + + @@ -1485,13 +1485,13 @@ - + - - + + @@ -1605,5 +1605,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + #Permissions# + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/de/srsoftware/widerhall/Constants.java b/src/main/java/de/srsoftware/widerhall/Constants.java index 477e637..1acd74d 100644 --- a/src/main/java/de/srsoftware/widerhall/Constants.java +++ b/src/main/java/de/srsoftware/widerhall/Constants.java @@ -1,9 +1,9 @@ package de.srsoftware.widerhall; public class Constants { - public static final String ADMIN = "Admin"; public static final String BASE = "base"; public static final String BASE_URL = "base_url"; + public static final String CONFIG = "configuration"; public static final String DB = "database"; public static final String DOMAIN = "domain"; public static final String EMAIL = "email"; @@ -14,9 +14,11 @@ public class Constants { public static final String INDEX = "index"; public static final String INT = "INT"; public static final String LIST = "list"; + public static final String LOCATIONS = "locations"; public static final String NAME = "name"; public static final String NOTES = "notes"; public static final String PASSWORD = "password"; + public static final String PERMISSIONS = "permissions"; public static final Object PORT = "port"; public static final String PREFIX = "prefix"; public static final String PROTOCOL = "mail.store.protocol"; @@ -26,6 +28,4 @@ public class Constants { public static final String VARCHAR = "VARCHAR(255)"; - public static final String CONFIG = "configuration"; - public static final String LOCATIONS = "locations"; } diff --git a/src/main/java/de/srsoftware/widerhall/data/Database.java b/src/main/java/de/srsoftware/widerhall/data/Database.java index f5b2d20..b653b4a 100644 --- a/src/main/java/de/srsoftware/widerhall/data/Database.java +++ b/src/main/java/de/srsoftware/widerhall/data/Database.java @@ -36,6 +36,7 @@ public class Database { } public ResultSet exec() throws SQLException { + LOG.debug("Executing {}",this); var args = new ArrayList<>(); if (!where.isEmpty()){ var clauses = new ArrayList(); @@ -51,7 +52,6 @@ public class Database { sql.append(String.join(" AND ",clauses)); } - LOG.debug("SQL: {}",sql); try { var stmt = Database.this.conn.prepareStatement(sql()); if (!args.isEmpty()) { @@ -64,6 +64,7 @@ public class Database { } public void run() throws SQLException { + LOG.debug("Running {}",this); var args = new ArrayList<>(); if (!setValues.isEmpty()){ @@ -106,7 +107,6 @@ public class Database { sql.append(String.join(" AND ",clauses)); } - LOG.debug("SQL: {}",sql); try { var stmt = conn.prepareStatement(sql()); if (!args.isEmpty()) { @@ -134,7 +134,7 @@ public class Database { if (!setValues.isEmpty()){ var keys = new ArrayList(); var expressions = new ArrayList(); - for (var entry : setValues.entrySet()) expressions.add(entry.getKey()+" = entry.getValue()"); + for (var entry : setValues.entrySet()) expressions.add(entry.getKey()+" = "+entry.getValue()); sql.append(" SET ").append(String.join(", ",expressions)); } diff --git a/src/main/java/de/srsoftware/widerhall/data/ListMember.java b/src/main/java/de/srsoftware/widerhall/data/ListMember.java index 80dcb3e..916b9f7 100644 --- a/src/main/java/de/srsoftware/widerhall/data/ListMember.java +++ b/src/main/java/de/srsoftware/widerhall/data/ListMember.java @@ -71,11 +71,16 @@ public class ListMember { Database.open().query(sql).run(); } + public boolean hasState(int testState) { + return (state & testState) > 0; + } + + public static Set listsOwnedBy(User user) { var list = new HashSet(); try { var request = Database.open().select(TABLE_NAME, LIST_EMAIL, STATE+" & "+STATE_OWNER+" as "+STATE); - if (!user.is(ADMIN)) request = request.where(USER_EMAIL, user.email()).where(STATE, STATE_OWNER); + if (!user.hashPermission(User.PERMISSION_ADMIN)) request = request.where(USER_EMAIL, user.email()).where(STATE, STATE_OWNER); var rs = request.exec(); while (rs.next()) list.add(rs.getString(LIST_EMAIL)); } catch (SQLException e) { @@ -84,6 +89,26 @@ public class ListMember { return list; } + public static ListMember load(MailingList list,User user) throws SQLException { + var rs = Database + .open() + .select(TABLE_NAME) + .where(LIST_EMAIL,list.email()) + .where(USER_EMAIL,user.email()) + .exec(); + try { + if (rs.next()) { + return new ListMember(rs.getString(LIST_EMAIL), + rs.getString(USER_EMAIL), + rs.getInt(STATE), + rs.getString(TOKEN)); + } + } finally { + rs.close(); + } + return null; + } + public static Map of(String listEmail) throws SQLException { var rs = Database.open() .select(TABLE_NAME) @@ -142,5 +167,4 @@ public class ListMember { } } } - } diff --git a/src/main/java/de/srsoftware/widerhall/data/MailingList.java b/src/main/java/de/srsoftware/widerhall/data/MailingList.java index 4652e2c..a470a96 100644 --- a/src/main/java/de/srsoftware/widerhall/data/MailingList.java +++ b/src/main/java/de/srsoftware/widerhall/data/MailingList.java @@ -13,6 +13,7 @@ import java.util.*; import static de.srsoftware.widerhall.Constants.*; import static de.srsoftware.widerhall.Util.t; +import static de.srsoftware.widerhall.data.User.PERMISSION_ADMIN; public class MailingList { private static final Logger LOG = LoggerFactory.getLogger(MailingList.class); @@ -31,7 +32,8 @@ public class MailingList { private final String email; public static final String TABLE_NAME = "Lists"; private final String imapPass, imapHost, imapUser; - private final int imapPort, state; + private final int imapPort; + private int state; private final SmtpClient smtp; private static final HashMap lists = new HashMap<>(); @@ -75,22 +77,26 @@ public class MailingList { } - public static void enable(String listEmail, boolean enable) throws SQLException { - Database.open() - .update(TABLE_NAME) - .set(STATE,enable ? STATE+" | "+ STATE_ENABLED : Database.xor(STATE,STATE_ENABLED)) - .where(EMAIL, listEmail).run(); + public void enable(boolean enable) throws SQLException { + state = enable ? state | STATE_ENABLED : state ^ (state & STATE_ENABLED); + Database.open().update(TABLE_NAME).set(STATE,state).where(EMAIL, email()).run(); } - public static void hide(String listEmail, boolean hide) throws SQLException { - Database.open() - .update(TABLE_NAME) - .set(STATE,hide ? STATE+" | "+ STATE_PUBLIC : Database.xor(STATE,STATE_PUBLIC)) - .where(EMAIL, listEmail).run(); + public void hide(boolean hide) throws SQLException { + state = hide ? state ^ (state & STATE_PUBLIC) : state | STATE_PUBLIC; + Database.open().update(TABLE_NAME).set(STATE,state).where(EMAIL, email()).run(); } - public static boolean isOpen(String list) { - return openLists().stream().filter(ml -> ml.email.equals(list)).count() > 0; + public boolean isOpenFor(User user) { + if ((state & STATE_PUBLIC) > 0) return true; + if (user == null) return false; + try { + var member = ListMember.load(this,user); + return member.hasState(ListMember.STATE_OWNER|ListMember.STATE_SUBSCRIBER); + } catch (SQLException e) { + LOG.warn("Was not able to load ListMember: ",e); + return false; + } } public static Set editableBy(User user) { @@ -117,6 +123,7 @@ public class MailingList { } public static MailingList load(String listEmail) { + if (listEmail == null) return null; var ml = lists.get(listEmail); if (ml == null) try { var rs = Database.open() @@ -214,7 +221,7 @@ public class MailingList { public static Set subscribable(User user) { try { if (user == null) return openLists(); - if (user.is(ADMIN)) { + if (user.hashPermission(PERMISSION_ADMIN)) { var rs = Database.open().select(TABLE_NAME).exec(); var result = new HashSet(); while (rs.next()) result.add(MailingList.from(rs)); diff --git a/src/main/java/de/srsoftware/widerhall/data/User.java b/src/main/java/de/srsoftware/widerhall/data/User.java index c35e906..5797683 100644 --- a/src/main/java/de/srsoftware/widerhall/data/User.java +++ b/src/main/java/de/srsoftware/widerhall/data/User.java @@ -16,14 +16,19 @@ import static de.srsoftware.widerhall.Constants.*; public class User { public static final String TABLE_NAME = "Users"; private static final Logger LOG = LoggerFactory.getLogger(User.class); + private static final HashMap users = new HashMap<>(); + public static final int PERMISSION_ADMIN = 1; + public static final int PERMISSION_CREATE_LISTS = 2; private String email, salt, hashedPass, name; + private int permissions; - public User(String email, String name, String salt, String hashedPass) { + public User(String email, String name, String salt, String hashedPass, int permissions) { this.email = email; this.name = name; this.salt = salt; this.hashedPass = hashedPass; + this.permissions = permissions; } /*********** field accessors ***************/ @@ -39,12 +44,22 @@ public class User { return name; } + public int permissions(){ + return permissions; + } + public String salt(){ return salt; } /************** end of field accessors ****************/ + public void addPermission(int newPermission) throws SQLException { + permissions |= newPermission; + Database.open().update(TABLE_NAME).set(PERMISSIONS,permissions).run(); + } + + public static User create(String email, String name, String password) throws SQLException { String salt = null; String hashedPass = null; @@ -52,7 +67,7 @@ public class User { salt = Util.sha256(email + name + LocalDate.now()); hashedPass = Util.sha256(password + salt); } - return new User(email,name,salt,hashedPass).save(); + return new User(email,name,salt,hashedPass,0).save(); } public static void createTable() throws SQLException { @@ -60,16 +75,17 @@ public class User { .append("CREATE TABLE ").append(TABLE_NAME) .append(" (") .append(EMAIL).append(" ").append(VARCHAR).append(" NOT NULL PRIMARY KEY, ") + .append(NAME).append(" ").append(VARCHAR).append(", ") + .append(PERMISSIONS).append(" ").append(INT).append(", ") .append(SALT).append(" ").append(VARCHAR).append(", ") - .append(HASHED_PASS).append(" ").append(VARCHAR).append(", ") - .append(NAME).append(" ").append(VARCHAR) + .append(HASHED_PASS).append(" ").append(VARCHAR) + .append(");"); Database.open().query(sql).run(); } - public boolean is(String test){ - if (test == null) return false; - return test.equals(name) || test.equals(email); + public boolean hashPermission(int permission){ + return (permissions & permission) > 0; } @@ -82,14 +98,21 @@ public class User { var query = Database.open().select(TABLE_NAME); if (emails != null && !emails.isEmpty()) query.where(EMAIL,emails); var rs = query.exec(); - while (rs.next()) userList.add(new User( - rs.getString(EMAIL), - rs.getString(NAME), - rs.getString(SALT), - rs.getString(HASHED_PASS))); + while (rs.next()) userList.add(User.from(rs)); return userList; } + private static User from(ResultSet rs) throws SQLException { + var email = rs.getString(EMAIL); + var user = users.get(email); + if (user == null) users.put(email,user = new User( + rs.getString(EMAIL), + rs.getString(NAME), + rs.getString(SALT), + rs.getString(HASHED_PASS), + rs.getInt(PERMISSIONS))); + return user; + } public static User loadUser(String email, String password) throws InvalidKeyException, SQLException { @@ -99,14 +122,8 @@ public class User { .exec(); try { if (rs.next()) { - email = rs.getString(EMAIL); - var name = rs.getString(NAME); - var hashedPassword = rs.getString(HASHED_PASS); - var salt = rs.getString(SALT); - var loadedUser = new User(email, name, salt, hashedPassword); + var loadedUser = User.from(rs); if (loadedUser.matching(password)) return loadedUser; - } else if (noUsers()){ - return User.create(email,"Admin",password); } } finally { rs.close(); @@ -134,8 +151,15 @@ public class User { return false; } + public String permissionList(){ + var list = new ArrayList(); + if (hashPermission(PERMISSION_ADMIN)) list.add("admin"); + if (hashPermission(PERMISSION_CREATE_LISTS)) list.add("create lists"); + return String.join(", ",list); + } + public Map safeMap(){ - return Map.of(NAME,name,EMAIL,email,PASSWORD,hashedPassword() == null ? "no" : "yes"); + return Map.of(NAME,name,EMAIL,email,PERMISSIONS,permissionList(),PASSWORD,hashedPassword() == null ? "no" : "yes"); } private User save() throws SQLException { diff --git a/src/main/java/de/srsoftware/widerhall/web/Rest.java b/src/main/java/de/srsoftware/widerhall/web/Rest.java index 4475ab0..81882d2 100644 --- a/src/main/java/de/srsoftware/widerhall/web/Rest.java +++ b/src/main/java/de/srsoftware/widerhall/web/Rest.java @@ -59,7 +59,7 @@ public class Rest extends HttpServlet { switch (path) { case USER_LIST: try { - json.put("users", (user.is(ADMIN) ? User.loadAll() : List.of(user)).stream().map(User::safeMap).toList()); + json.put("users", (user.hashPermission(User.PERMISSION_ADMIN) ? User.loadAll() : List.of(user)).stream().map(User::safeMap).toList()); } catch (SQLException e) { LOG.debug("Failed to load user list:",e); json.put(ERROR,"failed to load user list"); @@ -140,7 +140,7 @@ public class Rest extends HttpServlet { } private Map listMembers(String listEmail, User user) { - if (user.is(ADMIN) || ListMember.listsOwnedBy(user).contains(listEmail)) { + if (user.hashPermission(User.PERMISSION_ADMIN) || ListMember.listsOwnedBy(user).contains(listEmail)) { try { var members = ListMember.of(listEmail) .entrySet() @@ -161,9 +161,9 @@ public class Rest extends HttpServlet { } private Map enableList(String listEmail, User user, boolean enable) { - if (user.is(ADMIN) || ListMember.listsOwnedBy(user).contains(listEmail)){ + if (user.hashPermission(User.PERMISSION_ADMIN) || ListMember.listsOwnedBy(user).contains(listEmail)){ try { - MailingList.enable(listEmail,enable); + MailingList.load(listEmail).enable(enable); return Map.of(SUCCESS,t("Mailing list '{}' was {}!",listEmail,enable ? "enabled" : "disabled")); } catch (SQLException e) { LOG.error("Failed to enable/disable mailing list: ",e); @@ -174,9 +174,9 @@ public class Rest extends HttpServlet { } private Map hideList(String listEmail, User user, boolean hide) { - if (user.is(ADMIN) || ListMember.listsOwnedBy(user).contains(listEmail)){ + if (user.hashPermission(User.PERMISSION_ADMIN) || ListMember.listsOwnedBy(user).contains(listEmail)){ try { - MailingList.hide(listEmail,hide); + MailingList.load(listEmail).hide(hide); return Map.of(SUCCESS,t("Mailing list '{}' was {}!",listEmail,hide ? "hidden" : "made public")); } catch (SQLException e) { LOG.error("Failed to (un)hide mailing list: ",e); diff --git a/src/main/java/de/srsoftware/widerhall/web/Web.java b/src/main/java/de/srsoftware/widerhall/web/Web.java index f72468a..9f77722 100644 --- a/src/main/java/de/srsoftware/widerhall/web/Web.java +++ b/src/main/java/de/srsoftware/widerhall/web/Web.java @@ -1,6 +1,7 @@ package de.srsoftware.widerhall.web; import de.srsoftware.widerhall.Configuration; +import de.srsoftware.widerhall.Constants; import de.srsoftware.widerhall.Util; import de.srsoftware.widerhall.data.ListMember; import de.srsoftware.widerhall.data.MailingList; @@ -30,6 +31,7 @@ public class Web extends HttpServlet { private static final String ADD_LIST = "add_list"; private static final String CONFIRM = "confirm"; private static final Logger LOG = LoggerFactory.getLogger(Web.class); + private static final String ADMIN = "admin"; private static final String LOGIN = "login"; private static final String LOGOUT = "logout"; private static final String REGISTER = "register"; @@ -58,80 +60,84 @@ public class Web extends HttpServlet { private String addList(HttpServletRequest req, HttpServletResponse resp) { var o = req.getSession().getAttribute(USER); - if (o instanceof User user){ - var data = new HashMap(); - data.put(USER,user); - - var name = req.getParameter(NAME); - data.put(NAME,name); - - var email = req.getParameter(EMAIL); - data.put(EMAIL,email); - - var imapHost = req.getParameter(IMAP_HOST); - data.put(IMAP_HOST,imapHost); - var imapUser = req.getParameter(IMAP_USER); - data.put(IMAP_USER,imapUser); - var imapPass = req.getParameter(IMAP_PASS); - var smtpHost = req.getParameter(SMTP_HOST); - data.put(SMTP_HOST,smtpHost); - var smtpUser = req.getParameter(SMTP_USER); - data.put(SMTP_USER,smtpUser); - var smtpPass = req.getParameter(SMTP_PASS); - - Integer imapPort = 993; - data.put(IMAP_PORT,imapPort); - - Integer smtpPort = 465; - data.put(SMTP_PORT,smtpPort); - - if (name == null || name.isBlank() || email == null || email.isBlank()) { - data.put(ERROR,"List name and address are required!"); - return loadTemplate(ADD_LIST,data,resp); - } + if (!(o instanceof User user)) { + return redirectTo(LOGIN,resp); + } + var data = new HashMap(); + data.put(USER, user); - if (!Util.isEmail(email)){ - data.put(ERROR,t("List email ({}) is not a valid email address!",email)); - return loadTemplate(ADD_LIST,data,resp); - } + if (!user.hashPermission(User.PERMISSION_CREATE_LISTS)){ + data.put(ERROR,t("You are not allowed to create new mailing lists!")); + return loadTemplate(ADMIN,data,resp); + } - if (imapHost == null || imapHost.isBlank() || imapUser == null || imapUser.isBlank() || imapPass == null || imapPass.isBlank()) { - data.put(ERROR,"IMAP credentials are required!"); - return loadTemplate(ADD_LIST,data,resp); - } + var name = req.getParameter(NAME); + data.put(NAME, name); + var email = req.getParameter(EMAIL); + data.put(EMAIL, email); + + var imapHost = req.getParameter(IMAP_HOST); + data.put(IMAP_HOST, imapHost); + var imapUser = req.getParameter(IMAP_USER); + data.put(IMAP_USER, imapUser); + var imapPass = req.getParameter(IMAP_PASS); + var smtpHost = req.getParameter(SMTP_HOST); + data.put(SMTP_HOST, smtpHost); + var smtpUser = req.getParameter(SMTP_USER); + data.put(SMTP_USER, smtpUser); + var smtpPass = req.getParameter(SMTP_PASS); + + Integer imapPort = 993; + data.put(IMAP_PORT, imapPort); + + Integer smtpPort = 465; + data.put(SMTP_PORT, smtpPort); + + if (name == null || name.isBlank() || email == null || email.isBlank()) { + data.put(ERROR, "List name and address are required!"); + return loadTemplate(ADD_LIST, data, resp); + } - try { - imapPort = Integer.parseInt(req.getParameter(IMAP_PORT)); - data.put(IMAP_PORT,imapPort); - } catch (NumberFormatException nfe){ - data.put(ERROR,t("'{}' is not a proper port number!",req.getParameter(IMAP_PORT))); - 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 (smtpHost == null || smtpHost.isBlank() || smtpUser == null || smtpUser.isBlank() || smtpPass == null || smtpPass.isBlank()) { - data.put(ERROR,"SMTP credentials are required!"); - return loadTemplate(ADD_LIST,data,resp); - } + if (imapHost == null || imapHost.isBlank() || imapUser == null || imapUser.isBlank() || imapPass == null || imapPass.isBlank()) { + data.put(ERROR, "IMAP credentials are required!"); + return loadTemplate(ADD_LIST, data, resp); + } - try { - smtpPort = Integer.parseInt(req.getParameter(SMTP_PORT)); - data.put(SMTP_PORT,smtpPort); - } catch (NumberFormatException nfe){ - data.put(ERROR,t("'{}' is not a proper port number!",req.getParameter(SMTP_PORT))); - return loadTemplate(ADD_LIST,data,resp); - } - try { - var list = MailingList.create(email,name,imapHost,imapPort,imapUser,imapPass,smtpHost,smtpPort,smtpUser,smtpPass); - ListMember.create(list,user,ListMember.STATE_OWNER); - return redirectTo(INDEX,resp); - } catch (SQLException e) { - return t("Failed to create list '{}': {}",name,e.getMessage()); - } + try { + imapPort = Integer.parseInt(req.getParameter(IMAP_PORT)); + data.put(IMAP_PORT, imapPort); + } catch (NumberFormatException nfe) { + data.put(ERROR, t("'{}' is not a proper port number!", req.getParameter(IMAP_PORT))); + return loadTemplate(ADD_LIST, data, resp); } - return redirectTo(LOGIN,resp); + if (smtpHost == null || smtpHost.isBlank() || smtpUser == null || smtpUser.isBlank() || smtpPass == null || smtpPass.isBlank()) { + data.put(ERROR, "SMTP credentials are required!"); + return loadTemplate(ADD_LIST, data, resp); + } + + try { + smtpPort = Integer.parseInt(req.getParameter(SMTP_PORT)); + data.put(SMTP_PORT, smtpPort); + } catch (NumberFormatException nfe) { + data.put(ERROR, t("'{}' is not a proper port number!", req.getParameter(SMTP_PORT))); + return loadTemplate(ADD_LIST, data, resp); + } + + try { + var list = MailingList.create(email, name, imapHost, imapPort, imapUser, imapPass, smtpHost, smtpPort, smtpUser, smtpPass); + ListMember.create(list, user, ListMember.STATE_OWNER); + return redirectTo(INDEX, resp); + } catch (SQLException e) { + return t("Failed to create list '{}': {}", name, e.getMessage()); + } } private String confirm(HttpServletRequest req, HttpServletResponse resp) { @@ -181,8 +187,9 @@ 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); + var listEmail = req.getParameter(LIST); + var list = MailingList.load(listEmail); + if (list != null) data.put(LIST,list.minimalMap()); switch (path){ case CONFIRM: return confirm(req,resp); @@ -195,12 +202,11 @@ public class Web extends HttpServlet { case UNSUBSCRIBE: return loadTemplate(path,data,resp); case SUBSCRIBE: - // TODO check permission - if (MailingList.isOpen(list)) { - data.put(LIST, list); + if (list.isOpenFor(user)) { + data.put(LIST,listEmail); return loadTemplate(path, data, resp); } - return t("You are not allowed to subscribe to '{}'!",list); + return t("You are not allowed to subscribe to '{}'!",list.email()); case "js": resp.setContentType("text/javascript"); return loadTemplate(path,data,resp); @@ -326,12 +332,9 @@ public class Web extends HttpServlet { if (!pass.equals(pass_repeat)) return loadTemplate(REGISTER,Map.of(ERROR,"Passwords do not match!",NAME,name,EMAIL,email),resp); if (Util.simplePassword(pass)) return loadTemplate(REGISTER,Map.of(ERROR,"Password to short or to simple!",NAME,name,EMAIL,email),resp); + var firstUser = false; try { - if (User.noUsers()) { // we are registering the first user, which is forced to be „Admin“ - name = ADMIN; - } else { - if (ADMIN.equals(name)) return loadTemplate(REGISTER,Map.of(ERROR,t("Name must not be „{}“",ADMIN),NAME,name,EMAIL,email),resp); - } + firstUser = User.noUsers(); } catch (SQLException e) { return t("Failed to access user database: {}",e.getMessage()); } @@ -339,9 +342,11 @@ public class Web extends HttpServlet { try { var user = User.create(email, name, pass); + if (firstUser) user.addPermission(User.PERMISSION_ADMIN|User.PERMISSION_CREATE_LISTS); req.getSession().setAttribute("user",user); return redirectTo(INDEX,resp); } catch (SQLException e) { + LOG.warn("Failed to create new user:",e); return t("Failed to create new user: {}",e.getMessage()); } } @@ -388,6 +393,11 @@ public class Web extends HttpServlet { } data.put(USER,user.safeMap()); + if (!list.isOpenFor(user)){ + data.put(ERROR,t("You are not allowed to join {}!",list.email())); + return loadTemplate(SUBSCRIBE,data,resp); + } + try { list.requestSubscription(user,skipConfirmation); data.put(NOTES,t("Successfully subscribed '{}' to '{}'.",user.email(),list.email())); @@ -454,6 +464,4 @@ public class Web extends HttpServlet { } } - - } diff --git a/static/templates/js.st b/static/templates/js.st index 349eb1c..0334c63 100644 --- a/static/templates/js.st +++ b/static/templates/js.st @@ -62,7 +62,7 @@ function showListOfEditableLists(data){ select.appendTo($('')).appendTo(row); - $('').text(list.imap_host).appendTo(row); + $('').text(list.imap_host).appendTo(row); $('').text(list.imap_port).appendTo(row); $('').text(list.imap_user).appendTo(row); $('').text(list.smtp_host).appendTo(row); @@ -70,10 +70,11 @@ function showListOfEditableLists(data){ $('').text(list.smtp_user).appendTo(row); row.appendTo('#listlist'); } - if (data.user.name == 'Admin'){ - $('a[href=register]').show(); + console.log(data.user); + if (data.user.permissions.includes('create lists')){ + $('a[href=add_list]').show(); } else { - $('a[href=register]').hide(); + $('a[href=add_list]').hide(); } } @@ -128,9 +129,10 @@ function showUserList(data){ $('').text(user.name).appendTo(row); $('').text(user.email).appendTo(row); $('').text(user.password).appendTo(row); + $('').text(user.permissions).appendTo(row); row.appendTo('#userlist'); } - if (data.user.name == 'Admin'){ + if (data.user.permissions.includes('admin')){ $('a[href=register]').show(); } else { $('a[href=register]').hide(); diff --git a/static/templates/listadminlist.st b/static/templates/listadminlist.st index 1ddb358..3a687b6 100644 --- a/static/templates/listadminlist.st +++ b/static/templates/listadminlist.st @@ -1,5 +1,5 @@
- List of mailinglists + List of (editable) mailinglists diff --git a/static/templates/login.st b/static/templates/login.st index 2049ba8..00bb540 100644 --- a/static/templates/login.st +++ b/static/templates/login.st @@ -7,8 +7,9 @@ -

Widerhall login

+ «navigation()» «messages()» +

Widerhall login

Login-Daten diff --git a/static/templates/userlist.st b/static/templates/userlist.st index 2e5c77c..78e5046 100644 --- a/static/templates/userlist.st +++ b/static/templates/userlist.st @@ -5,6 +5,7 @@
+
List
User name Email PasswordPermissions
Register new user