/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.jackrabbit.oak.exercise.security.authorization.advanced;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.security.Principal;
import java.util.Map;
import javax.jcr.ImportUUIDBehavior;
import javax.jcr.Node;
import javax.jcr.Repository;
import javax.jcr.Session;
import javax.jcr.nodetype.NodeDefinition;
import javax.jcr.nodetype.PropertyDefinition;
import javax.jcr.security.AccessControlManager;
import javax.jcr.security.AccessControlPolicy;
import javax.jcr.security.AccessControlPolicyIterator;
import javax.jcr.security.NamedAccessControlPolicy;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import org.apache.jackrabbit.api.security.principal.PrincipalManager;
import org.apache.jackrabbit.oak.AbstractSecurityTest;
import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.api.ContentSession;
import org.apache.jackrabbit.oak.api.Root;
import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.exercise.security.authorization.models.simplifiedroles.ThreeRolesAuthorizationConfiguration;
import org.apache.jackrabbit.oak.exercise.security.authorization.models.simplifiedroles.ThreeRolesConstants;
import org.apache.jackrabbit.oak.exercise.security.principal.CustomPrincipalConfiguration;
import org.apache.jackrabbit.oak.jcr.Jcr;
import org.apache.jackrabbit.oak.jcr.repository.RepositoryImpl;
import org.apache.jackrabbit.oak.namepath.NamePathMapper;
import org.apache.jackrabbit.oak.plugins.nodetype.ReadOnlyNodeTypeManager;
import org.apache.jackrabbit.oak.plugins.tree.TreeUtil;
import org.apache.jackrabbit.oak.security.authorization.composite.CompositeAuthorizationConfiguration;
import org.apache.jackrabbit.oak.security.internal.SecurityProviderHelper;
import org.apache.jackrabbit.oak.spi.nodetype.NodeTypeConstants;
import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
import org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.PolicyOwner;
import org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionProvider;
import org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions;
import org.apache.jackrabbit.oak.spi.security.principal.EveryonePrincipal;
import org.apache.jackrabbit.oak.spi.security.principal.PrincipalConfiguration;
import org.apache.jackrabbit.oak.spi.whiteboard.DefaultWhiteboard;
import org.apache.jackrabbit.oak.spi.xml.ProtectedNodeImporter;
import org.jetbrains.annotations.NotNull;
import org.junit.Test;

import static junit.framework.TestCase.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

