Index: oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImpl.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImpl.java (revision 1853083) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImpl.java (date 1549469176000) @@ -42,6 +42,7 @@ import com.google.common.base.Function; import com.google.common.base.Objects; import com.google.common.base.Predicate; +import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; @@ -593,7 +594,7 @@ if (v == null) { throw new AccessControlException("Missing mandatory restriction rep:nodePath"); } else { - return getOakPath(v.getString()); + return getOakPath(Strings.emptyToNull(v.getString())); } } Index: oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/PrincipalRestrictionProvider.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/PrincipalRestrictionProvider.java (revision 1853083) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/restriction/PrincipalRestrictionProvider.java (date 1549532381000) @@ -18,7 +18,6 @@ import java.util.HashSet; import java.util.Set; -import javax.jcr.PropertyType; import javax.jcr.RepositoryException; import javax.jcr.Value; @@ -63,8 +62,14 @@ @NotNull @Override public Restriction createRestriction(@Nullable String oakPath, @NotNull String oakName, @NotNull Value value) throws RepositoryException { - if (REP_NODE_PATH.equals(oakName) && PropertyType.PATH == value.getType()) { - return new RestrictionImpl(PropertyStates.createProperty(oakName, value), true); + if (REP_NODE_PATH.equals(oakName)) { + PropertyState property; + if (value.getString().isEmpty()) { + property = PropertyStates.createProperty(oakName, "", Type.STRING); + } else { + property = PropertyStates.createProperty(oakName, value); + } + return new RestrictionImpl(property, true); } else { return base.createRestriction(oakPath, oakName, value); } @@ -80,9 +85,13 @@ @Override public Set readRestrictions(@Nullable String oakPath, @NotNull Tree aceTree) { Set restrictions = new HashSet<>(base.readRestrictions(oakPath, aceTree)); - String value = (oakPath == null) ? "" : oakPath; - PropertyState nodePathProp = PropertyStates.createProperty(REP_NODE_PATH, value, Type.PATH); - restrictions.add(new RestrictionImpl(nodePathProp, true)); + PropertyState property; + if (oakPath == null) { + property = PropertyStates.createProperty(REP_NODE_PATH, "", Type.STRING); + } else { + property = PropertyStates.createProperty(REP_NODE_PATH, oakPath, Type.PATH); + } + restrictions.add(new RestrictionImpl(property, true)); return restrictions; } Index: oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImplTest.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImplTest.java (revision 1853083) +++ oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImplTest.java (date 1549473720000) @@ -161,6 +161,11 @@ return npMapper; } + private NamePathMapper getNamePathMapperWithLocalRemapping() { + NameMapper remapped = new LocalNameMapper(root, singletonMap(TEST_LOCAL_PREFIX, TEST_URI)); + return new NamePathMapperImpl(remapped); + } + private void registerNamespace(String prefix, String uri) throws Exception { NamespaceRegistry nsRegistry = new ReadWriteNamespaceRegistry(root) { @Override @@ -343,14 +348,11 @@ public void testGetSupportedPrivilegesIncludingPathConversion() throws Exception { List allPrivileges = Arrays.asList(getPrivilegeManager(root).getRegisteredPrivileges()); - List testPaths = new ArrayList(); + List testPaths = new ArrayList<>(); testPaths.add('/' + TEST_LOCAL_PREFIX + ":testRoot"); testPaths.add("/{" + TEST_URI + "}testRoot"); - NameMapper remapped = new LocalNameMapper( - root, singletonMap(TEST_LOCAL_PREFIX, TEST_URI)); - - AccessControlManager acMgr = createAccessControlManager(root, new NamePathMapperImpl(remapped)); + AccessControlManager acMgr = createAccessControlManager(root, getNamePathMapperWithLocalRemapping()); for (String path : testPaths) { Privilege[] supported = acMgr.getSupportedPrivileges(path); @@ -377,8 +379,7 @@ @Test public void testPrivilegeFromName() throws Exception { - List allPrivileges = Arrays.asList(getPrivilegeManager(root).getRegisteredPrivileges()); - for (Privilege privilege : allPrivileges) { + for (Privilege privilege : getPrivilegeManager(root).getRegisteredPrivileges()) { Privilege p = acMgr.privilegeFromName(privilege.getName()); assertEquals(privilege, p); } @@ -1860,6 +1861,41 @@ assertEquals(1, policies.length); } + @Test + public void testGetPoliciesByPrincipalRemapped() throws Exception { + setupPolicy(testPath); + root.commit(); + + NamePathMapper mapper = getNamePathMapperWithLocalRemapping(); + AccessControlPolicy[] policies = createAccessControlManager(root, mapper).getPolicies(testPrincipal); + assertNotNull(policies); + assertEquals(1, policies.length); + + List entries = ((ACL) policies[0]).getEntries(); + assertEquals(mapper.getJcrPath(testPath), entries.get(0).getRestriction(REP_NODE_PATH).getString()); + } + + @Test + public void testGetPoliciesByPrincipalRepositoryLevel() throws Exception { + setupPolicy(null, privilegesFromNames(PrivilegeConstants.JCR_NODE_TYPE_DEFINITION_MANAGEMENT)); + + // changes not yet persisted -> no existing policies found for user + AccessControlPolicy[] policies = acMgr.getPolicies(testPrincipal); + assertNotNull(policies); + assertEquals(0, policies.length); + + // after persisting changes -> policies must be found + root.commit(); + policies = acMgr.getPolicies(testPrincipal); + assertNotNull(policies); + assertEquals(1, policies.length); + JackrabbitAccessControlList acl = (JackrabbitAccessControlList) policies[0]; + AccessControlEntry[] entries = acl.getAccessControlEntries(); + assertEquals(1, entries.length); + JackrabbitAccessControlEntry entry = (JackrabbitAccessControlEntry) entries[0]; + assertTrue(entry.getRestriction(REP_NODE_PATH).getString().isEmpty()); + } + @Test public void testTestSessionGetPolicies() throws Exception { setupPolicy(testPath); @@ -2255,6 +2291,56 @@ assertEquals(2, ((ACL) acMgr.getPolicies(testPath)[0]).getAccessControlEntries().length); } + @Test + public void testSetPrincipalPolicyRemapped() throws Exception { + setupPolicy(testPath); + root.commit(); + + NamePathMapper mapper = getNamePathMapperWithLocalRemapping(); + JackrabbitAccessControlManager remappedAcMgr = createAccessControlManager(root, mapper); + JackrabbitAccessControlPolicy[] policies = remappedAcMgr.getPolicies(testPrincipal); + assertNotNull(policies); + assertEquals(1, policies.length); + + ACL acl = (ACL) policies[0]; + Value pathValue = new ValueFactoryImpl(root, mapper).createValue(mapper.getJcrPath(testPath), PropertyType.PATH); + assertTrue(acl.addEntry(testPrincipal, testPrivileges, true, Collections.singletonMap(REP_NODE_PATH, pathValue))); + remappedAcMgr.setPolicy(acl.getPath(), acl); + root.commit(); + + AccessControlPolicy[] acps = remappedAcMgr.getPolicies(mapper.getJcrPath(testPath)); + assertEquals(1, acps.length); + assertEquals(2, ((ACL) acps[0]).getAccessControlEntries().length); + + acps = acMgr.getPolicies(testPath); + assertEquals(1, acps.length); + assertEquals(2, ((ACL) acps[0]).getAccessControlEntries().length); + } + + @Test + public void testSetPrincipalPolicyForRepositoryLevel() throws Exception { + assertEquals(0, acMgr.getPolicies((String)null).length); + + JackrabbitAccessControlPolicy[] policies = acMgr.getApplicablePolicies(testPrincipal); + ACL acl = (ACL) policies[0]; + + Map restrictions = new HashMap(); + restrictions.put(REP_NODE_PATH, getValueFactory().createValue("", PropertyType.STRING)); + Privilege[] privs = privilegesFromNames(PrivilegeConstants.JCR_NAMESPACE_MANAGEMENT); + assertTrue(acl.addEntry(testPrincipal, privs, true, restrictions)); + + acMgr.setPolicy(acl.getPath(), acl); + + AccessControlPolicy[] repoLevelPolicies = acMgr.getPolicies((String)null); + assertEquals(1, repoLevelPolicies.length); + + AccessControlEntry[] entries = ((JackrabbitAccessControlList) repoLevelPolicies[0]).getAccessControlEntries(); + assertEquals(1, entries.length); + + assertArrayEquals(privs, entries[0].getPrivileges()); + assertEquals(testPrincipal, entries[0].getPrincipal()); + } + @Test public void testSetPrincipalPolicyWithNewMvRestriction() throws Exception { setupPolicy(testPath); @@ -2371,6 +2457,39 @@ acMgr.removePolicy(acl.getPath(), acl); } + + @Test + public void testRemovePoliciesByPrincipalRemapped() throws Exception { + setupPolicy(testPath); + root.commit(); + + NamePathMapper mapper = getNamePathMapperWithLocalRemapping(); + JackrabbitAccessControlManager remappedAcMgr = createAccessControlManager(root, mapper); + JackrabbitAccessControlPolicy[] policies = remappedAcMgr.getPolicies(testPrincipal); + assertNotNull(policies); + assertEquals(1, policies.length); + + remappedAcMgr.removePolicy(policies[0].getPath(), policies[0]); + root.commit(); + + assertEquals(0, acMgr.getPolicies(testPath).length); + } + + @Test + public void testRemovePrincipalPolicyForRepositoryLevel() throws Exception { + setupPolicy(null, privilegesFromNames(PrivilegeConstants.JCR_NAMESPACE_MANAGEMENT)); + root.commit(); + + JackrabbitAccessControlPolicy[] policies = acMgr.getPolicies(testPrincipal); + assertEquals(1, policies.length); + + acMgr.removePolicy(policies[0].getPath(), policies[0]); + root.commit(); + + AccessControlPolicy[] repoLevelPolicies = acMgr.getPolicies((String)null); + assertEquals(0, repoLevelPolicies.length); + } + private final static class TestACL extends AbstractAccessControlList { private final List entries = new ArrayList();