Package org.structr.common

Source Code of org.structr.common.AccessControlTest

/**
* Copyright (C) 2010-2014 Morgner UG (haftungsbeschränkt)
*
* This file is part of Structr <http://structr.org>.
*
* Structr is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* Structr is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Structr.  If not, see <http://www.gnu.org/licenses/>.
*/

package org.structr.common;

import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.structr.common.error.FrameworkException;
import org.structr.core.Result;
import org.structr.core.app.App;
import org.structr.core.app.StructrApp;
import org.structr.core.entity.AbstractNode;
import org.structr.core.entity.Person;
import org.structr.core.entity.Principal;
import org.structr.core.entity.ResourceAccess;
import org.structr.core.entity.TestOne;
import org.structr.core.entity.TestUser;
import org.structr.core.graph.NodeInterface;
import org.structr.core.graph.Tx;
import org.structr.core.property.PropertyKey;
import org.structr.core.property.PropertyMap;

//~--- classes ----------------------------------------------------------------

/**
* Test access control with different permission levels.
*
* @author Axel Morgner
*/
public class AccessControlTest extends StructrTest {

  private static final Logger logger = Logger.getLogger(AccessControlTest.class.getName());

  //~--- methods --------------------------------------------------------

  @Override
  public void test00DbAvailable() {

    super.test00DbAvailable();

  }

  public void test01PublicAccessToNonPublicNode() {

    // remove auto-generated resource access objects
    clearResourceAccess();

    try {

      List<TestUser> users = createTestNodes(TestUser.class, 1);
      TestUser user = (TestUser) users.get(0);

      // Create node with user context
      Class type = TestOne.class;
      TestOne t1 = createTestNode(TestOne.class, user);

      SecurityContext publicContext = SecurityContext.getInstance(null, AccessMode.Frontend);

      try (final Tx tx = app.tx()) {

        Result result = StructrApp.getInstance(publicContext).nodeQuery(type).getResult();

        // Node should not be visible in public context (no user logged in)
        assertTrue(result.isEmpty());
      }

    } catch (FrameworkException ex) {

      logger.log(Level.SEVERE, ex.toString());
      fail("Unexpected exception");

    }

  }


  public void test02PublicAccessToPublicNode() {

    // remove auto-generated resource access objects
    clearResourceAccess();

    try {

      List<TestUser> users = createTestNodes(TestUser.class, 1);
      TestUser user = (TestUser) users.get(0);

      PropertyMap props = new PropertyMap();
      props.put(AbstractNode.visibleToPublicUsers, true);

      // Create two nodes with user context, one of them is visible to public users
      Class type = TestOne.class;
      TestOne t1 = createTestNode(TestOne.class, props, user);
      TestOne t2 = createTestNode(TestOne.class, user);

      SecurityContext publicContext = SecurityContext.getInstance(null, AccessMode.Frontend);

      try (final Tx tx = app.tx()) {

        Result result = StructrApp.getInstance(publicContext).nodeQuery(type).getResult();

        assertEquals(1, result.size());
        assertEquals(t1.getUuid(), result.get(0).getUuid());
      }

    } catch (FrameworkException ex) {

      logger.log(Level.SEVERE, ex.toString());
      fail("Unexpected exception");

    }

  }

  public void test03PublicAccessToProtectedNode() {

    // remove auto-generated resource access objects
    clearResourceAccess();

    try {

      List<TestUser> users = createTestNodes(TestUser.class, 1);
      TestUser user = (TestUser) users.get(0);

      PropertyMap props = new PropertyMap();
      props.put(AbstractNode.visibleToPublicUsers, true);

      // Create two nodes with user context, one of them is visible to public users
      Class type = TestOne.class;
      TestOne t1 = createTestNode(TestOne.class, props, user);

      props = new PropertyMap();
      props.put(AbstractNode.visibleToAuthenticatedUsers, true);

      TestOne t2 = createTestNode(TestOne.class, props, user);

      SecurityContext publicContext = SecurityContext.getInstance(null, AccessMode.Frontend);

      try (final Tx tx = app.tx()) {
        Result result = StructrApp.getInstance(publicContext).nodeQuery(type).getResult();

        assertEquals(1, result.size());
        assertEquals(t1.getUuid(), result.get(0).getUuid());
      }

    } catch (FrameworkException ex) {

      logger.log(Level.SEVERE, ex.toString());
      fail("Unexpected exception");

    }

  }