/**
 * <pre>
 * Module: Advanced Authorization Topics
 * =============================================================================
 *
 * Title: Writing Custom Authorization : Access Control Management
 * -----------------------------------------------------------------------------
 *
 * Goal:
 * Learn how to write your own access control management and how to properly
 * secure access control content.
 * The exercises is this lesson will make use of a authorization model stub that
 * already has the permission evaluation implemented. The entry point of that model
 * is {@link ThreeRolesAuthorizationConfiguration}.
 *
 * Exercises:
 *
 * - {@link #testGetPolicies()}
 *   Complete the implementation of {@link AccessControlManager#getPolicies(String)}
 *   such that the test passes.
 *   Adjust the number of expected policies and the type of policies according
 *   to your implementation.
 *
 *   Questions:
 *   - what type of policy do you want to expose?
 *   - does any of the existing types of access control policies fit your needs?
 *     existing types include
 *     > {@link NamedAccessControlPolicy},
 *     > {@link javax.jcr.security.AccessControlList},
 *     > {@link org.apache.jackrabbit.api.security.JackrabbitAccessControlList},
 *     > {@link org.apache.jackrabbit.api.security.authorization.PrincipalSetPolicy}
 *   - if you choose to define your own policy type: what does it look like?
 *   - should {@link AccessControlManager#getPolicies(String)} return one or many policies?
 *
 * - {@link #testGetEffectivePolicies()}
 *   Complete the implementation of {@link AccessControlManager#getEffectivePolicies(String)}
 *   such that the test passes.
 *   NOTE: computation of effective policies is specified to be a best-effort operation.
 *
 *   Questions:
 *   - what type of policy do you want to expose?
 *   - what are the effective policies for those nodes that don't have the custom
 *     policy set? or in other words: which nodes are affected by the policy set
 *     at /test/a in the test setup?
 *   - does the set of effective policies include any default policies that have
 *     not been explicit set?
 *   - what's the maximal number of effective policies your implementation may return?
 *
 * - {@link #testGetApplicablePolicies()}
 *   Complete the implementation of {@link AccessControlManager#testGetApplicablePolicies(String)}
 *   such that the test passes.
 *
 *   Questions:
 *   - what type of policies do you expose here?
 *   - are they they same as with {@link #testGetPolicies()} and/or {@link #testGetEffectivePolicies()}?
 *   - does /test/a still have applicable policies?
 *   - what about the path outside of the tree defined by 'supportedPath' configuration option?
 *   - as you learned in the previous section and can see in {@link org.apache.jackrabbit.oak.exercise.security.authorization.models.simplifiedroles.ThreeRolesPermissionProvider}
 *     this simplified authorization model doesn't respect nesting of policies in a
 *     given tree. what does that mean for the applicable policies?
 *   - what's the maximal number of applicable policies your implementation may return at a given path?
 *
 * - {@link #testSetPolicy()}
 *   Implement {@link AccessControlManager#setPolicy(String, AccessControlPolicy)} and
 *   {@link PolicyOwner#defines(String, AccessControlPolicy)} such that policies
 *   can be written to the repository in a composite authorization setup.
 *   The {@link PolicyOwner} is also required for the subsequent tests.
 *
 * - {@link #testSetModifiedPolicy()}
 *   Modify the custom access control setup at /test/a such that the principal
 *   associated with the test-user get moved from the editor to the owner set.
 *
 * - {@link #testRemovePolicy()}
 *   Implement {@link AccessControlManager#removePolicy(String, AccessControlPolicy)} such
 *   that the test passes.
 *
 * - {@link #testAccessControlContentIsProtected()}
 *   Your authorization setup should come with some validation of the access control
 *   content written to the repository.
 *   Write a {@link org.apache.jackrabbit.oak.spi.commit.ValidatorProvider} and
 *   plug it into the authorization configuration such that the test-case passes
 *   and discuss each of the assertions made.
 *
 *   Questions:
 *   - Can you identify possible shortcomings with the 4 validation steps proposed?
 *   - Under which circumstances could any of them might not be desirable?
 *
 * - {@link #testAccessControlItemsAreProtectedByNodeTypeDefinition()}
 *   Identify the code in the simplifiedroles authorization model that makes sure
 *   the simple policy node and it's properties have JCR item definitions that are
 *   protected.
 *
 *   Discuss why this is needed and what the effect of this measure is.
 *   Complete the test case by
 *   - testing the protected status of access control content using JCR API calls.
 *   - verifying the protected status using JCR write API
 *
 *   Question:
 *   - Can you identify which parts of Oak are responsible for enforcing the protected status?
 *
 * - {@link #testImportNodeWithPolicy}
 *   This is a follow-up on {@link #testAccessControlItemsAreProtectedByNodeTypeDefinition()} as
 *   the protected item definitions are not only enforced upon regular write
 *   operations but also when calling {@link javax.jcr.Session#importXML(String, InputStream, int)},
 *   {@link javax.jcr.Workspace#importXML(String, InputStream, int)} and related calls.
 *
 *   Fix the simplifiedroles authorization model such that the test passes.
 *   Hint: you need to implement a custom implementation of {@link ProtectedNodeImporter}
 *   and ensure the {@link AuthorizationConfiguration#getProtectedItemImporters()}
 *   exposes it to the security setup.
 *
 * - {@link #testImportNodeWithPolicyAndUnknownPrincipal}
 *   Variant of {@link #testImportNodeWithPolicy} that attempts to import a policy
 *   referring to an {@code Principal} that is not known to any of the providers.
 *
 *   Questions:
 *   - What do you need to do to the setup and possibly your importer code such
 *     that importing unknown principals is allowed?
 *   - In case your importer didn't check the validity of the principals:
 *     Discuss the adjustments you would need to make to your importer in order
 *     to enforce the different levels of validation check.
 *
 *
 * Advanced Exercise
 * -----------------------------------------------------------------------------
 *
 * The AccessControlManager stub doesn't implement {@link org.apache.jackrabbit.api.security.JackrabbitAccessControlManager}.
 * Take a look at the additional methods defined by the extension in Jackrabbit API.
 *
 * As you can see the extra methods all related to access control management by
 * {@link Principal}.
 *
 * Questions:
 * - Would it be possible/sensible to have your implementation additionally implement
 *   the methods {@link org.apache.jackrabbit.api.security.JackrabbitAccessControlManager}?
 *
 * - If you think it's possible, what would the implementation look like?
 *
 * - Can you spot any obstacles with that approach?
 *
 *
 * Related Exercises:
 * -----------------------------------------------------------------------------
 *
 * - {@link L5_CustomPermissionEvaluationTest}
 *
 * </pre>
 */
