Search in sources :

Example 11 with RenderContext

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

the class RenderContextTest method testFiltering.

@Test
public void testFiltering() {
    final List<TestOne> testOnes = new LinkedList<>();
    try (final Tx tx = app.tx()) {
        testOnes.addAll(createTestNodes(TestOne.class, 20));
        final RenderContext ctx = new RenderContext(securityContext);
        final TestOne testOne = testOnes.get(0);
        // test filtering
        ctx.setDetailsDataObject(testOnes.get(5));
        final Object value = Scripting.evaluate(ctx, testOne, "${filter(find('TestOne'), not(equal(data.id, current.id)))}", "test");
        assertNotNull("Invalid filter result", value);
        assertTrue("Invalid filter result", value instanceof List);
        assertEquals("Invalid filter result", 19, ((List) value).size());
        tx.success();
    } catch (FrameworkException fex) {
        logger.warn("", fex);
        fail("Unexpected exception.");
    }
}
Also used : RenderContext(org.structr.web.common.RenderContext) Tx(org.structr.core.graph.Tx) FrameworkException(org.structr.common.error.FrameworkException) LinkedList(java.util.LinkedList) NodeList(org.w3c.dom.NodeList) List(java.util.List) TestOne(org.structr.web.entity.TestOne) LinkedList(java.util.LinkedList) Test(org.junit.Test) StructrUiTest(org.structr.web.StructrUiTest)

Example 12 with RenderContext

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

the class RenderContextTest method testNotionTransformedPropertyAccess.

