Search in sources :

Example 6 with EditMode

use of org.structr.web.common.RenderContext.EditMode in project structr by structr.

the class Content method renderContent.

/*
	@Override
	public String getIdHash() {

		final DOMNode _parent = getProperty(DOMNode.parent);
		if (_parent != null) {

			String dataHash = _parent.getProperty(DOMNode.dataHashProperty);
			if (dataHash == null) {
				dataHash = _parent.getIdHash();
			}

			return dataHash + "Content" + treeGetChildPosition(this);
		}

		return super.getIdHash();
	}

	*/
public static void renderContent(final Content thisNode, final RenderContext renderContext, final int depth) throws FrameworkException {
    final SecurityContext securityContext = thisNode.getSecurityContext();
    try {
        final EditMode edit = renderContext.getEditMode(securityContext.getUser(false));
        if (EditMode.DEPLOYMENT.equals(edit)) {
            final AsyncBuffer buf = renderContext.getBuffer();
            // output ownership comments
            DOMNode.renderDeploymentExportComments(thisNode, buf, true);
            // EditMode "deployment" means "output raw content, do not interpret in any way
            buf.append(escapeForHtml(thisNode.getContent()));
            return;
        }
        if (thisNode.isDeleted() || thisNode.isHidden() || !thisNode.displayForLocale(renderContext) || !thisNode.displayForConditions(renderContext)) {
            return;
        }
        final String id = thisNode.getUuid();
        final boolean inBody = renderContext.inBody();
        final AsyncBuffer out = renderContext.getBuffer();
        final String _contentType = thisNode.getContentType();
        // apply configuration for shared component if present
        final String _sharedComponentConfiguration = thisNode.getSharedComponentConfiguration();
        if (StringUtils.isNotBlank(_sharedComponentConfiguration)) {
            Scripting.evaluate(renderContext, thisNode, "${" + _sharedComponentConfiguration + "}", "shared component configuration");
        }
        // fetch content with variable replacement
        String _content = thisNode.getPropertyWithVariableReplacement(renderContext, StructrApp.key(Content.class, "content"));
        if (!(EditMode.RAW.equals(edit) || EditMode.WIDGET.equals(edit)) && (_contentType == null || ("text/plain".equals(_contentType)))) {
            _content = escapeForHtml(_content);
        }
        if (EditMode.CONTENT.equals(edit) && inBody && thisNode.isGranted(Permission.write, securityContext)) {
            if ("text/javascript".equals(_contentType)) {
                // Javascript will only be given some local vars
                out.append("// data-structr-type='").append(thisNode.getType()).append("'\n// data-structr-id='").append(id).append("'\n");
            } else if ("text/css".equals(_contentType)) {
                // CSS will only be given some local vars
                out.append("/* data-structr-type='").append(thisNode.getType()).append("'*/\n/* data-structr-id='").append(id).append("'*/\n");
            } else {
                // In edit mode, add an artificial comment tag around content nodes within body to make them editable
                final String cleanedContent = StringUtils.remove(StringUtils.remove(org.apache.commons.lang3.StringUtils.replace(thisNode.getContent(), "\n", "\\\\n"), "<!--"), "-->");
                out.append("<!--data-structr-id=\"".concat(id).concat("\" data-structr-raw-value=\"").concat(escapeForHtmlAttributes(cleanedContent)).concat("\"-->"));
            }
        }
        // examine content type and apply converter
        if (_contentType != null) {
            final Adapter<String, String> converter = ContentConverters.getConverterForType(_contentType);
            if (converter != null) {
                try {
                    // apply adapter
                    _content = converter.adapt(_content);
                } catch (FrameworkException fex) {
                    logger.warn("Unable to convert content: {}", fex.getMessage());
                }
            }
        }
        // replace newlines with <br /> for rendering
        if (((_contentType == null) || _contentType.equals("text/plain")) && (_content != null) && !_content.isEmpty()) {
            final DOMNode _parent = thisNode.getParent();
            if (_parent == null || !(_parent instanceof Textarea)) {
                _content = _content.replaceAll("[\\n]{1}", "<br>");
            }
        }
        if (_content != null) {
            // insert whitespace to make element clickable
            if (EditMode.CONTENT.equals(edit) && _content.length() == 0) {
                _content = "--- empty ---";
            }
            out.append(_content);
        }
        if (EditMode.CONTENT.equals(edit) && inBody && !("text/javascript".equals(_contentType) && !("text/css".equals(_contentType)))) {
            out.append("<!---->");
        }
    } catch (Throwable t) {
        // catch exception to prevent ugly status 500 error pages in frontend.
        logger.error("", t);
    }
}
Also used : FrameworkException(org.structr.common.error.FrameworkException) Textarea(org.structr.web.entity.html.Textarea) SecurityContext(org.structr.common.SecurityContext) EditMode(org.structr.web.common.RenderContext.EditMode) AsyncBuffer(org.structr.web.common.AsyncBuffer)

