use of org.structr.common.SecurityContext in project structr by structr.
the class UploadServlet method doPut.
@Override
protected void doPut(final HttpServletRequest request, final HttpServletResponse response) throws ServletException {
try (final Tx tx = StructrApp.getInstance().tx(true, false, false)) {
final String uuid = PathHelper.getName(request.getPathInfo());
if (uuid == null) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
response.getOutputStream().write("URL path doesn't end with UUID.\n".getBytes("UTF-8"));
return;
}
Matcher matcher = threadLocalUUIDMatcher.get();
matcher.reset(uuid);
if (!matcher.matches()) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
response.getOutputStream().write("ERROR (400): URL path doesn't end with UUID.\n".getBytes("UTF-8"));
return;
}
final SecurityContext securityContext = getConfig().getAuthenticator().initializeAndExamineRequest(request, response);
// Ensure access mode is frontend
securityContext.setAccessMode(AccessMode.Frontend);
request.setCharacterEncoding("UTF-8");
// Important: Set character encoding before calling response.getWriter() !!, see Servlet Spec 5.4
response.setCharacterEncoding("UTF-8");
// don't continue on redirects
if (response.getStatus() == 302) {
return;
}
uploader.setFileSizeMax(MEGABYTE * Settings.UploadMaxFileSize.getValue());
uploader.setSizeMax(MEGABYTE * Settings.UploadMaxRequestSize.getValue());
FileItemIterator fileItemsIterator = uploader.getItemIterator(request);
while (fileItemsIterator.hasNext()) {
final FileItemStream fileItem = fileItemsIterator.next();
try {
final GraphObject node = StructrApp.getInstance().getNodeById(uuid);
if (node == null) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
response.getOutputStream().write("ERROR (404): File not found.\n".getBytes("UTF-8"));
}
if (node instanceof org.structr.web.entity.File) {
final File file = (File) node;
if (file.isGranted(Permission.write, securityContext)) {
try (final InputStream is = fileItem.openStream()) {
FileHelper.writeToFile(file, is);
file.increaseVersion();
// upload trigger
file.notifyUploadCompletion();
}
} else {
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
response.getOutputStream().write("ERROR (403): Write access forbidden.\n".getBytes("UTF-8"));
}
}
} catch (IOException ex) {
logger.warn("Could not write to file", ex);
}
}
tx.success();
} catch (FrameworkException | IOException | FileUploadException t) {
logger.error("Exception while processing request", t);
UiAuthenticator.writeInternalServerError(response);
}
}
use of org.structr.common.SecurityContext in project structr by structr.
the class WebSocketDataGSONAdapter method serialize.
// ~--- methods --------------------------------------------------------
@Override
public JsonElement serialize(WebSocketMessage src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject root = new JsonObject();
JsonObject jsonNodeData = new JsonObject();
JsonObject jsonRelData = new JsonObject();
JsonArray removedProperties = new JsonArray();
JsonArray modifiedProperties = new JsonArray();
if (src.getCommand() != null) {
root.add("command", new JsonPrimitive(src.getCommand()));
}
if (src.getId() != null) {
root.add("id", new JsonPrimitive(src.getId()));
}
if (src.getPageId() != null) {
root.add("pageId", new JsonPrimitive(src.getPageId()));
}
if (src.getMessage() != null) {
root.add("message", new JsonPrimitive(src.getMessage()));
}
if (src.getJsonErrorObject() != null) {
root.add("error", src.getJsonErrorObject());
}
if (src.getCode() != 0) {
root.add("code", new JsonPrimitive(src.getCode()));
}
if (src.getSessionId() != null) {
root.add("sessionId", new JsonPrimitive(src.getSessionId()));
}
if (src.getCallback() != null) {
root.add("callback", new JsonPrimitive(src.getCallback()));
}
if (src.getButton() != null) {
root.add("button", new JsonPrimitive(src.getButton()));
}
if (src.getParent() != null) {
root.add("parent", new JsonPrimitive(src.getParent()));
}
if (src.getView() != null) {
root.add("view", new JsonPrimitive(src.getView()));
}
if (src.getSortKey() != null) {
root.add("sort", new JsonPrimitive(src.getSortKey()));
}
if (src.getSortOrder() != null) {
root.add("order", new JsonPrimitive(src.getSortOrder()));
}
if (src.getPageSize() > 0) {
root.add("pageSize", new JsonPrimitive(src.getPageSize()));
}
if (src.getPage() > 0) {
root.add("page", new JsonPrimitive(src.getPage()));
}
JsonArray nodesWithChildren = new JsonArray();
Set<String> nwc = src.getNodesWithChildren();
if ((nwc != null) && !src.getNodesWithChildren().isEmpty()) {
for (String nodeId : nwc) {
nodesWithChildren.add(new JsonPrimitive(nodeId));
}
root.add("nodesWithChildren", nodesWithChildren);
}
// serialize session valid flag (output only)
root.add("sessionValid", new JsonPrimitive(src.isSessionValid()));
// UPDATE only, serialize only removed and modified properties and use the correct values
if ((src.getGraphObject() != null)) {
if (!src.getModifiedProperties().isEmpty()) {
for (PropertyKey modifiedKey : src.getModifiedProperties()) {
modifiedProperties.add(toJsonPrimitive(modifiedKey));
}
root.add("modifiedProperties", modifiedProperties);
}
if (!src.getRemovedProperties().isEmpty()) {
for (PropertyKey removedKey : src.getRemovedProperties()) {
removedProperties.add(toJsonPrimitive(removedKey));
}
root.add("removedProperties", removedProperties);
}
}
// serialize node data
if (src.getNodeData() != null) {
for (Entry<String, Object> entry : src.getNodeData().entrySet()) {
Object value = entry.getValue();
String key = entry.getKey();
if (value != null) {
jsonNodeData.add(key, toJsonPrimitive(value));
}
}
root.add("data", jsonNodeData);
}
// serialize relationship data
if (src.getRelData() != null) {
for (Entry<String, Object> entry : src.getRelData().entrySet()) {
Object value = entry.getValue();
String key = entry.getKey();
if (value != null) {
jsonRelData.add(key, toJsonPrimitive(value));
}
}
root.add("relData", jsonRelData);
}
// serialize result list
if (src.getResult() != null) {
if ("GRAPHQL".equals(src.getCommand())) {
try {
if (src.getResult() != null && !src.getResult().isEmpty()) {
final GraphObject firstResultObject = src.getResult().get(0);
final SecurityContext securityContext = firstResultObject.getSecurityContext();
final StringWriter output = new StringWriter();
final String query = (String) src.getNodeData().get("query");
final Document doc = GraphQLRequest.parse(new Parser(), query);
final GraphQLWriter graphQLWriter = new GraphQLWriter(false);
graphQLWriter.stream(securityContext, output, new GraphQLRequest(securityContext, doc, query));
JsonElement graphQLResult = new JsonParser().parse(output.toString());
root.add("result", graphQLResult);
} else {
root.add("result", new JsonArray());
}
} catch (IOException | FrameworkException ex) {
logger.warn("Unable to set process GraphQL query", ex);
}
} else {
if (src.getView() != null) {
try {
propertyView.set(null, src.getView());
} catch (FrameworkException fex) {
logger.warn("Unable to set property view", fex);
}
} else {
try {
propertyView.set(null, PropertyView.Ui);
} catch (FrameworkException fex) {
logger.warn("Unable to set property view", fex);
}
}
JsonArray result = new JsonArray();
for (GraphObject obj : src.getResult()) {
result.add(graphObjectSerializer.serialize(obj, System.currentTimeMillis()));
}
root.add("result", result);
}
root.add("rawResultCount", toJsonPrimitive(src.getRawResultCount()));
}
return root;
}
use of org.structr.common.SecurityContext in project structr by structr.
the class WebsocketController method broadcast.
private void broadcast(final WebSocketMessage webSocketData, final String exemptedSessionId) {
// session must be valid to be received by the client
webSocketData.setSessionValid(true);
final String pagePath = (String) webSocketData.getNodeData().get("pagePath");
final String encodedPath = URIUtil.encodePath(pagePath);
final List<StructrWebSocket> clientsToRemove = new LinkedList<>();
final List<? extends GraphObject> result = webSocketData.getResult();
final String command = webSocketData.getCommand();
final GraphObject obj = webSocketData.getGraphObject();
String message;
// create message
for (StructrWebSocket socket : clients) {
String clientPagePath = socket.getPagePath();
if (clientPagePath != null && !clientPagePath.equals(encodedPath)) {
continue;
}
Session session = socket.getSession();
if (session != null && socket.isAuthenticated()) {
final SecurityContext securityContext = socket.getSecurityContext();
if (exemptedSessionId != null && exemptedSessionId.equals(securityContext.getSessionId())) {
// session id is supposed to be exempted from this broadcast message
continue;
}
// THEN skip sending a message
if (obj instanceof AbstractNode) {
final AbstractNode node = (AbstractNode) obj;
if (node.isHidden() || !securityContext.isVisible(node)) {
continue;
}
} else {
if (!socket.isPrivilegedUser(socket.getCurrentUser())) {
continue;
}
}
if (result != null && !result.isEmpty() && BroadcastCommands.contains(command)) {
final WebSocketMessage clientData = webSocketData.copy();
clientData.setResult(filter(securityContext, result));
message = gson.toJson(clientData, WebSocketMessage.class);
} else {
message = gson.toJson(webSocketData, WebSocketMessage.class);
}
try {
session.getRemote().sendString(message);
} catch (Throwable t) {
if (t instanceof WebSocketException) {
WebSocketException wse = (WebSocketException) t;
if ("RemoteEndpoint unavailable, current state [CLOSED], expecting [OPEN or CONNECTED]".equals(wse.getMessage())) {
clientsToRemove.add(socket);
}
}
logger.debug("Error sending message to client.", t);
}
}
}
for (StructrWebSocket s : clientsToRemove) {
unregisterClient(s);
logger.warn("Client removed from broadcast list: {}", s);
}
}
use of org.structr.common.SecurityContext in project structr by structr.
the class SyncModeCommand method processMessage.
@Override
public void processMessage(final WebSocketMessage webSocketData) {
final Class<Relation> relType = StructrApp.getConfiguration().getRelationshipEntityClass("DOMNodeSYNCDOMNode");
final SecurityContext securityContext = getWebSocket().getSecurityContext();
final String sourceId = webSocketData.getId();
final Map<String, Object> properties = webSocketData.getNodeData();
final String targetId = (String) properties.get("targetId");
final String syncMode = (String) properties.get("syncMode");
final DOMNode sourceNode = (DOMNode) getNode(sourceId);
final DOMNode targetNode = (DOMNode) getNode(targetId);
final App app = StructrApp.getInstance(securityContext);
if ((sourceNode != null) && (targetNode != null)) {
try {
app.create(sourceNode, targetNode, relType);
if (syncMode.equals("bidir")) {
app.create(targetNode, sourceNode, relType);
}
} catch (Throwable t) {
getWebSocket().send(MessageBuilder.status().code(400).message(t.getMessage()).build(), true);
}
} else {
getWebSocket().send(MessageBuilder.status().code(400).message("The SYNC_MODE command needs id and targetId!").build(), true);
}
}
use of org.structr.common.SecurityContext in project structr by structr.
the class UnarchiveCommand method processMessage.
@Override
public void processMessage(final WebSocketMessage webSocketData) {
final Set<String> supportedByArchiveStreamFactory = new HashSet<>(Arrays.asList(new String[] { ArchiveStreamFactory.AR, ArchiveStreamFactory.ARJ, ArchiveStreamFactory.CPIO, ArchiveStreamFactory.DUMP, ArchiveStreamFactory.JAR, ArchiveStreamFactory.TAR, ArchiveStreamFactory.SEVEN_Z, ArchiveStreamFactory.ZIP }));
final SecurityContext securityContext = getWebSocket().getSecurityContext();
final App app = StructrApp.getInstance(securityContext);
try {
final String id = (String) webSocketData.getId();
final String parentFolderId = (String) webSocketData.getNodeData().get("parentFolderId");
final File file;
try (final Tx tx = app.tx()) {
file = app.get(File.class, id);
if (file == null) {
getWebSocket().send(MessageBuilder.status().code(400).message("File not found: ".concat(id)).build(), true);
return;
}
final String fileExtension = StringUtils.substringAfterLast(file.getName(), ".");
if (!supportedByArchiveStreamFactory.contains(fileExtension)) {
getWebSocket().send(MessageBuilder.status().code(400).message("Unsupported archive format: ".concat(fileExtension)).build(), true);
return;
}
tx.success();
}
// no transaction here since this is a bulk command
unarchive(securityContext, file, parentFolderId);
} catch (Throwable t) {
logger.warn("", t);
String msg = t.toString();
try (final Tx tx = app.tx()) {
// return error message
getWebSocket().send(MessageBuilder.status().code(400).message("Could not unarchive file: ".concat((msg != null) ? msg : "")).build(), true);
getWebSocket().send(MessageBuilder.finished().callback(callback).data("success", false).build(), true);
tx.success();
} catch (FrameworkException ignore) {
}
}
}
Aggregations