Index: vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/JackrabbitACLImporter.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/JackrabbitACLImporter.java (revision 1863941) +++ vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/JackrabbitACLImporter.java (date 1564407725000) @@ -20,7 +20,6 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -32,6 +31,7 @@ import javax.jcr.Value; import javax.jcr.ValueFactory; import javax.jcr.security.AccessControlEntry; +import javax.jcr.security.AccessControlException; import javax.jcr.security.AccessControlManager; import javax.jcr.security.AccessControlPolicy; import javax.jcr.security.AccessControlPolicyIterator; @@ -39,8 +39,12 @@ import org.apache.jackrabbit.api.JackrabbitSession; import org.apache.jackrabbit.api.security.JackrabbitAccessControlList; +import org.apache.jackrabbit.api.security.JackrabbitAccessControlManager; +import org.apache.jackrabbit.api.security.authorization.PrincipalAccessControlList; import org.apache.jackrabbit.api.security.authorization.PrincipalSetPolicy; import org.apache.jackrabbit.api.security.principal.PrincipalManager; +import org.apache.jackrabbit.api.security.user.Authorizable; +import org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils; import org.apache.jackrabbit.vault.fs.io.AccessControlHandling; import org.apache.jackrabbit.vault.util.DocViewNode; import org.apache.jackrabbit.vault.util.DocViewProperty; @@ -104,7 +108,7 @@ this.states.push(State.INITIAL); } - public void startNode(DocViewNode node) throws SAXException { + public void startNode(DocViewNode node) { State state = states.peek(); switch (state) { case INITIAL: @@ -114,6 +118,9 @@ } else if ("rep:CugPolicy".equals(node.primary)) { importPolicy = new ImportedPrincipalSet(node); state = State.PRINCIPAL_SET_POLICY; + } else if ("rep:PrincipalPolicy".equals(node.primary)) { + importPolicy = new ImportedPrincipalAcList(node); + state = State.ACL; } else { log.error("Error while reading access control content: Expected rep:ACL or rep:CugPolicy but was: {}", node.primary); state = State.ERROR; @@ -183,6 +190,17 @@ } return null; } + + T getPolicy(Class clz, Principal principal) throws RepositoryException { + if (acMgr instanceof JackrabbitAccessControlManager) { + for (AccessControlPolicy p : ((JackrabbitAccessControlManager) acMgr).getPolicies(principal)) { + if (clz.isAssignableFrom(p.getClass())) { + return (T) p; + } + } + } + return null; + } T getApplicablePolicy(Class clz) throws RepositoryException { AccessControlPolicyIterator iter = acMgr.getApplicablePolicies(accessControlledPath); @@ -195,8 +213,21 @@ // no applicable policy throw new RepositoryException("no applicable AccessControlPolicy of type "+ clz + " on " + - (accessControlledPath == null ? "'root'" : accessControlledPath)); + (accessControlledPath == null ? "'root'" : accessControlledPath)); } + + T getApplicablePolicy(Class clz, Principal principal) throws RepositoryException { + if (acMgr instanceof JackrabbitAccessControlManager) { + for (AccessControlPolicy p : ((JackrabbitAccessControlManager) acMgr).getApplicablePolicies(principal)) { + if (clz.isAssignableFrom(p.getClass())) { + return (T) p; + } + } + } + + // no applicable policy + throw new AccessControlException("no applicable AccessControlPolicy of type "+ clz + " for " + principal.getName()); + } } private final class ImportedAcList extends ImportedPolicy { @@ -236,8 +267,6 @@ @Override void apply(List paths) throws RepositoryException { - final ValueFactory valueFactory = session.getValueFactory(); - // find principals of existing ACL JackrabbitAccessControlList acl = getPolicy(JackrabbitAccessControlList.class); Set existingPrincipals = new HashSet(); @@ -257,17 +286,17 @@ acl = getApplicablePolicy(JackrabbitAccessControlList.class); } - // clear all ACEs of the package principals for merge (VLT-94), otherwise the `acl.addEntry()` below - // might just combine the privileges. - if (aclHandling == AccessControlHandling.MERGE) { - for (ACE entry : aceList) { - for (AccessControlEntry ace : acl.getAccessControlEntries()) { - if (ace.getPrincipal().getName().equals(entry.principalName)) { - acl.removeAccessControlEntry(ace); - } - } - } - } + // clear all ACEs of the package principals for merge (VLT-94), otherwise the `acl.addEntry()` below + // might just combine the privileges. + if (aclHandling == AccessControlHandling.MERGE) { + for (ACE entry : aceList) { + for (AccessControlEntry ace : acl.getAccessControlEntries()) { + if (ace.getPrincipal().getName().equals(entry.principalName)) { + acl.removeAccessControlEntry(ace); + } + } + } + } // apply ACEs of package for (ACE ace : aceList) { @@ -278,28 +307,10 @@ } Principal principal = getPrincipal(principalName); - Privilege[] privileges = new Privilege[ace.privileges.length]; - for (int i = 0; i < privileges.length; i++) { - privileges[i] = acMgr.privilegeFromName(ace.privileges[i]); - } Map svRestrictions = new HashMap(); Map mvRestrictions = new HashMap(); - for (String restName : acl.getRestrictionNames()) { - DocViewProperty restriction = ace.restrictions.get(restName); - if (restriction != null) { - Value[] values = new Value[restriction.values.length]; - int type = acl.getRestrictionType(restName); - for (int i=0; i { + + private final Principal principal; + private final List entries = new ArrayList<>(); + private PrincipalEntry currentEntry; + + private ImportedPrincipalAcList(DocViewNode node) { + String principalName = node.getValue("rep:principalName"); + Principal p = pMgr.getPrincipal(principalName); + if (p == null) { + try { + Authorizable a = session.getUserManager().getAuthorizableByPath(accessControlledPath); + if (a != null) { + p = a.getPrincipal(); + } + } catch (RepositoryException e) { + log.debug("Error while trying to retrieve user/group from access controlled path {}, {}", accessControlledPath, e.getMessage()); + } + if (p == null) { + p = getPrincipal(principalName); + } + } + principal = p; + } + + @Override + State append(State state, DocViewNode childNode) { + if (state == State.ACL) { + if (!"rep:PrincipalEntry".equals(childNode.primary)) { + log.error("Unexpected node type of access control entry: {}", childNode.primary); + return State.ERROR; + } + currentEntry = new PrincipalEntry(childNode); + entries.add(currentEntry); + return State.ACE; + } else if (state == State.ACE) { + currentEntry.addRestrictions(childNode); + return State.RESTRICTION; + } else { + log.error("Error while reading access control content: Unexpected node: {} for state {}", childNode.primary, state); + return State.ERROR; + } + } + + @Override + void endNode(State state) { + if (state == State.ACE) { + currentEntry = null; + } + } + + @Override + void apply(List paths) throws RepositoryException { + if (aclHandling == AccessControlHandling.MERGE_PRESERVE) { + log.debug("MERGE_PRESERVE for principal-based access control list is equivalent to IGNORE."); + return; + } + + PrincipalAccessControlList acl = getPolicy(PrincipalAccessControlList.class, principal); + if (acl != null && aclHandling == AccessControlHandling.OVERWRITE) { + // remove existing policy for 'OVERWRITE' + acMgr.removePolicy(acl.getPath(), acl); + acl = null; + } - private final boolean allow; - private final String principalName; + if (acl == null) { + acl = getApplicablePolicy(PrincipalAccessControlList.class, principal); + } + + // apply ACEs of package for MERGE and OVERWRITE + for (PrincipalEntry entry : entries) { + Map svRestrictions = new HashMap<>(); + Map mvRestrictions = new HashMap(); + entry.convertRestrictions(acl, session.getValueFactory(), svRestrictions, mvRestrictions); + acl.addEntry(entry.effectivePath, entry.getPrivileges(acMgr), svRestrictions, mvRestrictions); + } + acMgr.setPolicy(acl.getPath(), acl); + + if (accessControlledPath == null) { + addPathIfExists(paths, "/rep:repoPolicy"); + } else if ("/".equals(accessControlledPath)) { + addPathIfExists(paths, "/rep:policy"); + } else { + addPathIfExists(paths, accessControlledPath + "/rep:policy"); + } + } + } + + private static class AbstractEntry { + private final String[] privileges; private final Map restrictions = new HashMap(); + private AbstractEntry(DocViewNode node) { + privileges = node.getValues("rep:privileges"); + addRestrictions(node); + } + + void addRestrictions(DocViewNode node) { + restrictions.putAll(node.props); + } + + void convertRestrictions(JackrabbitAccessControlList acl, ValueFactory vf, Map svRestrictions, Map mvRestrictions) throws RepositoryException { + for (String restName : acl.getRestrictionNames()) { + DocViewProperty restriction = restrictions.get(restName); + if (restriction != null) { + Value[] values = new Value[restriction.values.length]; + int type = acl.getRestrictionType(restName); + for (int i=0; iUTF-8 =================================================================== --- vault-core/src/main/java/org/apache/jackrabbit/vault/fs/spi/impl/jcr20/JcrACLManagement.java (revision 1863941) +++ vault-core/src/main/java/org/apache/jackrabbit/vault/fs/spi/impl/jcr20/JcrACLManagement.java (date 1563267748000) @@ -33,7 +33,7 @@ * {@inheritDoc} */ public boolean isACLNodeType(String name) { - return name.equals("rep:ACL") || name.equals("rep:CugPolicy"); + return name.equals("rep:ACL") || name.equals("rep:CugPolicy") || name.equals("rep:PrincipalPolicy"); } /** @@ -42,7 +42,8 @@ public boolean isAccessControllableMixin(String name) { return name.equals("rep:AccessControllable") || name.equals("rep:RepoAccessControllable") - || name.equals("rep:CugMixin"); + || name.equals("rep:CugMixin") + || name.equals("rep:PrincipalBasedMixin"); } /** @@ -70,6 +71,11 @@ if (!node.isNodeType("rep:CugMixin")) { node.addMixin("rep:CugMixin"); modified = true; + } + } else if ("rep:PrincipalPolicy".equals(policyPrimaryType)) { + if (!node.isNodeType("rep:PrincipalBasedMixin")) { + node.addMixin("rep:PrincipalBasedMixin"); + modified = true; } } return modified; Index: vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/integration/PrincipalBasedTest.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/integration/PrincipalBasedTest.java (date 1564407363000) +++ vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/integration/PrincipalBasedTest.java (date 1564407363000) @@ -0,0 +1,350 @@ +/* + * 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.vault.packaging.integration; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; +import org.apache.jackrabbit.JcrConstants; +import org.apache.jackrabbit.api.JackrabbitSession; +import org.apache.jackrabbit.api.security.JackrabbitAccessControlManager; +import org.apache.jackrabbit.api.security.authorization.PrincipalAccessControlList; +import org.apache.jackrabbit.api.security.user.User; +import org.apache.jackrabbit.api.security.user.UserManager; +import org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils; +import org.apache.jackrabbit.oak.commons.PathUtils; +import org.apache.jackrabbit.oak.jcr.Jcr; +import org.apache.jackrabbit.oak.security.internal.SecurityProviderHelper; +import org.apache.jackrabbit.oak.spi.mount.Mounts; +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.AccessControlConstants; +import org.apache.jackrabbit.oak.spi.security.authorization.principalbased.FilterProvider; +import org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.FilterProviderImpl; +import org.apache.jackrabbit.oak.spi.security.authorization.principalbased.impl.PrincipalBasedAuthorizationConfiguration; +import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants; +import org.apache.jackrabbit.oak.spi.security.user.UserConfiguration; +import org.apache.jackrabbit.oak.spi.security.user.UserConstants; +import org.apache.jackrabbit.vault.fs.api.ImportMode; +import org.apache.jackrabbit.vault.fs.io.AccessControlHandling; +import org.apache.jackrabbit.vault.fs.io.ImportOptions; +import org.apache.sling.testing.mock.osgi.junit.OsgiContext; +import org.jetbrains.annotations.NotNull; +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Ignore; +import org.junit.Test; + +import javax.jcr.PropertyType; +import javax.jcr.RepositoryException; +import javax.jcr.Value; +import javax.jcr.ValueFactory; +import javax.jcr.security.AccessControlEntry; +import javax.jcr.security.AccessControlPolicy; +import javax.jcr.security.Privilege; +import java.security.Principal; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.junit.Assume.assumeTrue; + +public class PrincipalBasedTest extends IntegrationTestBase { + + private static final String INTERMEDIATE_PATH = "intermediate"; + private static final String EFFECTIVE_PATH = "/testroot/secured"; + private static final String SYSTEM_USER_ID = "testSystemUser"; + private static String SERVICE_USER_PATH; + static { + String usersPath = getSecurityConfigurationParameters().getConfigValue(UserConfiguration.NAME, ConfigurationParameters.EMPTY).getConfigValue(UserConstants.PARAM_USER_PATH, UserConstants.DEFAULT_USER_PATH); + SERVICE_USER_PATH = PathUtils.concat(usersPath, UserConstants.DEFAULT_SYSTEM_RELATIVE_PATH, INTERMEDIATE_PATH); + } + @ClassRule + public static final OsgiContext context = new OsgiContext(); + + private UserManager userManager; + private User testUser; + + private JackrabbitAccessControlManager acMgr; + private AccessControlEntry[] existingEntries; + private AccessControlEntry[] packageEntries; + + @Override + @Before + public void setUp() throws Exception { + super.setUp(); + + userManager = ((JackrabbitSession) admin).getUserManager(); + testUser = userManager.createSystemUser(SYSTEM_USER_ID, SERVICE_USER_PATH); + admin.save(); + + ValueFactory vf = admin.getValueFactory(); + + acMgr = (JackrabbitAccessControlManager) admin.getAccessControlManager(); + for (AccessControlPolicy policy : acMgr.getApplicablePolicies(testUser.getPrincipal())) { + if (policy instanceof PrincipalAccessControlList) { + PrincipalAccessControlList pacl = (PrincipalAccessControlList) policy; + Map mvRestrictions = ImmutableMap.of(AccessControlConstants.REP_ITEM_NAMES, new Value[]{vf.createValue(JcrConstants.JCR_CONTENT, PropertyType.NAME)}); + pacl.addEntry(EFFECTIVE_PATH, AccessControlUtils.privilegesFromNames(acMgr, Privilege.JCR_READ), ImmutableMap.of(), mvRestrictions); + pacl.addEntry(null, AccessControlUtils.privilegesFromNames(acMgr, PrivilegeConstants.JCR_NAMESPACE_MANAGEMENT)); + existingEntries = pacl.getAccessControlEntries(); + acMgr.setPolicy(pacl.getPath(), pacl); + break; + } + } + admin.save(); + + User testUser2 = userManager.createSystemUser(SYSTEM_USER_ID+"_2", SERVICE_USER_PATH); + for (AccessControlPolicy policy : acMgr.getApplicablePolicies(testUser2.getPrincipal())) { + if (policy instanceof PrincipalAccessControlList) { + PrincipalAccessControlList pacl = (PrincipalAccessControlList) policy; + + pacl.addEntry(EFFECTIVE_PATH, AccessControlUtils.privilegesFromNames(acMgr, Privilege.JCR_WRITE), ImmutableMap.of("rep:glob", vf.createValue("*")), ImmutableMap.of()); + pacl.addEntry(EFFECTIVE_PATH, AccessControlUtils.privilegesFromNames(acMgr, Privilege.JCR_LOCK_MANAGEMENT), ImmutableMap.of("rep:glob", vf.createValue("*/foo")), ImmutableMap.of("rep:itemNames", new Value[] {vf.createValue("jcr:content", PropertyType.NAME), vf.createValue("jcr:data", PropertyType.NAME)})); + pacl.addEntry("/content", AccessControlUtils.privilegesFromNames(acMgr, Privilege.JCR_READ), ImmutableMap.of(), ImmutableMap.of()); + pacl.addEntry(null, AccessControlUtils.privilegesFromNames(acMgr, PrivilegeConstants.JCR_WORKSPACE_MANAGEMENT, PrivilegeConstants.JCR_NAMESPACE_MANAGEMENT)); + packageEntries = pacl.getAccessControlEntries(); + break; + } + } + admin.refresh(false); + } + + @Override + @After + public void tearDown() throws Exception { + try { + User u = userManager.getAuthorizable(SYSTEM_USER_ID, User.class); + if (u != null) { + u.remove(); + admin.save(); + } + } finally { + super.tearDown(); + shutdownRepository(); + initRepository(); + } + } + + @BeforeClass + public static void initRepository() { + repository = new Jcr() + .with(createSecurityProvider()) + .withAtomicCounter() + .createRepository(); + } + + public static SecurityProvider createSecurityProvider() { + SecurityProvider securityProvider = IntegrationTestBase.createSecurityProvider(); + + FilterProvider fp = new FilterProviderImpl(); + // trigger activate method + context.registerInjectActivateService(fp, ImmutableMap.of("path", SERVICE_USER_PATH)); + + PrincipalBasedAuthorizationConfiguration principalBasedAuthorizationConfiguration = new PrincipalBasedAuthorizationConfiguration(); + principalBasedAuthorizationConfiguration.bindFilterProvider(fp); + principalBasedAuthorizationConfiguration.bindMountInfoProvider(Mounts.defaultMountInfoProvider()); + SecurityProviderHelper.updateConfig(securityProvider, principalBasedAuthorizationConfiguration, AuthorizationConfiguration.class); + return securityProvider; + } + + private void assertPolicy(@NotNull Principal principal, @NotNull AccessControlEntry... expectedEntries) throws RepositoryException { + for (AccessControlPolicy policy : acMgr.getPolicies(principal)) { + if (policy instanceof PrincipalAccessControlList) { + PrincipalAccessControlList pacl = (PrincipalAccessControlList) policy; + AccessControlEntry[] aces = pacl.getAccessControlEntries(); + assertEquals(expectedEntries.length, aces.length); + + for (int i = 0; i < expectedEntries.length; i++) { + assertTrue(expectedEntries[i] instanceof PrincipalAccessControlList.Entry); + assertTrue(aces[i] instanceof PrincipalAccessControlList.Entry); + + + PrincipalAccessControlList.Entry entry = (PrincipalAccessControlList.Entry) aces[i]; + PrincipalAccessControlList.Entry expected = (PrincipalAccessControlList.Entry) expectedEntries[i]; + + assertEquals(expected.getEffectivePath(), entry.getEffectivePath()); + assertEquals(ImmutableSet.copyOf(expected.getPrivileges()), ImmutableSet.copyOf(entry.getPrivileges())); + assertEquals(ImmutableSet.copyOf(expected.getRestrictionNames()), ImmutableSet.copyOf(entry.getRestrictionNames())); + for (String rName : expected.getRestrictionNames()) { + if (pacl.isMultiValueRestriction(rName)) { + assertArrayEquals(expected.getRestrictions(rName), entry.getRestrictions(rName)); + } else { + assertEquals(expected.getRestriction(rName), entry.getRestriction(rName)); + } + } + } + return; + } + } + fail("expected PrincipalAccessControlList for principal " + principal.getName()); + } + + @Test + public void testHandlingIgnoreModeUpdate() throws Exception { + assumeTrue(isOak()); + ImportOptions opts = getDefaultOptions(); + opts.setAccessControlHandling(AccessControlHandling.IGNORE); + opts.setImportMode(ImportMode.UPDATE); + + extractVaultPackage("testpackages/principalbased.zip", opts); + assertPolicy(testUser.getPrincipal(), existingEntries); + } + + @Test + public void testHandlingIgnoreModeMerge() throws Exception { + assumeTrue(isOak()); + ImportOptions opts = getDefaultOptions(); + opts.setAccessControlHandling(AccessControlHandling.IGNORE); + opts.setImportMode(ImportMode.MERGE); + + extractVaultPackage("testpackages/principalbased.zip", opts); + assertPolicy(testUser.getPrincipal(), existingEntries); + } + + @Ignore("Enable once Oak 1.18.0 is released") + @Test + public void testHandlingIgnoreModeReplace() throws Exception { + assumeTrue(isOak()); + ImportOptions opts = getDefaultOptions(); + opts.setAccessControlHandling(AccessControlHandling.IGNORE); + opts.setImportMode(ImportMode.REPLACE); + + extractVaultPackage("testpackages/principalbased.zip", opts); + // user may have been moved due to 'replace' mode -> need to retrieve again + Principal p = userManager.getAuthorizable(SYSTEM_USER_ID).getPrincipal(); + assertEquals(0, acMgr.getPolicies(p).length); + } + + @Test + public void testHandlingOverwriteModeUpdate() throws Exception { + assumeTrue(isOak()); + ImportOptions opts = getDefaultOptions(); + opts.setAccessControlHandling(AccessControlHandling.OVERWRITE); + opts.setImportMode(ImportMode.UPDATE); + + extractVaultPackage("testpackages/principalbased.zip"); + assertPolicy(testUser.getPrincipal(), packageEntries); + } + + @Test + public void testHandlingOverwriteModeMerge() throws Exception { + assumeTrue(isOak()); + ImportOptions opts = getDefaultOptions(); + opts.setAccessControlHandling(AccessControlHandling.OVERWRITE); + opts.setImportMode(ImportMode.MERGE); + + extractVaultPackage("testpackages/principalbased.zip"); + assertPolicy(testUser.getPrincipal(), packageEntries); + } + + @Test + public void testHandlingOverwriteModeReplace() throws Exception { + assumeTrue(isOak()); + ImportOptions opts = getDefaultOptions(); + opts.setAccessControlHandling(AccessControlHandling.OVERWRITE); + opts.setImportMode(ImportMode.REPLACE); + + extractVaultPackage("testpackages/principalbased.zip"); + assertPolicy(testUser.getPrincipal(), packageEntries); + } + + @Test + public void testHandlingMergeModeUpdate() throws Exception { + assumeTrue(isOak()); + ImportOptions opts = getDefaultOptions(); + opts.setAccessControlHandling(AccessControlHandling.MERGE); + opts.setImportMode(ImportMode.UPDATE); + + extractVaultPackage("testpackages/principalbased.zip", opts); + + List expected = Lists.newArrayList(existingEntries); + expected.addAll(ImmutableList.copyOf(packageEntries)); + assertPolicy(testUser.getPrincipal(), expected.toArray(new AccessControlEntry[0])); + } + + @Test + public void testHandlingMergeModeMerge() throws Exception { + assumeTrue(isOak()); + ImportOptions opts = getDefaultOptions(); + opts.setAccessControlHandling(AccessControlHandling.MERGE); + opts.setImportMode(ImportMode.MERGE); + + extractVaultPackage("testpackages/principalbased.zip", opts); + + List expected = Lists.newArrayList(existingEntries); + expected.addAll(ImmutableList.copyOf(packageEntries)); + assertPolicy(testUser.getPrincipal(), expected.toArray(new AccessControlEntry[0])); + } + + @Ignore("Enable once Oak 1.18.0 is released") + @Test + public void testHandlingMergeModeReplace() throws Exception { + assumeTrue(isOak()); + ImportOptions opts = getDefaultOptions(); + opts.setAccessControlHandling(AccessControlHandling.MERGE); + opts.setImportMode(ImportMode.REPLACE); + + extractVaultPackage("testpackages/principalbased.zip", opts); + + // user may have been moved due to 'replace' mode -> need to retrieve again + assertPolicy(userManager.getAuthorizable(SYSTEM_USER_ID).getPrincipal(), packageEntries); + } + + @Test + public void testHandlingMergePreserveModeUpdate() throws Exception { + assumeTrue(isOak()); + ImportOptions opts = getDefaultOptions(); + opts.setAccessControlHandling(AccessControlHandling.MERGE_PRESERVE); + opts.setImportMode(ImportMode.UPDATE); + + extractVaultPackage("testpackages/principalbased.zip", opts); + assertPolicy(testUser.getPrincipal(), existingEntries); + } + + @Test + public void testHandlingMergePreserveModeMerge() throws Exception { + assumeTrue(isOak()); + ImportOptions opts = getDefaultOptions(); + opts.setAccessControlHandling(AccessControlHandling.MERGE_PRESERVE); + opts.setImportMode(ImportMode.MERGE); + + extractVaultPackage("testpackages/principalbased.zip", opts); + assertPolicy(testUser.getPrincipal(), existingEntries); + } + + @Ignore("Enable once Oak 1.18.0 is released") + @Test + public void testHandlingMergePreserveModeReplace() throws Exception { + assumeTrue(isOak()); + ImportOptions opts = getDefaultOptions(); + opts.setAccessControlHandling(AccessControlHandling.MERGE_PRESERVE); + opts.setImportMode(ImportMode.REPLACE); + + extractVaultPackage("testpackages/principalbased.zip", opts); + // user may have been moved due to 'replace' mode -> need to retrieve again + Principal p = userManager.getAuthorizable(SYSTEM_USER_ID).getPrincipal(); + assertEquals(0, acMgr.getPolicies(p).length); + } +} \ No newline at end of file Index: vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/jcr_root/.content.xml IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/jcr_root/.content.xml (date 1563870020000) +++ vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/jcr_root/.content.xml (date 1563870020000) @@ -0,0 +1,6 @@ + + Index: vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/jcr_root/home/.content.xml IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/jcr_root/home/.content.xml (date 1563870020000) +++ vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/jcr_root/home/.content.xml (date 1563870020000) @@ -0,0 +1,4 @@ + + Index: vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/jcr_root/home/users/.content.xml IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/jcr_root/home/users/.content.xml (date 1563870020000) +++ vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/jcr_root/home/users/.content.xml (date 1563870020000) @@ -0,0 +1,4 @@ + + Index: vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/jcr_root/home/users/system/.content.xml IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/jcr_root/home/users/system/.content.xml (date 1563870020000) +++ vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/jcr_root/home/users/system/.content.xml (date 1563870020000) @@ -0,0 +1,4 @@ + + Index: vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/jcr_root/home/users/system/intermediate/.content.xml IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/jcr_root/home/users/system/intermediate/.content.xml (date 1563870020000) +++ vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/jcr_root/home/users/system/intermediate/.content.xml (date 1563870020000) @@ -0,0 +1,3 @@ + + Index: vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/jcr_root/home/users/system/intermediate/tBUjdNwIM-i9bTqCYP5D/.content.xml IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/jcr_root/home/users/system/intermediate/tBUjdNwIM-i9bTqCYP5D/.content.xml (date 1563959464000) +++ vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/jcr_root/home/users/system/intermediate/tBUjdNwIM-i9bTqCYP5D/.content.xml (date 1563959464000) @@ -0,0 +1,7 @@ + + Index: vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/jcr_root/home/users/system/intermediate/tBUjdNwIM-i9bTqCYP5D/_rep_principalPolicy.xml IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/jcr_root/home/users/system/intermediate/tBUjdNwIM-i9bTqCYP5D/_rep_principalPolicy.xml (date 1563958103000) +++ vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/jcr_root/home/users/system/intermediate/tBUjdNwIM-i9bTqCYP5D/_rep_principalPolicy.xml (date 1563958103000) @@ -0,0 +1,44 @@ + + + + + + + + + + + Index: vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/META-INF/MANIFEST.MF IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/META-INF/MANIFEST.MF (date 1563870020000) +++ vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/META-INF/MANIFEST.MF (date 1563870020000) @@ -0,0 +1,5 @@ +Manifest-Version: 1.0 +Content-Package-Roots: /home/users/system/intermediate +Content-Package-Type: content +Content-Package-Id: my_packages:testsystemuser + Index: vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/META-INF/vault/config.xml IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/META-INF/vault/config.xml (date 1563870020000) +++ vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/META-INF/vault/config.xml (date 1563870020000) @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Index: vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/META-INF/vault/definition/.content.xml IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/META-INF/vault/definition/.content.xml (date 1563958824000) +++ vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/META-INF/vault/definition/.content.xml (date 1563958824000) @@ -0,0 +1,32 @@ + + + + + + + Index: vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/META-INF/vault/filter.xml IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/META-INF/vault/filter.xml (date 1563957273000) +++ vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/META-INF/vault/filter.xml (date 1563957273000) @@ -0,0 +1,4 @@ + + + + Index: vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/META-INF/vault/nodetypes.cnd IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/META-INF/vault/nodetypes.cnd (date 1563870020000) +++ vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/META-INF/vault/nodetypes.cnd (date 1563870020000) @@ -0,0 +1,10 @@ +<'rep'='internal'> + +[rep:Password] + - * (undefined) protected + - * (undefined) protected multiple + +[rep:RepoAccessControllable] + mixin + + rep:repoPolicy (rep:Policy) protected ignore + Index: vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/META-INF/vault/properties.xml IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/META-INF/vault/properties.xml (date 1563958824000) +++ vault-core/src/test/resources/org/apache/jackrabbit/vault/packaging/integration/testpackages/principalbased.zip/META-INF/vault/properties.xml (date 1563958824000) @@ -0,0 +1,20 @@ + + + +FileVault Package Properties +admin +principalbased_overwrite +2019-07-23T10:20:20.089+02:00 +admin +2019-07-23T10:20:20.170+02:00 +1 + +content + +2 + +2019-07-23T10:20:20.089+02:00 +integrationtesting +admin +OVERWRITE + Index: vault-core/pom.xml IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- vault-core/pom.xml (revision 1863941) +++ vault-core/pom.xml (date 1563440369000) @@ -223,6 +223,12 @@ test + org.apache.sling + org.apache.sling.testing.osgi-mock + 2.3.10 + test + + org.apache.jackrabbit jackrabbit-core ${jackrabbit.version} @@ -232,6 +238,13 @@ org.apache.jackrabbit oak-core ${oak.version} + test + + + org.apache.jackrabbit + oak-core + ${oak.version} + tests test @@ -243,6 +256,12 @@ org.apache.jackrabbit oak-segment-tar + ${oak.version} + test + + + org.apache.jackrabbit + oak-authorization-principalbased ${oak.version} test