content: /*
   * This library is part of OpenCms -
   * the Open Source Content Management System
   *
   * Copyright (c) Alkacon Software GmbH & Co. KG (https://www.alkacon.com)
   *
   * This library is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
   * This library 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
   * Lesser General Public License for more details.
   *
   * For further information about Alkacon Software GmbH & Co. KG, please see the
   * company website: https://www.alkacon.com
   *
   * For further information about OpenCms, please see the
   * project website: https://www.opencms.org
   *
   * You should have received a copy of the GNU Lesser General Public
   * License along with this library; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   */
  
  package org.opencms.security;
  
  import org.opencms.db.CmsDbConsistencyException;
  import org.opencms.db.CmsDbEntryNotFoundException;
  import org.opencms.file.CmsDataAccessException;
  import org.opencms.file.CmsFolder;
  import org.opencms.file.CmsGroup;
  import org.opencms.file.CmsObject;
  import org.opencms.file.CmsProject;
  import org.opencms.file.CmsPropertyDefinition;
  import org.opencms.file.CmsResource;
  import org.opencms.file.CmsResourceFilter;
  import org.opencms.file.CmsUser;
  import org.opencms.file.CmsVfsException;
  import org.opencms.file.CmsVfsResourceNotFoundException;
  import org.opencms.lock.CmsLockType;
  import org.opencms.main.CmsException;
  import org.opencms.main.CmsIllegalArgumentException;
  import org.opencms.main.OpenCms;
  import org.opencms.relations.CmsRelation;
  import org.opencms.relations.CmsRelationFilter;
  import org.opencms.test.OpenCmsTestCase;
  import org.opencms.test.OpenCmsTestProperties;
  import org.opencms.util.CmsUUID;
  
  import java.util.ArrayList;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Locale;
  
  import junit.extensions.TestSetup;
  import junit.framework.Test;
  import junit.framework.TestSuite;
  
  /**
   * Unit tests for operations with organizational units.<p>
   */
  @SuppressWarnings({"unchecked", "rawtypes"})
  public class TestOrganizationalUnits extends OpenCmsTestCase {
  
      /**
       * Default JUnit constructor.<p>
       *
       * @param arg0 JUnit parameters
       */
      public TestOrganizationalUnits(String arg0) {
  
          super(arg0);
      }
  
      /**
       * Returns all organizational unit dependent roles.<p>
       *
       * @param ouFqn the organizational unit
       *
       * @return all organizational unit dependent roles
       */
      public static List getOuRoles(String ouFqn) {
  
          List roles = new ArrayList();
          Iterator itRoles = CmsRole.getSystemRoles().iterator();
          while (itRoles.hasNext()) {
              CmsRole role = (CmsRole)itRoles.next();
              if (!role.isOrganizationalUnitIndependent()) {
                  roles.add(role.forOrgUnit(ouFqn));
              }
          }
          return roles;
      }
  
      /**
       * Test suite for this test class.<p>
       *
       * @return the test suite
       */
      public static Test suite() {
  
          OpenCmsTestProperties.initialize(org.opencms.test.AllTests.TEST_PROPERTIES_PATH);
  
          TestSuite suite = new TestSuite();
          suite.setName(TestOrganizationalUnits.class.getName());
  
          suite.addTest(new TestOrganizationalUnits("testOuNotFound"));
          suite.addTest(new TestOrganizationalUnits("testRootOu"));
          suite.addTest(new TestOrganizationalUnits("testRootRoles"));
          suite.addTest(new TestOrganizationalUnits("testFirstLevelOu"));
          suite.addTest(new TestOrganizationalUnits("testFirstLevelRoles"));
          suite.addTest(new TestOrganizationalUnits("testDeeperLevelOu"));
          suite.addTest(new TestOrganizationalUnits("testDeeperLevelRoles"));
          suite.addTest(new TestOrganizationalUnits("testResourceAssociations"));
          suite.addTest(new TestOrganizationalUnits("testPrincipalAssociations"));
          suite.addTest(new TestOrganizationalUnits("testRoleInheritance"));
          suite.addTest(new TestOrganizationalUnits("testParallelRoles"));
          suite.addTest(new TestOrganizationalUnits("testUserLogin"));
          suite.addTest(new TestOrganizationalUnits("testMembership"));
          suite.addTest(new TestOrganizationalUnits("testPersistence"));
          suite.addTest(new TestOrganizationalUnits("testDelete"));
          suite.addTest(new TestOrganizationalUnits("testRoleCacheIssue"));
          suite.addTest(new TestOrganizationalUnits("testBadName"));
          suite.addTest(new TestOrganizationalUnits("testWebuserOU"));
  
          TestSetup wrapper = new TestSetup(suite) {
  
              @Override
              protected void setUp() {
  
                  setupOpenCms("simpletest", "/");
              }
  
              @Override
              protected void tearDown() {
  
                  removeOpenCms();
              }
          };
  
          return wrapper;
      }
  
      /**
       * Tests ou creation with illegal name.<p>
       *
       * @throws Throwable if something goes wrong
       */
      public void testBadName() throws Throwable {
  
          CmsObject cms = getCmsObject();
          echo("Trying to create an organizational unit with an illegal name");
  
          String[] badNames = new String[] {"/abc abc", "/\u00E4bc", "/de\u20AC", "/.."};
  
          for (int i = 0; i < badNames.length; i++) {
              try {
                  OpenCms.getOrgUnitManager().createOrganizationalUnit(cms, badNames[i], "bad name test", 0, "/");
                  fail("it should not be possible to create an ou with name " + badNames[i]);
              } catch (CmsIllegalArgumentException e) {
                  // ok
              }
          }
      }
  
      /**
       * Tests handling with a deeper level ou.<p>
       *
       * @throws Throwable if something goes wrong
       */
      public void testDeeperLevelOu() throws Throwable {
  
          CmsObject cms = getCmsObject();
          echo("Testing handling with a deeper level ou");
  
          // check the root ou
          CmsOrganizationalUnit rootOu = OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, "");
          CmsOrganizationalUnit ou = OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, "test");
  
          // create a deeper ou
          CmsOrganizationalUnit ou2 = OpenCms.getOrgUnitManager().createOrganizationalUnit(
              cms,
              ou.getName() + "test2/",
              "my test ou2",
              0,
              "/folder1");
  
          // check default project
          CmsProject defProj2 = cms.readProject(ou2.getName() + "Offline");
  
          // check the ou attributes
          assertEquals(0, ou2.getFlags());
          assertEquals("test/", ou2.getParentFqn());
          assertEquals("test/test2/", ou2.getName());
          assertEquals(cms.readFolder("/system/orgunits/test/test2").getStructureId(), ou2.getId());
          assertEquals(defProj2.getUuid(), ou2.getProjectId());
  
          // check ou resources
          List ou2Resources = OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(cms, ou2.getName());
          assertEquals(1, ou2Resources.size());
          assertTrue(ou2Resources.contains(cms.readResource("/folder1")));
  
          // check the project resources
          List projRes2 = cms.readProjectResources(defProj2);
          assertEquals(ou2Resources.size(), projRes2.size());
          for (int i = 0; i < projRes2.size(); i++) {
              assertTrue(projRes2.contains(((CmsResource)ou2Resources.get(i)).getRootPath()));
              assertTrue(
                  ou2Resources.contains(
                      cms.readResource(cms.getRequestContext().removeSiteRoot((String)projRes2.get(i)))));
          }
  
          // check the ous
          List rootOus = OpenCms.getOrgUnitManager().getOrganizationalUnits(cms, rootOu.getName(), false);
          assertEquals(1, rootOus.size());
          assertTrue(rootOus.contains(ou));
  
          List ouOus = OpenCms.getOrgUnitManager().getOrganizationalUnits(cms, ou.getName(), false);
          assertEquals(1, ouOus.size());
          assertTrue(ouOus.contains(ou2));
  
          List ou2Ous = OpenCms.getOrgUnitManager().getOrganizationalUnits(cms, ou2.getName(), false);
          assertTrue(ou2Ous.isEmpty());
  
          List rootSubOus = OpenCms.getOrgUnitManager().getOrganizationalUnits(cms, rootOu.getName(), true);
          assertEquals(2, rootSubOus.size());
          assertTrue(rootSubOus.contains(ou));
          assertTrue(rootSubOus.contains(ou2));
  
          List ouSubOus = OpenCms.getOrgUnitManager().getOrganizationalUnits(cms, ou.getName(), true);
          assertEquals(1, ouSubOus.size());
          assertTrue(ouSubOus.contains(ou2));
  
          List ou2SubOus = OpenCms.getOrgUnitManager().getOrganizationalUnits(cms, ou2.getName(), true);
          assertTrue(ou2SubOus.isEmpty());
  
          OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, ou.getName());
          try {
              OpenCms.getOrgUnitManager().deleteOrganizationalUnit(cms, ou.getName());
              fail("should not be possible to delete a ou having sub-ous");
          } catch (CmsDataAccessException e) {
              // ok, ignore
          }
          OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, ou.getName());
      }
  
      /**
       * Tests system roles in a deeper level ou.<p>
       *
       * @throws Throwable if something goes wrong
       */
      public void testDeeperLevelRoles() throws Throwable {
  
          CmsObject cms = getCmsObject();
          echo("Testing system roles in a deeper level ou");
  
          // check the ous
          CmsOrganizationalUnit rootOu = OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, "");
          CmsOrganizationalUnit flOu = OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, "test/");
          CmsOrganizationalUnit dlOu = OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, "test/test2/");
  
          // check just the roles of the root ou
          List myRoles = OpenCms.getRoleManager().getRoles(cms, rootOu.getName(), false);
          assertEquals(CmsRole.getSystemRoles().size(), myRoles.size());
          for (int i = 0; i < myRoles.size(); i++) {
              CmsRole role = (CmsRole)myRoles.get(i);
              assertEquals("", role.getOuFqn());
              assertTrue(myRoles.contains(CmsRole.getSystemRoles().get(i).forOrgUnit("")));
              assertTrue(CmsRole.getSystemRoles().contains(role.forOrgUnit(null)));
          }
          // check all roles
          myRoles = OpenCms.getRoleManager().getRoles(cms, rootOu.getName(), true);
          assertEquals(
              CmsRole.getSystemRoles().size() + getOuRoles(flOu.getName()).size() + getOuRoles(dlOu.getName()).size(),
              myRoles.size());
          List rootRoles = new ArrayList(CmsRole.getSystemRoles().size());
          List flRoles = new ArrayList(getOuRoles(flOu.getName()).size());
          List dlRoles = new ArrayList(getOuRoles(dlOu.getName()).size());
          Iterator itRoles = myRoles.iterator();
          while (itRoles.hasNext()) {
              CmsRole role = (CmsRole)itRoles.next();
              if (role.getOuFqn().equals(rootOu.getName())) {
                  rootRoles.add(role);
              } else if (role.getOuFqn().equals(flOu.getName())) {
                  flRoles.add(role);
              } else {
                  assertEquals(dlOu.getName(), role.getOuFqn());
                  dlRoles.add(role);
              }
          }
          for (int i = 0; i < rootRoles.size(); i++) {
              assertTrue(CmsRole.getSystemRoles().contains((((CmsRole)rootRoles.get(i)).forOrgUnit(null))));
              assertTrue(rootRoles.contains(CmsRole.getSystemRoles().get(i).forOrgUnit("")));
          }
          for (int i = 0; i < flRoles.size(); i++) {
              assertTrue(getOuRoles(flOu.getName()).contains(flRoles.get(i)));
              assertTrue(flRoles.contains(getOuRoles(flOu.getName()).get(i)));
          }
          for (int i = 0; i < dlRoles.size(); i++) {
              assertTrue(getOuRoles(dlOu.getName()).contains(dlRoles.get(i)));
              assertTrue(dlRoles.contains(getOuRoles(dlOu.getName()).get(i)));
          }
          // check just the roles of the first level ou
          flRoles = OpenCms.getRoleManager().getRoles(cms, flOu.getName(), false);
          assertEquals(getOuRoles(flOu.getName()).size(), flRoles.size());
          for (int i = 0; i < flRoles.size(); i++) {
              assertTrue(getOuRoles(flOu.getName()).contains(flRoles.get(i)));
              assertTrue(flRoles.contains(getOuRoles(flOu.getName()).get(i)));
          }
  
          // check all roles in the first level ou and deeper
          myRoles = OpenCms.getRoleManager().getRoles(cms, flOu.getName(), true);
          assertEquals(getOuRoles(flOu.getName()).size() + getOuRoles(dlOu.getName()).size(), myRoles.size());
          flRoles = new ArrayList(getOuRoles(flOu.getName()).size());
          dlRoles = new ArrayList(getOuRoles(dlOu.getName()).size());
          itRoles = myRoles.iterator();
          while (itRoles.hasNext()) {
              CmsRole role = (CmsRole)itRoles.next();
              if (role.getOuFqn().equals(flOu.getName())) {
                  flRoles.add(role);
              } else {
                  assertEquals(dlOu.getName(), role.getOuFqn());
                  dlRoles.add(role);
              }
          }
          for (int i = 0; i < flRoles.size(); i++) {
              assertTrue(getOuRoles(flOu.getName()).contains(flRoles.get(i)));
              assertTrue(flRoles.contains(getOuRoles(flOu.getName()).get(i)));
          }
          for (int i = 0; i < dlRoles.size(); i++) {
              assertTrue(getOuRoles(dlOu.getName()).contains(dlRoles.get(i)));
              assertTrue(dlRoles.contains(getOuRoles(dlOu.getName()).get(i)));
          }
          // check just the roles of the deeper level ou
          dlRoles = OpenCms.getRoleManager().getRoles(cms, dlOu.getName(), false);
          assertEquals(getOuRoles(dlOu.getName()).size(), dlRoles.size());
          for (int i = 0; i < dlRoles.size(); i++) {
              assertTrue(getOuRoles(dlOu.getName()).contains(dlRoles.get(i)));
              assertTrue(dlRoles.contains(getOuRoles(dlOu.getName()).get(i)));
          }
          // check again including (missing) sub-ous
          dlRoles = OpenCms.getRoleManager().getRoles(cms, dlOu.getName(), true);
          assertEquals(getOuRoles(dlOu.getName()).size(), dlRoles.size());
          for (int i = 0; i < dlRoles.size(); i++) {
              assertTrue(getOuRoles(dlOu.getName()).contains(dlRoles.get(i)));
              assertTrue(dlRoles.contains(getOuRoles(dlOu.getName()).get(i)));
          }
      }
  
      /**
       * Tests deleting organizational units.<p>
       *
       * @throws Throwable if something goes wrong
       */
      public void testDelete() throws Throwable {
  
          CmsObject cms = getCmsObject();
          echo("Testing deleting organizational units");
  
          OpenCms.getRoleManager().addUserToRole(cms, CmsRole.ROOT_ADMIN, "test/test1");
          cms.loginUser("test/test2/test1", "test1");
          cms.getRequestContext().setCurrentProject(cms.readProject("Offline"));
          try {
              OpenCms.getOrgUnitManager().deleteOrganizationalUnit(cms, cms.getRequestContext().getOuFqn());
              fail(
                  "it should not be possible to delete an organizational unit that is used in the current request context");
          } catch (CmsDbConsistencyException e) {
              // ok, now check the error message
              assertEquals(
                  ((CmsDbConsistencyException)e.getCause()).getMessageContainer().getKey(),
                  org.opencms.db.Messages.ERR_ORGUNIT_DELETE_IN_CONTEXT_1);
          }
          try {
              OpenCms.getOrgUnitManager().deleteOrganizationalUnit(
                  cms,
                  cms.getRequestContext().getCurrentUser().getOuFqn());
              fail("it should not be possible to delete an organizational unit that is used by the current user");
          } catch (CmsDbConsistencyException e) {
              // ok, now check the error message
              assertEquals(
                  ((CmsDbConsistencyException)e.getCause()).getMessageContainer().getKey(),
                  org.opencms.db.Messages.ERR_ORGUNIT_DELETE_IN_CONTEXT_1);
          }
          cms.loginUser("Admin", "admin");
          cms.getRequestContext().setCurrentProject(cms.readProject("Offline"));
          try {
              OpenCms.getOrgUnitManager().deleteOrganizationalUnit(cms, "test");
              fail("it should not be possible to delete an organizational unit that has sub-organizational units");
          } catch (CmsDbConsistencyException e) {
              // ok, now check the error message
              assertEquals(
                  ((CmsDbConsistencyException)e.getCause()).getMessageContainer().getKey(),
                  org.opencms.db.Messages.ERR_ORGUNIT_DELETE_SUB_ORGUNITS_1);
          }
  
          CmsOrganizationalUnit ou2 = OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, "test/test2");
          cms.createGroup(ou2.getName() + "group2", "test group", 0, null);
          try {
              OpenCms.getOrgUnitManager().deleteOrganizationalUnit(cms, ou2.getName());
              fail("it should not be possible to delete an organizational unit that has groups & users units");
          } catch (CmsDbConsistencyException e) {
              // ok, now check the error message
              assertEquals(
                  ((CmsDbConsistencyException)e.getCause()).getMessageContainer().getKey(),
                  org.opencms.db.Messages.ERR_ORGUNIT_DELETE_GROUPS_1);
          }
  
          Iterator itGroups = OpenCms.getOrgUnitManager().getGroups(cms, ou2.getName(), false).iterator();
          while (itGroups.hasNext()) {
              CmsGroup group = (CmsGroup)itGroups.next();
              cms.deleteGroup(group.getName());
          }
          assertTrue(OpenCms.getOrgUnitManager().getGroups(cms, ou2.getName(), true).isEmpty());
  
          try {
              OpenCms.getOrgUnitManager().deleteOrganizationalUnit(cms, ou2.getName());
              fail("it should not be possible to delete an organizational unit that has users");
          } catch (CmsDbConsistencyException e) {
              // ok, now check the error message
              assertEquals(
                  ((CmsDbConsistencyException)e.getCause()).getMessageContainer().getKey(),
                  org.opencms.db.Messages.ERR_ORGUNIT_DELETE_USERS_1);
          }
  
          Iterator itUsers = OpenCms.getOrgUnitManager().getUsers(cms, ou2.getName(), false).iterator();
          while (itUsers.hasNext()) {
              CmsUser user = (CmsUser)itUsers.next();
              cms.deleteUser(user.getName());
          }
          assertTrue(OpenCms.getOrgUnitManager().getUsers(cms, ou2.getName(), true).isEmpty());
  
          OpenCms.getOrgUnitManager().deleteOrganizationalUnit(cms, ou2.getName());
  
          // check persistence
          try {
              cms.readFolder("/system/orgunits/root/test/test2", CmsResourceFilter.ALL);
              fail("it should not be possible to read the underlying resource after deleting an organizational unit");
          } catch (CmsVfsResourceNotFoundException e) {
              // ok, ignore
          }
          // check online project
          cms.getRequestContext().setCurrentProject(cms.readProject(CmsProject.ONLINE_PROJECT_ID));
          try {
              cms.readFolder("/system/orgunits/root/test/test2", CmsResourceFilter.ALL);
              fail("it should not be possible to read the underlying resource after deleting an organizational unit");
          } catch (CmsVfsResourceNotFoundException e) {
              // ok, ignore
          }
      }
  
      /**
       * Tests handling with a first level ou.<p>
       *
       * @throws Throwable if something goes wrong
       */
      public void testFirstLevelOu() throws Throwable {
  
          CmsObject cms = getCmsObject();
          echo("Testing handling with a first level ou");
  
          // check the root ou
          CmsOrganizationalUnit rootOu = OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, "");
  
          cms.addUserToGroup("test1", "Administrators");
          cms.loginUser("test1", "test1");
          cms.getRequestContext().setCurrentProject(cms.readProject("Offline"));
          cms.lockResource("/system/");
  
          cms.loginUser("Admin", "admin");
          cms.getRequestContext().setCurrentProject(cms.readProject("Offline"));
  
          // create a first level ou
          CmsOrganizationalUnit ou = OpenCms.getOrgUnitManager().createOrganizationalUnit(
              cms,
              "test/",
              "my test ou",
              0,
              "");
  
          // check default project
          CmsProject defProj = cms.readProject(ou.getName() + "Offline");
  
          // check the ou attributes
          assertEquals(0, ou.getFlags());
          assertEquals("", ou.getParentFqn());
          assertEquals("my test ou", ou.getDescription());
          assertEquals("test/", ou.getName());
          assertEquals(cms.readFolder("/system/orgunits/test").getStructureId(), ou.getId());
          assertEquals(defProj.getUuid(), ou.getProjectId());
  
          // check ou resources
          List ouResources = OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(cms, ou.getName());
          assertEquals(1, ouResources.size());
          assertTrue(ouResources.contains(cms.readResource("/")));
  
          // check the project resources
          List projRes = cms.readProjectResources(defProj);
          assertEquals(ouResources.size(), projRes.size());
          for (int i = 0; i < projRes.size(); i++) {
              assertTrue(projRes.contains(((CmsResource)ouResources.get(i)).getRootPath()));
              assertTrue(
                  ouResources.contains(cms.readResource(cms.getRequestContext().removeSiteRoot((String)projRes.get(i)))));
          }
  
          // check the ous
          List rootOus = OpenCms.getOrgUnitManager().getOrganizationalUnits(cms, rootOu.getName(), false);
          assertEquals(1, rootOus.size());
          assertTrue(rootOus.contains(ou));
  
          List ouOus = OpenCms.getOrgUnitManager().getOrganizationalUnits(cms, ou.getName(), false);
          assertTrue(ouOus.isEmpty());
  
          List rootSubOus = OpenCms.getOrgUnitManager().getOrganizationalUnits(cms, rootOu.getName(), true);
          assertEquals(1, rootSubOus.size());
          assertTrue(rootSubOus.contains(ou));
  
          List ouSubOus = OpenCms.getOrgUnitManager().getOrganizationalUnits(cms, ou.getName(), true);
          assertTrue(ouSubOus.isEmpty());
  
          // test to update ou attributes
          ou.setDescription("new ou description");
          ou.setFlags(123);
          OpenCms.getOrgUnitManager().writeOrganizationalUnit(cms, ou);
  
          ou = OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, ou.getName());
          // check the ou attributes again
          assertEquals(123, ou.getFlags());
          assertEquals("", ou.getParentFqn());
          assertEquals("new ou description", ou.getDescription());
          assertEquals("test/", ou.getName());
          assertEquals(cms.readFolder("/system/orgunits/test").getStructureId(), ou.getId());
          assertTrue(cms.readFolder("/system/orgunits/test").isInternal());
          assertEquals(defProj.getUuid(), ou.getProjectId());
  
          ou.setFlags(0);
          OpenCms.getOrgUnitManager().writeOrganizationalUnit(cms, ou);
  
          ou = OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, ou.getName());
          assertEquals(0, ou.getFlags());
          assertTrue(cms.readFolder("/system/orgunits/test").isInternal());
  
          // create a first level ou
          CmsOrganizationalUnit ou2 = OpenCms.getOrgUnitManager().createOrganizationalUnit(
              cms,
              "test2/",
              "my test ou2 in the root",
              0,
              "");
  
          // check default project
          CmsProject defProj2 = cms.readProject(ou2.getName() + "Offline");
  
          // check the ou attributes
          assertEquals(0, ou2.getFlags());
          assertEquals("", ou2.getParentFqn());
          assertEquals("my test ou2 in the root", ou2.getDescription());
          assertEquals("test2/", ou2.getName());
          assertEquals(cms.readFolder("/system/orgunits/test2").getStructureId(), ou2.getId());
          assertEquals(defProj2.getUuid(), ou2.getProjectId());
  
          // check ou resources
          List ou2Resources = OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(cms, ou2.getName());
          assertEquals(1, ou2Resources.size());
          assertTrue(ou2Resources.contains(cms.readResource("/")));
  
          // check the project resources
          List projRes2 = cms.readProjectResources(defProj2);
          assertEquals(ou2Resources.size(), projRes2.size());
          for (int i = 0; i < projRes2.size(); i++) {
              assertTrue(projRes2.contains(((CmsResource)ou2Resources.get(i)).getRootPath()));
              assertTrue(
                  ou2Resources.contains(
                      cms.readResource(cms.getRequestContext().removeSiteRoot((String)projRes2.get(i)))));
          }
  
          // check the ous
          rootOus = OpenCms.getOrgUnitManager().getOrganizationalUnits(cms, rootOu.getName(), false);
          assertEquals(2, rootOus.size());
          assertTrue(rootOus.contains(ou));
          assertTrue(rootOus.contains(ou2));
  
          List ou2Ous = OpenCms.getOrgUnitManager().getOrganizationalUnits(cms, ou2.getName(), false);
          assertTrue(ou2Ous.isEmpty());
  
          rootSubOus = OpenCms.getOrgUnitManager().getOrganizationalUnits(cms, rootOu.getName(), true);
          assertEquals(2, rootSubOus.size());
          assertTrue(rootSubOus.contains(ou));
          assertTrue(rootSubOus.contains(ou2));
  
          List ou2SubOus = OpenCms.getOrgUnitManager().getOrganizationalUnits(cms, ou2.getName(), true);
          assertTrue(ou2SubOus.isEmpty());
  
          // delete 2nd ou
          OpenCms.getOrgUnitManager().deleteOrganizationalUnit(cms, ou2.getName());
  
          try {
              OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, ou2.getName());
              fail("it should not be possible to read the deleted ou");
          } catch (CmsDataAccessException e) {
              // ok, ignore
          }
  
          try {
              cms.readProject(defProj2.getUuid());
              fail("it should not be possible to read the default project of a deleted ou");
          } catch (CmsDataAccessException e) {
              // ok, ignore
          }
  
          try {
              cms.readProject(defProj2.getName());
              fail("it should not be possible to read the default project of a deleted ou");
          } catch (CmsDataAccessException e) {
              // ok, ignore
          }
  
          // check the ous again
          rootOus = OpenCms.getOrgUnitManager().getOrganizationalUnits(cms, rootOu.getName(), false);
          assertEquals(1, rootOus.size());
          assertTrue(rootOus.contains(ou));
  
          ouOus = OpenCms.getOrgUnitManager().getOrganizationalUnits(cms, ou.getName(), false);
          assertTrue(ouOus.isEmpty());
  
          rootSubOus = OpenCms.getOrgUnitManager().getOrganizationalUnits(cms, rootOu.getName(), true);
          assertEquals(1, rootSubOus.size());
          assertTrue(rootSubOus.contains(ou));
  
          List ouSubous = OpenCms.getOrgUnitManager().getOrganizationalUnits(cms, ou.getName(), true);
          assertTrue(ouSubous.isEmpty());
  
          // check default users & groups for the new ou
          List groups = OpenCms.getOrgUnitManager().getGroups(cms, ou.getName(), false);
          assertEquals(1, groups.size());
          assertTrue(groups.contains(cms.readGroup(ou.getName() + OpenCms.getDefaultUsers().getGroupUsers())));
          groups = OpenCms.getOrgUnitManager().getGroups(cms, ou.getName(), true);
          assertEquals(1, groups.size());
          assertTrue(groups.contains(cms.readGroup(ou.getName() + OpenCms.getDefaultUsers().getGroupUsers())));
          assertTrue(OpenCms.getOrgUnitManager().getUsers(cms, ou.getName(), false).isEmpty());
          assertTrue(OpenCms.getOrgUnitManager().getUsers(cms, ou.getName(), true).isEmpty());
  
          // check the root ou principals again
          List rootGroups = OpenCms.getOrgUnitManager().getGroups(cms, rootOu.getName(), false);
          assertEquals(7, rootGroups.size());
          assertTrue(rootGroups.contains(cms.readGroup(OpenCms.getDefaultUsers().getGroupAdministrators())));
          assertTrue(rootGroups.contains(cms.readGroup(OpenCms.getDefaultUsers().getGroupUsers())));
          assertTrue(rootGroups.contains(cms.readGroup(OpenCms.getDefaultUsers().getGroupGuests())));
          assertTrue(rootGroups.contains(cms.readGroup("group1")));
          assertTrue(rootGroups.contains(cms.readGroup("group2")));
          assertTrue(rootGroups.contains(cms.readGroup("group3")));
  
          List rootSubGroups = OpenCms.getOrgUnitManager().getGroups(cms, rootOu.getName(), true);
          assertEquals(8, rootSubGroups.size());
          assertTrue(rootSubGroups.contains(cms.readGroup(OpenCms.getDefaultUsers().getGroupAdministrators())));
          assertTrue(rootSubGroups.contains(cms.readGroup(OpenCms.getDefaultUsers().getGroupUsers())));
          assertTrue(rootSubGroups.contains(cms.readGroup(OpenCms.getDefaultUsers().getGroupGuests())));
          assertTrue(rootSubGroups.contains(cms.readGroup("group1")));
          assertTrue(rootSubGroups.contains(cms.readGroup("group2")));
          assertTrue(rootSubGroups.contains(cms.readGroup("group3")));
          assertTrue(rootSubGroups.contains(cms.readGroup(ou.getName() + OpenCms.getDefaultUsers().getGroupUsers())));
  
          List rootUsers = OpenCms.getOrgUnitManager().getUsers(cms, rootOu.getName(), false);
          assertEquals(5, rootUsers.size());
          assertTrue(rootUsers.contains(cms.readUser(OpenCms.getDefaultUsers().getUserAdmin())));
          assertTrue(rootUsers.contains(cms.readUser(OpenCms.getDefaultUsers().getUserExport())));
          assertTrue(rootUsers.contains(cms.readUser(OpenCms.getDefaultUsers().getUserGuest())));
          assertTrue(rootUsers.contains(cms.readUser("test1")));
          assertTrue(rootUsers.contains(cms.readUser("test2")));
  
          List rootSubUsers = OpenCms.getOrgUnitManager().getUsers(cms, rootOu.getName(), true);
          assertEquals(5, rootSubUsers.size());
          assertTrue(rootSubUsers.contains(cms.readUser(OpenCms.getDefaultUsers().getUserAdmin())));
          assertTrue(rootSubUsers.contains(cms.readUser(OpenCms.getDefaultUsers().getUserExport())));
          assertTrue(rootSubUsers.contains(cms.readUser(OpenCms.getDefaultUsers().getUserGuest())));
          assertTrue(rootSubUsers.contains(cms.readUser("test1")));
          assertTrue(rootSubUsers.contains(cms.readUser("test2")));
          cms.removeUserFromGroup("test1", "Administrators");
          assertLock(cms, "/system/", CmsLockType.EXCLUSIVE, cms.readUser("test1"));
          cms.changeLock("/system/");
          cms.unlockResource("/system/");
      }
  
      /**
       * Tests system roles in first level ou.<p>
       *
       * @throws Throwable if something goes wrong
       */
      public void testFirstLevelRoles() throws Throwable {
  
          CmsObject cms = getCmsObject();
          echo("Testing system roles in first level ou");
  
          // check the ous
          CmsOrganizationalUnit rootOu = OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, "");
          CmsOrganizationalUnit flOu = OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, "test/");
  
          // check just the roles of the root ou
          List myRoles = OpenCms.getRoleManager().getRoles(cms, rootOu.getName(), false);
          assertEquals(CmsRole.getSystemRoles().size(), myRoles.size());
          for (int i = 0; i < myRoles.size(); i++) {
              CmsRole role = (CmsRole)myRoles.get(i);
              assertEquals("", role.getOuFqn());
              assertTrue(myRoles.contains(CmsRole.getSystemRoles().get(i).forOrgUnit("")));
              assertTrue(CmsRole.getSystemRoles().contains(role.forOrgUnit(null)));
          }
          // check all roles
          myRoles = OpenCms.getRoleManager().getRoles(cms, rootOu.getName(), true);
          assertEquals(CmsRole.getSystemRoles().size() + getOuRoles(flOu.getName()).size(), myRoles.size());
          for (int i = 0; i < myRoles.size(); i++) {
              CmsRole role = (CmsRole)myRoles.get(i);
              if (!role.getOuFqn().equals(rootOu.getName())) {
                  assertEquals(flOu.getName(), role.getOuFqn());
                  if (i < CmsRole.getSystemRoles().size()) {
                      assertTrue(myRoles.contains(CmsRole.getSystemRoles().get(i).forOrgUnit(flOu.getName())));
                  }
              } else {
                  assertEquals(rootOu.getName(), role.getOuFqn());
                  if (i < CmsRole.getSystemRoles().size()) {
                      assertTrue(myRoles.contains(CmsRole.getSystemRoles().get(i).forOrgUnit(rootOu.getName())));
                  }
              }
              assertTrue(CmsRole.getSystemRoles().contains(role.forOrgUnit(null)));
          }
          // check just the roles of the first level ou
          myRoles = OpenCms.getRoleManager().getRoles(cms, flOu.getName(), false);
          assertEquals(getOuRoles(flOu.getName()).size(), myRoles.size());
          for (int i = 0; i < myRoles.size(); i++) {
              CmsRole role = (CmsRole)myRoles.get(i);
              assertEquals(flOu.getName(), role.getOuFqn());
              assertTrue(myRoles.contains(((CmsRole)getOuRoles(flOu.getName()).get(i)).forOrgUnit(flOu.getName())));
              assertTrue(getOuRoles(flOu.getName()).contains(role.forOrgUnit(flOu.getName())));
          }
          // check again including (missing) sub-ous
          myRoles = OpenCms.getRoleManager().getRoles(cms, flOu.getName(), true);
          assertEquals(getOuRoles(flOu.getName()).size(), myRoles.size());
          for (int i = 0; i < myRoles.size(); i++) {
              CmsRole role = (CmsRole)myRoles.get(i);
              assertEquals(flOu.getName(), role.getOuFqn());
              assertTrue(myRoles.contains(((CmsRole)getOuRoles(flOu.getName()).get(i)).forOrgUnit(flOu.getName())));
              assertTrue(getOuRoles(flOu.getName()).contains(role.forOrgUnit(flOu.getName())));
          }
      }
  
      /**
       * Tests user/group membership.<p>
       *
       * @throws Throwable if something goes wrong
       */
      public void testMembership() throws Throwable {
  
          CmsObject cms = getCmsObject();
          echo("Testing user/group membership");
  
          // this is the current situation:
          // /test/test1 is member of /test/group1 in the /test ou
  
          assertEquals(3, OpenCms.getOrgUnitManager().getUsers(cms, "", false).size());
          assertEquals(5, OpenCms.getOrgUnitManager().getUsers(cms, "", true).size());
          // try to create another user 'test1' in the root ou
          cms.createUser("test1", "test1", "test user", null);
  
          assertEquals(4, OpenCms.getOrgUnitManager().getUsers(cms, "", false).size());
          assertEquals(6, OpenCms.getOrgUnitManager().getUsers(cms, "", true).size());
  
          assertEquals(1, OpenCms.getOrgUnitManager().getUsers(cms, "test", false).size());
          assertEquals(2, OpenCms.getOrgUnitManager().getUsers(cms, "test", true).size());
          try {
              // try to create another user 'test1' in the /test ou
              cms.createUser("test/test1", "test1", "test user", null);
              fail("it could not be possible to create 2 users with the same name in an ou");
          } catch (CmsException e) {
              // ok, ignore
          }
          assertEquals(1, OpenCms.getOrgUnitManager().getUsers(cms, "test/", false).size());
          assertEquals(2, OpenCms.getOrgUnitManager().getUsers(cms, "test/", true).size());
  
          assertEquals(1, OpenCms.getOrgUnitManager().getGroups(cms, "test/", false).size());
          assertEquals(2, OpenCms.getOrgUnitManager().getGroups(cms, "test/", true).size());
          // try to create another group 'group1' in the test ou
          cms.createGroup("test/group1", "test group", 0, null);
  
          assertEquals(7, OpenCms.getOrgUnitManager().getGroups(cms, "", false).size());
          assertEquals(11, OpenCms.getOrgUnitManager().getGroups(cms, "", true).size());
  
          assertEquals(2, OpenCms.getOrgUnitManager().getGroups(cms, "test", false).size());
          assertEquals(3, OpenCms.getOrgUnitManager().getGroups(cms, "test", true).size());
          try {
              // try to create another group 'group1' in the /test ou
              cms.createGroup("test/group1", "test group", 0, null);
              fail("it could not be possible to create 2 groups with the same name in an ou");
          } catch (CmsException e) {
              // ok, ignore
          }
          assertEquals(2, OpenCms.getOrgUnitManager().getGroups(cms, "test", false).size());
          assertEquals(3, OpenCms.getOrgUnitManager().getGroups(cms, "test", true).size());
  
          cms.addUserToGroup("test/test1", "test/group1");
  
          assertEquals(1, cms.getUsersOfGroup("test/group1").size());
          assertTrue(cms.getUsersOfGroup("test/group1").contains(cms.readUser("test/test1")));
          assertTrue(cms.getGroupsOfUser("test1", false).isEmpty());
          // add user of root ou to group of 1st level ou
          cms.addUserToGroup("test1", "test/group1");
          assertEquals(2, cms.getUsersOfGroup("test/group1").size());
          assertTrue(cms.getUsersOfGroup("test/group1").contains(cms.readUser("test/test1")));
          assertTrue(cms.getUsersOfGroup("test/group1").contains(cms.readUser("test1")));
          assertEquals(1, cms.getGroupsOfUser("test1", false).size());
          assertTrue(cms.getGroupsOfUser("test1", false).contains(cms.readGroup("test/group1")));
  
          assertTrue(cms.getUsersOfGroup("group1").isEmpty());
          assertEquals(3, cms.getGroupsOfUser("test/test1", true).size());
          assertTrue(cms.getGroupsOfUser("test/test1", true).contains(cms.readGroup("test/group1")));
          // add user of 1st level ou to group of root ou
          cms.addUserToGroup("test/test1", "group1");
          assertEquals(1, cms.getUsersOfGroup("group1").size());
          assertTrue(cms.getUsersOfGroup("group1").contains(cms.readUser("test/test1")));
          assertEquals(4, cms.getGroupsOfUser("test/test1", true).size());
          assertTrue(cms.getGroupsOfUser("test/test1", true).contains(cms.readGroup("test/group1")));
          assertTrue(cms.getGroupsOfUser("test/test1", true).contains(cms.readGroup("group1")));
      }
  
      /**
       * Tests exception when ou not found.<p>
       *
       * @throws Throwable if something goes wrong
       */
      public void testOuNotFound() throws Throwable {
  
          CmsObject cms = getCmsObject();
          echo("Trying to read an unexistant ou");
  
          try {
              OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, "/testOuNotFound/");
          } catch (CmsDbEntryNotFoundException e) {
              // ok, this is the expected exception
          }
      }
  
      /**
       * Tests roles on parallel ous.<p>
       *
       * @throws Throwable if something goes wrong
       */
      public void testParallelRoles() throws Throwable {
  
          CmsObject cms = getCmsObject();
          echo("Testing roles on parallel ous");
  
          CmsUser user = cms.readUser("test/test1");
  
          // check preconditions
          assertEquals(
              3,
              OpenCms.getRoleManager().getOrgUnitsForRole(cms, CmsRole.ADMINISTRATOR.forOrgUnit(""), true).size());
  
          cms.loginUser(user.getName(), "test1");
          List ous = OpenCms.getRoleManager().getOrgUnitsForRole(cms, CmsRole.ADMINISTRATOR.forOrgUnit(""), true);
          assertTrue(ous.isEmpty());
  
          // create a new ou
          cms = getCmsObject();
          OpenCms.getRoleManager().addUserToRole(cms, CmsRole.ADMINISTRATOR.forOrgUnit("test/"), user.getName());
  
          // check it
          cms.loginUser(user.getName(), "test1");
          ous = OpenCms.getRoleManager().getOrgUnitsForRole(cms, CmsRole.ADMINISTRATOR.forOrgUnit(""), true);
          assertEquals(2, ous.size());
          assertTrue(ous.contains(OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, "test")));
          assertTrue(ous.contains(OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, "test/test2")));
  
          // create a new ou
          cms = getCmsObject();
          cms.getRequestContext().setSiteRoot("");
          OpenCms.getOrgUnitManager().createOrganizationalUnit(cms, "test3", "test3", 0, "/system/");
          // set it up
          OpenCms.getRoleManager().addUserToRole(cms, CmsRole.ADMINISTRATOR.forOrgUnit("test3/"), user.getName());
  
          // check the result
          assertEquals(
              4,
              OpenCms.getRoleManager().getOrgUnitsForRole(cms, CmsRole.ADMINISTRATOR.forOrgUnit(""), true).size());
  
          cms.loginUser(user.getName(), "test1");
          ous = OpenCms.getRoleManager().getOrgUnitsForRole(cms, CmsRole.ADMINISTRATOR.forOrgUnit(""), true);
          assertEquals(3, ous.size());
          assertTrue(ous.contains(OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, "test")));
          assertTrue(ous.contains(OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, "test/test2")));
          assertTrue(ous.contains(OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, "test3")));
      }
  
      /**
       * Tests organizational units persistence.<p>
       *
       * @throws Throwable if something goes wrong
       */
      public void testPersistence() throws Throwable {
  
          CmsObject cms = getCmsObject();
          echo("Testing organizational units persistence");
  
          // check the root ou
          CmsOrganizationalUnit rootOu = OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, "");
          CmsOrganizationalUnit ou = OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, "test");
          CmsOrganizationalUnit ou2 = OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, ou.getName() + "test2");
  
          // check offline project
          CmsFolder rootOuFolder = cms.readFolder("/system/orgunits/");
          assertEquals(rootOu.getId(), rootOuFolder.getStructureId());
          assertEquals(rootOu.getFlags(), rootOuFolder.getFlags() & ~CmsResource.FLAG_INTERNAL);
          assertTrue(rootOuFolder.getState().isUnchanged());
          assertTrue(rootOuFolder.isInternal());
          assertEquals(
              rootOu.getDescription(),
              cms.readPropertyObject(rootOuFolder, CmsPropertyDefinition.PROPERTY_DESCRIPTION, false).getValue());
          assertOrgUnitResources(cms, rootOu);
  
          CmsFolder ouFolder = cms.readFolder("/system/orgunits/test");
          assertEquals(ou.getId(), ouFolder.getStructureId());
          assertEquals(ou.getFlags(), ouFolder.getFlags() & ~CmsResource.FLAG_INTERNAL);
          assertTrue(ouFolder.getState().isUnchanged());
          assertTrue(ouFolder.isInternal());
          assertEquals(
              ou.getDescription(),
              cms.readPropertyObject(ouFolder, CmsPropertyDefinition.PROPERTY_DESCRIPTION, false).getValue());
          assertOrgUnitResources(cms, ou);
  
          CmsFolder ou2Folder = cms.readFolder("/system/orgunits/test/test2");
          assertEquals(ou2.getId(), ou2Folder.getStructureId());
          assertEquals(ou2.getFlags(), ou2Folder.getFlags() & ~CmsResource.FLAG_INTERNAL);
          assertTrue(ou2Folder.getState().isUnchanged());
          assertTrue(ou2Folder.isInternal());
          assertEquals(
              ou2.getDescription(),
              cms.readPropertyObject(ou2Folder, CmsPropertyDefinition.PROPERTY_DESCRIPTION, false).getValue());
          assertOrgUnitResources(cms, ou2);
  
          // now check the online project
          cms.getRequestContext().setCurrentProject(cms.readProject(CmsProject.ONLINE_PROJECT_ID));
          rootOuFolder = cms.readFolder("/system/orgunits/");
          assertEquals(rootOu.getId(), rootOuFolder.getStructureId());
          assertEquals(rootOu.getFlags(), rootOuFolder.getFlags() & ~CmsResource.FLAG_INTERNAL);
          assertTrue(rootOuFolder.getState().isUnchanged());
          assertTrue(rootOuFolder.isInternal());
          assertEquals(
              rootOu.getDescription(),
              cms.readPropertyObject(rootOuFolder, CmsPropertyDefinition.PROPERTY_DESCRIPTION, false).getValue());
          assertOrgUnitResources(cms, rootOu);
  
          ouFolder = cms.readFolder("/system/orgunits/test");
          assertEquals(ou.getId(), ouFolder.getStructureId());
          assertEquals(ou.getFlags(), ouFolder.getFlags() & ~CmsResource.FLAG_INTERNAL);
          assertTrue(ouFolder.getState().isUnchanged());
          assertTrue(ouFolder.isInternal());
          assertEquals(
              ou.getDescription(),
              cms.readPropertyObject(ouFolder, CmsPropertyDefinition.PROPERTY_DESCRIPTION, false).getValue());
          assertOrgUnitResources(cms, ou);
  
          ou2Folder = cms.readFolder("/system/orgunits/test/test2");
          assertEquals(ou2.getId(), ou2Folder.getStructureId());
          assertEquals(ou2.getFlags(), ou2Folder.getFlags() & ~CmsResource.FLAG_INTERNAL);
          assertTrue(ou2Folder.getState().isUnchanged());
          assertTrue(ou2Folder.isInternal());
          assertEquals(
              ou2.getDescription(),
              cms.readPropertyObject(ou2Folder, CmsPropertyDefinition.PROPERTY_DESCRIPTION, false).getValue());
          assertOrgUnitResources(cms, ou2);
      }
  
      /**
       * Tests handling with a deeper level ou.<p>
       *
       * @throws Throwable if something goes wrong
       */
      public void testPrincipalAssociations() throws Throwable {
  
          CmsObject cms = getCmsObject();
          echo("Testing handling principal associations");
  
          // read the ous
          CmsOrganizationalUnit rootOu = OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, "");
          CmsOrganizationalUnit ou = OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, "test");
          CmsOrganizationalUnit ou2 = OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, ou.getName() + "test2");
  
          try {
              // try move to move /test1 to /test/test1
              OpenCms.getOrgUnitManager().setUsersOrganizationalUnit(cms, ou.getName(), "test1");
              fail("it should not be possible to move the user to other ou (since it is still member of a group)");
          } catch (CmsDbConsistencyException e) {
              // ok, ignore
          }
          cms.removeUserFromGroup("test1", "group1");
          // move to move /test1 to /test/test1
          OpenCms.getOrgUnitManager().setUsersOrganizationalUnit(cms, ou.getName(), "test1");
  
          try {
              cms.readUser("test1");
              fail("it should not be possible to read the user in the old ou");
          } catch (CmsDbEntryNotFoundException e) {
              // ok, ignore
          }
          cms.readUser("test/test1");
          assertTrue(cms.getGroupsOfUser("test/test1", false).isEmpty());
  
          List rootUsers = OpenCms.getOrgUnitManager().getUsers(cms, rootOu.getName(), false);
          assertEquals(4, rootUsers.size());
          assertFalse(rootUsers.contains(cms.readUser("test/test1")));
          List rootSubusers = OpenCms.getOrgUnitManager().getUsers(cms, rootOu.getName(), true);
          assertEquals(5, rootSubusers.size());
          assertTrue(rootSubusers.contains(cms.readUser("test/test1")));
  
          List ouUsers = OpenCms.getOrgUnitManager().getUsers(cms, ou.getName(), false);
          assertEquals(1, ouUsers.size());
          assertTrue(ouUsers.contains(cms.readUser("test/test1")));
          List ouSubusers = OpenCms.getOrgUnitManager().getUsers(cms, ou.getName(), true);
          assertEquals(1, ouSubusers.size());
          assertTrue(ouSubusers.contains(cms.readUser("test/test1")));
  
          cms.removeUserFromGroup("test2", "Users");
          cms.removeUserFromGroup("test2", "group2");
          // move to move /test2 to /test/test2/test2
          OpenCms.getOrgUnitManager().setUsersOrganizationalUnit(cms, ou2.getName(), "test2");
  
          try {
              cms.readUser("test2");
              fail("it should not be possible to read the user in the old ou");
          } catch (CmsDbEntryNotFoundException e) {
              // ok, ignore
          }
          cms.readUser("test/test2/test2");
          assertTrue(cms.getGroupsOfUser("test/test2/test2", false).isEmpty());
  
          rootUsers = OpenCms.getOrgUnitManager().getUsers(cms, rootOu.getName(), false);
          assertEquals(3, rootUsers.size());
          assertFalse(rootUsers.contains(cms.readUser("test/test1")));
          assertFalse(rootUsers.contains(cms.readUser("test/test2/test2")));
  
          rootSubusers = OpenCms.getOrgUnitManager().getUsers(cms, rootOu.getName(), true);
          assertEquals(5, rootSubusers.size());
          assertTrue(rootSubusers.contains(cms.readUser("test/test1")));
          assertTrue(rootSubusers.contains(cms.readUser("test/test2/test2")));
  
          List ouGroups = OpenCms.getOrgUnitManager().getGroups(cms, ou.getName(), false);
          assertEquals(1, ouGroups.size());
          assertTrue(ouGroups.contains(cms.readGroup(ou.getName() + OpenCms.getDefaultUsers().getGroupUsers())));
  
          List ouSubgroups = OpenCms.getOrgUnitManager().getGroups(cms, ou.getName(), true);
          assertEquals(2, ouSubgroups.size());
          assertTrue(ouSubgroups.contains(cms.readGroup(ou.getName() + OpenCms.getDefaultUsers().getGroupUsers())));
          assertTrue(ouSubgroups.contains(cms.readGroup(ou2.getName() + OpenCms.getDefaultUsers().getGroupUsers())));
  
          ouUsers = OpenCms.getOrgUnitManager().getUsers(cms, ou.getName(), false);
          assertEquals(1, ouUsers.size());
          assertTrue(ouUsers.contains(cms.readUser("test/test1")));
  
          ouSubusers = OpenCms.getOrgUnitManager().getUsers(cms, ou.getName(), true);
          assertEquals(2, ouSubusers.size());
          assertTrue(ouSubusers.contains(cms.readUser("test/test1")));
          assertTrue(ouSubusers.contains(cms.readUser("test/test2/test2")));
      }
  
      /**
       * Tests handling with resource associations.<p>
       *
       * @throws Throwable if something goes wrong
       */
      public void testResourceAssociations() throws Throwable {
  
          CmsObject cms = getCmsObject();
          echo("Testing handling with resource associations");
  
          // read the ous
          CmsOrganizationalUnit rootOu = OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, "");
          CmsOrganizationalUnit ou = OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, "test");
          CmsOrganizationalUnit ou2 = OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, "test/test2");
  
          try {
              OpenCms.getOrgUnitManager().createOrganizationalUnit(cms, "/doesnotexist/test2/", "my test ou2", 0, "");
              fail("should not be possible to create a new ou with a not valid parent");
          } catch (CmsDataAccessException e) {
              // ok, just be sure the ou has not been created
              assertEquals(2, OpenCms.getOrgUnitManager().getOrganizationalUnits(cms, rootOu.getName(), true).size());
              assertTrue(OpenCms.getOrgUnitManager().getOrganizationalUnits(cms, rootOu.getName(), true).contains(ou));
              assertTrue(OpenCms.getOrgUnitManager().getOrganizationalUnits(cms, rootOu.getName(), true).contains(ou2));
          }
  
          try {
              OpenCms.getOrgUnitManager().createOrganizationalUnit(
                  cms,
                  ou2.getName() + "test3/",
                  "my test ou3",
                  0,
                  "/folder2");
              fail("should not be possible to create a new ou with a resource out of the parent scope");
          } catch (CmsDataAccessException e) {
              // ok, just be sure the ou has not been created
              assertEquals(2, OpenCms.getOrgUnitManager().getOrganizationalUnits(cms, rootOu.getName(), true).size());
              assertTrue(OpenCms.getOrgUnitManager().getOrganizationalUnits(cms, rootOu.getName(), true).contains(ou));
              assertTrue(OpenCms.getOrgUnitManager().getOrganizationalUnits(cms, rootOu.getName(), true).contains(ou2));
          }
  
          // test adding the same resource as a parent ou resource
          assertEquals(1, OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(cms, ou2.getName()).size());
          assertTrue(
              OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(cms, ou2.getName()).contains(
                  cms.readResource("/folder1")));
          CmsOrganizationalUnit ou3 = OpenCms.getOrgUnitManager().createOrganizationalUnit(
              cms,
              ou2.getName() + "test3",
              "it will not last too long",
              0,
              "/folder1");
          assertEquals(1, OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(cms, ou3.getName()).size());
          assertTrue(
              OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(cms, ou3.getName()).contains(
                  cms.readResource("/folder1")));
          OpenCms.getOrgUnitManager().deleteOrganizationalUnit(cms, ou3.getName());
  
          // test removing all resources
          assertEquals(1, OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(cms, ou2.getName()).size());
          assertTrue(
              OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(cms, ou2.getName()).contains(
                  cms.readResource("/folder1")));
          try {
              // remove a resource
              OpenCms.getOrgUnitManager().removeResourceFromOrgUnit(cms, ou2.getName(), "/folder1");
              fail("it should not be possible to remove all resources");
          } catch (CmsDataAccessException e) {
              assertEquals(
                  ((CmsDataAccessException)e.getCause()).getMessageContainer().getKey(),
                  org.opencms.db.generic.Messages.ERR_ORGUNIT_REMOVE_LAST_RESOURCE_2);
              // ok, check again just to be sure
              assertEquals(1, OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(cms, ou2.getName()).size());
              assertTrue(
                  OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(cms, ou2.getName()).contains(
                      cms.readResource("/folder1")));
          }
  
          // check default project
          CmsProject defProj = cms.readProject(ou.getName() + "Offline");
  
          // check the project resources
          List projRes = cms.readProjectResources(defProj);
          List ouResources = OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(cms, ou.getName());
          assertEquals(ouResources.size(), projRes.size());
          for (int i = 0; i < projRes.size(); i++) {
              assertTrue(projRes.contains(((CmsResource)ouResources.get(i)).getRootPath()));
              assertTrue(
                  ouResources.contains(cms.readResource(cms.getRequestContext().removeSiteRoot((String)projRes.get(i)))));
          }
  
          try {
              OpenCms.getOrgUnitManager().addResourceToOrgUnit(cms, ou.getName(), "/sites/doesnotexist");
              fail("should not be possible to add an unexistent resource to an ou");
          } catch (CmsDataAccessException e) {
              // ok, just be sure
              assertEquals(1, OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(cms, ou.getName()).size());
              assertTrue(
                  OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(cms, ou.getName()).contains(
                      cms.readResource("/")));
          }
          // check the project resources
          projRes = cms.readProjectResources(defProj);
          ouResources = OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(cms, ou.getName());
          assertEquals(ouResources.size(), projRes.size());
          for (int i = 0; i < projRes.size(); i++) {
              assertTrue(projRes.contains(((CmsResource)ouResources.get(i)).getRootPath()));
              assertTrue(
                  ouResources.contains(cms.readResource(cms.getRequestContext().removeSiteRoot((String)projRes.get(i)))));
          }
  
          // add an additional resource
          OpenCms.getOrgUnitManager().addResourceToOrgUnit(cms, ou2.getName(), "/folder2");
          // check ou resources again
          assertEquals(2, OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(cms, ou2.getName()).size());
          assertTrue(
              OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(cms, ou2.getName()).contains(
                  cms.readResource("/folder1")));
          assertTrue(
              OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(cms, ou2.getName()).contains(
                  cms.readResource("/folder2")));
  
          // check the project resources
          CmsProject defProj2 = cms.readProject(ou2.getName() + "Offline");
          List projRes2 = cms.readProjectResources(defProj2);
          List ou2Resources = OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(cms, ou2.getName());
          assertEquals(ou2Resources.size(), projRes2.size());
          for (int i = 0; i < projRes2.size(); i++) {
              assertTrue(projRes2.contains(((CmsResource)ou2Resources.get(i)).getRootPath()));
              assertTrue(
                  ou2Resources.contains(
                      cms.readResource(cms.getRequestContext().removeSiteRoot((String)projRes2.get(i)))));
          }
  
          // resource remotion tests
          try {
              OpenCms.getOrgUnitManager().removeResourceFromOrgUnit(cms, ou2.getName(), "/folder1/index.html");
              fail("should not be possible to remove an not associated resource from an ou");
          } catch (CmsDataAccessException e) {
              // ok, just be sure
              assertEquals(2, OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(cms, ou2.getName()).size());
              assertTrue(
                  OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(cms, ou2.getName()).contains(
                      cms.readResource("/folder1")));
              assertTrue(
                  OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(cms, ou2.getName()).contains(
                      cms.readResource("/folder2")));
          }
          // check the project resources
          projRes2 = cms.readProjectResources(defProj2);
          ou2Resources = OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(cms, ou2.getName());
          assertEquals(ou2Resources.size(), projRes2.size());
          for (int i = 0; i < projRes2.size(); i++) {
              assertTrue(projRes2.contains(((CmsResource)ou2Resources.get(i)).getRootPath()));
              assertTrue(
                  ou2Resources.contains(
                      cms.readResource(cms.getRequestContext().removeSiteRoot((String)projRes2.get(i)))));
          }
  
          // remove a resource
          OpenCms.getOrgUnitManager().removeResourceFromOrgUnit(cms, ou2.getName(), "/folder1");
          // check ou resource
          assertEquals(1, OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(cms, ou2.getName()).size());
          assertTrue(
              OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(cms, ou2.getName()).contains(
                  cms.readResource("/folder2")));
          // check the project resources
          projRes2 = cms.readProjectResources(defProj2);
          ou2Resources = OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(cms, ou2.getName());
          assertEquals(ou2Resources.size(), projRes2.size());
          for (int i = 0; i < projRes2.size(); i++) {
              assertTrue(projRes2.contains(((CmsResource)ou2Resources.get(i)).getRootPath()));
              assertTrue(
                  ou2Resources.contains(
                      cms.readResource(cms.getRequestContext().removeSiteRoot((String)projRes2.get(i)))));
          }
      }
  
      /**
       * Tests role cache issue after creating a new ou.<p>
       *
       * @throws Throwable if something goes wrong
       */
      public void testRoleCacheIssue() throws Throwable {
  
          CmsObject cms = getCmsObject();
          echo("Test role cache issue after creating a new ou");
  
          // ensure the roles are cached
          List roles = OpenCms.getRoleManager().getRolesOfUser(
              cms,
              cms.getRequestContext().getCurrentUser().getName(),
              "",
              true,
              false,
              true);
  
          // create a new ou
          OpenCms.getOrgUnitManager().createOrganizationalUnit(cms, "/testRoleIssue", "Test role cache issue", 0, "/");
  
          List newRoles = OpenCms.getRoleManager().getRolesOfUser(
              cms,
              cms.getRequestContext().getCurrentUser().getName(),
              "",
              true,
              false,
              true);
  
          assertTrue(newRoles.size() > roles.size());
      }
  
      /**
       * Tests the inheritance of role memberships.<p>
       *
       * @throws Throwable if something goes wrong
       */
      public void testRoleInheritance() throws Throwable {
  
          CmsObject cms = getCmsObject();
          echo("Testing the inheritance of role memberships");
  
          cms.getRequestContext().setSiteRoot("");
  
          CmsRoleManager roleMan = OpenCms.getRoleManager();
          CmsOrgUnitManager ouMan = OpenCms.getOrgUnitManager();
          // check the root ou
          CmsOrganizationalUnit rootOu = ouMan.readOrganizationalUnit(cms, "");
          CmsResource rootRes = (ouMan.getResourcesForOrganizationalUnit(cms, rootOu.getName()).get(0)); // /
          CmsOrganizationalUnit ou = ouMan.readOrganizationalUnit(cms, "test");
          CmsResource ouRes = (ouMan.getResourcesForOrganizationalUnit(cms, ou.getName()).get(0)); // /sites/default/
          CmsOrganizationalUnit ou2 = ouMan.readOrganizationalUnit(cms, ou.getName() + "test2");
          CmsResource ou2Res = (ouMan.getResourcesForOrganizationalUnit(cms, ou2.getName()).get(0)); // /sites/default/folder2/
          CmsUser user = cms.readUser("test/test1");
          // check preconditions
          assertFalse(
              roleMan.hasRoleForResource(
                  cms,
                  user.getName(),
                  CmsRole.ACCOUNT_MANAGER,
                  cms.getRequestContext().getSitePath(rootRes)));
          assertFalse(
              roleMan.hasRoleForResource(
                  cms,
                  user.getName(),
                  CmsRole.ACCOUNT_MANAGER,
                  cms.getRequestContext().getSitePath(ouRes)));
          assertFalse(
              roleMan.hasRoleForResource(
                  cms,
                  user.getName(),
                  CmsRole.ACCOUNT_MANAGER,
                  cms.getRequestContext().getSitePath(ou2Res)));
  
          assertTrue(
              roleMan.hasRoleForResource(cms, CmsRole.ACCOUNT_MANAGER, cms.getRequestContext().getSitePath(rootRes)));
          assertTrue(
              roleMan.hasRoleForResource(cms, CmsRole.ACCOUNT_MANAGER, cms.getRequestContext().getSitePath(ouRes)));
          assertTrue(
              roleMan.hasRoleForResource(cms, CmsRole.ACCOUNT_MANAGER, cms.getRequestContext().getSitePath(ou2Res)));
  
          assertFalse(roleMan.hasRole(cms, user.getName(), CmsRole.ACCOUNT_MANAGER.forOrgUnit(ou.getName())));
          assertTrue(roleMan.getRolesOfUser(cms, user.getName(), ou.getName(), true, false, false).isEmpty());
          assertEquals(
              1,
              roleMan.getUsersOfRole(cms, CmsRole.ACCOUNT_MANAGER.forOrgUnit(ou.getName()), true, false).size());
          assertTrue(
              roleMan.getUsersOfRole(cms, CmsRole.ACCOUNT_MANAGER.forOrgUnit(ou.getName()), true, false).contains(
                  cms.readUser(OpenCms.getDefaultUsers().getUserAdmin())));
          // add user to role
          roleMan.addUserToRole(cms, CmsRole.ACCOUNT_MANAGER.forOrgUnit(ou.getName()), user.getName());
          // check role in the given ou
          assertTrue(roleMan.hasRole(cms, user.getName(), CmsRole.ACCOUNT_MANAGER.forOrgUnit(ou.getName())));
          assertEquals(7, roleMan.getRolesOfUser(cms, user.getName(), ou.getName(), false, false, false).size());
          assertTrue(
              roleMan.getRolesOfUser(cms, user.getName(), ou.getName(), false, false, false).contains(
                  CmsRole.ACCOUNT_MANAGER.forOrgUnit(ou.getName())));
          assertTrue(
              roleMan.getRolesOfUser(cms, user.getName(), ou.getName(), false, false, false).contains(
                  CmsRole.WORKPLACE_USER.forOrgUnit(ou.getName())));
          assertEquals(1, roleMan.getRolesOfUser(cms, user.getName(), ou.getName(), false, true, false).size());
          assertTrue(
              roleMan.getRolesOfUser(cms, user.getName(), ou.getName(), false, true, false).contains(
                  CmsRole.ACCOUNT_MANAGER.forOrgUnit(ou.getName())));
          assertFalse(
              roleMan.getRolesOfUser(cms, user.getName(), ou.getName(), false, true, false).contains(
                  CmsRole.WORKPLACE_USER.forOrgUnit(ou.getName())));
          assertEquals(14, roleMan.getRolesOfUser(cms, user.getName(), ou.getName(), true, false, false).size());
          assertTrue(
              roleMan.getRolesOfUser(cms, user.getName(), ou.getName(), true, false, false).contains(
                  CmsRole.ACCOUNT_MANAGER.forOrgUnit(ou.getName())));
          assertTrue(
              roleMan.getRolesOfUser(cms, user.getName(), ou.getName(), true, false, false).contains(
                  CmsRole.WORKPLACE_USER.forOrgUnit(ou.getName())));
          assertEquals(1, roleMan.getRolesOfUser(cms, user.getName(), ou.getName(), true, true, false).size());
          assertTrue(
              roleMan.getRolesOfUser(cms, user.getName(), ou.getName(), true, true, false).contains(
                  CmsRole.ACCOUNT_MANAGER.forOrgUnit(ou.getName())));
          assertFalse(
              roleMan.getRolesOfUser(cms, user.getName(), ou.getName(), true, true, false).contains(
                  CmsRole.WORKPLACE_USER.forOrgUnit(ou.getName())));
          assertEquals(
              1,
              roleMan.getUsersOfRole(cms, CmsRole.ACCOUNT_MANAGER.forOrgUnit(ou.getName()), false, false).size());
          assertTrue(
              roleMan.getUsersOfRole(cms, CmsRole.ACCOUNT_MANAGER.forOrgUnit(ou.getName()), false, false).contains(user));
          assertEquals(
              1,
              roleMan.getUsersOfRole(cms, CmsRole.ACCOUNT_MANAGER.forOrgUnit(ou.getName()), false, true).size());
          assertTrue(
              roleMan.getUsersOfRole(cms, CmsRole.ACCOUNT_MANAGER.forOrgUnit(ou.getName()), false, true).contains(user));
          assertEquals(
              2,
              roleMan.getUsersOfRole(cms, CmsRole.ACCOUNT_MANAGER.forOrgUnit(ou.getName()), true, false).size());
          assertTrue(
              roleMan.getUsersOfRole(cms, CmsRole.ACCOUNT_MANAGER.forOrgUnit(ou.getName()), true, false).contains(user));
          assertEquals(
              1,
              roleMan.getUsersOfRole(cms, CmsRole.ACCOUNT_MANAGER.forOrgUnit(ou.getName()), true, true).size());
          assertTrue(
              roleMan.getUsersOfRole(cms, CmsRole.ACCOUNT_MANAGER.forOrgUnit(ou.getName()), true, false).contains(user));
          // check role in deeper ou
          assertTrue(roleMan.hasRole(cms, user.getName(), CmsRole.ACCOUNT_MANAGER.forOrgUnit(ou2.getName())));
          assertTrue(roleMan.getRolesOfUser(cms, user.getName(), ou2.getName(), false, false, false).isEmpty());
          assertTrue(roleMan.getRolesOfUser(cms, user.getName(), ou2.getName(), false, true, false).isEmpty());
          assertEquals(13, roleMan.getRolesOfUser(cms, user.getName(), ou2.getName(), true, false, false).size());
          assertTrue(roleMan.getRolesOfUser(cms, user.getName(), ou2.getName(), true, true, false).isEmpty());
          assertEquals(
              0,
              roleMan.getUsersOfRole(cms, CmsRole.ACCOUNT_MANAGER.forOrgUnit(ou2.getName()), false, false).size());
          assertTrue(
              roleMan.getUsersOfRole(cms, CmsRole.ACCOUNT_MANAGER.forOrgUnit(ou2.getName()), false, true).isEmpty());
          assertEquals(
              2,
              roleMan.getUsersOfRole(cms, CmsRole.ACCOUNT_MANAGER.forOrgUnit(ou2.getName()), true, false).size());
          assertTrue(
              roleMan.getUsersOfRole(cms, CmsRole.ACCOUNT_MANAGER.forOrgUnit(ou2.getName()), true, false).contains(
                  cms.readUser(OpenCms.getDefaultUsers().getUserAdmin())));
          assertTrue(
              roleMan.getUsersOfRole(cms, CmsRole.ACCOUNT_MANAGER.forOrgUnit(ou2.getName()), true, true).isEmpty());
          // check role in higher ou
          assertFalse(roleMan.hasRole(cms, user.getName(), CmsRole.ACCOUNT_MANAGER.forOrgUnit(rootOu.getName())));
          assertEquals(14, roleMan.getRolesOfUser(cms, user.getName(), rootOu.getName(), true, false, false).size());
          assertTrue(
              roleMan.getRolesOfUser(cms, user.getName(), rootOu.getName(), true, false, false).contains(
                  CmsRole.ACCOUNT_MANAGER.forOrgUnit(ou.getName())));
          assertTrue(roleMan.getRolesOfUser(cms, user.getName(), rootOu.getName(), false, false, false).isEmpty());
          assertEquals(
              1,
              roleMan.getUsersOfRole(cms, CmsRole.ACCOUNT_MANAGER.forOrgUnit(rootOu.getName()), true, false).size());
          assertTrue(
              roleMan.getUsersOfRole(cms, CmsRole.ACCOUNT_MANAGER.forOrgUnit(rootOu.getName()), true, false).contains(
                  cms.readUser(OpenCms.getDefaultUsers().getUserAdmin())));
          // check resources
          assertFalse(
              roleMan.hasRoleForResource(
                  cms,
                  user.getName(),
                  CmsRole.ACCOUNT_MANAGER,
                  cms.getRequestContext().getSitePath(rootRes)));
          assertTrue(
              roleMan.hasRoleForResource(
                  cms,
                  user.getName(),
                  CmsRole.ACCOUNT_MANAGER,
                  cms.getRequestContext().getSitePath(ouRes)));
          assertTrue(
              roleMan.hasRoleForResource(
                  cms,
                  user.getName(),
                  CmsRole.ACCOUNT_MANAGER,
                  cms.getRequestContext().getSitePath(ou2Res)));
      }
  
      /**
       * Tests the root ou automatic creation.<p>
       *
       * @throws Throwable if something goes wrong
       */
      public void testRootOu() throws Throwable {
  
          CmsObject cms = getCmsObject();
          echo("Testing the automatic creation of the root organizational units");
  
          // check the root ou
          CmsOrganizationalUnit rootOu = OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, "");
  
          // check all the ous
          assertTrue(OpenCms.getOrgUnitManager().getOrganizationalUnits(cms, rootOu.getName(), false).isEmpty());
          assertTrue(OpenCms.getOrgUnitManager().getOrganizationalUnits(cms, rootOu.getName(), true).isEmpty());
  
          // check the root ou attributes
          assertEquals(0, rootOu.getFlags());
          assertNull(rootOu.getParentFqn());
          assertEquals("root organizational unit", rootOu.getDescription(Locale.ENGLISH));
          assertEquals("", rootOu.getName());
          assertEquals(CmsUUID.getNullUUID(), rootOu.getProjectId());
          assertEquals(cms.readFolder("/system/orgunits").getStructureId(), rootOu.getId());
  
          // check root ou resources
          List rootResources = OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(cms, rootOu.getName());
          assertEquals(1, rootResources.size());
          String site = cms.getRequestContext().getSiteRoot();
          cms.getRequestContext().setSiteRoot("/");
          assertTrue(rootResources.contains(cms.readResource("/")));
          cms.getRequestContext().setSiteRoot(site);
  
          // check the root ou principals
          List rootGroups = OpenCms.getOrgUnitManager().getGroups(cms, rootOu.getName(), false);
          assertEquals(7, rootGroups.size());
          assertTrue(rootGroups.contains(cms.readGroup(OpenCms.getDefaultUsers().getGroupAdministrators())));
          assertTrue(rootGroups.contains(cms.readGroup(OpenCms.getDefaultUsers().getGroupUsers())));
          assertTrue(rootGroups.contains(cms.readGroup(OpenCms.getDefaultUsers().getGroupGuests())));
          assertTrue(rootGroups.contains(cms.readGroup("group1")));
          assertTrue(rootGroups.contains(cms.readGroup("group2")));
          assertTrue(rootGroups.contains(cms.readGroup("group3")));
  
          List rootSubGroups = OpenCms.getOrgUnitManager().getGroups(cms, rootOu.getName(), true);
          assertEquals(7, rootSubGroups.size());
          assertTrue(rootSubGroups.contains(cms.readGroup(OpenCms.getDefaultUsers().getGroupAdministrators())));
          assertTrue(rootSubGroups.contains(cms.readGroup(OpenCms.getDefaultUsers().getGroupUsers())));
          assertTrue(rootSubGroups.contains(cms.readGroup(OpenCms.getDefaultUsers().getGroupGuests())));
          assertTrue(rootSubGroups.contains(cms.readGroup("group1")));
          assertTrue(rootSubGroups.contains(cms.readGroup("group2")));
          assertTrue(rootSubGroups.contains(cms.readGroup("group3")));
  
          List rootUsers = OpenCms.getOrgUnitManager().getUsers(cms, rootOu.getName(), false);
          assertEquals(5, rootUsers.size());
          assertTrue(rootUsers.contains(cms.readUser(OpenCms.getDefaultUsers().getUserAdmin())));
          assertTrue(rootUsers.contains(cms.readUser(OpenCms.getDefaultUsers().getUserExport())));
          assertTrue(rootUsers.contains(cms.readUser(OpenCms.getDefaultUsers().getUserGuest())));
          assertTrue(rootUsers.contains(cms.readUser("test1")));
          assertTrue(rootUsers.contains(cms.readUser("test2")));
  
          List rootSubUsers = OpenCms.getOrgUnitManager().getUsers(cms, rootOu.getName(), true);
          assertEquals(5, rootSubUsers.size());
          assertTrue(rootSubUsers.contains(cms.readUser(OpenCms.getDefaultUsers().getUserAdmin())));
          assertTrue(rootSubUsers.contains(cms.readUser(OpenCms.getDefaultUsers().getUserExport())));
          assertTrue(rootSubUsers.contains(cms.readUser(OpenCms.getDefaultUsers().getUserGuest())));
          assertTrue(rootSubUsers.contains(cms.readUser("test1")));
          assertTrue(rootSubUsers.contains(cms.readUser("test2")));
  
          rootOu.setDescription("new description");
          OpenCms.getOrgUnitManager().writeOrganizationalUnit(cms, rootOu);
  
          try {
              OpenCms.getOrgUnitManager().deleteOrganizationalUnit(cms, rootOu.getName());
              fail("should not be able to delete the root ou");
          } catch (CmsDataAccessException e) {
              // ok, ignore
          }
      }
  
      /**
       * Tests system roles in root ou.<p>
       *
       * @throws Throwable if something goes wrong
       */
      public void testRootRoles() throws Throwable {
  
          CmsObject cms = getCmsObject();
          echo("Testing system roles in root ou");
  
          // check just the roles of the root ou
          List myRoles = OpenCms.getRoleManager().getRoles(cms, "", false);
          assertEquals(CmsRole.getSystemRoles().size(), myRoles.size());
          for (int i = 0; i < myRoles.size(); i++) {
              CmsRole role = (CmsRole)myRoles.get(i);
              assertEquals("", role.getOuFqn());
              assertTrue(myRoles.contains(CmsRole.getSystemRoles().get(i).forOrgUnit("")));
              assertTrue(CmsRole.getSystemRoles().contains(role.forOrgUnit(null)));
          }
          // check all roles (but since there are no more ous, it is the same as before)
          myRoles = OpenCms.getRoleManager().getRoles(cms, "", true);
          assertEquals(CmsRole.getSystemRoles().size(), myRoles.size());
          for (int i = 0; i < myRoles.size(); i++) {
              CmsRole role = (CmsRole)myRoles.get(i);
              assertEquals("", role.getOuFqn());
              assertTrue(myRoles.contains(CmsRole.getSystemRoles().get(i).forOrgUnit("")));
              assertTrue(CmsRole.getSystemRoles().contains(role.forOrgUnit(null)));
          }
      }
  
      /**
       * Tests login.<p>
       *
       * @throws Throwable if something goes wrong
       */
      public void testUserLogin() throws Throwable {
  
          CmsObject cms = getCmsObject();
          echo("Testing login");
  
          // login users in respective ous
          cms.loginUser("test/test1", "test1");
          assertEquals("test/", cms.getRequestContext().getOuFqn());
          assertEquals("test/test1", cms.getRequestContext().getCurrentUser().getName());
          cms.loginUser("test/test2/test2", "test2");
          assertEquals("test/test2/", cms.getRequestContext().getOuFqn());
          assertEquals("test/test2/test2", cms.getRequestContext().getCurrentUser().getName());
  
          // login user in deeper ou
          cms.loginUser("test/test2/test1", "test1");
          assertEquals("test/", cms.getRequestContext().getOuFqn());
          assertEquals("test/test1", cms.getRequestContext().getCurrentUser().getName());
  
          try {
              // try login user in higher ou
              cms.loginUser("test/test2", "test2");
              fail("It should not be possible to login an user in a higher ou");
          } catch (CmsAuthentificationException e) {
              // ok, ignore
          }
      }
  
      /**
       * Tests webuser ou behavior.<p>
       *
       * @throws Throwable if something goes wrong
       */
      public void testWebuserOU() throws Throwable {
  
          CmsObject cms = getCmsObject();
          echo("Test webuser ou behavior");
  
          // try to create a normal ou without associated resource
          try {
              OpenCms.getOrgUnitManager().createOrganizationalUnit(cms, "/webuser", "webuser test", 0, null);
              fail("it should not be possible to create a normal ou without associated resource");
          } catch (CmsVfsException e) {
              // ok
          }
  
          // create a webuser ou without associated resource
          CmsOrganizationalUnit ou = OpenCms.getOrgUnitManager().createOrganizationalUnit(
              cms,
              "/webuser",
              "webuser test",
              CmsOrganizationalUnit.FLAG_WEBUSERS,
              null);
          // check the new created ou
          // no default Users group
          try {
              cms.readGroup(ou.getName() + OpenCms.getDefaultUsers().getGroupUsers());
              fail("webuser ou should not have a default group");
          } catch (CmsDbEntryNotFoundException e) {
              // ok, ignore
          }
          assertTrue(OpenCms.getOrgUnitManager().getGroups(cms, ou.getName(), true).isEmpty());
          // no default Offline project
          try {
              cms.readProject(ou.getName() + "Offline");
              fail("webuser ou should not have a default project");
          } catch (CmsDbEntryNotFoundException e) {
              // ok, ignore
          }
          // no roles except account manager
          List roles = OpenCms.getRoleManager().getRoles(cms, ou.getName(), true);
          assertEquals(1, roles.size());
          assertEquals(CmsRole.ACCOUNT_MANAGER.forOrgUnit(ou.getName()), roles.get(0));
          // check resources
          assertTrue(OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(cms, ou.getName()).isEmpty());
  
          // add a resource
          OpenCms.getOrgUnitManager().addResourceToOrgUnit(cms, ou.getName(), "/");
          // check
          List res = OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(cms, ou.getName());
          assertEquals(1, res.size());
          assertEquals(cms.readResource("/"), res.get(0));
          // remove resource
          OpenCms.getOrgUnitManager().removeResourceFromOrgUnit(cms, ou.getName(), "/");
          // check resources
          assertTrue(OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(cms, ou.getName()).isEmpty());
      }
  
      /**
       * Returns the list of associated resource root paths.<p>
       *
       * @param cms the cms context
       * @param ou the organizational unit to get the resources for
       *
       * @throws CmsException if something goes wrong
       */
      private void assertOrgUnitResources(CmsObject cms, CmsOrganizationalUnit ou) throws CmsException {
  
          List resourceList = new ArrayList();
          Iterator itResources = OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(
              cms,
              ou.getName()).iterator();
          while (itResources.hasNext()) {
              CmsResource resource = (CmsResource)itResources.next();
              resourceList.add(resource.getRootPath());
          }
          List relations = cms.getRelationsForResource(
              cms.getSitePath(cms.readResource(ou.getId())),
              CmsRelationFilter.TARGETS);
          assertEquals(relations.size(), resourceList.size());
          Iterator itRelations = relations.iterator();
          while (itRelations.hasNext()) {
              CmsRelation relation = (CmsRelation)itRelations.next();
              assertTrue(resourceList.contains(relation.getTargetPath()));
          }
      }
  }
  