working on poll permissions
Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
/* © SRSoftware 2025 */
|
||||
package de.srsoftware.umbrella.poll;
|
||||
|
||||
import de.srsoftware.umbrella.core.model.Permission;
|
||||
import de.srsoftware.umbrella.core.model.Poll;
|
||||
import de.srsoftware.umbrella.core.model.UmbrellaUser;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
@@ -11,12 +11,14 @@ import java.util.Map;
|
||||
public interface PollDb {
|
||||
Collection<Poll> listPolls(UmbrellaUser user);
|
||||
|
||||
Poll.Evaluation loadEvaluation(String id);
|
||||
|
||||
Poll loadPoll(String id);
|
||||
|
||||
Poll save(Poll poll);
|
||||
|
||||
void saveSelection(Poll poll, Map<Integer,Integer> optionsToWeights, String guestName);
|
||||
|
||||
void saveSelection(Poll poll, Map<Integer,Integer> optionsToWeights, UmbrellaUser user);
|
||||
|
||||
Poll.Evaluation loadEvaluation(String id);
|
||||
void setPermission(String pollId, UmbrellaUser userId, Permission permission);
|
||||
}
|
||||
|
||||
@@ -3,14 +3,15 @@ package de.srsoftware.umbrella.poll;
|
||||
|
||||
import static de.srsoftware.umbrella.core.ConnectionProvider.connect;
|
||||
import static de.srsoftware.umbrella.core.ModuleRegistry.userService;
|
||||
import static de.srsoftware.umbrella.core.constants.Field.FIELD;
|
||||
import static de.srsoftware.umbrella.core.constants.Field.ID;
|
||||
import static de.srsoftware.umbrella.core.constants.Field.*;
|
||||
import static de.srsoftware.umbrella.core.constants.Path.*;
|
||||
import static de.srsoftware.umbrella.core.constants.Path.WEIGHT;
|
||||
import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.*;
|
||||
import static de.srsoftware.umbrella.poll.Constants.CONFIG_DATABASE;
|
||||
import static java.lang.System.Logger.Level.WARNING;
|
||||
import static java.net.HttpURLConnection.HTTP_OK;
|
||||
import static java.text.MessageFormat.format;
|
||||
|
||||
import static de.srsoftware.umbrella.core.model.Permission.READ_ONLY;
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import de.srsoftware.configuration.Configuration;
|
||||
import de.srsoftware.tools.Path;
|
||||
@@ -21,6 +22,7 @@ import de.srsoftware.umbrella.core.api.PollService;
|
||||
import de.srsoftware.umbrella.core.constants.Field;
|
||||
import de.srsoftware.umbrella.core.constants.Text;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.model.Permission;
|
||||
import de.srsoftware.umbrella.core.model.Poll;
|
||||
import de.srsoftware.umbrella.core.model.Token;
|
||||
import de.srsoftware.umbrella.core.model.UmbrellaUser;
|
||||
@@ -119,8 +121,8 @@ public class PollModule extends BaseHandler implements PollService {
|
||||
var poll = pollDb.loadPoll(pollId);
|
||||
var permitted = user.equals(poll.owner());
|
||||
if (!permitted) {
|
||||
var permission = poll.shares().get(user);
|
||||
if (permission == null || permission < 2) throw forbidden(Text.NOT_ALLOWED_TO_EDIT, Field.OBJECT,Text.POLL);
|
||||
var permission = poll.permissions().get(user);
|
||||
if (permission == null || permission == READ_ONLY) throw forbidden(Text.NOT_ALLOWED_TO_EDIT, Field.OBJECT,Text.POLL);
|
||||
}
|
||||
return poll;
|
||||
}
|
||||
@@ -144,6 +146,8 @@ public class PollModule extends BaseHandler implements PollService {
|
||||
poll.description(json.getString(key)); break;
|
||||
case Field.NAME:
|
||||
poll.name(json.getString(key)); break;
|
||||
case PRIVATE:
|
||||
poll.setPrivate(json.getBoolean(key)); break;
|
||||
case null, default:
|
||||
throw UmbrellaException.badRequest(Text.UNKNOWN_FIELD,ID,key);
|
||||
}
|
||||
@@ -194,7 +198,7 @@ public class PollModule extends BaseHandler implements PollService {
|
||||
var json = json(ex);
|
||||
if (!json.has(Field.NAME)) throw missingField(Field.NAME);
|
||||
var name = json.getString(Field.NAME);
|
||||
var poll = new Poll(null,user,name,"",true, List.of(), Map.of(),Map.of());
|
||||
var poll = new Poll(null,user,name,"",true, List.of(), Map.of());
|
||||
return sendContent(ex,pollDb.save(poll));
|
||||
}
|
||||
|
||||
@@ -203,17 +207,40 @@ public class PollModule extends BaseHandler implements PollService {
|
||||
var poll = pollDb.loadPoll(id);
|
||||
var permitted = user.equals(poll.owner());
|
||||
if (!permitted) {
|
||||
var permission = poll.shares().get(user);
|
||||
if (permission == null || permission < 2) throw forbidden(Text.NOT_ALLOWED_TO_EDIT, Field.OBJECT,Text.POLL);
|
||||
var permission = poll.permissions().get(user);
|
||||
if (permission == null || permission == READ_ONLY) throw forbidden(Text.NOT_ALLOWED_TO_EDIT, Field.OBJECT,Text.POLL);
|
||||
}
|
||||
var head = path.pop();
|
||||
return switch (head){
|
||||
case PERMISSIONS -> postPermission(ex, poll, user);
|
||||
case OPTION -> postOption(ex, poll);
|
||||
case SELECT -> postSelection(ex, poll, user);
|
||||
case null, default -> notFound(ex);
|
||||
};
|
||||
}
|
||||
|
||||
private boolean postPermission(HttpExchange ex, Poll poll, UmbrellaUser user) throws IOException {
|
||||
LOG.log(WARNING,"Permission check not implemented for postPermission");
|
||||
|
||||
var json = json(ex);
|
||||
if (!json.has(USER_ID)) throw missingField(USER_ID);
|
||||
if (!json.has(PERMISSION)) throw missingField(PERMISSION);
|
||||
if (!(json.get(USER_ID) instanceof Number userId)) throw invalidField(USER_ID,NUMBER);
|
||||
if (!(json.get(PERMISSION) instanceof Number perm)) throw invalidField(PERMISSION,NUMBER);
|
||||
var modifiedUser = userService().loadUser(userId.longValue());
|
||||
if (perm.intValue() == 0){
|
||||
pollDb.setPermission(poll.id(), modifiedUser, null);
|
||||
return sendEmptyResponse(HTTP_OK,ex);
|
||||
}
|
||||
var permission = Permission.of(perm.intValue());
|
||||
if (permission == Permission.ASSIGNEE) permission = Permission.EDIT;
|
||||
pollDb.setPermission(poll.id(), modifiedUser, permission);
|
||||
return sendContent(ex,Map.of(
|
||||
Field.USER,modifiedUser.toMap(),
|
||||
PERMISSION, permission.toMap()
|
||||
));
|
||||
}
|
||||
|
||||
private boolean postSelection(HttpExchange ex, Poll poll, UmbrellaUser user) throws IOException {
|
||||
var json = json(ex);
|
||||
if (!json.has(Field.SELECTION)) throw missingField(Field.SELECTION);
|
||||
|
||||
@@ -16,6 +16,7 @@ import de.srsoftware.umbrella.core.BaseDb;
|
||||
import de.srsoftware.umbrella.core.constants.Field;
|
||||
import de.srsoftware.umbrella.core.constants.Text;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.model.Permission;
|
||||
import de.srsoftware.umbrella.core.model.Poll;
|
||||
import de.srsoftware.umbrella.core.model.UmbrellaUser;
|
||||
|
||||
@@ -123,15 +124,16 @@ public class SqliteDb extends BaseDb implements PollDb {
|
||||
@Override
|
||||
public Collection<Poll> listPolls(UmbrellaUser user) {
|
||||
try {
|
||||
var sql = "SELECT DISTINCT {0}.*, {5} FROM {0} LEFT JOIN {1} ON {0}.{2} = {1}.{4} WHERE {0}.{3} = ? OR {1}.{3} = ? ORDER BY {6} ASC;";
|
||||
var ps = db.prepareStatement(format(sql,TABLE_POLLS,TABLE_SHARES, ID, USER_ID, POLL_ID, PERMISSION, NAME));
|
||||
var sql = "SELECT DISTINCT {0}.*, {5} FROM {0} LEFT JOIN {1} ON {0}.{2} = {1}.{4} WHERE {0}.{7} IS FALSE OR {0}.{3} = ? OR {1}.{3} = ? ORDER BY {6} ASC;";
|
||||
var ps = db.prepareStatement(format(sql,TABLE_POLLS,TABLE_SHARES, ID, USER_ID, POLL_ID, PERMISSION, NAME, PRIVATE));
|
||||
ps.setLong(1,user.id());
|
||||
ps.setLong(2, user.id());
|
||||
var rs = ps.executeQuery();
|
||||
var list = new ArrayList<Poll>();
|
||||
while (rs.next()) {
|
||||
var poll = Poll.of(rs);
|
||||
poll.shares().put(user,rs.getLong(PERMISSION));
|
||||
var perm = rs.getInt(PERMISSION);
|
||||
if (perm != 0) poll.permissions().put(user,Permission.of(perm));
|
||||
list.add(poll);
|
||||
}
|
||||
rs.close();
|
||||
@@ -176,11 +178,13 @@ public class SqliteDb extends BaseDb implements PollDb {
|
||||
rs.close();
|
||||
|
||||
rs = select(ALL).from(TABLE_SHARES).where(POLL_ID,equal(id)).exec(db);
|
||||
var shares = new HashMap<Long,Long>();
|
||||
while (rs.next()) shares.put(rs.getLong(USER_ID),rs.getLong(PERMISSION));
|
||||
var permissions = new HashMap<Long,Permission>();
|
||||
while (rs.next()) permissions.put(rs.getLong(USER_ID),Permission.of(rs.getInt(PERMISSION)));
|
||||
rs.close();
|
||||
var users = userService().list(null,null,shares.keySet());
|
||||
for (var entry : users.entrySet())poll.shares().put(entry.getValue(),shares.get(entry.getKey()));
|
||||
if (!permissions.isEmpty()) {
|
||||
var users = userService().list(null, null, permissions.keySet());
|
||||
for (var entry : users.entrySet()) poll.permissions().put(entry.getValue(), permissions.get(entry.getKey()));
|
||||
}
|
||||
return poll;
|
||||
} catch (SQLException e) {
|
||||
throw failedToLoadObject(Text.POLL,id).causedBy(e);
|
||||
@@ -211,7 +215,7 @@ public class SqliteDb extends BaseDb implements PollDb {
|
||||
} catch (SQLException e) {
|
||||
throw failedToStoreObject(poll);
|
||||
}
|
||||
return new Poll(uuid,poll.owner(),poll.name(),poll.description(),poll.isPrivate(), List.of(), Map.of(), Map.of());
|
||||
return new Poll(uuid,poll.owner(),poll.name(),poll.description(),poll.isPrivate(), List.of(), Map.of());
|
||||
}
|
||||
|
||||
private Poll.Option saveNew(String pollId, Poll.Option option) throws SQLException {
|
||||
@@ -246,9 +250,21 @@ public class SqliteDb extends BaseDb implements PollDb {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPermission(String pollId, UmbrellaUser user, Permission permission) {
|
||||
try {
|
||||
if (permission == null){
|
||||
delete().from(TABLE_SHARES).where(POLL_ID,equal(pollId)).where(USER_ID,equal(user.id())).execute(db);
|
||||
} else replaceInto(TABLE_SHARES, POLL_ID, USER_ID, PERMISSION)
|
||||
.values(pollId, user.id(), permission.code()).execute(db).close();
|
||||
} catch (SQLException e) {
|
||||
throw failedToStoreObject(Text.PERMISSION);
|
||||
}
|
||||
}
|
||||
|
||||
private Poll update(Poll poll) {
|
||||
if (poll.isDirty(NAME, DESCRIPTION)) try {
|
||||
replaceInto(TABLE_POLLS,ID,Field.USER_ID,NAME,DESCRIPTION).values(poll.id(),poll.owner().id(),poll.name(),poll.description()).execute(db).close();
|
||||
if (poll.isDirty(NAME, DESCRIPTION,PRIVATE)) try {
|
||||
replaceInto(TABLE_POLLS,ID,Field.USER_ID,NAME,DESCRIPTION,PRIVATE).values(poll.id(),poll.owner().id(),poll.name(),poll.description(),poll.isPrivate()).execute(db).close();
|
||||
} catch (SQLException e){
|
||||
throw failedToStoreObject(poll);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user