@Test
public void testNotionTransformedPropertyAccess() {
    NodeInterface project = null;
    NodeInterface task1 = null;
    NodeInterface task2 = null;
    NodeInterface task3 = null;
    try (final Tx tx = app.tx()) {
        final SchemaNode projectNode = app.create(SchemaNode.class, new NodeAttribute(SchemaNode.name, "Project"), new NodeAttribute(new StringProperty("_taskList"), "Notion(tasks, id, name)"), new NodeAttribute(new StringProperty("_taskNames"), "Notion(tasks, name)"));
        final SchemaNode taskNode = app.create(SchemaNode.class, new NodeAttribute(SchemaNode.name, "Task"));
        // create schema relationship
        final PropertyMap taskProperties = new PropertyMap();
        taskProperties.put(SchemaRelationshipNode.sourceNode, projectNode);
        taskProperties.put(SchemaRelationshipNode.targetNode, taskNode);
        taskProperties.put(SchemaRelationshipNode.relationshipType, "TASK");
        taskProperties.put(SchemaRelationshipNode.relationshipType, "TASK");
        taskProperties.put(SchemaRelationshipNode.sourceMultiplicity, "1");
        taskProperties.put(SchemaRelationshipNode.targetMultiplicity, "*");
        taskProperties.put(SchemaRelationshipNode.sourceJsonName, "project");
        taskProperties.put(SchemaRelationshipNode.targetJsonName, "tasks");
        app.create(SchemaRelationshipNode.class, taskProperties);
        // create schema relationship
        final PropertyMap currentTaskProperties = new PropertyMap();
        currentTaskProperties.put(SchemaRelationshipNode.sourceNode, projectNode);
        currentTaskProperties.put(SchemaRelationshipNode.targetNode, taskNode);
        currentTaskProperties.put(SchemaRelationshipNode.relationshipType, "CURRENT");
        currentTaskProperties.put(SchemaRelationshipNode.sourceMultiplicity, "1");
        currentTaskProperties.put(SchemaRelationshipNode.targetMultiplicity, "1");
        currentTaskProperties.put(SchemaRelationshipNode.sourceJsonName, "project");
        currentTaskProperties.put(SchemaRelationshipNode.targetJsonName, "currentTask");
        app.create(SchemaRelationshipNode.class, currentTaskProperties);
        // compile the stuff
        tx.success();
    } catch (FrameworkException fex) {
        logger.warn("", fex);
        fail("Unexpected exception");
    }
    final ConfigurationProvider config = StructrApp.getConfiguration();
    final Class projectClass = config.getNodeEntityClass("Project");
    final Class taskClass = config.getNodeEntityClass("Task");
    final PropertyKey currentTaskKey = StructrApp.key(projectClass, "currentTask");
    final PropertyKey tasksKey = StructrApp.key(projectClass, "tasks");
    // create parent/child relationship
    try (final Tx tx = app.tx()) {
        project = app.create(projectClass, new NodeAttribute(SchemaNode.name, "Project1"));
        task1 = app.create(taskClass, new NodeAttribute(SchemaNode.name, "Task1"));
        task2 = app.create(taskClass, new NodeAttribute(SchemaNode.name, "Task2"));
        task3 = app.create(taskClass, new NodeAttribute(SchemaNode.name, "Task3"));
        // add task to project
        final List tasks = new LinkedList<>();
        tasks.add(task1);
        tasks.add(task2);
        tasks.add(task3);
        final PropertyMap projectProperties = new PropertyMap();
        projectProperties.put(tasksKey, tasks);
        projectProperties.put(currentTaskKey, task3);
        project.setProperties(project.getSecurityContext(), projectProperties);
        tx.success();
    } catch (FrameworkException fex) {
        logger.warn("", fex);
        fail("Unexpected exception");
    }
    // check property access in template expressions
    try (final Tx tx = app.tx()) {
        final RenderContext renderContext = new RenderContext(securityContext);
        renderContext.putDataObject("project", project);
        renderContext.putDataObject("task", task1);
        assertEquals("Invalid dot syntax result: ", "Project1", Scripting.replaceVariables(renderContext, project, "${project.name}"));
        assertEquals("Invalid dot syntax result: ", "Task1", Scripting.replaceVariables(renderContext, project, "${project.tasks[0].name}"));
        assertEquals("Invalid dot syntax result: ", "Task2", Scripting.replaceVariables(renderContext, project, "${project.tasks[1].name}"));
        assertEquals("Invalid dot syntax result: ", "Task3", Scripting.replaceVariables(renderContext, project, "${project.tasks[2].name}"));
        assertEquals("Invalid dot syntax result: ", "[Task1, Task2, Task3]", Scripting.replaceVariables(renderContext, project, "${project.taskNames}"));
        assertEquals("Invalid dot syntax result: ", "Task1", Scripting.replaceVariables(renderContext, project, "${project.taskNames[0]}"));
        assertEquals("Invalid dot syntax result: ", "Task2", Scripting.replaceVariables(renderContext, project, "${project.taskNames[1]}"));
        assertEquals("Invalid dot syntax result: ", "Task3", Scripting.replaceVariables(renderContext, project, "${project.taskNames[2]}"));
        assertEquals("Invalid dot syntax result: ", "Task3", Scripting.replaceVariables(renderContext, project, "${project.currentTask.name}"));
        tx.success();
    } catch (FrameworkException fex) {
        logger.warn("", fex);
        fail("Unexpected exception");
    }
}
Also used : NodeAttribute(org.structr.core.graph.NodeAttribute) RenderContext(org.structr.web.common.RenderContext) Tx(org.structr.core.graph.Tx) FrameworkException(org.structr.common.error.FrameworkException) ConfigurationProvider(org.structr.schema.ConfigurationProvider) StringProperty(org.structr.core.property.StringProperty) LinkedList(java.util.LinkedList) SchemaNode(org.structr.core.entity.SchemaNode) PropertyMap(org.structr.core.property.PropertyMap) LinkedList(java.util.LinkedList) NodeList(org.w3c.dom.NodeList) List(java.util.List) NodeInterface(org.structr.core.graph.NodeInterface) PropertyKey(org.structr.core.property.PropertyKey) Test(org.junit.Test) StructrUiTest(org.structr.web.StructrUiTest)

Example 13 with RenderContext

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

the class RenderContextTest method testVariableReplacement.