Example 7 with EditMode

use of org.structr.web.common.RenderContext.EditMode in project structr by structr.

the class Template method renderContent.

/*
	public static final org.structr.common.View uiView                                   = new org.structr.common.View(Content.class, PropertyView.Ui,
		children, childrenIds, content, contentType, parent, pageId, hideOnDetail, hideOnIndex, sharedComponent, syncedNodes, dataKey, restQuery, cypherQuery, xpathQuery, functionQuery,
		showForLocales, hideForLocales, showConditions, hideConditions, isContent
	);

	public static final org.structr.common.View publicView                               = new org.structr.common.View(Content.class, PropertyView.Public,
		children, childrenIds, content, contentType, parent, pageId, hideOnDetail, hideOnIndex, sharedComponent, syncedNodes, dataKey, restQuery, cypherQuery, xpathQuery, functionQuery,
		showForLocales, hideForLocales, showConditions, hideConditions, isContent
	);
	*/
public static void renderContent(final Template thisTemplate, final RenderContext renderContext, final int depth) throws FrameworkException {
    final SecurityContext securityContext = thisTemplate.getSecurityContext();
    final EditMode editMode = renderContext.getEditMode(securityContext.getUser(false));
    if (EditMode.DEPLOYMENT.equals(editMode)) {
        final DOMNode _syncedNode = thisTemplate.getSharedComponent();
        final AsyncBuffer out = renderContext.getBuffer();
        if (depth > 0) {
            out.append(DOMNode.indent(depth, renderContext));
        }
        DOMNode.renderDeploymentExportComments(thisTemplate, out, true);
        out.append("<structr:template src=\"");
        if (_syncedNode != null) {
            // use name of synced node
            final String _name = _syncedNode.getProperty(AbstractNode.name);
            out.append(_name != null ? _name.concat("-").concat(_syncedNode.getUuid()) : _syncedNode.getUuid());
        } else {
            // use name of local template
            final String _name = thisTemplate.getProperty(AbstractNode.name);
            out.append(_name != null ? _name.concat("-").concat(thisTemplate.getUuid()) : thisTemplate.getUuid());
        }
        out.append("\"");
        DOMNode.renderSharedComponentConfiguration(thisTemplate, out, editMode);
        // include custom attributes in templates as well!
        DOMNode.renderCustomAttributes(thisTemplate, out, securityContext, renderContext);
        out.append(">");
        // fetch children
        final List<RelationshipInterface> rels = thisTemplate.getChildRelationships();
        if (rels.isEmpty()) {
            // No child relationships, maybe this node is in sync with another node
            if (_syncedNode != null) {
                rels.addAll(_syncedNode.getChildRelationships());
            }
        }
        for (final RelationshipInterface rel : rels) {
            final DOMNode subNode = (DOMNode) rel.getTargetNode();
            subNode.render(renderContext, depth + 1);
        }
        out.append(DOMNode.indent(depth, renderContext));
        out.append("</structr:template>");
        out.append(DOMNode.indent(depth - 1, renderContext));
    } else {
        // "super" call using static method..
        Content.renderContent(thisTemplate, renderContext, depth);
    }
}
Also used : SecurityContext(org.structr.common.SecurityContext) RelationshipInterface(org.structr.core.graph.RelationshipInterface) EditMode(org.structr.web.common.RenderContext.EditMode) AsyncBuffer(org.structr.web.common.AsyncBuffer)