public class L4_CustomAccessControlManagementTest extends AbstractSecurityTest {

    @Override
    protected SecurityProvider initSecurityProvider() {
        ThreeRolesAuthorizationConfiguration threeRolesAuthorizationConfiguration = new ThreeRolesAuthorizationConfiguration();
        threeRolesAuthorizationConfiguration.setParameters(ConfigurationParameters.of("supportedPath", "/test"));

        CustomPrincipalConfiguration pc = new CustomPrincipalConfiguration();
        pc.setParameters(ConfigurationParameters.of("knownPrincipals", new String[] {"principalR", "principalE", "principalO"}));

        SecurityProvider sp = super.initSecurityProvider();
        SecurityProviderHelper.updateConfig(sp, threeRolesAuthorizationConfiguration, AuthorizationConfiguration.class);
        SecurityProviderHelper.updateConfig(sp, pc, PrincipalConfiguration.class);

        return sp;
    }

    @Override
    protected ConfigurationParameters getSecurityConfigParameters() {
        return ConfigurationParameters.of("authorizationCompositionType", CompositeAuthorizationConfiguration.CompositionType.OR.toString());
    }

    @Override
    public void before() throws Exception {
        super.before();

        Tree testTree = TreeUtil.addChild(root.getTree("/"), "test", NodeTypeConstants.NT_OAK_UNSTRUCTURED);
        Tree aTree = TreeUtil.addChild(testTree, "a", NodeTypeConstants.NT_OAK_UNSTRUCTURED);
        aTree.setProperty("aProp", "value");

        Tree abTree = TreeUtil.addChild(aTree, "b", NodeTypeConstants.NT_OAK_UNSTRUCTURED);
        abTree.setProperty("abProp", "value");


        TreeUtil.addMixin(aTree, ThreeRolesConstants.MIX_REP_THREE_ROLES_POLICY, root.getTree(NodeTypeConstants.NODE_TYPES_PATH), null);
        Tree rolePolicy = TreeUtil.addChild(aTree, ThreeRolesConstants.REP_3_ROLES_POLICY, ThreeRolesConstants.NT_REP_THREE_ROLES_POLICY);
        rolePolicy.setProperty(ThreeRolesConstants.REP_READERS, ImmutableSet.of("principalR", EveryonePrincipal.NAME), Type.STRINGS);
        rolePolicy.setProperty(ThreeRolesConstants.REP_EDITORS, ImmutableSet.of("principalE",getTestUser().getPrincipal().getName()), Type.STRINGS);
        rolePolicy.setProperty(ThreeRolesConstants.REP_OWNERS,  ImmutableSet.of("principalO"), Type.STRINGS);

        // add one node outside the scope of the supported path
        Tree outside = TreeUtil.addChild(root.getTree("/"), "outside", NodeTypeConstants.NT_OAK_UNSTRUCTURED);

        root.commit();

        // to verify that setup with CompositeAuthorizationConfiguration.CompositionType.OR
        // uncomment the lines below
        /*
        try (ContentSession cs = createTestSession()) {
            Root r = createTestSession().getLatestRoot();
            assertTrue(r.getTree("/test/a").exists());
        }
        */
    }

    private AccessControlManager getAcManager(@NotNull Root root) {
        return getConfig(AuthorizationConfiguration.class).getAccessControlManager(root, NamePathMapper.DEFAULT);
    }

