Author: angela
Date: Wed Aug  7 14:54:16 2013
New Revision: 1511344

URL: http://svn.apache.org/r1511344
Log:
OAK-51 : Access Control Management (preparation for JCR-3637 and restriction 
related test cases)

Modified:
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/AbstractRestrictionProvider.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/ACLTest.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ACETest.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/AbstractRestrictionProviderTest.java

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/AbstractRestrictionProvider.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/AbstractRestrictionProvider.java?rev=1511344&r1=1511343&r2=1511344&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/AbstractRestrictionProvider.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/AbstractRestrictionProvider.java
 Wed Aug  7 14:54:16 2013
@@ -16,12 +16,14 @@
  */
 package org.apache.jackrabbit.oak.spi.security.authorization.restriction;
 
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 import javax.jcr.AccessDeniedException;
 import javax.jcr.NamespaceRegistry;
 import javax.jcr.PropertyType;
@@ -61,13 +63,7 @@ public abstract class AbstractRestrictio
 
     @Override
     public Restriction createRestriction(String oakPath, String oakName, Value 
value) throws RepositoryException {
-        if (isUnsupportedPath(oakPath)) {
-            throw new AccessControlException("Unsupported restriction at " + 
oakPath);
-        }
-        RestrictionDefinition definition = supported.get(oakName);
-        if (definition == null) {
-            throw new AccessControlException("Unsupported restriction: " + 
oakName);
-        }
+        RestrictionDefinition definition = getDefinition(oakPath, oakName);
         Type<?> requiredType = definition.getRequiredType();
         int tag = requiredType.tag();
         if (tag != PropertyType.UNDEFINED && tag != value.getType()) {
@@ -84,13 +80,7 @@ public abstract class AbstractRestrictio
 
     @Override
     public Restriction createRestriction(String oakPath, String oakName, 
Value... values) throws RepositoryException {
-        if (isUnsupportedPath(oakPath)) {
-            throw new AccessControlException("Unsupported restriction at " + 
oakPath);
-        }
-        RestrictionDefinition definition = supported.get(oakName);
-        if (definition == null) {
-            throw new AccessControlException("Unsupported restriction: " + 
oakName);
-        }
+        RestrictionDefinition definition = getDefinition(oakPath, oakName);
         Type<?> requiredType = definition.getRequiredType();
         for (Value v : values) {
             if (requiredType.tag() != PropertyType.UNDEFINED && 
requiredType.tag() != v.getType()) {
@@ -100,7 +90,7 @@ public abstract class AbstractRestrictio
 
         PropertyState propertyState;
         if (requiredType.isArray()) {
-            propertyState = PropertyStates.createProperty(oakName, 
ImmutableList.of(values));
+            propertyState = PropertyStates.createProperty(oakName, 
Arrays.asList(values), requiredType.tag());
         } else {
             if (values.length != 1) {
                 throw new AccessControlException("Unsupported restriction: 
Expected single value.");
@@ -145,29 +135,46 @@ public abstract class AbstractRestrictio
     @Override
     public void validateRestrictions(String oakPath, Tree aceTree) throws 
AccessControlException {
         Map<String, PropertyState> restrictionProperties = 
getRestrictionProperties(aceTree);
-        if (isUnsupportedPath(oakPath) && !restrictionProperties.isEmpty()) {
-            throw new AccessControlException("Restrictions not supported with 
'null' path.");
-        }
-        for (Map.Entry<String, PropertyState> entry : 
restrictionProperties.entrySet()) {
-            String restrName = entry.getKey();
-            RestrictionDefinition def = supported.get(restrName);
-            if (def == null) {
-                throw new AccessControlException("Unsupported restriction: " + 
restrName);
-            }
-            Type<?> type = entry.getValue().getType();
-            if (type != def.getRequiredType()) {
-                throw new AccessControlException("Invalid restriction type '" 
+ type + "'. Expected " + def.getRequiredType());
-            }
-        }
-        for (RestrictionDefinition def : supported.values()) {
-            if (def.isMandatory() && 
!restrictionProperties.containsKey(def.getName())) {
-                throw new AccessControlException("Mandatory restriction " + 
def.getName() + " is missing.");
+        if (isUnsupportedPath(oakPath)) {
+            if (!restrictionProperties.isEmpty()) {
+                throw new AccessControlException("Restrictions not supported 
with 'null' path.");
+            }
+        } else {
+            // supported path -> validate restrictions and test if mandatory
+            // restrictions are present.
+            for (Map.Entry<String, PropertyState> entry : 
restrictionProperties.entrySet()) {
+                String restrName = entry.getKey();
+                RestrictionDefinition def = supported.get(restrName);
+                if (def == null) {
+                    throw new AccessControlException("Unsupported restriction: 
" + restrName);
+                }
+                Type<?> type = entry.getValue().getType();
+                if (type != def.getRequiredType()) {
+                    throw new AccessControlException("Invalid restriction type 
'" + type + "'. Expected " + def.getRequiredType());
+                }
+            }
+            for (RestrictionDefinition def : supported.values()) {
+                if (def.isMandatory() && 
!restrictionProperties.containsKey(def.getName())) {
+                    throw new AccessControlException("Mandatory restriction " 
+ def.getName() + " is missing.");
+                }
             }
         }
     }
 
     //------------------------------------------------------------< private 
>---
     @Nonnull
+    private RestrictionDefinition getDefinition(@Nullable String oakPath, 
@Nonnull String oakName) throws AccessControlException {
+        if (isUnsupportedPath(oakPath)) {
+            throw new AccessControlException("Unsupported restriction at " + 
oakPath);
+        }
+        RestrictionDefinition definition = supported.get(oakName);
+        if (definition == null) {
+            throw new AccessControlException("Unsupported restriction: " + 
oakName);
+        }
+        return definition;
+    }
+
+    @Nonnull
     private Restriction createRestriction(PropertyState propertyState, 
RestrictionDefinition definition) {
         return new RestrictionImpl(propertyState, definition.isMandatory());
     }

Modified: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/ACLTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/ACLTest.java?rev=1511344&r1=1511343&r2=1511344&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/ACLTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/ACLTest.java
 Wed Aug  7 14:54:16 2013
@@ -211,6 +211,10 @@ public class ACLTest extends AbstractAcc
                     return null;
                 }
 
+                public Value[] getRestrictions(String restrictionName) {
+                    return null;
+                }
+
                 public Principal getPrincipal() {
                     return testPrincipal;
                 }

Modified: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ACETest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ACETest.java?rev=1511344&r1=1511343&r2=1511344&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ACETest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ACETest.java
 Wed Aug  7 14:54:16 2013
@@ -19,26 +19,36 @@ package org.apache.jackrabbit.oak.spi.se
 import java.security.Principal;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
+import javax.jcr.PropertyType;
 import javax.jcr.RepositoryException;
 import javax.jcr.Value;
+import javax.jcr.ValueFactory;
+import javax.jcr.ValueFormatException;
 import javax.jcr.security.AccessControlEntry;
 import javax.jcr.security.AccessControlException;
 import javax.jcr.security.AccessControlManager;
 import javax.jcr.security.Privilege;
 
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
 import org.apache.jackrabbit.api.security.JackrabbitAccessControlEntry;
 import 
org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils;
+import org.apache.jackrabbit.oak.plugins.value.ValueFactoryImpl;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.restriction.Restriction;
 import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
 import org.junit.Before;
 import org.junit.Test;
 
+import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
@@ -51,6 +61,10 @@ public class ACETest extends AbstractAcc
     private Principal testPrincipal;
     private AccessControlManager acMgr;
 
+    private Value globValue;
+    private Value[] nameValues;
+    private Value nameValue;
+
     @Override
     @Before
     public void before() throws Exception {
@@ -62,6 +76,13 @@ public class ACETest extends AbstractAcc
                 return "TestPrincipal";
             }
         };
+        ValueFactory valueFactory = new 
ValueFactoryImpl(root.getBlobFactory(), namePathMapper);
+        globValue = valueFactory.createValue("*");
+        nameValue = valueFactory.createValue("nt:file", PropertyType.NAME);
+        nameValues = new Value[] {
+                valueFactory.createValue("nt:folder", PropertyType.NAME),
+                valueFactory.createValue("nt:file", PropertyType.NAME)
+        };
     }
 
     private ACE createEntry(String... privilegeNames)
@@ -80,6 +101,20 @@ public class ACETest extends AbstractAcc
         return new ACE(principal, privileges, isAllow, null, namePathMapper);
     }
 
+    private ACE createEntry(Set<Restriction> restrictions) throws Exception {
+        return new ACE(testPrincipal,
+                privilegesFromNames(PrivilegeConstants.JCR_READ), true,
+                restrictions, namePathMapper);
+    }
+
+    private Restriction createRestriction(String name, Value value) throws 
Exception {
+        return getRestrictionProvider().createRestriction("/a/b/c", name, 
value);
+    }
+
+    private Restriction createRestriction(String name, Value[] values) throws 
Exception {
+        return getRestrictionProvider().createRestriction("/a/b/c", name, 
values);
+    }
+
     @Test
     public void testIsAllow() throws RepositoryException {
         ACE ace = createEntry(new String[]{PrivilegeConstants.JCR_READ}, true);
@@ -98,6 +133,19 @@ public class ACETest extends AbstractAcc
     }
 
     @Test
+    public void testNullPrincipal() throws Exception {
+        try {
+            Privilege[] privs = new Privilege[]{
+                    acMgr.privilegeFromName(PrivilegeConstants.JCR_ALL)
+            };
+            createEntry(null, privs, true);
+            fail("Principal must not be null");
+        } catch (AccessControlException e) {
+            // success
+        }
+    }
+
+    @Test
     public void testGetPrivileges() throws RepositoryException {
         ACE entry = createEntry(new String[]{PrivilegeConstants.JCR_READ}, 
true);
 
@@ -125,6 +173,196 @@ public class ACETest extends AbstractAcc
     }
 
     @Test
+    public void testNullPrivileges() throws Exception {
+        try {
+            createEntry(testPrincipal, null, true);
+            fail("Principal must not be null");
+        } catch (AccessControlException e) {
+            // success
+        }
+    }
+
+    @Test
+    public void testEmptyPrivileges() throws Exception {
+        try {
+            createEntry(testPrincipal, new Privilege[0], true);
+            fail("Privilege array must not be null.");
+        } catch (AccessControlException e) {
+            // success
+        }
+    }
+
+    @Test
+    public void testRedundantPrivileges() throws Exception {
+        ACE ace = createEntry(PrivilegeConstants.JCR_READ, 
PrivilegeConstants.JCR_READ);
+        Privilege[] privs = ace.getPrivileges();
+        assertEquals(1, privs.length);
+        assertEquals(PrivilegeConstants.JCR_READ, privs[0].getName());
+    }
+
+    /**
+     * @since oak 1.0 ACE doesn't validate privileges.
+     */
+    @Test
+    public void testUnknownPrivilege() throws Exception {
+        Privilege invalidPriv = new Privilege() {
+            public String getName() {
+                return "";
+            }
+
+            public boolean isAbstract() {
+                return false;
+            }
+
+            public boolean isAggregate() {
+                return false;
+            }
+
+            public Privilege[] getDeclaredAggregatePrivileges() {
+                return new Privilege[0];
+            }
+
+            public Privilege[] getAggregatePrivileges() {
+                return new Privilege[0];
+            }
+        };
+        Privilege[] privs = new Privilege[]{invalidPriv, 
acMgr.privilegeFromName(PrivilegeConstants.JCR_READ)};
+        createEntry(testPrincipal, privs, true);
+    }
+
+    @Test
+    public void testGetRestrictionNames() throws Exception {
+        // empty restrictions
+        String[] restrictionNames = 
createEntry(Collections.<Restriction>emptySet()).getRestrictionNames();
+        assertNotNull(restrictionNames);
+        assertEquals(0, restrictionNames.length);
+
+        Restriction globRestr = 
createRestriction(AccessControlConstants.REP_GLOB, globValue);
+        Restriction nameRestr = 
createRestriction(AccessControlConstants.REP_NT_NAMES, nameValues);
+
+        // single restriction
+        restrictionNames = 
createEntry(ImmutableSet.of(globRestr)).getRestrictionNames();
+        assertEquals(1, restrictionNames.length);
+
+        // 2 restrictions
+        restrictionNames = createEntry(ImmutableSet.of(globRestr, 
nameRestr)).getRestrictionNames();
+        assertEquals(2, restrictionNames.length);
+    }
+
+    @Test
+    public void testGetRestrictionForEmpty() throws Exception {
+        // empty restrictions
+        Value val = 
createEntry(Collections.<Restriction>emptySet()).getRestriction(AccessControlConstants.REP_GLOB);
+        assertNull(val);
+    }
+
+    @Test
+    public void testGetNonExistingRestriction() throws Exception {
+        // single valued restriction
+        Restriction globRestr = 
createRestriction(AccessControlConstants.REP_GLOB, globValue);
+        ACE ace = createEntry(ImmutableSet.of(globRestr));
+        assertNull(ace.getRestriction(AccessControlConstants.REP_NT_NAMES));
+    }
+
+    @Test
+    public void testGetRestrictionForSingleValued() throws Exception {
+        // single valued restriction
+        Restriction globRestr = 
createRestriction(AccessControlConstants.REP_GLOB, globValue);
+        ACE ace = createEntry(ImmutableSet.of(globRestr));
+        Value val = ace.getRestriction(AccessControlConstants.REP_GLOB);
+        assertNotNull(val);
+        assertEquals(globValue, val);
+    }
+
+    /**
+     * @since OAK 1.0: support for multi-value restrictions
+     */
+    @Test
+    public void testGetRestrictionForMultiValued() throws Exception {
+        // multivalued restriction
+        Restriction nameRestr = 
createRestriction(AccessControlConstants.REP_NT_NAMES, nameValues);
+        ACE ace = createEntry(ImmutableSet.of(nameRestr));
+        try {
+            ace.getRestriction(AccessControlConstants.REP_NT_NAMES);
+            fail("Multiple restriction values");
+        } catch (ValueFormatException e) {
+            // success
+        }
+    }
+
+    /**
+     * @since OAK 1.0: support for multi-value restrictions
+     */
+    @Test
+    public void testGetRestrictionForMultiValued2() throws Exception {
+        // single value restriction stored in multi-value property
+        Restriction singleNameRestr = 
createRestriction(AccessControlConstants.REP_NT_NAMES, new Value[] {nameValue});
+
+        ACE ace = createEntry(ImmutableSet.of(singleNameRestr));
+        Value val = ace.getRestriction(AccessControlConstants.REP_NT_NAMES);
+        assertEquals(nameValue, val);
+    }
+
+    /**
+     * @since OAK 1.0: support for multi-value restrictions
+     */
+    @Test
+    public void testGetEmptyRestrictions() throws Exception {
+        // empty restrictions
+        Value[] vs = 
createEntry(Collections.<Restriction>emptySet()).getRestrictions(AccessControlConstants.REP_GLOB);
+        assertNull(vs);
+    }
+
+    /**
+     * @since OAK 1.0: support for multi-value restrictions
+     */
+    @Test
+    public void testGetNonExistingRestrictions() throws Exception {
+        Restriction nameRestr = 
createRestriction(AccessControlConstants.REP_NT_NAMES, nameValues);
+        ACE ace = createEntry(ImmutableSet.of(nameRestr));
+        assertNull(ace.getRestrictions(AccessControlConstants.REP_GLOB));
+    }
+
+    /**
+     * @since OAK 1.0: support for multi-value restrictions
+     */
+    @Test
+    public void testGetRestrictionsForSingleValue() throws Exception {
+        // single valued restriction
+        Restriction globRestr = 
createRestriction(AccessControlConstants.REP_GLOB, globValue);
+        ACE ace = createEntry(ImmutableSet.of(globRestr));
+        Value[] vs = ace.getRestrictions(AccessControlConstants.REP_GLOB);
+        assertNotNull(vs);
+        assertArrayEquals(new Value[] {globValue}, vs);
+    }
+
+    /**
+     * @since OAK 1.0: support for multi-value restrictions
+     */
+    @Test
+    public void testGetRestrictionsForMultiValued() throws Exception {
+        // multivalued restriction
+        Restriction nameRestr = 
createRestriction(AccessControlConstants.REP_NT_NAMES, nameValues);
+        ACE ace = createEntry(ImmutableSet.of(nameRestr));
+        Value[] vs = ace.getRestrictions(AccessControlConstants.REP_NT_NAMES);
+        assertEquals(2, vs.length);
+        assertArrayEquals(nameValues, vs);
+    }
+
+    /**
+     * @since OAK 1.0: support for multi-value restrictions
+     */
+    @Test
+    public void testGetRestrictionsForMultiValued2() throws Exception {
+        // single value restriction stored in multi-value property
+        Restriction singleNameRestr = 
createRestriction(AccessControlConstants.REP_NT_NAMES, new Value[] {nameValue});
+        ACE ace = createEntry(ImmutableSet.of(singleNameRestr));
+        Value[] vs = ace.getRestrictions(AccessControlConstants.REP_NT_NAMES);
+        assertEquals(1, vs.length);
+        assertEquals(nameValue, vs[0]);
+    }
+
+    @Test
     public void testEquals() throws RepositoryException {
 
         Map<AccessControlEntry, AccessControlEntry> equalAces = new 
HashMap<AccessControlEntry, AccessControlEntry>();
@@ -218,6 +456,10 @@ public class ACETest extends AbstractAcc
                 return null;
             }
 
+            public Value[] getRestrictions(String restrictionName) {
+                return null;
+            }
+
             public Principal getPrincipal() {
                 return testPrincipal;
             }
@@ -303,6 +545,10 @@ public class ACETest extends AbstractAcc
                 return null;
             }
 
+            public Value[] getRestrictions(String restrictionName) {
+                return null;
+            }
+
             public Principal getPrincipal() {
                 return testPrincipal;
             }
@@ -318,75 +564,4 @@ public class ACETest extends AbstractAcc
         }
 
     }
-
-    @Test
-    public void testNullPrincipal() throws Exception {
-        try {
-            Privilege[] privs = new Privilege[]{
-                    acMgr.privilegeFromName(PrivilegeConstants.JCR_ALL)
-            };
-            createEntry(null, privs, true);
-            fail("Principal must not be null");
-        } catch (AccessControlException e) {
-            // success
-        }
-    }
-
-    @Test
-    public void testNullPrivileges() throws Exception {
-        try {
-            createEntry(testPrincipal, null, true);
-            fail("Principal must not be null");
-        } catch (AccessControlException e) {
-            // success
-        }
-    }
-
-    @Test
-    public void testEmptyPrivileges() throws Exception {
-        try {
-            createEntry(testPrincipal, new Privilege[0], true);
-            fail("Privilege array must not be null.");
-        } catch (AccessControlException e) {
-            // success
-        }
-    }
-
-    @Test
-    public void testRedundantPrivileges() throws Exception {
-        ACE ace = createEntry(PrivilegeConstants.JCR_READ, 
PrivilegeConstants.JCR_READ);
-        Privilege[] privs = ace.getPrivileges();
-        assertEquals(1, privs.length);
-        assertEquals(PrivilegeConstants.JCR_READ, privs[0].getName());
-    }
-
-    /**
-     * @since oak 1.0 ACE doesn't validate privileges.
-     */
-    @Test
-    public void testUnknownPrivilege() throws Exception {
-        Privilege invalidPriv = new Privilege() {
-            public String getName() {
-                return "";
-            }
-
-            public boolean isAbstract() {
-                return false;
-            }
-
-            public boolean isAggregate() {
-                return false;
-            }
-
-            public Privilege[] getDeclaredAggregatePrivileges() {
-                return new Privilege[0];
-            }
-
-            public Privilege[] getAggregatePrivileges() {
-                return new Privilege[0];
-            }
-        };
-        Privilege[] privs = new Privilege[]{invalidPriv, 
acMgr.privilegeFromName(PrivilegeConstants.JCR_READ)};
-        createEntry(testPrincipal, privs, true);
-    }
 }
\ No newline at end of file

Modified: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/AbstractRestrictionProviderTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/AbstractRestrictionProviderTest.java?rev=1511344&r1=1511343&r2=1511344&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/AbstractRestrictionProviderTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/restriction/AbstractRestrictionProviderTest.java
 Wed Aug  7 14:54:16 2013
@@ -16,18 +16,246 @@
  */
 package org.apache.jackrabbit.oak.spi.security.authorization.restriction;
 
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import javax.jcr.PropertyType;
+import javax.jcr.Value;
+import javax.jcr.ValueFactory;
+import javax.jcr.security.AccessControlException;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.jackrabbit.oak.AbstractSecurityTest;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.plugins.value.ValueFactoryImpl;
+import 
org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants;
+import org.apache.jackrabbit.oak.util.NodeUtil;
+import org.junit.After;
+import org.junit.Before;
 import org.junit.Test;
 
-public class AbstractRestrictionProviderTest {
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public class AbstractRestrictionProviderTest extends AbstractSecurityTest 
implements AccessControlConstants {
+
+    private String unsupportedPath = null;
+    private String testPath = "/testRoot";
+
+    private Value globValue;
+    private Value[] nameValues;
+    private Value nameValue;
+
+    private ValueFactory valueFactory;
+    private AbstractRestrictionProvider restrictionProvider;
+
+    @Before
+    @Override
+    public void before() throws Exception {
+        super.before();
+
+        valueFactory = new ValueFactoryImpl(root.getBlobFactory(), 
namePathMapper);
+        globValue = valueFactory.createValue("*");
+        nameValue = valueFactory.createValue("nt:file", PropertyType.NAME);
+        nameValues = new Value[] {
+                valueFactory.createValue("nt:folder", PropertyType.NAME),
+                valueFactory.createValue("nt:file", PropertyType.NAME)
+        };
+
+        restrictionProvider = new TestProvider();
+    }
+
+    @After
+    @Override
+    public void after() throws Exception {
+        try {
+            root.refresh();
+        } finally {
+            super.after();
+        }
+    }
+
+    private Tree getAceTree(Restriction... restrictions) throws Exception {
+        NodeUtil rootNode = new NodeUtil(root.getTree("/"));
+        NodeUtil tmp = rootNode.addChild("testRoot", 
JcrConstants.NT_UNSTRUCTURED);
+        Tree ace = tmp.addChild("rep:policy", NT_REP_ACL).addChild("ace0", 
NT_REP_GRANT_ACE).getTree();
+        restrictionProvider.writeRestrictions(tmp.getTree().getPath(), ace, 
ImmutableSet.copyOf(restrictions));
+        return ace;
+    }
+
 
     @Test
-    public void testCreateRestriction() {
-        // TODO
+    public void testGetSupportedRestrictions() throws Exception {
+        Set<RestrictionDefinition> defs = 
restrictionProvider.getSupportedRestrictions(testPath);
+        assertNotNull(defs);
+        assertEquals(TestProvider.supportedRestrictions().size(), defs.size());
+        for (RestrictionDefinition def : 
TestProvider.supportedRestrictions().values()) {
+            assertTrue(defs.contains(def));
+        }
     }
 
     @Test
-    public void testCreateMvRestriction() {
-        // TODO
+    public void testGetSupportedRestrictionsForUnsupportedPath() throws 
Exception {
+        Set<RestrictionDefinition> defs = 
restrictionProvider.getSupportedRestrictions(unsupportedPath);
+        assertNotNull(defs);
+        assertTrue(defs.isEmpty());
+    }
+
+    @Test
+    public void testCreateForUnsupportedPath() throws Exception {
+        try {
+            restrictionProvider.createRestriction(unsupportedPath, REP_GLOB, 
globValue);
+            fail();
+        } catch (AccessControlException e) {
+            // success
+        }
+
+        try {
+            restrictionProvider.createRestriction(unsupportedPath, 
REP_NT_NAMES, nameValues);
+            fail();
+        } catch (AccessControlException e) {
+            // success
+        }
+    }
+
+    @Test
+    public void testCreateForUnsupportedName() throws Exception {
+        try {
+            restrictionProvider.createRestriction(unsupportedPath, 
"unsupported", globValue);
+            fail();
+        } catch (AccessControlException e) {
+            // success
+        }
+
+        try {
+            restrictionProvider.createRestriction(unsupportedPath, 
"unsupported", nameValues);
+            fail();
+        } catch (AccessControlException e) {
+            // success
+        }
+    }
+
+    @Test
+    public void testCreateForUnsupportedType() throws Exception {
+        try {
+            restrictionProvider.createRestriction(unsupportedPath, REP_GLOB, 
valueFactory.createValue(true));
+            fail();
+        } catch (AccessControlException e) {
+            // success
+        }
+        try {
+            restrictionProvider.createRestriction(unsupportedPath, 
REP_NT_NAMES,
+                    valueFactory.createValue("nt:file", PropertyType.NAME),
+                    valueFactory.createValue(true));
+            fail();
+        } catch (AccessControlException e) {
+            // success
+        }
+    }
+
+    @Test
+    public void testCreateForUnsupportedMultiValues() throws Exception {
+        try {
+            restrictionProvider.createRestriction(unsupportedPath, REP_GLOB,
+                    valueFactory.createValue("*"),
+                    valueFactory.createValue("/a/*"));
+            fail();
+        } catch (AccessControlException e) {
+            // success
+        }
+    }
+
+    @Test
+    public void testCreateRestriction() throws Exception {
+        Restriction r = restrictionProvider.createRestriction(testPath, 
REP_GLOB, globValue);
+        assertNotNull(r);
+        assertEquals(REP_GLOB, r.getName());
+        assertEquals(globValue.getString(), 
r.getProperty().getValue(Type.STRING));
+    }
+
+    @Test
+    public void testCreateMvRestriction() throws Exception {
+        Restriction r = restrictionProvider.createRestriction(testPath, 
REP_NT_NAMES,
+                valueFactory.createValue("nt:folder", PropertyType.NAME),
+                valueFactory.createValue("nt:file", PropertyType.NAME));
+        assertNotNull(r);
+        assertEquals(REP_NT_NAMES, r.getName());
+        assertEquals(Type.NAMES, r.getRequiredType());
+
+        PropertyState ps = r.getProperty();
+        assertTrue(ps.isArray());
+        assertEquals(Type.NAMES, ps.getType());
+
+        List<Value> vs = ValueFactoryImpl.createValues(ps, namePathMapper);
+        assertArrayEquals(nameValues, vs.toArray(new Value[vs.size()]));
+    }
+
+    @Test
+    public void testCreateMvRestriction2() throws Exception {
+        Restriction r = restrictionProvider.createRestriction(testPath, 
REP_NT_NAMES, nameValues);
+        assertNotNull(r);
+        assertEquals(REP_NT_NAMES, r.getName());
+        assertEquals(Type.NAMES, r.getRequiredType());
+
+        PropertyState ps = r.getProperty();
+        assertTrue(ps.isArray());
+        assertEquals(Type.NAMES, ps.getType());
+
+        List<Value> vs = ValueFactoryImpl.createValues(ps, namePathMapper);
+        assertArrayEquals(nameValues, vs.toArray(new Value[vs.size()]));
+    }
+
+    @Test
+    public void testCreateMvRestriction3() throws Exception {
+        Restriction r = restrictionProvider.createRestriction(testPath, 
REP_NT_NAMES, nameValue);
+        assertNotNull(r);
+        assertEquals(REP_NT_NAMES, r.getName());
+        assertEquals(Type.NAMES, r.getRequiredType());
+
+        assertTrue(r.getProperty().isArray());
+        assertEquals(Type.NAMES, r.getProperty().getType());
+
+        List<Value> vs = ValueFactoryImpl.createValues(r.getProperty(), 
namePathMapper);
+        assertArrayEquals(new Value[] {nameValue}, vs.toArray(new 
Value[vs.size()]));
+    }
+
+    @Test
+    public void testCreateEmptyMvRestriction() throws Exception {
+        Restriction r = restrictionProvider.createRestriction(testPath, 
REP_NT_NAMES);
+        assertNotNull(r);
+        assertEquals(REP_NT_NAMES, r.getName());
+        assertEquals(Type.NAMES, r.getRequiredType());
+
+        assertTrue(r.getProperty().isArray());
+        assertEquals(Type.NAMES, r.getProperty().getType());
+
+        List<Value> vs = ValueFactoryImpl.createValues(r.getProperty(), 
namePathMapper);
+        assertNotNull(vs);
+        assertEquals(0, vs.size());
+    }
+
+    @Test
+    public void testCreateEmptyMvRestriction2() throws Exception {
+        Restriction r = restrictionProvider.createRestriction(testPath, 
REP_NT_NAMES, new Value[0]);
+        assertNotNull(r);
+        assertEquals(REP_NT_NAMES, r.getName());
+        assertEquals(Type.NAMES, r.getRequiredType());
+
+        assertTrue(r.getProperty().isArray());
+        assertEquals(Type.NAMES, r.getProperty().getType());
+
+        List<Value> vs = ValueFactoryImpl.createValues(r.getProperty(), 
namePathMapper);
+        assertNotNull(vs);
+        assertEquals(0, vs.size());
     }
 
     @Test
@@ -41,7 +269,89 @@ public class AbstractRestrictionProvider
     }
 
     @Test
-    public void testValidateRestrictions() {
-        // TODO
+    public void testValidateRestrictionsUnsupportedPath() throws Exception {
+        // empty restrictions => must succeed
+        restrictionProvider.validateRestrictions(null, getAceTree());
+
+
+        // non-empty restrictions => must fail
+        try {
+            Restriction restr = 
restrictionProvider.createRestriction(testPath, REP_GLOB, globValue);
+            restrictionProvider.validateRestrictions(null, getAceTree(restr));
+            fail();
+        } catch (AccessControlException e) {
+            // success
+        }
+    }
+
+    @Test
+    public void testValidateRestrictionsWrongType() throws Exception {
+        Restriction mand = restrictionProvider.createRestriction(testPath, 
"mandatory", valueFactory.createValue(true));
+        try {
+            Tree ace = getAceTree(mand);
+            new NodeUtil(ace).getChild(REP_RESTRICTIONS).setBoolean(REP_GLOB, 
true);
+
+            restrictionProvider.validateRestrictions(testPath, ace);
+            fail("wrong type with restriction 'rep:glob");
+        } catch (AccessControlException e) {
+            // success
+        }
+    }
+
+    @Test
+    public void testValidateRestrictionsUnsupportedRestriction() throws 
Exception {
+        Restriction mand = restrictionProvider.createRestriction(testPath, 
"mandatory", valueFactory.createValue(true));
+        try {
+            Tree ace = getAceTree(mand);
+            new 
NodeUtil(ace).getChild(REP_RESTRICTIONS).setString("Unsupported", "value");
+
+            restrictionProvider.validateRestrictions(testPath, ace);
+            fail("wrong type with restriction 'rep:glob");
+        } catch (AccessControlException e) {
+            // success
+        }
+    }
+
+    @Test
+    public void testValidateRestrictionsMissingMandatory() throws Exception {
+        Restriction glob = restrictionProvider.createRestriction(testPath, 
REP_GLOB, globValue);
+        try {
+            restrictionProvider.validateRestrictions(testPath, 
getAceTree(glob));
+            fail("missing mandatory restriction");
+        } catch (AccessControlException e) {
+            // success
+        }
+    }
+
+    @Test
+    public void testValidateRestrictions() throws Exception {
+        Restriction glob = restrictionProvider.createRestriction(testPath, 
REP_GLOB, globValue);
+        Restriction ntNames = restrictionProvider.createRestriction(testPath, 
REP_NT_NAMES, nameValues);
+        Restriction mand = restrictionProvider.createRestriction(testPath, 
"mandatory", valueFactory.createValue(true));
+
+        restrictionProvider.validateRestrictions(testPath, getAceTree(mand));
+        restrictionProvider.validateRestrictions(testPath, getAceTree(mand, 
glob));
+        restrictionProvider.validateRestrictions(testPath, getAceTree(mand, 
ntNames));
+        restrictionProvider.validateRestrictions(testPath, getAceTree(mand, 
glob, ntNames));
+    }
+
+    private static final class TestProvider extends 
AbstractRestrictionProvider {
+
+        private TestProvider() {
+            super(supportedRestrictions());
+        }
+
+        private static Map<String, RestrictionDefinition> 
supportedRestrictions() {
+            RestrictionDefinition glob = new 
RestrictionDefinitionImpl(REP_GLOB, Type.STRING, false);
+            RestrictionDefinition nts  = new 
RestrictionDefinitionImpl(REP_NT_NAMES, Type.NAMES, false);
+            RestrictionDefinition mand = new 
RestrictionDefinitionImpl("mandatory", Type.BOOLEAN, true);
+            return ImmutableMap.of(glob.getName(), glob, nts.getName(), nts, 
mand.getName(), mand);
+        }
+
+        @Nonnull
+        @Override
+        public RestrictionPattern getPattern(@Nullable String oakPath, 
@Nonnull Tree tree) {
+            throw new UnsupportedOperationException();
+        }
     }
 }
\ No newline at end of file


Reply via email to