Example 8 with EditMode

use of org.structr.web.common.RenderContext.EditMode in project structr by structr.

the class HtmlServlet method doGet.

@Override
protected void doGet(final HttpServletRequest request, final HttpServletResponse response) {
    final Authenticator auth = getConfig().getAuthenticator();
    List<Page> pages = null;
    boolean requestUriContainsUuids = false;
    SecurityContext securityContext;
    final App app;
    try {
        assertInitialized();
        final String path = request.getPathInfo() != null ? request.getPathInfo() : "/";
        // check for registration (has its own tx because of write access
        if (checkRegistration(auth, request, response, path)) {
            return;
        }
        // check for registration (has its own tx because of write access
        if (checkResetPassword(auth, request, response, path)) {
            return;
        }
        // isolate request authentication in a transaction
        try (final Tx tx = StructrApp.getInstance().tx()) {
            securityContext = auth.initializeAndExamineRequest(request, response);
            tx.success();
        } catch (AuthenticationException aex) {
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
            return;
        }
        app = StructrApp.getInstance(securityContext);
        try (final Tx tx = app.tx()) {
            // 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");
            boolean dontCache = false;
            logger.debug("Path info {}", path);
            // don't continue on redirects
            if (response.getStatus() == 302) {
                tx.success();
                return;
            }
            final Principal user = securityContext.getUser(false);
            if (user != null) {
                // Don't cache if a user is logged in
                dontCache = true;
            }
            final RenderContext renderContext = RenderContext.getInstance(securityContext, request, response);
            renderContext.setResourceProvider(config.getResourceProvider());
            final EditMode edit = renderContext.getEditMode(user);
            DOMNode rootElement = null;
            AbstractNode dataNode = null;
            final String[] uriParts = PathHelper.getParts(path);
            if ((uriParts == null) || (uriParts.length == 0)) {
                // find a visible page
                rootElement = findIndexPage(securityContext, pages, edit);
                logger.debug("No path supplied, trying to find index page");
            } else {
                if (rootElement == null) {
                    rootElement = findPage(securityContext, pages, path, edit);
                } else {
                    dontCache = true;
                }
            }
            if (rootElement == null) {
                // No page found
                // In case of a file, try to find a file with the query string in the filename
                final String queryString = request.getQueryString();
                // Look for a file, first include the query string
                File file = findFile(securityContext, request, path + (queryString != null ? "?" + queryString : ""));
                // If no file with query string in the file name found, try without query string
                if (file == null) {
                    file = findFile(securityContext, request, path);
                }
                if (file != null) {
                    streamFile(securityContext, file, request, response, edit);
                    tx.success();
                    return;
                }
                if (uriParts != null) {
                    // store remaining path parts in request
                    final Matcher matcher = threadLocalUUIDMatcher.get();
                    for (int i = 0; i < uriParts.length; i++) {
                        request.setAttribute(uriParts[i], i);
                        matcher.reset(uriParts[i]);
                        // set to "true" if part matches UUID pattern
                        requestUriContainsUuids |= matcher.matches();
                    }
                }
                if (!requestUriContainsUuids) {
                    // Try to find a data node by name
                    dataNode = findFirstNodeByName(securityContext, request, path);
                } else {
                    dataNode = findNodeByUuid(securityContext, PathHelper.getName(path));
                }
                // if (dataNode != null && !(dataNode instanceof Linkable)) {
                if (dataNode != null) {
                    // Last path part matches a data node
                    // Remove last path part and try again searching for a page
                    // clear possible entry points
                    request.removeAttribute(POSSIBLE_ENTRY_POINTS_KEY);
                    rootElement = findPage(securityContext, pages, StringUtils.substringBeforeLast(path, PathHelper.PATH_SEP), edit);
                    renderContext.setDetailsDataObject(dataNode);
                    // Start rendering on data node
                    if (rootElement == null && dataNode instanceof DOMNode) {
                        // check visibleForSite here as well
                        if (!(dataNode instanceof Page) || isVisibleForSite(request, (Page) dataNode)) {
                            rootElement = ((DOMNode) dataNode);
                        }
                    }
                }
            }
            // look for pages with HTTP Basic Authentication (must be done as superuser)
            if (rootElement == null) {
                final HttpBasicAuthResult authResult = checkHttpBasicAuth(request, response, path);
                switch(authResult.authState()) {
                    // Element with Basic Auth found and authentication succeeded
                    case Authenticated:
                        final Linkable result = authResult.getRootElement();
                        if (result instanceof Page) {
                            rootElement = (DOMNode) result;
                            securityContext = authResult.getSecurityContext();
                            renderContext.pushSecurityContext(securityContext);
                        } else if (result instanceof File) {
                            streamFile(authResult.getSecurityContext(), (File) result, request, response, EditMode.NONE);
                            tx.success();
                            return;
                        }
                        break;
                    // Page with Basic Auth found but not yet authenticated
                    case MustAuthenticate:
                        final Page errorPage = StructrApp.getInstance().nodeQuery(Page.class).and(StructrApp.key(Page.class, "showOnErrorCodes"), "401", false).getFirst();
                        if (errorPage != null && isVisibleForSite(request, errorPage)) {
                            // set error page
                            rootElement = errorPage;
                            // don't cache the error page
                            dontCache = true;
                        } else {
                            // send error
                            response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
                            tx.success();
                            return;
                        }
                        break;
                    // no Basic Auth for given path, go on
                    case NoBasicAuth:
                        break;
                }
            }
            // Still nothing found, do error handling
            if (rootElement == null) {
                rootElement = notFound(response, securityContext);
            }
            if (rootElement == null) {
                tx.success();
                return;
            }
            // check dont cache flag on page (if root element is a page)
            // but don't modify true to false
            dontCache |= rootElement.dontCache();
            if (EditMode.WIDGET.equals(edit) || dontCache) {
                setNoCacheHeaders(response);
            }
            if (!securityContext.isVisible(rootElement)) {
                rootElement = notFound(response, securityContext);
                if (rootElement == null) {
                    tx.success();
                    return;
                }
            } else {
                if (!EditMode.WIDGET.equals(edit) && !dontCache && notModifiedSince(request, response, rootElement, dontCache)) {
                    ServletOutputStream out = response.getOutputStream();
                    out.flush();
                    // response.flushBuffer();
                    out.close();
                } else {
                    // prepare response
                    response.setCharacterEncoding("UTF-8");
                    String contentType = rootElement.getProperty(StructrApp.key(Page.class, "contentType"));
                    if (contentType == null) {
                        // Default
                        contentType = "text/html;charset=UTF-8";
                    }
                    if (contentType.equals("text/html")) {
                        contentType = contentType.concat(";charset=UTF-8");
                    }
                    response.setContentType(contentType);
                    setCustomResponseHeaders(response);
                    final boolean createsRawData = rootElement.getProperty(StructrApp.key(Page.class, "pageCreatesRawData"));
                    // async or not?
                    if (isAsync && !createsRawData) {
                        final AsyncContext async = request.startAsync();
                        final ServletOutputStream out = async.getResponse().getOutputStream();
                        final AtomicBoolean finished = new AtomicBoolean(false);
                        final DOMNode rootNode = rootElement;
                        threadPool.submit(new Runnable() {

                            @Override
                            public void run() {
                                try (final Tx tx = app.tx()) {
                                    // render
                                    rootNode.render(renderContext, 0);
                                    finished.set(true);
                                    tx.success();
                                } catch (Throwable t) {
                                    t.printStackTrace();
                                    logger.warn("Error while rendering page {}: {}", rootNode.getName(), t.getMessage());
                                    try {
                                        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                                        finished.set(true);
                                    } catch (IOException ex) {
                                        logger.warn("", ex);
                                    }
                                }
                            }
                        });
                        // start output write listener
                        out.setWriteListener(new WriteListener() {

                            @Override
                            public void onWritePossible() throws IOException {
                                try {
                                    final Queue<String> queue = renderContext.getBuffer().getQueue();
                                    while (out.isReady()) {
                                        String buffer = null;
                                        synchronized (queue) {
                                            buffer = queue.poll();
                                        }
                                        if (buffer != null) {
                                            out.print(buffer);
                                        } else {
                                            if (finished.get()) {
                                                async.complete();
                                                // prevent this block from being called again
                                                break;
                                            }
                                            Thread.sleep(1);
                                        }
                                    }
                                } catch (Throwable t) {
                                    logger.warn("", t);
                                }
                            }

                            @Override
                            public void onError(Throwable t) {
                                logger.warn("", t);
                            }
                        });
                    } else {
                        final StringRenderBuffer buffer = new StringRenderBuffer();
                        renderContext.setBuffer(buffer);
                        // render
                        rootElement.render(renderContext, 0);
                        try {
                            response.getOutputStream().write(buffer.getBuffer().toString().getBytes("utf-8"));
                            response.getOutputStream().flush();
                            response.getOutputStream().close();
                        } catch (IOException ioex) {
                            logger.warn("", ioex);
                        }
                    }
                }
            }
            tx.success();
        } catch (FrameworkException fex) {
            logger.error("Exception while processing request: {}", fex.getMessage());
        }
    } catch (FrameworkException fex) {
        logger.error("Exception while processing request: {}", fex.getMessage());
        UiAuthenticator.writeFrameworkException(response, fex);
    } catch (IOException ioex) {
        logger.error("Exception while processing request: {}", ioex.getMessage());
        UiAuthenticator.writeInternalServerError(response);
    }
}
Also used : App(org.structr.core.app.App) StructrApp(org.structr.core.app.StructrApp) StringRenderBuffer(org.structr.web.common.StringRenderBuffer) AuthenticationException(org.structr.core.auth.exception.AuthenticationException) AbstractNode(org.structr.core.entity.AbstractNode) Matcher(java.util.regex.Matcher) ThreadLocalMatcher(org.structr.common.ThreadLocalMatcher) ServletOutputStream(javax.servlet.ServletOutputStream) Page(org.structr.web.entity.dom.Page) AsyncContext(javax.servlet.AsyncContext) DOMNode(org.structr.web.entity.dom.DOMNode) WriteListener(javax.servlet.WriteListener) Queue(java.util.Queue) UiAuthenticator(org.structr.web.auth.UiAuthenticator) Authenticator(org.structr.core.auth.Authenticator) RenderContext(org.structr.web.common.RenderContext) Tx(org.structr.core.graph.Tx) FrameworkException(org.structr.common.error.FrameworkException) IOException(java.io.IOException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) SecurityContext(org.structr.common.SecurityContext) EditMode(org.structr.web.common.RenderContext.EditMode) Linkable(org.structr.web.entity.Linkable) AbstractFile(org.structr.web.entity.AbstractFile) File(org.structr.web.entity.File) Principal(org.structr.core.entity.Principal)