  public void test04BackendUserAccessToProtectedNode() {

    // remove auto-generated resource access objects
    clearResourceAccess();

    try {

      List<TestUser> users = createTestNodes(TestUser.class, 2);
      TestUser user1 = (TestUser) users.get(0);
      TestUser user2 = (TestUser) users.get(1);

      PropertyMap props = new PropertyMap();
      props.put(AbstractNode.visibleToPublicUsers, true);

      // Create two nodes with user context, one of them is visible to public users
      Class type = TestOne.class;
      TestOne t1 = createTestNode(TestOne.class, props, user1);

      props = new PropertyMap();
      props.put(AbstractNode.visibleToAuthenticatedUsers, true);

      TestOne t2 = createTestNode(TestOne.class, props, user1);

      // Let another user search
      SecurityContext user2Context = SecurityContext.getInstance(user2, AccessMode.Backend);

      try (final Tx tx = app.tx()) {
        Result result = StructrApp.getInstance(user2Context).nodeQuery(type).getResult();

        assertEquals(2, result.size());
      }

    } catch (FrameworkException ex) {

      logger.log(Level.SEVERE, ex.toString());
      fail("Unexpected exception");

    }

  }

  public void test05FrontendUserAccessToProtectedNode() {

    // remove auto-generated resource access objects
    clearResourceAccess();

    try {

      List<TestUser> users = createTestNodes(TestUser.class, 2);
      TestUser user1 = (TestUser) users.get(0);
      TestUser user2 = (TestUser) users.get(1);

      PropertyMap props = new PropertyMap();
      props.put(AbstractNode.visibleToPublicUsers, true);

      // Create two nodes with user context, one of them is visible to public users
      Class type = TestOne.class;
      TestOne t1 = createTestNode(TestOne.class, props, user1);

      props = new PropertyMap();
      props.put(AbstractNode.visibleToAuthenticatedUsers, true);

      TestOne t2 = createTestNode(TestOne.class, props, user1);

      // Let another user search
      SecurityContext user2Context = SecurityContext.getInstance(user2, AccessMode.Frontend);

      try (final Tx tx = app.tx()) {

        Result result = StructrApp.getInstance(user2Context).nodeQuery(type).getResult();

        assertEquals(2, result.size());
      }

    } catch (FrameworkException ex) {

      logger.log(Level.SEVERE, ex.toString());
      fail("Unexpected exception");

    }

  }

  public void test06GrantReadPermission() {

    // remove auto-generated resource access objects
    clearResourceAccess();

    try {

      List<TestUser> users = createTestNodes(TestUser.class, 2);
      TestUser user1 = (TestUser) users.get(0);
      TestUser user2 = (TestUser) users.get(1);
      Result result = null;

      // Let user 1 create a node
      Class type = TestOne.class;
      final TestOne t1 = createTestNode(TestOne.class, user1);

      try (final Tx tx = app.tx()) {

        // Grant read permission to user 2
        user2.grant(Permission.read, t1);
        tx.success();
      }

      // Let user 2 search
      SecurityContext user2Context = SecurityContext.getInstance(user2, AccessMode.Backend);

      try (final Tx tx = app.tx()) {

        result = StructrApp.getInstance(user2Context).nodeQuery(type).getResult();

        assertEquals(1, result.size());
        assertEquals(t1.getUuid(), result.get(0).getUuid());
      }

      try (final Tx tx = app.tx()) {

        // Revoke permission again
        user2.revoke(Permission.read, t1);
        tx.success();
      }

      try (final Tx tx = app.tx()) {

        result = StructrApp.getInstance(user2Context).nodeQuery(type).getResult();
        assertTrue(result.isEmpty());
      }

    } catch (FrameworkException ex) {

      logger.log(Level.SEVERE, ex.toString());
      fail("Unexpected exception");

    }

  }

