Index: oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/ACL.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/ACL.java (revision 1850855) +++ oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/ACL.java (date 1547135648000) @@ -100,9 +100,17 @@ } for (RestrictionDefinition def : getRestrictionProvider().getSupportedRestrictions(getOakPath())) { - String jcrName = getNamePathMapper().getJcrName(def.getName()); - if (def.isMandatory() && (restrictions == null || !restrictions.containsKey(jcrName))) { - throw new AccessControlException("Mandatory restriction " + jcrName + " is missing."); + if (def.isMandatory()) { + String jcrName = getNamePathMapper().getJcrName(def.getName()); + boolean mandatoryPresent = false; + if (def.getRequiredType().isArray()) { + mandatoryPresent = (mvRestrictions != null && mvRestrictions.containsKey(jcrName)); + } else { + mandatoryPresent = (restrictions != null && restrictions.containsKey(jcrName)); + } + if (!mandatoryPresent) { + throw new AccessControlException("Mandatory restriction " + jcrName + " is missing."); + } } } Index: oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/ACLTest.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/ACLTest.java (revision 1850855) +++ oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/ACLTest.java (date 1547135066000) @@ -830,18 +830,53 @@ } } + @Test(expected = AccessControlException.class) + public void testMandatoryRestrictions() throws Exception { + RestrictionProvider rp = new TestRestrictionProvider("mandatory", Type.NAME, true); + + JackrabbitAccessControlList acl = createACL(TEST_PATH, new ArrayList(), namePathMapper, rp); + acl.addEntry(testPrincipal, testPrivileges, false, Collections.emptyMap(), Collections.emptyMap()); + } + @Test - public void testMandatoryRestrictions() throws Exception { + public void testMandatoryRestrictionsPresent() throws Exception { + RestrictionProvider rp = new TestRestrictionProvider("mandatory", Type.NAME, true); + + JackrabbitAccessControlList acl = createACL(TEST_PATH, new ArrayList(), namePathMapper, rp); + acl.addEntry(testPrincipal, testPrivileges, false, Collections.singletonMap("mandatory", valueFactory.createValue("name", PropertyType.NAME)), Collections.emptyMap()); + } + + @Test(expected = AccessControlException.class) + public void testMandatoryRestrictionsPresentAsMV() throws Exception { RestrictionProvider rp = new TestRestrictionProvider("mandatory", Type.NAME, true); JackrabbitAccessControlList acl = createACL(TEST_PATH, new ArrayList(), namePathMapper, rp); - try { - acl.addEntry(testPrincipal, testPrivileges, false, Collections.emptyMap()); - fail("Mandatory restriction must be enforced."); - } catch (AccessControlException e) { - // mandatory restriction missing -> success - } + acl.addEntry(testPrincipal, testPrivileges, false, Collections.emptyMap(), Collections.singletonMap("mandatory", new Value[] {valueFactory.createValue("name", PropertyType.NAME)})); + } + + @Test(expected = AccessControlException.class) + public void testMandatoryMVRestrictions() throws Exception { + RestrictionProvider rp = new TestRestrictionProvider("mandatory", Type.NAMES, true); + + JackrabbitAccessControlList acl = createACL(TEST_PATH, new ArrayList(), namePathMapper, rp); + acl.addEntry(testPrincipal, testPrivileges, false, Collections.emptyMap(), Collections.emptyMap()); } + + @Test(expected = AccessControlException.class) + public void testMandatoryMVRestrictionsPresentAsSingle() throws Exception { + RestrictionProvider rp = new TestRestrictionProvider("mandatory", Type.NAMES, true); + + JackrabbitAccessControlList acl = createACL(TEST_PATH, new ArrayList(), namePathMapper, rp); + acl.addEntry(testPrincipal, testPrivileges, false, Collections.singletonMap("mandatory", valueFactory.createValue("name", PropertyType.NAME)), Collections.emptyMap()); + } + + @Test + public void testMandatoryMVRestrictionsPresent() throws Exception { + RestrictionProvider rp = new TestRestrictionProvider("mandatory", Type.NAMES, true); + + JackrabbitAccessControlList acl = createACL(TEST_PATH, new ArrayList(), namePathMapper, rp); + acl.addEntry(testPrincipal, testPrivileges, false, Collections.emptyMap(), Collections.singletonMap("mandatory", new Value[] {valueFactory.createValue("name", PropertyType.NAME)})); + } //--------------------------------------------------------------------------