    private Repository buildJcrRepository() {
        return new RepositoryImpl(
                getContentRepository(),
                new DefaultWhiteboard(),
                getSecurityProvider(),
                Jcr.DEFAULT_OBSERVATION_QUEUE_LENGTH,
                null,
                false);
    }


    /**
     * EXERCISE: complete {@link AccessControlManager#getPolicies(String)} such that
     * the policy that has been 'manually' created in the setup is properly exposed
     * by the access control management API.
     */
    @Test
    public void testGetPolicies() throws Exception {
        AccessControlPolicy[] policies = getAcManager(root).getPolicies("/test/a");

        int len = -1; // EXERCISE: set expected length. 1 is the minimum but there might be more.
        assertEquals(len, policies.length);

        // EXERCISE: additionally assert that the policies is of the type you defined
        for (int i = 0; i < len; i++) {
            assertTrue(policies[i] instanceof AccessControlPolicy); // EXERCISE: replace by type chosen!
        }
    }

    @Test
    public void testGetEffectivePolicies() throws Exception {
        // EXERCISE: set expected number of effective policies for all paths in the map.
        Map<String,Integer> m = ImmutableMap.of("/", -1, "/test", -1, "/test/a/b", -1, "/outside", -1);

        for (String path : m.keySet()) {
            AccessControlPolicy[] policies = getAcManager(root).getEffectivePolicies(path);

            int len = m.get(path); // EXERCISE: set expected length. 1 is the minimum but there might be more.
            assertEquals(len, policies.length);

            // EXERCISE: additionally assert that the policies is of the type you defined
            for (int i = 0; i < len; i++) {
                assertTrue(policies[i] instanceof AccessControlPolicy); // EXERCISE: replace by type chosen!
            }
        }
    }

    @Test
    public void testGetApplicablePolicies() throws Exception {
        // EXERCISE: set expected number of applicable policies for all paths in the map.
        Map<String,Integer> m = ImmutableMap.of("/test/a", -1, "/test/a/b", -1, "/outside", -1);

        for (String path : m.keySet()) {
            AccessControlPolicyIterator it = getAcManager(root).getApplicablePolicies(path);
            assertEquals(m.get(path).longValue(), it.getSize());

            // EXERCISE: additionally assert that the policies is of the type you defined
            while (it.hasNext()) {
                assertTrue(it.nextAccessControlPolicy() instanceof AccessControlPolicy); // EXERCISE: replace by type chosen!
            }
        }
    }

    @Test
    public void testSetPolicy() throws Exception {
        Tree t = TreeUtil.addChild(root.getTree("/test"), "another", NodeTypeConstants.NT_OAK_UNSTRUCTURED);
        AccessControlManager acMgr = getAcManager(root);
        AccessControlPolicy[] policies = acMgr.getPolicies(t.getPath());

        // EXERCISE: set your custom policy/policies at /test/another such that
        //           the following assertions pass.
        // ... write your code here

        root.commit();

        PrincipalManager pm = getPrincipalManager(root);
        Map<Principal,Long> m = ImmutableMap.of(
                getTestUser().getPrincipal(), Permissions.NO_PERMISSION,
                pm.getEveryone(), Permissions.NO_PERMISSION,
                pm.getPrincipal("principalR"), Permissions.READ,
                pm.getPrincipal("principalE"), Permissions.NO_PERMISSION,
                pm.getPrincipal("principalO"), ThreeRolesConstants.SUPPORTED_PERMISSIONS
        );
        for (Principal principal : m.keySet()) {
            PermissionProvider pp = getConfig(AuthorizationConfiguration.class).getPermissionProvider(root, adminSession.getWorkspaceName(), ImmutableSet.of(principal));
            assertTrue(pp.isGranted(t, null, m.get(principal)));
        }
    }