Example 9 with EditMode

use of org.structr.web.common.RenderContext.EditMode in project structr by structr.

the class DOMElement method renderContent.

static void renderContent(final DOMElement thisElement, final RenderContext renderContext, final int depth) throws FrameworkException {
    if (thisElement.isDeleted() || thisElement.isHidden() || !thisElement.displayForLocale(renderContext) || !thisElement.displayForConditions(renderContext)) {
        return;
    }
    // final variables
    final SecurityContext securityContext = renderContext.getSecurityContext();
    final AsyncBuffer out = renderContext.getBuffer();
    final EditMode editMode = renderContext.getEditMode(securityContext.getUser(false));
    final boolean isVoid = thisElement.isVoidElement();
    final String _tag = thisElement.getTag();
    // non-final variables
    Result localResult = renderContext.getResult();
    boolean anyChildNodeCreatesNewLine = false;
    thisElement.renderStructrAppLib(out, securityContext, renderContext, depth);
    if (depth > 0 && !thisElement.avoidWhitespace()) {
        out.append(DOMNode.indent(depth, renderContext));
    }
    if (StringUtils.isNotBlank(_tag)) {
        if (EditMode.DEPLOYMENT.equals(editMode)) {
            // comment accordingly.
            if (DOMNode.renderDeploymentExportComments(thisElement, out, false)) {
                // restore indentation
                if (depth > 0 && !thisElement.avoidWhitespace()) {
                    out.append(DOMNode.indent(depth, renderContext));
                }
            }
        }
        thisElement.openingTag(out, _tag, editMode, renderContext, depth);
        try {
            // in body?
            if (lowercaseBodyName.equals(thisElement.getTagName())) {
                renderContext.setInBody(true);
            }
            // only render children if we are not in a shared component scenario and not in deployment mode
            if (thisElement.getSharedComponent() == null || !EditMode.DEPLOYMENT.equals(editMode)) {
                // fetch children
                final List<RelationshipInterface> rels = thisElement.getChildRelationships();
                if (rels.isEmpty()) {
                    // No child relationships, maybe this node is in sync with another node
                    final DOMElement _syncedNode = (DOMElement) thisElement.getSharedComponent();
                    if (_syncedNode != null) {
                        rels.addAll(_syncedNode.getChildRelationships());
                    }
                }
                // apply configuration for shared component if present
                final String _sharedComponentConfiguration = thisElement.getProperty(StructrApp.key(DOMElement.class, "sharedComponentConfiguration"));
                if (StringUtils.isNotBlank(_sharedComponentConfiguration)) {
                    Scripting.evaluate(renderContext, thisElement, "${" + _sharedComponentConfiguration + "}", "shared component configuration");
                }
                for (final RelationshipInterface rel : rels) {
                    final DOMNode subNode = (DOMNode) rel.getTargetNode();
                    if (subNode instanceof DOMElement) {
                        anyChildNodeCreatesNewLine = (anyChildNodeCreatesNewLine || !(subNode.avoidWhitespace()));
                    }
                    subNode.render(renderContext, depth + 1);
                }
            }
        } catch (Throwable t) {
            out.append("Error while rendering node ").append(thisElement.getUuid()).append(": ").append(t.getMessage());
            logger.warn("", t);
        }
        // render end tag, if needed (= if not singleton tags)
        if (StringUtils.isNotBlank(_tag) && (!isVoid)) {
            // only insert a newline + indentation before the closing tag if any child-element used a newline
            final DOMElement _syncedNode = (DOMElement) thisElement.getSharedComponent();
            final boolean isTemplate = _syncedNode != null && EditMode.DEPLOYMENT.equals(editMode);
            if (anyChildNodeCreatesNewLine || isTemplate) {
                out.append(DOMNode.indent(depth, renderContext));
            }
            if (_syncedNode != null && EditMode.DEPLOYMENT.equals(editMode)) {
                out.append("</structr:component>");
            } else if (isTemplate) {
                out.append("</structr:template>");
            } else {
                out.append("</").append(_tag).append(">");
            }
        }
    }
    // Set result for this level again, if there was any
    if (localResult != null) {
        renderContext.setResult(localResult);
    }
}
Also used : SecurityContext(org.structr.common.SecurityContext) RelationshipInterface(org.structr.core.graph.RelationshipInterface) EditMode(org.structr.web.common.RenderContext.EditMode) AsyncBuffer(org.structr.web.common.AsyncBuffer) Result(org.structr.core.Result)

