| /* |
| * 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(); |
| } |
| } |
| } |