@Test
public void testVariableReplacement() {
    NodeInterface detailsDataObject = null;
    Page page = null;
    DOMNode html = null;
    DOMNode head = null;
    DOMNode body = null;
    DOMNode title = null;
    DOMNode h1 = null;
    DOMNode div1 = null;
    DOMNode p1 = null;
    DOMNode div2 = null;
    DOMNode p2 = null;
    DOMNode div3 = null;
    DOMNode p3 = null;
    A a = null;
    DOMNode div4 = null;
    DOMNode p4 = null;
    TestOne testOne = null;
    try (final Tx tx = app.tx()) {
        detailsDataObject = app.create(TestOne.class, "TestOne");
        page = Page.createNewPage(securityContext, "testpage");
        page.setProperties(page.getSecurityContext(), new PropertyMap(Page.visibleToPublicUsers, true));
        assertTrue(page != null);
        assertTrue(page instanceof Page);
        html = (DOMNode) page.createElement("html");
        head = (DOMNode) page.createElement("head");
        body = (DOMNode) page.createElement("body");
        title = (DOMNode) page.createElement("title");
        h1 = (DOMNode) page.createElement("h1");
        div1 = (DOMNode) page.createElement("div");
        p1 = (DOMNode) page.createElement("p");
        div2 = (DOMNode) page.createElement("div");
        p2 = (DOMNode) page.createElement("p");
        div3 = (DOMNode) page.createElement("div");
        p3 = (DOMNode) page.createElement("p");
        a = (A) page.createElement("a");
        div4 = (DOMNode) page.createElement("div");
        p4 = (DOMNode) page.createElement("p");
        // add HTML element to page
        page.appendChild(html);
        // add HEAD and BODY elements to HTML
        html.appendChild(head);
        html.appendChild(body);
        // add TITLE element to HEAD
        head.appendChild(title);
        // add H1 element to BODY
        body.appendChild(h1);
        // add DIV element 1 to BODY
        body.appendChild(div1);
        div1.appendChild(p1);
        // add DIV element 2 to DIV
        div1.appendChild(div2);
        div2.appendChild(p2);
        // add DIV element 3 to DIV
        div2.appendChild(div3);
        div3.appendChild(p3);
        // add link to p3
        p3.appendChild(a);
        a.setLinkable(page);
        body.appendChild(div4);
        div4.appendChild(p4);
        final PropertyMap p4Properties = new PropertyMap();
        p4Properties.put(StructrApp.key(DOMElement.class, "restQuery"), "/divs");
        p4Properties.put(StructrApp.key(DOMElement.class, "dataKey"), "div");
        p4.setProperties(p4.getSecurityContext(), p4Properties);
        NodeList paragraphs = page.getElementsByTagName("p");
        assertEquals(p1, paragraphs.item(0));
        assertEquals(p2, paragraphs.item(1));
        assertEquals(p3, paragraphs.item(2));
        assertEquals(p4, paragraphs.item(3));
        // create users
        final User tester1 = app.create(User.class, new NodeAttribute<>(StructrApp.key(User.class, "name"), "tester1"), new NodeAttribute<>(StructrApp.key(User.class, "eMail"), "tester1@test.com"));
        final User tester2 = app.create(User.class, new NodeAttribute<>(StructrApp.key(User.class, "name"), "tester2"), new NodeAttribute<>(StructrApp.key(User.class, "eMail"), "tester2@test.com"));
        assertNotNull("User tester1 should exist.", tester1);
        assertNotNull("User tester2 should exist.", tester2);
        // create admin user for later use
        final PropertyMap adminProperties = new PropertyMap();
        adminProperties.put(StructrApp.key(User.class, "name"), "admin");
        adminProperties.put(StructrApp.key(User.class, "password"), "admin");
        adminProperties.put(StructrApp.key(User.class, "isAdmin"), true);
        app.create(User.class, adminProperties);
        tx.success();
    } catch (FrameworkException fex) {
        fail("Unexpected exception");
    }
    try (final Tx tx = app.tx()) {
        final RenderContext ctx = new RenderContext(securityContext);
        ctx.setDetailsDataObject(detailsDataObject);
        ctx.setPage(page);
        // test for "empty" return value
        assertEquals("", Scripting.replaceVariables(ctx, p1, "${err}"));
        assertEquals("", Scripting.replaceVariables(ctx, p1, "${this.error}"));
        assertEquals("", Scripting.replaceVariables(ctx, p1, "${this.this.this.error}"));
        assertEquals("", Scripting.replaceVariables(ctx, p1, "${parent.error}"));
        assertEquals("", Scripting.replaceVariables(ctx, p1, "${this.owner}"));
        assertEquals("", Scripting.replaceVariables(ctx, p1, "${parent.owner}"));
        // other functions are tested in the ActionContextTest in structr-core, see there.
        assertEquals("true", Scripting.replaceVariables(ctx, p1, "${true}"));
        assertEquals("false", Scripting.replaceVariables(ctx, p1, "${false}"));
        assertEquals("yes", Scripting.replaceVariables(ctx, p1, "${if(true, \"yes\", \"no\")}"));
        assertEquals("no", Scripting.replaceVariables(ctx, p1, "${if(false, \"yes\", \"no\")}"));
        assertEquals("true", Scripting.replaceVariables(ctx, p1, "${if(true, true, false)}"));
        assertEquals("false", Scripting.replaceVariables(ctx, p1, "${if(false, true, false)}"));
        // test keywords
        assertEquals("${id} should evaluate to the ID if the current details object", detailsDataObject.getUuid(), Scripting.replaceVariables(ctx, p1, "${id}"));
        ctx.setDetailsDataObject(null);
        assertEquals("${id} should evaluate to the ID if the current details object", "abc12345", Scripting.replaceVariables(ctx, p1, "${id!abc12345}"));
        ctx.setDetailsDataObject(detailsDataObject);
        assertEquals("${id} should be equal to ${current.id}", "true", Scripting.replaceVariables(ctx, p1, "${equal(id, current.id)}"));
        assertEquals("${element} should evaluate to the current DOM node", p1.toString(), Scripting.replaceVariables(ctx, p1, "${element}"));
        assertNull(Scripting.replaceVariables(ctx, p1, "${if(true, null, \"no\")}"));
        assertNull(Scripting.replaceVariables(ctx, p1, "${null}"));
        assertEquals("Invalid replacement result", "/testpage?" + page.getUuid(), Scripting.replaceVariables(ctx, p1, "/${page.name}?${page.id}"));
        assertEquals("Invalid replacement result", "/testpage?" + page.getUuid(), Scripting.replaceVariables(ctx, a, "/${link.name}?${link.id}"));
        // these tests find single element => success
        assertEquals("Invalid replacement result", page.getUuid(), Scripting.replaceVariables(ctx, a, "${get(find('Page', 'name', 'testpage'), 'id')}"));
        assertEquals("Invalid replacement result", a.getUuid(), Scripting.replaceVariables(ctx, a, "${get(find('A'), 'id')}"));
        // this test finds multiple <p> elements => error
        assertEquals("Invalid replacement result", GetFunction.ERROR_MESSAGE_GET_ENTITY, Scripting.replaceVariables(ctx, a, "${get(find('P'), 'id')}"));
        // more complex replacement
        // assertEquals("Invalid replacement result", "", a.replaceVariables(ctx, securityContext, "${get(find('P'), 'id')}"));
        // String default value
        assertEquals("bar", Scripting.replaceVariables(ctx, p1, "${request.foo!bar}"));
        // Number default value (will be evaluated to a string)
        assertEquals("1", Scripting.replaceVariables(ctx, p1, "${page.position!1}"));
        // Number default value
        assertEquals("true", Scripting.replaceVariables(ctx, p1, "${equal(42, this.null!42)}"));
        final User tester1 = app.nodeQuery(User.class).andName("tester1").getFirst();
        final User tester2 = app.nodeQuery(User.class).andName("tester2").getFirst();
        assertNotNull("User tester1 should exist.", tester1);
        assertNotNull("User tester2 should exist.", tester2);
        final ActionContext tester1Context = new ActionContext(SecurityContext.getInstance(tester1, AccessMode.Backend));
        final ActionContext tester2Context = new ActionContext(SecurityContext.getInstance(tester2, AccessMode.Backend));
        // users
        assertEquals("tester1", Scripting.replaceVariables(tester1Context, p1, "${me.name}"));
        assertEquals("tester2", Scripting.replaceVariables(tester2Context, p2, "${me.name}"));
        // allow unauthenticated GET on /pages
        grant("Page/_Ui", 16, true);
        // test GET REST access
        assertEquals("Invalid GET notation result", page.getName(), Scripting.replaceVariables(ctx, p1, "${from_json(GET('http://localhost:" + httpPort + "/structr/rest/pages/ui')).result[0].name}"));
        grant("Folder", 64, true);
        grant("_login", 64, false);
        assertEquals("Invalid POST result", "201", Scripting.replaceVariables(ctx, page, "${POST('http://localhost:" + httpPort + "/structr/rest/folders', '{name:status}').status}"));
        assertEquals("Invalid POST result", "1.0", Scripting.replaceVariables(ctx, page, "${POST('http://localhost:" + httpPort + "/structr/rest/folders', '{name:result_count}').body.result_count}"));
        assertEquals("Invalid POST result", "application/json;charset=utf-8", Scripting.replaceVariables(ctx, page, "${POST('http://localhost:" + httpPort + "/structr/rest/folders', '{name:content-type}').headers.Content-Type}"));
        // test POST with invalid name containing curly braces to provoke 422
        assertEquals("Invalid POST result", "422", Scripting.replaceVariables(ctx, page, "${POST('http://localhost:" + httpPort + "/structr/rest/folders', '{name:\"ShouldFail/xyz\"}').status}"));
        // test login and sessions
        final String sessionIdCookie = Scripting.replaceVariables(ctx, page, "${POST('http://localhost:" + httpPort + "/structr/rest/login', '{name:admin,password:admin}').headers.Set-Cookie}");
        final String sessionId = HttpCookie.parse(sessionIdCookie).get(0).getValue();
        // test authenticated GET request using session ID cookie
        assertEquals("Invalid authenticated GET result", "admin", Scripting.replaceVariables(ctx, page, "${add_header('Cookie', 'JSESSIONID=" + sessionId + ";Path=/')}${from_json(GET('http://localhost:" + httpPort + "/structr/rest/users')).result[0].name}"));
        assertEquals("Invalid authenticated GET result", "tester1", Scripting.replaceVariables(ctx, page, "${add_header('Cookie', 'JSESSIONID=" + sessionId + ";Path=/')}${from_json(GET('http://localhost:" + httpPort + "/structr/rest/users')).result[1].name}"));
        assertEquals("Invalid authenticated GET result", "tester2", Scripting.replaceVariables(ctx, page, "${add_header('Cookie', 'JSESSIONID=" + sessionId + ";Path=/')}${from_json(GET('http://localhost:" + httpPort + "/structr/rest/users')).result[2].name}"));
        // locale
        final String localeString = ctx.getLocale().toString();
        assertEquals("Invalid locale result", localeString, Scripting.replaceVariables(ctx, page, "${locale}"));
        // set new details object
        final TestOne detailsDataObject2 = app.create(TestOne.class, "TestOne");
        Scripting.replaceVariables(ctx, p1, "${set_details_object(first(find('TestOne', 'id', '" + detailsDataObject2.getUuid() + "')))}");
        assertEquals("${current.id} should resolve to new details object", detailsDataObject2.getUuid(), Scripting.replaceVariables(ctx, p1, "${current.id}"));
        // test values() with single parameter
        assertEquals("Invalid values() result", "[test]", Scripting.replaceVariables(ctx, page, "${values(from_json('{name:test}'))}"));
        testOne = createTestNode(TestOne.class);
        testOne.setProperty(TestOne.htmlString, "<a b=\"c\">&d</a>");
        // escape_html
        assertEquals("Invalid escape_html() result", "&lt;a b=&quot;c&quot;&gt;&amp;d&lt;/a&gt;", Scripting.replaceVariables(ctx, testOne, "${escape_html(this.htmlString)}"));
        testOne.setProperty(TestOne.htmlString, "&lt;a b=&quot;c&quot;&gt;&amp;d&lt;/a&gt;");
        // unescape_html
        assertEquals("Invalid unescape_html() result", "<a b=\"c\">&d</a>", Scripting.replaceVariables(ctx, testOne, "${unescape_html(this.htmlString)}"));
        tx.success();
    } catch (FrameworkException fex) {
        logger.warn("", fex);
        fail("Unexpected exception");
    }
}
Also used : A(org.structr.web.entity.html.A) RenderContext(org.structr.web.common.RenderContext) User(org.structr.web.entity.User) Tx(org.structr.core.graph.Tx) FrameworkException(org.structr.common.error.FrameworkException) NodeList(org.w3c.dom.NodeList) Page(org.structr.web.entity.dom.Page) DOMElement(org.structr.web.entity.dom.DOMElement) ActionContext(org.structr.schema.action.ActionContext) PropertyMap(org.structr.core.property.PropertyMap) TestOne(org.structr.web.entity.TestOne) DOMNode(org.structr.web.entity.dom.DOMNode) NodeInterface(org.structr.core.graph.NodeInterface) Test(org.junit.Test) StructrUiTest(org.structr.web.StructrUiTest)