Example 10 with EditMode

use of org.structr.web.common.RenderContext.EditMode in project structr by structr.

the class HtmlServlet method doHead.

@Override
protected void doHead(final HttpServletRequest request, final HttpServletResponse response) {
    final Authenticator auth = getConfig().getAuthenticator();
    SecurityContext securityContext;
    List<Page> pages = null;
    boolean requestUriContainsUuids = false;
    final App app;
    try {
        assertInitialized();
        String path = request.getPathInfo();
        // isolate request authentication in a transaction
        try (final Tx tx = StructrApp.getInstance().tx()) {
            securityContext = auth.initializeAndExamineRequest(request, response);
            tx.success();
        }
        app = StructrApp.getInstance(securityContext);
        try (final Tx tx = app.tx()) {
            // 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");
            response.setContentLength(0);
            boolean dontCache = false;
            logger.debug("Path info {}", path);
            // don't continue on redirects
            if (response.getStatus() == 302) {
                tx.success();
                return;
            }
            final Principal user = securityContext.getUser(false);
            if (user != null) {
                // Don't cache if a user is logged in
                dontCache = true;
            }
            final RenderContext renderContext = RenderContext.getInstance(securityContext, request, response);
            renderContext.setResourceProvider(config.getResourceProvider());
            final EditMode edit = renderContext.getEditMode(user);
            DOMNode rootElement = null;
            AbstractNode dataNode = null;
            String[] uriParts = PathHelper.getParts(path);
            if ((uriParts == null) || (uriParts.length == 0)) {
                // find a visible page
                rootElement = findIndexPage(securityContext, pages, edit);
                logger.debug("No path supplied, trying to find index page");
            } else {
                if (rootElement == null) {
                    rootElement = findPage(securityContext, pages, path, edit);
                } else {
                    dontCache = true;
                }
            }
            if (rootElement == null) {
                // No page found
                // Look for a file
                File file = findFile(securityContext, request, path);
                if (file != null) {
                    // streamFile(securityContext, file, request, response, edit);
                    tx.success();
                    return;
                }
                if (uriParts != null) {
                    // store remaining path parts in request
                    Matcher matcher = threadLocalUUIDMatcher.get();
                    for (int i = 0; i < uriParts.length; i++) {
                        request.setAttribute(uriParts[i], i);
                        matcher.reset(uriParts[i]);
                        // set to "true" if part matches UUID pattern
                        requestUriContainsUuids |= matcher.matches();
                    }
                }
                if (!requestUriContainsUuids) {
                    // Try to find a data node by name
                    dataNode = findFirstNodeByName(securityContext, request, path);
                } else {
                    dataNode = findNodeByUuid(securityContext, PathHelper.getName(path));
                }
                if (dataNode != null && !(dataNode instanceof Linkable)) {
                    // Last path part matches a data node
                    // Remove last path part and try again searching for a page
                    // clear possible entry points
                    request.removeAttribute(POSSIBLE_ENTRY_POINTS_KEY);
                    rootElement = findPage(securityContext, pages, StringUtils.substringBeforeLast(path, PathHelper.PATH_SEP), edit);
                    renderContext.setDetailsDataObject(dataNode);
                    // Start rendering on data node
                    if (rootElement == null && dataNode instanceof DOMNode) {
                        rootElement = ((DOMNode) dataNode);
                    }
                }
            }
            // look for pages with HTTP Basic Authentication (must be done as superuser)
            if (rootElement == null) {
                final HttpBasicAuthResult authResult = checkHttpBasicAuth(request, response, path);
                switch(authResult.authState()) {
                    // Element with Basic Auth found and authentication succeeded
                    case Authenticated:
                        final Linkable result = authResult.getRootElement();
                        if (result instanceof Page) {
                            rootElement = (DOMNode) result;
                            renderContext.pushSecurityContext(authResult.getSecurityContext());
                        } else if (result instanceof File) {
                            // streamFile(authResult.getSecurityContext(), (File)result, request, response, EditMode.NONE);
                            tx.success();
                            return;
                        }
                        break;
                    // Page with Basic Auth found but not yet authenticated
                    case MustAuthenticate:
                        tx.success();
                        return;
                    // no Basic Auth for given path, go on
                    case NoBasicAuth:
                        break;
                }
            }
            // Still nothing found, do error handling
            if (rootElement == null) {
                // Check if security context has set an 401 status
                if (response.getStatus() == HttpServletResponse.SC_UNAUTHORIZED) {
                    try {
                        UiAuthenticator.writeUnauthorized(response);
                    } catch (IllegalStateException ise) {
                    }
                } else {
                    rootElement = notFound(response, securityContext);
                }
            }
            if (rootElement == null) {
                // no content
                response.setContentLength(0);
                response.getOutputStream().close();
                tx.success();
                return;
            }
            // check dont cache flag on page (if root element is a page)
            // but don't modify true to false
            dontCache |= rootElement.dontCache();
            if (EditMode.WIDGET.equals(edit) || dontCache) {
                setNoCacheHeaders(response);
            }
            if (!securityContext.isVisible(rootElement)) {
                rootElement = notFound(response, securityContext);
                if (rootElement == null) {
                    tx.success();
                    return;
                }
            }
            if (securityContext.isVisible(rootElement)) {
                if (!EditMode.WIDGET.equals(edit) && !dontCache && notModifiedSince(request, response, rootElement, dontCache)) {
                    response.getOutputStream().close();
                } else {
                    // prepare response
                    response.setCharacterEncoding("UTF-8");
                    String contentType = rootElement.getProperty(StructrApp.key(Page.class, "contentType"));
                    if (contentType == null) {
                        // Default
                        contentType = "text/html;charset=UTF-8";
                    }
                    if (contentType.equals("text/html")) {
                        contentType = contentType.concat(";charset=UTF-8");
                    }
                    response.setContentType(contentType);
                    setCustomResponseHeaders(response);
                    response.getOutputStream().close();
                }
            } else {
                notFound(response, securityContext);
                response.getOutputStream().close();
            }
            tx.success();
        } catch (Throwable fex) {
            logger.error("Exception while processing request", fex);
        }
    } catch (FrameworkException t) {
        logger.error("Exception while processing request", t);
        UiAuthenticator.writeInternalServerError(response);
    }
}
Also used : App(org.structr.core.app.App) StructrApp(org.structr.core.app.StructrApp) RenderContext(org.structr.web.common.RenderContext) Tx(org.structr.core.graph.Tx) FrameworkException(org.structr.common.error.FrameworkException) AbstractNode(org.structr.core.entity.AbstractNode) Matcher(java.util.regex.Matcher) ThreadLocalMatcher(org.structr.common.ThreadLocalMatcher) Page(org.structr.web.entity.dom.Page) SecurityContext(org.structr.common.SecurityContext) EditMode(org.structr.web.common.RenderContext.EditMode) Linkable(org.structr.web.entity.Linkable) DOMNode(org.structr.web.entity.dom.DOMNode) AbstractFile(org.structr.web.entity.AbstractFile) File(org.structr.web.entity.File) UiAuthenticator(org.structr.web.auth.UiAuthenticator) Authenticator(org.structr.core.auth.Authenticator) Principal(org.structr.core.entity.Principal)

Aggregations

EditMode (org.structr.web.common.RenderContext.EditMode)10 SecurityContext (org.structr.common.SecurityContext)6 FrameworkException (org.structr.common.error.FrameworkException)4 AsyncBuffer (org.structr.web.common.AsyncBuffer)3 Matcher (java.util.regex.Matcher)2 ThreadLocalMatcher (org.structr.common.ThreadLocalMatcher)2 GraphObject (org.structr.core.GraphObject)2 App (org.structr.core.app.App)2 StructrApp (org.structr.core.app.StructrApp)2 Authenticator (org.structr.core.auth.Authenticator)2 AbstractNode (org.structr.core.entity.AbstractNode)2 Principal (org.structr.core.entity.Principal)2 RelationshipInterface (org.structr.core.graph.RelationshipInterface)2 Tx (org.structr.core.graph.Tx)2 PropertyKey (org.structr.core.property.PropertyKey)2 UiAuthenticator (org.structr.web.auth.UiAuthenticator)2 RenderContext (org.structr.web.common.RenderContext)2 AbstractFile (org.structr.web.entity.AbstractFile)2 File (org.structr.web.entity.File)2 Linkable (org.structr.web.entity.Linkable)2