  public void test07ResultCount() {

    // remove auto-generated resource access objects
    clearResourceAccess();

    try {

      final List<Person> persons = createTestNodes(Person.class, 1);
      final Class type = TestOne.class;
      final List<NodeInterface> nodes = createTestNodes(type, 10);

      try (final Tx tx = app.tx()) {
        nodes.get(3).setProperty(AbstractNode.visibleToPublicUsers, true);
        nodes.get(5).setProperty(AbstractNode.visibleToPublicUsers, true);
        nodes.get(7).setProperty(AbstractNode.visibleToPublicUsers, true);
        tx.success();
      }

      SecurityContext publicContext = SecurityContext.getInstance(null, AccessMode.Frontend);

      try (final Tx tx = app.tx()) {

        Result result = StructrApp.getInstance(publicContext).nodeQuery(type).getResult();

        assertEquals(3, result.size());
        assertEquals(3, (int) result.getRawResultCount());

        assertEquals(nodes.get(3).getUuid(), result.get(0).getUuid());
        assertEquals(nodes.get(5).getUuid(), result.get(1).getUuid());
        assertEquals(nodes.get(7).getUuid(), result.get(2).getUuid());
      }

    } catch (FrameworkException ex) {

      logger.log(Level.SEVERE, ex.toString());
      fail("Unexpected exception");

    }

  }

  public void test07ResultCountWithPaging() {

    // remove auto-generated resource access objects
    clearResourceAccess();

    try {

      final List<Person> persons = createTestNodes(Person.class, 1);
      final Class type = TestOne.class;
      final List<NodeInterface> nodes = createTestNodes(type, 10);
      int count = 0;

      try (final Tx tx = app.tx()) {

        // add names to make sorting work...
        for (final NodeInterface node : nodes) {
          node.setProperty(AbstractNode.name, "node0" + count++);
        }

        nodes.get(3).setProperty(AbstractNode.visibleToPublicUsers, true);
        nodes.get(5).setProperty(AbstractNode.visibleToPublicUsers, true);
        nodes.get(7).setProperty(AbstractNode.visibleToPublicUsers, true);
        nodes.get(9).setProperty(AbstractNode.visibleToPublicUsers, true);
        tx.success();
      }

      SecurityContext publicContext = SecurityContext.getInstance(null, AccessMode.Frontend);

      PropertyKey sortKey = AbstractNode.name;
      boolean sortDesc    = false;
      int pageSize        = 2;
      int page            = 1;

      try (final Tx tx = app.tx()) {

        Result result = StructrApp.getInstance(publicContext).nodeQuery(type).sort(sortKey).order(sortDesc).page(page).pageSize(pageSize).getResult();

        assertEquals(2, result.size());
        assertEquals(4, (int) result.getRawResultCount());

        assertEquals(nodes.get(3).getUuid(), result.get(0).getUuid());
        assertEquals(nodes.get(5).getUuid(), result.get(1).getUuid());
      }

    } catch (FrameworkException ex) {

      logger.log(Level.SEVERE, ex.toString());
      fail("Unexpected exception");

    }

  }

  protected <T extends AbstractNode> T createTestNode(final Class<T> type, final Principal user) throws FrameworkException {
    return (T)createTestNode(type, new PropertyMap(), user);
  }

  protected <T extends AbstractNode> T createTestNode(final Class<T> type, final PropertyMap props, final Principal user) throws FrameworkException {

    final App backendApp = StructrApp.getInstance(SecurityContext.getInstance(user, AccessMode.Backend));

    try (final Tx tx = backendApp.tx()) {

      final T result = backendApp.create(type, props);
      tx.success();

      return result;
    }
  }

  public static void clearResourceAccess() {

    final App app = StructrApp.getInstance();

    try (final Tx tx = app.tx()) {

      for (final ResourceAccess access : app.nodeQuery(ResourceAccess.class).getAsList()) {
        app.delete(access);
      }

      tx.success();

    } catch (Throwable t) {

      t.printStackTrace();
    }
  }

}
TOP

Related Classes of org.structr.common.AccessControlTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.