    @Test
    public void testSetModifiedPolicy() throws Exception {
        AccessControlManager acMgr = getAcManager(root);
        AccessControlPolicy[] policies = acMgr.getPolicies("/test/a");

        // EXERCISE: modify policies such that the testuser principal becomes owner instead of editor
        // ... write your code here

        for (AccessControlPolicy policy : policies) {
            acMgr.setPolicy("/test/a", policy);
        }
        root.commit();

        try (ContentSession cs = createTestSession()) {
            Root r = createTestSession().getLatestRoot();
            PermissionProvider pp = getConfig(AuthorizationConfiguration.class).getPermissionProvider(r, cs.getWorkspaceName(), cs.getAuthInfo().getPrincipals());
            assertTrue(pp.isGranted("/test/a", Permissions.getString(ThreeRolesConstants.SUPPORTED_PERMISSIONS)));
        }
    }

    @Test
    public void testRemovePolicy() throws Exception {
        AccessControlManager acMgr = getAcManager(root);
        for (AccessControlPolicy policy : acMgr.getPolicies("/test/a")) {
            acMgr.removePolicy("/test/a", policy);
        }
        root.commit();
        assertEquals(0, acMgr.getPolicies("/test/a").length);

    }

    @Test
    public void testAccessControlContentIsProtected() throws Exception {
        Tree test = root.getTree("/test");

        try {
            Tree missingMixin = TreeUtil.addChild(test, ThreeRolesConstants.REP_3_ROLES_POLICY, ThreeRolesConstants.NT_REP_THREE_ROLES_POLICY);
            root.commit();
            fail("Adding policy without mixin must fail.");
        } catch (CommitFailedException e) {
            // success
        }

        try {
            test.setProperty(ThreeRolesConstants.REP_OWNERS, 437);
            root.commit();
            fail("Using name of protected policy property outside of the context of a policy must fail.");
        } catch (CommitFailedException e) {
            // success
        }

        try {
            Tree b = root.getTree("/test/a/b");
            TreeUtil.addMixin(b, ThreeRolesConstants.MIX_REP_THREE_ROLES_POLICY, root.getTree(NodeTypeConstants.NODE_TYPES_PATH), null);
            Tree nestedPolicy = TreeUtil.addChild(b, ThreeRolesConstants.REP_3_ROLES_POLICY, ThreeRolesConstants.NT_REP_THREE_ROLES_POLICY);
            root.commit();

            fail("Creation of nested three-roles-policy must fail (NOTE: this is an arbitrary limitation for the sake of simplifying permission evaluation).");
        } catch (CommitFailedException e) {
            // success
        }

        try {
            Tree outside = root.getTree("/outside");
            TreeUtil.addMixin(outside, ThreeRolesConstants.MIX_REP_THREE_ROLES_POLICY, root.getTree(NodeTypeConstants.NODE_TYPES_PATH), null);
            Tree nestedPolicy = TreeUtil.addChild(outside, ThreeRolesConstants.REP_3_ROLES_POLICY, ThreeRolesConstants.NT_REP_THREE_ROLES_POLICY);
            root.commit();

            fail("Creation of nested three-roles-policy outside of the configured supported path must fail.");
        } catch (CommitFailedException e) {
            // success
        }

    }

    @Test
    public void testAccessControlItemsAreProtectedByNodeTypeDefinition() throws Exception {
        ReadOnlyNodeTypeManager ntMgr = ReadOnlyNodeTypeManager.getInstance(root, NamePathMapper.DEFAULT);

        Tree aTree = root.getTree("/test/a");
        Tree policyTree = aTree.getChild(ThreeRolesConstants.REP_3_ROLES_POLICY);

        NodeDefinition policyDef = ntMgr.getDefinition(aTree, policyTree);
        assertTrue(policyDef.isProtected());

        for (String propName : new String[] {ThreeRolesConstants.REP_READERS, ThreeRolesConstants.REP_EDITORS, ThreeRolesConstants.REP_OWNERS}) {
            PropertyDefinition propDef = ntMgr.getDefinition(policyTree, policyTree.getProperty(propName), true);
            assertTrue(propDef.isProtected());
        }

        Repository jcrRepository = buildJcrRepository();

        // EXERCISE: test protected status of items using JCR API calls
        // EXERCISE: verify that the protected status of the access control content is enforced
        // ... write your code here
    }