Example 14 with RenderContext

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

the class SearchCommand method processMessage.

@Override
public void processMessage(final WebSocketMessage webSocketData) {
    final SecurityContext securityContext = getWebSocket().getSecurityContext();
    final String searchString = (String) webSocketData.getNodeData().get("searchString");
    final Boolean exactSearch = (Boolean) webSocketData.getNodeData().get("exact");
    final String restQuery = (String) webSocketData.getNodeData().get("restQuery");
    final String cypherQuery = (String) webSocketData.getNodeData().get("cypherQuery");
    final String paramString = (String) webSocketData.getNodeData().get("cypherParams");
    final String typeString = (String) webSocketData.getNodeData().get("type");
    final int pageSize = webSocketData.getPageSize();
    final int page = webSocketData.getPage();
    Class type = null;
    if (typeString != null) {
        type = SchemaHelper.getEntityClassForRawType(typeString);
    }
    if (searchString == null) {
        if (cypherQuery != null) {
            try {
                Map<String, Object> obj = null;
                if (StringUtils.isNoneBlank(paramString)) {
                    obj = new Gson().fromJson(paramString, Map.class);
                }
                final List<GraphObject> result = StructrApp.getInstance(securityContext).cypher(cypherQuery, obj);
                int resultCountBeforePaging = result.size();
                webSocketData.setRawResultCount(resultCountBeforePaging);
                if (page != 0 && pageSize != 0) {
                    webSocketData.setResult(result.subList((page - 1) * pageSize, Math.min(page * pageSize, resultCountBeforePaging)));
                } else {
                    webSocketData.setResult(result);
                }
                getWebSocket().send(webSocketData, true);
                return;
            } catch (Exception ex) {
                logger.warn("Exception occured", ex);
                getWebSocket().send(MessageBuilder.status().code(400).message(ex.getMessage()).build(), true);
                return;
            }
        }
        if (restQuery != null) {
            final RestDataSource restDataSource = new RestDataSource();
            try {
                securityContext.setRequest(getWebSocket().getRequest());
                webSocketData.setResult(restDataSource.getData(new RenderContext(securityContext), restQuery));
                getWebSocket().send(webSocketData, true);
                return;
            } catch (FrameworkException ex) {
                logger.error("", ex);
                return;
            }
        }
    }
    final String sortOrder = webSocketData.getSortOrder();
    final String sortKey = webSocketData.getSortKey();
    final PropertyKey sortProperty = StructrApp.key(AbstractNode.class, sortKey);
    final Query query = StructrApp.getInstance(securityContext).nodeQuery().includeDeletedAndHidden().sort(sortProperty).order("desc".equals(sortOrder));
    query.and(AbstractNode.name, searchString, exactSearch);
    if (type != null) {
        query.andType(type);
    }
    try {
        // do search
        final Result result = query.getResult();
        // set full result list
        webSocketData.setResult(result.getResults());
        // send only over local connection
        getWebSocket().send(webSocketData, true);
    } catch (FrameworkException fex) {
        logger.warn("Exception occured", fex);
        getWebSocket().send(MessageBuilder.status().code(fex.getStatus()).message(fex.getMessage()).build(), true);
    }
}
Also used : RenderContext(org.structr.web.common.RenderContext) FrameworkException(org.structr.common.error.FrameworkException) Query(org.structr.core.app.Query) Gson(com.google.gson.Gson) GraphObject(org.structr.core.GraphObject) RestDataSource(org.structr.web.datasource.RestDataSource) FrameworkException(org.structr.common.error.FrameworkException) Result(org.structr.core.Result) SecurityContext(org.structr.common.SecurityContext) GraphObject(org.structr.core.GraphObject) Map(java.util.Map) PropertyKey(org.structr.core.property.PropertyKey)

Example 15 with RenderContext

use of org.structr.web.common.RenderContext 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

RenderContext (org.structr.web.common.RenderContext)15 FrameworkException (org.structr.common.error.FrameworkException)12 Tx (org.structr.core.graph.Tx)11 Test (org.junit.Test)9 StructrUiTest (org.structr.web.StructrUiTest)9 SecurityContext (org.structr.common.SecurityContext)5 NodeAttribute (org.structr.core.graph.NodeAttribute)5 NodeInterface (org.structr.core.graph.NodeInterface)5 DOMNode (org.structr.web.entity.dom.DOMNode)5 Page (org.structr.web.entity.dom.Page)5 App (org.structr.core.app.App)4 StructrApp (org.structr.core.app.StructrApp)4 LinkedList (java.util.LinkedList)3 AbstractNode (org.structr.core.entity.AbstractNode)3 Principal (org.structr.core.entity.Principal)3 PropertyKey (org.structr.core.property.PropertyKey)3 PropertyMap (org.structr.core.property.PropertyMap)3 StringProperty (org.structr.core.property.StringProperty)3 StringRenderBuffer (org.structr.web.common.StringRenderBuffer)3 File (org.structr.web.entity.File)3