    @Test
    public void testImportNodeWithPolicy() throws Exception {
        Repository jcrRepository = new RepositoryImpl(
                getContentRepository(),
                new DefaultWhiteboard(),
                getSecurityProvider(),
                Jcr.DEFAULT_OBSERVATION_QUEUE_LENGTH,
                null,
                false);

        Session adminSession = jcrRepository.login(getAdminCredentials(), null);
        try {
            String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
                    "<sv:node sv:name=\"another2\" xmlns:mix=\"http://www.jcp.org/jcr/mix/1.0\" xmlns:nt=\"http://www.jcp.org/jcr/nt/1.0\" xmlns:fn_old=\"http://www.w3.org/2004/10/xpath-functions\" xmlns:fn=\"http://www.w3.org/2005/xpath-functions\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:sv=\"http://www.jcp.org/jcr/sv/1.0\" xmlns:rep=\"internal\" xmlns:jcr=\"http://www.jcp.org/jcr/1.0\">" +
                        "<sv:property sv:name=\"jcr:primaryType\" sv:type=\"Name\"><sv:value>oak:Unstructured</sv:value></sv:property>" +
                        "<sv:property sv:name=\"jcr:mixinTypes\" sv:type=\"Name\"><sv:value>rep:ThreeRolesMixin</sv:value></sv:property>" +
                        "<sv:node sv:name=\"rep:threeRolesPolicy\" " +
                            "<sv:property sv:name=\"jcr:primaryType\" sv:type=\"Name\"><sv:value>rep:ThreeRolesPolicy</sv:value></sv:property>" +
                            "<sv:property sv:name=\"rep:readers\" sv:type=\"String\"><sv:value>principalR</sv:value></sv:property>" +
                        "</sv:node>" +
                    "</sv:node>";

            adminSession.importXML("/test", new ByteArrayInputStream(xml.getBytes()), ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW);

            Node n = adminSession.getNode("/test/another");
            AccessControlPolicy[] policies = adminSession.getAccessControlManager().getPolicies("/test/another");
            assertTrue(policies.length > 0);

        } finally {
            adminSession.refresh(false);
            adminSession.logout();
        }
    }

    @Test
    public void testImportNodeWithPolicyAndUnknownPrincipal() throws Exception {
        Repository jcrRepository = buildJcrRepository();

        Session adminSession = jcrRepository.login(getAdminCredentials(), null);
        try {
            String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
                    "<sv:node sv:name=\"another2\" xmlns:mix=\"http://www.jcp.org/jcr/mix/1.0\" xmlns:nt=\"http://www.jcp.org/jcr/nt/1.0\" xmlns:fn_old=\"http://www.w3.org/2004/10/xpath-functions\" xmlns:fn=\"http://www.w3.org/2005/xpath-functions\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:sv=\"http://www.jcp.org/jcr/sv/1.0\" xmlns:rep=\"internal\" xmlns:jcr=\"http://www.jcp.org/jcr/1.0\">" +
                        "<sv:property sv:name=\"jcr:primaryType\" sv:type=\"Name\"><sv:value>oak:Unstructured</sv:value></sv:property>" +
                        "<sv:property sv:name=\"jcr:mixinTypes\" sv:type=\"Name\"><sv:value>rep:ThreeRolesMixin</sv:value></sv:property>" +
                        "<sv:node sv:name=\"rep:threeRolesPolicy\" " +
                            "<sv:property sv:name=\"jcr:primaryType\" sv:type=\"Name\"><sv:value>rep:ThreeRolesPolicy</sv:value></sv:property>" +
                            "<sv:property sv:name=\"rep:readers\" sv:type=\"String\"><sv:value>unknownPrincipal</sv:value></sv:property>" +
                        "</sv:node>" +
                    "</sv:node>";

            adminSession.importXML("/test", new ByteArrayInputStream(xml.getBytes()), ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW);

            Node n = adminSession.getNode("/test/another");
            AccessControlPolicy[] policies = adminSession.getAccessControlManager().getPolicies("/test/another");
            assertTrue(policies.length > 0);

        } finally {
            adminSession.refresh(false);
            adminSession.logout();
        }
    }
}
