You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by an...@apache.org on 2021/12/14 11:22:53 UTC
[jackrabbit-oak] branch trunk updated: OAK-9637 : Additional API to retrieve PrivilegeCollection to avoid manual resolution of privilege aggregation
This is an automated email from the ASF dual-hosted git repository.
angela pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git
The following commit(s) were added to refs/heads/trunk by this push:
new fe6d29b OAK-9637 : Additional API to retrieve PrivilegeCollection to avoid manual resolution of privilege aggregation
new 759f9c8 Merge branch 'trunk' of https://github.com/apache/jackrabbit-oak into trunk
fe6d29b is described below
commit fe6d29b1e337f81c7ed4c51856b217ce3d44ca01
Author: angela <an...@adobe.com>
AuthorDate: Tue Dec 14 12:22:24 2021 +0100
OAK-9637 : Additional API to retrieve PrivilegeCollection to avoid manual resolution of privilege aggregation
---
.../impl/PrincipalBasedAccessControlManager.java | 5 +
.../principalbased/impl/PrincipalPolicyImpl.java | 5 +
.../principalbased/impl/AbstractEntryTest.java | 5 +
.../impl/PrincipalPolicyImplTest.java | 6 +
.../accesscontrol/AccessControlManagerImpl.java | 8 +-
.../authorization/accesscontrol/ACLTest.java | 34 +-----
.../accesscontrol/AbstractAccessControlTest.java | 10 ++
.../AccessControlManagerImplTest.java | 37 ++++++
.../authorization/accesscontrol/EntryTest.java | 134 ++++++++-------------
.../authorization/accesscontrol/UtilTest.java | 52 ++++----
.../L5_AccessControlListImplTest.java | 7 ++
.../api/security/JackrabbitAccessControlEntry.java | 20 ++-
.../security/JackrabbitAccessControlManager.java | 26 ++++
.../api/security/authorization/package-info.java | 2 +-
.../jackrabbit/api/security/package-info.java | 2 +-
.../security/authorization/accesscontrol/ACE.java | 30 ++++-
.../AbstractAccessControlManager.java | 37 +++---
.../accesscontrol/AbstractPrivilegeCollection.java | 68 +++++++++++
.../authorization/accesscontrol/package-info.java | 2 +-
.../authorization/accesscontrol/ACETest.java | 117 +++++++++++-------
.../AbstractAccessControlManagerTest.java | 11 ++
.../accesscontrol/AbstractAccessControlTest.java | 29 +++--
.../AbstractPrivilegeCollectionTest.java | 130 ++++++++++++++++++++
23 files changed, 562 insertions(+), 215 deletions(-)
diff --git a/oak-authorization-principalbased/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalBasedAccessControlManager.java b/oak-authorization-principalbased/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalBasedAccessControlManager.java
index 8204d8d..eaec709 100644
--- a/oak-authorization-principalbased/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalBasedAccessControlManager.java
+++ b/oak-authorization-principalbased/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalBasedAccessControlManager.java
@@ -404,6 +404,11 @@ class PrincipalBasedAccessControlManager extends AbstractAccessControlManager im
}
@Override
+ protected @NotNull PrivilegeBitsProvider getPrivilegeBitsProvider() {
+ return privilegeBitsProvider;
+ }
+
+ @Override
public Privilege[] getPrivileges() {
Set<String> names = privilegeBitsProvider.getPrivilegeNames(getPrivilegeBits());
return Utils.privilegesFromOakNames(names, mgrProvider.getPrivilegeManager(), getNamePathMapper());
diff --git a/oak-authorization-principalbased/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalPolicyImpl.java b/oak-authorization-principalbased/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalPolicyImpl.java
index b4d2413..5ecec6e 100644
--- a/oak-authorization-principalbased/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalPolicyImpl.java
+++ b/oak-authorization-principalbased/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalPolicyImpl.java
@@ -275,5 +275,10 @@ class PrincipalPolicyImpl extends AbstractAccessControlList implements Principal
@NotNull NamePathMapper getNamePathMapper() {
return PrincipalPolicyImpl.this.getNamePathMapper();
}
+
+ @Override
+ protected @NotNull PrivilegeBitsProvider getPrivilegeBitsProvider() {
+ return privilegeBitsProvider;
+ }
}
}
diff --git a/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/AbstractEntryTest.java b/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/AbstractEntryTest.java
index fa7593a..4699165 100644
--- a/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/AbstractEntryTest.java
+++ b/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/AbstractEntryTest.java
@@ -142,6 +142,11 @@ public class AbstractEntryTest extends AbstractPrincipalBasedTest {
}
@Override
+ protected @NotNull PrivilegeBitsProvider getPrivilegeBitsProvider() {
+ return bitsProvider;
+ }
+
+ @Override
public Privilege[] getPrivileges() {
try {
return privilegesFromNames(bitsProvider.getPrivilegeNames(getPrivilegeBits()));
diff --git a/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalPolicyImplTest.java b/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalPolicyImplTest.java
index 5b4732a..a821844 100644
--- a/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalPolicyImplTest.java
+++ b/oak-authorization-principalbased/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/principalbased/impl/PrincipalPolicyImplTest.java
@@ -22,6 +22,7 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import org.apache.jackrabbit.api.security.authorization.PrincipalAccessControlList;
+import org.apache.jackrabbit.api.security.authorization.PrivilegeCollection;
import org.apache.jackrabbit.api.security.authorization.PrivilegeManager;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Tree;
@@ -611,6 +612,11 @@ public class PrincipalPolicyImplTest extends AbstractPrincipalBasedTest {
}
@Override
+ public @NotNull PrivilegeCollection getPrivilegeCollection() throws RepositoryException {
+ return entry.getPrivilegeCollection();
+ }
+
+ @Override
public Principal getPrincipal() {
return entry.getPrincipal();
}
diff --git a/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImpl.java b/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImpl.java
index 237c23f..f8804c3 100644
--- a/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImpl.java
+++ b/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImpl.java
@@ -80,6 +80,7 @@ import org.apache.jackrabbit.oak.spi.security.authorization.restriction.Restrict
import org.apache.jackrabbit.oak.spi.security.principal.PrincipalConfiguration;
import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl;
import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBits;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBitsProvider;
import org.apache.jackrabbit.oak.spi.xml.ImportBehavior;
import org.apache.jackrabbit.util.ISO9075;
import org.apache.jackrabbit.util.Text;
@@ -683,7 +684,7 @@ public class AccessControlManagerImpl extends AbstractAccessControlManager imple
@Override
boolean checkValidPrincipal(@Nullable Principal principal) throws AccessControlException {
- // principal asspciated with the policy has been validated before -> make sure only entries for the same
+ // principal associated with the policy has been validated before -> make sure only entries for the same
// principal are created
if (principal == null || !this.principal.getName().equals(principal.getName())) {
throw new AccessControlException("Principal mismatch.");
@@ -756,6 +757,11 @@ public class AccessControlManagerImpl extends AbstractAccessControlManager imple
}
@Override
+ protected @NotNull PrivilegeBitsProvider getPrivilegeBitsProvider() {
+ return AccessControlManagerImpl.this.getPrivilegeBitsProvider();
+ }
+
+ @Override
public Privilege[] getPrivileges() {
Set<Privilege> privileges = new HashSet<>();
for (String name : getPrivilegeBitsProvider().getPrivilegeNames(getPrivilegeBits())) {
diff --git a/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/ACLTest.java b/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/ACLTest.java
index 4bcfc5a..cd1d9de 100644
--- a/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/ACLTest.java
+++ b/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/ACLTest.java
@@ -75,6 +75,8 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
/**
@@ -306,34 +308,10 @@ public class ACLTest extends AbstractAccessControlTest implements PrivilegeConst
@Test(expected = AccessControlException.class)
public void testRemoveInvalidEntry() throws Exception {
- acl.removeAccessControlEntry(new JackrabbitAccessControlEntry() {
- public boolean isAllow() {
- return false;
- }
-
- @NotNull
- public String[] getRestrictionNames() {
- return new String[0];
- }
-
- @Nullable
- public Value getRestriction(@NotNull String restrictionName) {
- return null;
- }
-
- @Nullable
- public Value[] getRestrictions(@NotNull String restrictionName) {
- return null;
- }
-
- public Principal getPrincipal() {
- return testPrincipal;
- }
-
- public Privilege[] getPrivileges() {
- return testPrivileges;
- }
- });
+ JackrabbitAccessControlEntry ace = mockAccessControlEntry(testPrincipal, testPrivileges);
+ acl.removeAccessControlEntry(ace);
+ verify(ace, never()).getPrincipal();
+ verify(ace, never()).getPrivileges();
}
@Test(expected = AccessControlException.class)
diff --git a/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AbstractAccessControlTest.java b/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AbstractAccessControlTest.java
index 51fdcab..55a2b76 100644
--- a/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AbstractAccessControlTest.java
+++ b/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AbstractAccessControlTest.java
@@ -17,6 +17,7 @@
package org.apache.jackrabbit.oak.security.authorization.accesscontrol;
import org.apache.jackrabbit.JcrConstants;
+import org.apache.jackrabbit.api.security.JackrabbitAccessControlEntry;
import org.apache.jackrabbit.api.security.authorization.PrivilegeManager;
import org.apache.jackrabbit.api.security.principal.PrincipalManager;
import org.apache.jackrabbit.oak.AbstractSecurityTest;
@@ -47,6 +48,8 @@ import java.util.Set;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
public abstract class AbstractAccessControlTest extends AbstractSecurityTest {
@@ -168,6 +171,13 @@ public abstract class AbstractAccessControlTest extends AbstractSecurityTest {
};
}
+ static JackrabbitAccessControlEntry mockAccessControlEntry(@NotNull Principal principal, @NotNull Privilege[] privs) {
+ JackrabbitAccessControlEntry ace = mock(JackrabbitAccessControlEntry.class);
+ when(ace.getPrincipal()).thenReturn(principal);
+ when(ace.getPrivileges()).thenReturn(privs);
+ return ace;
+ }
+
static void assertPolicies(@Nullable AccessControlPolicy[] policies, long expectedSize) {
assertNotNull(policies);
assertEquals(expectedSize, policies.length);
diff --git a/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImplTest.java b/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImplTest.java
index 01e54cf..ac796c6 100644
--- a/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImplTest.java
+++ b/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/AccessControlManagerImplTest.java
@@ -26,6 +26,7 @@ import org.apache.jackrabbit.api.security.JackrabbitAccessControlEntry;
import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
import org.apache.jackrabbit.api.security.JackrabbitAccessControlManager;
import org.apache.jackrabbit.api.security.JackrabbitAccessControlPolicy;
+import org.apache.jackrabbit.api.security.authorization.PrivilegeCollection;
import org.apache.jackrabbit.api.security.principal.GroupPrincipal;
import org.apache.jackrabbit.oak.api.ContentSession;
import org.apache.jackrabbit.oak.api.QueryEngine;
@@ -52,6 +53,7 @@ import org.apache.jackrabbit.oak.spi.security.authorization.restriction.Restrict
import org.apache.jackrabbit.oak.spi.security.principal.EveryonePrincipal;
import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl;
import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBits;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBitsProvider;
import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -89,11 +91,16 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Sets.newHashSet;
import static java.util.Collections.singletonMap;
import static org.apache.jackrabbit.oak.spi.nodetype.NodeTypeConstants.NT_OAK_UNSTRUCTURED;
+import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_ALL;
import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_LOCK_MANAGEMENT;
import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_READ;
+import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_VERSION_MANAGEMENT;
+import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.REP_READ_NODES;
+import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.REP_READ_PROPERTIES;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
@@ -1976,6 +1983,11 @@ public class AccessControlManagerImplTest extends AbstractAccessControlTest impl
Privilege[] privs = privilegesFromNames(PrivilegeConstants.JCR_LIFECYCLE_MANAGEMENT);
acl.getEntries().add(new ACE(testPrincipal, PrivilegeBits.BUILT_IN.get(PrivilegeConstants.JCR_LIFECYCLE_MANAGEMENT), false, Collections.emptySet(), getNamePathMapper()) {
@Override
+ protected @NotNull PrivilegeBitsProvider getPrivilegeBitsProvider() {
+ return AccessControlManagerImplTest.this.getBitsProvider();
+ }
+
+ @Override
public Privilege[] getPrivileges() {
return privs;
}
@@ -2071,6 +2083,31 @@ public class AccessControlManagerImplTest extends AbstractAccessControlTest impl
assertEquals(0, repoLevelPolicies.length);
}
+ //------------------------------------< privilegeCollectionFromNames() >---
+ @Test
+ public void testPrivilegeCollectionFromNames() throws Exception {
+ PrivilegeCollection pc = acMgr.privilegeCollectionFromNames(Privilege.JCR_READ, Privilege.JCR_WRITE, Privilege.JCR_VERSION_MANAGEMENT);
+
+ assertEquals(pc, acMgr.privilegeCollectionFromNames(Privilege.JCR_READ, Privilege.JCR_WRITE, Privilege.JCR_VERSION_MANAGEMENT));
+ assertEquals(pc, acMgr.privilegeCollectionFromNames(JCR_READ, PrivilegeConstants.JCR_WRITE, JCR_VERSION_MANAGEMENT));
+ assertEquals(pc, acMgr.privilegeCollectionFromNames(REP_READ_NODES, REP_READ_PROPERTIES, PrivilegeConstants.JCR_WRITE, JCR_VERSION_MANAGEMENT));
+
+ assertNotEquals(pc, acMgr.privilegeCollectionFromNames());
+ assertNotEquals(pc, acMgr.privilegeCollectionFromNames(JCR_READ));
+ assertNotEquals(pc, acMgr.privilegeCollectionFromNames(JCR_ALL));
+ assertNotEquals(pc, acMgr.privilegeCollectionFromNames(JCR_READ, PrivilegeConstants.JCR_WRITE));
+ assertNotEquals(pc, acMgr.privilegeCollectionFromNames(JCR_READ, JCR_VERSION_MANAGEMENT));
+
+ assertTrue(pc.includes());
+ assertTrue(pc.includes(Privilege.JCR_READ, Privilege.JCR_WRITE));
+ assertTrue(pc.includes(PrivilegeConstants.JCR_WRITE, Privilege.JCR_VERSION_MANAGEMENT));
+ assertTrue(pc.includes(REP_READ_NODES, PrivilegeConstants.JCR_ADD_CHILD_NODES));
+
+ assertFalse(pc.includes(PrivilegeConstants.JCR_ALL));
+ assertFalse(pc.includes(PrivilegeConstants.REP_WRITE));
+ assertFalse(pc.includes(PrivilegeConstants.REP_USER_MANAGEMENT, PrivilegeConstants.REP_ALTER_PROPERTIES));
+ }
+
private final static class TestACL extends AbstractAccessControlList {
private final List<JackrabbitAccessControlEntry> entries = new ArrayList<>();
diff --git a/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/EntryTest.java b/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/EntryTest.java
index 1542262..cd672a3 100644
--- a/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/EntryTest.java
+++ b/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/EntryTest.java
@@ -19,14 +19,16 @@ package org.apache.jackrabbit.oak.security.authorization.accesscontrol;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import org.apache.jackrabbit.api.security.JackrabbitAccessControlEntry;
+import org.apache.jackrabbit.api.security.authorization.PrivilegeCollection;
import org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils;
+import org.apache.jackrabbit.oak.namepath.impl.GlobalNameMapper;
+import org.apache.jackrabbit.oak.namepath.impl.NamePathMapperImpl;
import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.ACE;
import org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol.AccessControlConstants;
import org.apache.jackrabbit.oak.spi.security.authorization.restriction.Restriction;
import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBits;
import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import org.junit.Before;
import org.junit.Test;
@@ -48,6 +50,11 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_READ;
+import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_WRITE;
+import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.REP_ALTER_PROPERTIES;
+import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.REP_READ_NODES;
+import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.REP_READ_PROPERTIES;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -56,6 +63,8 @@ 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.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
public class EntryTest extends AbstractAccessControlTest {
@@ -69,6 +78,7 @@ public class EntryTest extends AbstractAccessControlTest {
@Before
public void before() throws Exception {
super.before();
+ namePathMapper = new NamePathMapperImpl(new GlobalNameMapper(root));
acMgr = getAccessControlManager(root);
testPrincipal = () -> "TestPrincipal";
@@ -97,7 +107,7 @@ public class EntryTest extends AbstractAccessControlTest {
}
private ACE createEntry(Set<Restriction> restrictions) throws Exception {
- return createEntry(testPrincipal, true, restrictions, PrivilegeConstants.JCR_READ);
+ return createEntry(testPrincipal, true, restrictions, JCR_READ);
}
private Restriction createRestriction(Value value) throws Exception {
@@ -110,16 +120,16 @@ public class EntryTest extends AbstractAccessControlTest {
@Test
public void testIsAllow() throws RepositoryException {
- ACE ace = createEntry(new String[]{PrivilegeConstants.JCR_READ}, true);
+ ACE ace = createEntry(new String[]{JCR_READ}, true);
assertTrue(ace.isAllow());
- ace = createEntry(new String[]{PrivilegeConstants.JCR_READ}, false);
+ ace = createEntry(new String[]{JCR_READ}, false);
assertFalse(ace.isAllow());
}
@Test
public void testGetPrincipal() throws RepositoryException {
- ACE tmpl = createEntry(new String[]{PrivilegeConstants.JCR_READ}, true);
+ ACE tmpl = createEntry(new String[]{JCR_READ}, true);
assertNotNull(tmpl.getPrincipal());
assertEquals(testPrincipal.getName(), tmpl.getPrincipal().getName());
assertSame(testPrincipal, tmpl.getPrincipal());
@@ -135,12 +145,12 @@ public class EntryTest extends AbstractAccessControlTest {
@Test
public void testGetPrivileges() throws RepositoryException {
- ACE entry = createEntry(new String[]{PrivilegeConstants.JCR_READ}, true);
+ ACE entry = createEntry(new String[]{JCR_READ}, true);
Privilege[] privs = entry.getPrivileges();
assertNotNull(privs);
assertEquals(1, privs.length);
- assertEquals(privs[0], acMgr.privilegeFromName(PrivilegeConstants.JCR_READ));
+ assertEquals(privs[0], acMgr.privilegeFromName(JCR_READ));
entry = createEntry(new String[]{PrivilegeConstants.REP_WRITE}, true);
privs = entry.getPrivileges();
@@ -162,11 +172,11 @@ public class EntryTest extends AbstractAccessControlTest {
@Test
public void testGetPrivilegeBits() throws RepositoryException {
- ACE entry = createEntry(new String[]{PrivilegeConstants.JCR_READ}, true);
+ ACE entry = createEntry(new String[]{JCR_READ}, true);
PrivilegeBits bits = entry.getPrivilegeBits();
assertNotNull(bits);
- assertEquals(bits, getBitsProvider().getBits(PrivilegeConstants.JCR_READ));
+ assertEquals(bits, getBitsProvider().getBits(JCR_READ));
entry = createEntry(new String[]{PrivilegeConstants.REP_WRITE}, true);
bits = entry.getPrivilegeBits();
@@ -184,20 +194,10 @@ public class EntryTest extends AbstractAccessControlTest {
assertEquals(expected, bits);
}
- @Test(expected = AccessControlException.class)
- public void testNullPrivileges() throws Exception {
- new EmptyACE(null);
- }
-
- @Test(expected = AccessControlException.class)
- public void testEmptyPrivileges() throws Exception {
- new EmptyACE(PrivilegeBits.EMPTY);
- }
-
@Test
public void testRedundantPrivileges() throws Exception {
- ACE ace = createEntry(PrivilegeConstants.JCR_READ, PrivilegeConstants.JCR_READ);
- assertEquals(getBitsProvider().getBits(PrivilegeConstants.JCR_READ), ace.getPrivilegeBits());
+ ACE ace = createEntry(JCR_READ, JCR_READ);
+ assertEquals(getBitsProvider().getBits(JCR_READ), ace.getPrivilegeBits());
}
/**
@@ -226,17 +226,17 @@ public class EntryTest extends AbstractAccessControlTest {
return new Privilege[0];
}
};
- Privilege[] privs = new Privilege[]{invalidPriv, acMgr.privilegeFromName(PrivilegeConstants.JCR_READ)};
+ Privilege[] privs = new Privilege[]{invalidPriv, acMgr.privilegeFromName(JCR_READ)};
ACE entry = createEntry(testPrincipal, privs, true);
- assertEquals(getBitsProvider().getBits(PrivilegeConstants.JCR_READ), entry.getPrivilegeBits());
+ assertEquals(getBitsProvider().getBits(JCR_READ), entry.getPrivilegeBits());
}
@Test
public void testAggregatePrivileges() throws Exception {
ACE ace = createEntry(PrivilegeConstants.REP_READ_NODES, PrivilegeConstants.REP_READ_PROPERTIES);
- assertEquals(getBitsProvider().getBits(PrivilegeConstants.JCR_READ), ace.getPrivilegeBits());
- assertArrayEquals(privilegesFromNames(PrivilegeConstants.JCR_READ), ace.getPrivileges());
+ assertEquals(getBitsProvider().getBits(JCR_READ), ace.getPrivilegeBits());
+ assertArrayEquals(privilegesFromNames(JCR_READ), ace.getPrivileges());
}
@Test
@@ -386,6 +386,23 @@ public class EntryTest extends AbstractAccessControlTest {
assertTrue(ace.getRestrictions().isEmpty());
}
+
+ @Test
+ public void testGetPrivilegeCollection() throws Exception {
+ PrivilegeCollection pc = createEntry(Privilege.JCR_READ, Privilege.JCR_WRITE).getPrivilegeCollection();
+ Set<Privilege> expected = ImmutableSet.copyOf(AccessControlUtils.privilegesFromNames(acMgr, Privilege.JCR_READ, Privilege.JCR_WRITE));
+ assertEquals(expected, ImmutableSet.copyOf(pc.getPrivileges()));
+
+ assertEquals(pc, createEntry(JCR_READ, JCR_WRITE).getPrivilegeCollection());
+ assertEquals(pc, createEntry(JCR_READ, PrivilegeConstants.JCR_ADD_CHILD_NODES, PrivilegeConstants.JCR_MODIFY_PROPERTIES,
+ PrivilegeConstants.JCR_WRITE).getPrivilegeCollection());
+
+ assertTrue(pc.includes(JCR_READ));
+ assertTrue(pc.includes(JCR_READ, JCR_WRITE));
+ assertTrue(pc.includes(JCR_READ, REP_READ_PROPERTIES, REP_READ_NODES, REP_ALTER_PROPERTIES));
+
+ assertFalse(pc.includes(Privilege.JCR_ALL));
+ }
@Test
public void testEquals() throws RepositoryException {
@@ -421,9 +438,9 @@ public class EntryTest extends AbstractAccessControlTest {
@Test
public void testEquals2() throws RepositoryException {
- ACE ace = createEntry(PrivilegeConstants.JCR_ADD_CHILD_NODES, PrivilegeConstants.JCR_READ);
+ ACE ace = createEntry(PrivilegeConstants.JCR_ADD_CHILD_NODES, JCR_READ);
// priv array contains duplicates
- ACE ace2 = createEntry(PrivilegeConstants.JCR_ADD_CHILD_NODES, PrivilegeConstants.JCR_ADD_CHILD_NODES, PrivilegeConstants.JCR_READ);
+ ACE ace2 = createEntry(PrivilegeConstants.JCR_ADD_CHILD_NODES, PrivilegeConstants.JCR_ADD_CHILD_NODES, JCR_READ);
assertEquals(ace, ace2);
}
@@ -441,7 +458,7 @@ public class EntryTest extends AbstractAccessControlTest {
otherAces.add(createEntry(princ, privs, true));
// ACE template with different privileges
- otherAces.add(createEntry(new String[]{PrivilegeConstants.JCR_READ}, true));
+ otherAces.add(createEntry(new String[]{JCR_READ}, true));
// ACE template with different 'allow' flag
otherAces.add(createEntry(new String[]{PrivilegeConstants.JCR_ALL}, false));
@@ -450,12 +467,15 @@ public class EntryTest extends AbstractAccessControlTest {
otherAces.add(createEntry(new String[]{PrivilegeConstants.REP_WRITE}, false));
// other ace impl
- JackrabbitAccessControlEntry pe = new Jace(testPrincipal, privs);
+ JackrabbitAccessControlEntry pe = mockAccessControlEntry(ace.getPrincipal(), ace.getPrivileges());
otherAces.add(pe);
for (JackrabbitAccessControlEntry otherAce : otherAces) {
assertNotEquals(ace, otherAce);
}
+
+ verify(pe, never()).getPrincipal();
+ verify(pe, never()).getPrivileges();
}
@Test
@@ -502,7 +522,7 @@ public class EntryTest extends AbstractAccessControlTest {
otherAces.add(createEntry(princ, privs, true));
// ACE template with different privileges
- otherAces.add(createEntry(new String[]{PrivilegeConstants.JCR_READ}, true));
+ otherAces.add(createEntry(new String[]{JCR_READ}, true));
// ACE template with different 'allow' flag
otherAces.add(createEntry(new String[]{PrivilegeConstants.JCR_ALL}, false));
@@ -511,62 +531,14 @@ public class EntryTest extends AbstractAccessControlTest {
otherAces.add(createEntry(new String[]{PrivilegeConstants.REP_WRITE}, false));
// other ace impl
- JackrabbitAccessControlEntry pe = new Jace(testPrincipal, privs);
+ JackrabbitAccessControlEntry pe = mockAccessControlEntry(ace.getPrincipal(), ace.getPrivileges());
otherAces.add(pe);
for (JackrabbitAccessControlEntry otherAce : otherAces) {
assertNotEquals(ace.hashCode(), otherAce.hashCode());
}
- }
-
- private class EmptyACE extends ACE {
-
- EmptyACE(PrivilegeBits privilegeBits) throws AccessControlException {
- super(testPrincipal, privilegeBits, true, null, namePathMapper);
- }
-
- @Override
- public Privilege[] getPrivileges() {
- return new Privilege[0];
- }
- }
-
- private static final class Jace implements JackrabbitAccessControlEntry {
-
- private final Principal principal;
- private final Privilege[] privs;
-
- private Jace(@NotNull Principal principal, @NotNull Privilege[] privs) {
- this.principal = principal;
- this.privs = privs;
- }
-
- public boolean isAllow() {
- return true;
- }
-
- @NotNull
- public String[] getRestrictionNames() {
- return new String[0];
- }
-
- @Nullable
- public Value getRestriction(@NotNull String restrictionName) {
- return null;
- }
-
- @Nullable
- public Value[] getRestrictions(@NotNull String restrictionName) {
- return null;
- }
-
- public Principal getPrincipal() {
- return principal;
- }
-
- public Privilege[] getPrivileges() {
- return privs;
- }
+ verify(pe, never()).getPrincipal();
+ verify(pe, never()).getPrivileges();
}
}
\ No newline at end of file
diff --git a/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/UtilTest.java b/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/UtilTest.java
index c0c179b..a7166f9 100644
--- a/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/UtilTest.java
+++ b/oak-core/src/test/java/org/apache/jackrabbit/oak/security/authorization/accesscontrol/UtilTest.java
@@ -16,10 +16,6 @@
*/
package org.apache.jackrabbit.oak.security.authorization.accesscontrol;
-import javax.jcr.RepositoryException;
-import javax.jcr.security.AccessControlException;
-import javax.jcr.security.Privilege;
-
import org.apache.jackrabbit.oak.AbstractSecurityTest;
import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.api.Type;
@@ -40,14 +36,21 @@ import org.apache.jackrabbit.oak.spi.xml.ProtectedItemImporter;
import org.junit.Before;
import org.junit.Test;
+import javax.jcr.security.AccessControlException;
+
import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.CALLS_REAL_METHODS;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.withSettings;
public class UtilTest extends AbstractSecurityTest {
@@ -116,8 +119,8 @@ public class UtilTest extends AbstractSecurityTest {
}
@Test
- public void testGenerateName() throws AccessControlException {
- ACE ace = new TestAce(true);
+ public void testGenerateName() {
+ ACE ace = mockACE(true);
String name = Util.generateAceName(ace, 0);
assertTrue(name.startsWith(ALLOW));
@@ -128,11 +131,14 @@ public class UtilTest extends AbstractSecurityTest {
assertTrue(name.startsWith(ALLOW));
assertEquals(ALLOW + 1, name);
assertEquals(name, Util.generateAceName(ace, 1));
+
+ verify(ace, times(4)).isAllow();
+ verifyNoMoreInteractions(ace);
}
@Test
- public void testGenerateName2() throws AccessControlException {
- ACE ace = new TestAce(false);
+ public void testGenerateName2() {
+ ACE ace = mockACE(false);
String name = Util.generateAceName(ace, 0);
assertTrue(name.startsWith(DENY));
@@ -143,34 +149,28 @@ public class UtilTest extends AbstractSecurityTest {
assertTrue(name.startsWith(DENY));
assertEquals(DENY + 2, name);
assertEquals(name, Util.generateAceName(ace, 2));
+
+ verify(ace, times(4)).isAllow();
+ verifyNoMoreInteractions(ace);
}
@Test
- public void testGenerateNameDifferentAllow() throws Exception {
- ACE allow = new TestAce(false);
- ACE deny = new TestAce(true);
+ public void testGenerateNameDifferentAllow() {
+ ACE allow = mockACE(false);
+ ACE deny = mockACE(true);
assertNotEquals(Util.generateAceName(allow, 0), Util.generateAceName(deny, 0));
assertNotEquals(Util.generateAceName(allow, 1), Util.generateAceName(deny, 1));
assertNotEquals(Util.generateAceName(allow, 20), Util.generateAceName(deny, 20));
assertNotEquals(Util.generateAceName(allow, 0), Util.generateAceName(deny, 1));
assertNotEquals(Util.generateAceName(allow, 1), Util.generateAceName(deny, 20));
-
+
+ verify(allow, times(5)).isAllow();
+ verify(deny, times(5)).isAllow();
+ verifyNoMoreInteractions(allow, deny);
}
- private final class TestAce extends ACE {
-
- TestAce(boolean isAllow) throws AccessControlException {
- super(EveryonePrincipal.getInstance(), bitsProvider.getBits(PrivilegeConstants.JCR_READ), isAllow, null, NamePathMapper.DEFAULT);
- }
-
- @Override
- public Privilege[] getPrivileges() {
- try {
- return privilegesFromNames(bitsProvider.getPrivilegeNames(getPrivilegeBits()));
- } catch (RepositoryException e) {
- throw new RuntimeException(e.getMessage());
- }
- }
+ private ACE mockACE(boolean isAllow) {
+ return mock(ACE.class, withSettings().useConstructor(EveryonePrincipal.getInstance(), bitsProvider.getBits(PrivilegeConstants.JCR_READ), isAllow, null, NamePathMapper.DEFAULT).defaultAnswer(CALLS_REAL_METHODS));
}
}
diff --git a/oak-exercise/src/test/java/org/apache/jackrabbit/oak/exercise/security/authorization/accesscontrol/L5_AccessControlListImplTest.java b/oak-exercise/src/test/java/org/apache/jackrabbit/oak/exercise/security/authorization/accesscontrol/L5_AccessControlListImplTest.java
index 1a76875..114b14e 100644
--- a/oak-exercise/src/test/java/org/apache/jackrabbit/oak/exercise/security/authorization/accesscontrol/L5_AccessControlListImplTest.java
+++ b/oak-exercise/src/test/java/org/apache/jackrabbit/oak/exercise/security/authorization/accesscontrol/L5_AccessControlListImplTest.java
@@ -20,6 +20,7 @@ import java.security.Principal;
import java.util.Collections;
import java.util.List;
import javax.jcr.RepositoryException;
+import javax.jcr.UnsupportedRepositoryOperationException;
import javax.jcr.Value;
import javax.jcr.security.AccessControlEntry;
import javax.jcr.security.AccessControlException;
@@ -31,6 +32,7 @@ import org.apache.jackrabbit.api.JackrabbitSession;
import org.apache.jackrabbit.api.JackrabbitWorkspace;
import org.apache.jackrabbit.api.security.JackrabbitAccessControlEntry;
import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
+import org.apache.jackrabbit.api.security.authorization.PrivilegeCollection;
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.commons.jackrabbit.authorization.AccessControlUtils;
import org.apache.jackrabbit.oak.exercise.ExerciseUtility;
@@ -266,6 +268,11 @@ public class L5_AccessControlListImplTest extends AbstractJCRTest {
return null;
}
+ @Override
+ public @NotNull PrivilegeCollection getPrivilegeCollection() throws RepositoryException {
+ throw new UnsupportedRepositoryOperationException();
+ }
+
public Principal getPrincipal() {
return testPrincipal;
}
diff --git a/oak-jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/JackrabbitAccessControlEntry.java b/oak-jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/JackrabbitAccessControlEntry.java
index 829915c..754e5e4 100644
--- a/oak-jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/JackrabbitAccessControlEntry.java
+++ b/oak-jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/JackrabbitAccessControlEntry.java
@@ -16,15 +16,16 @@
*/
package org.apache.jackrabbit.api.security;
+import org.apache.jackrabbit.api.security.authorization.PrivilegeCollection;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.osgi.annotation.versioning.ProviderType;
+
import javax.jcr.RepositoryException;
import javax.jcr.Value;
import javax.jcr.ValueFormatException;
import javax.jcr.security.AccessControlEntry;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.osgi.annotation.versioning.ProviderType;
-
/**
* <code>JackrabbitAccessControlEntry</code> is a Jackrabbit specific extension
* of the <code>AccessControlEntry</code> interface. It represents an single
@@ -83,4 +84,15 @@ public interface JackrabbitAccessControlEntry extends AccessControlEntry {
*/
@Nullable
Value[] getRestrictions(@NotNull String restrictionName) throws RepositoryException;
+
+ /**
+ * Returns a {@link PrivilegeCollection} representing the privileges associated with this entry.
+ *
+ * @return A {@link PrivilegeCollection} wrapping around the privileges defined for this instance of {@code JackrabbitAccessControlEntry}.
+ * @throws RepositoryException If an error occurs.
+ * @since Oak 1.42.0
+ * @see #getPrivileges()
+ */
+ @NotNull
+ PrivilegeCollection getPrivilegeCollection() throws RepositoryException;
}
diff --git a/oak-jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/JackrabbitAccessControlManager.java b/oak-jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/JackrabbitAccessControlManager.java
index 135ee74..50f434c 100644
--- a/oak-jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/JackrabbitAccessControlManager.java
+++ b/oak-jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/JackrabbitAccessControlManager.java
@@ -26,6 +26,8 @@ import javax.jcr.security.AccessControlPolicy;
import javax.jcr.security.Privilege;
import java.security.Principal;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Set;
import org.apache.jackrabbit.api.security.authorization.PrivilegeCollection;
@@ -220,4 +222,28 @@ public interface JackrabbitAccessControlManager extends AccessControlManager {
default PrivilegeCollection getPrivilegeCollection(@Nullable String absPath, @NotNull Set<Principal> principals) throws RepositoryException {
return new PrivilegeCollection.Default(getPrivileges(absPath, principals), this);
}
+
+ /**
+ * <p>Returns the {@link PrivilegeCollection} for the specified <code>privilegeNames</code>.
+ * Since the privilege names are JCR names, they may be passed in either
+ * qualified or expanded form (see specification for details on JCR names).</p>
+ *
+ * Note: For backwards compatibility this method comes with a default implementation that computes the {@link PrivilegeCollection}
+ * using regular JCR/Jackrabbit API, which might not be efficient. Implementations of {@link JackrabbitAccessControlManager}
+ * are therefore expected to overwrite the default.
+ *
+ * @param privilegeNames the names of existing privilege.
+ * @return the <code>PrivilegeCollection</code> representing the specified <code>privilegeNames</code>.
+ * @throws AccessControlException if no privilege with any of the specified names exists.
+ * @throws RepositoryException If another error occurs.
+ * @since Oak 1.42.0
+ */
+ @NotNull
+ default PrivilegeCollection privilegeCollectionFromNames(@NotNull String... privilegeNames) throws RepositoryException {
+ List<Privilege> privileges = new ArrayList<>();
+ for (String privilegeName : privilegeNames) {
+ privileges.add(privilegeFromName(privilegeName));
+ }
+ return new PrivilegeCollection.Default(privileges.toArray(new Privilege[0]), this);
+ }
}
\ No newline at end of file
diff --git a/oak-jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/authorization/package-info.java b/oak-jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/authorization/package-info.java
index 132dc73..d4e3e40 100644
--- a/oak-jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/authorization/package-info.java
+++ b/oak-jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/authorization/package-info.java
@@ -18,5 +18,5 @@
/**
* Jackrabbit extensions for authorization.
*/
-@org.osgi.annotation.versioning.Version("2.5.0")
+@org.osgi.annotation.versioning.Version("2.6.0")
package org.apache.jackrabbit.api.security.authorization;
diff --git a/oak-jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/package-info.java b/oak-jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/package-info.java
index 4e7c077..b4db9fd 100644
--- a/oak-jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/package-info.java
+++ b/oak-jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/package-info.java
@@ -18,5 +18,5 @@
/**
* Jackrabbit extensions for access control.
*/
-@org.osgi.annotation.versioning.Version("2.5.0")
+@org.osgi.annotation.versioning.Version("2.6.0")
package org.apache.jackrabbit.api.security;
diff --git a/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ACE.java b/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ACE.java
index 468731c..e070afd 100644
--- a/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ACE.java
+++ b/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ACE.java
@@ -20,17 +20,21 @@ import com.google.common.base.Objects;
import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableSet;
import org.apache.jackrabbit.api.security.JackrabbitAccessControlEntry;
+import org.apache.jackrabbit.api.security.authorization.PrivilegeCollection;
import org.apache.jackrabbit.oak.namepath.NamePathMapper;
import org.apache.jackrabbit.oak.plugins.value.jcr.PartialValueFactory;
import org.apache.jackrabbit.oak.spi.security.authorization.restriction.Restriction;
import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBits;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBitsProvider;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.osgi.annotation.versioning.ProviderType;
import javax.jcr.RepositoryException;
import javax.jcr.Value;
import javax.jcr.ValueFormatException;
import javax.jcr.security.AccessControlException;
+import javax.jcr.security.Privilege;
import java.security.Principal;
import java.util.Collections;
import java.util.List;
@@ -41,6 +45,7 @@ import java.util.Set;
* It asserts that the basic contract is fulfilled but does perform any additional
* validation on the principal, the privileges or the specified restrictions.
*/
+@ProviderType
public abstract class ACE implements JackrabbitAccessControlEntry {
private final Principal principal;
@@ -60,7 +65,7 @@ public abstract class ACE implements JackrabbitAccessControlEntry {
* @param isAllow {@code true} if the entry is granting privileges.
* @param restrictions A optional set of restrictions.
* @param namePathMapper The name-path mapper
- * @throws AccessControlException If the given {@code principal} or {@code privilgeBits} are {@code null} or if {@code privilgeBits} are {@link PrivilegeBits#isEmpty() empty}.
+ * @throws AccessControlException If the given {@code principal} or {@code privilegeBits} are {@code null} or if {@code privilegeBits} are {@link PrivilegeBits#isEmpty() empty}.
*/
public ACE(@Nullable Principal principal, @Nullable PrivilegeBits privilegeBits,
boolean isAllow, @Nullable Set<Restriction> restrictions,
@@ -87,6 +92,9 @@ public abstract class ACE implements JackrabbitAccessControlEntry {
public Set<Restriction> getRestrictions() {
return restrictions;
}
+
+ @NotNull
+ protected abstract PrivilegeBitsProvider getPrivilegeBitsProvider();
//-------------------------------------------------< AccessControlEntry >---
@NotNull
@@ -141,6 +149,26 @@ public abstract class ACE implements JackrabbitAccessControlEntry {
return null;
}
+ @Override
+ public @NotNull PrivilegeCollection getPrivilegeCollection() {
+ return new AbstractPrivilegeCollection(privilegeBits) {
+ @Override
+ public Privilege[] getPrivileges() {
+ return ACE.this.getPrivileges();
+ }
+
+ @Override
+ @NotNull PrivilegeBitsProvider getPrivilegeBitsProvider() {
+ return ACE.this.getPrivilegeBitsProvider();
+ }
+
+ @Override
+ @NotNull NamePathMapper getNamePathMapper() {
+ return namePathMapper;
+ }
+ };
+ }
+
//-------------------------------------------------------------< Object >---
@Override
diff --git a/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/AbstractAccessControlManager.java b/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/AbstractAccessControlManager.java
index 4b51d36..773e98d 100644
--- a/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/AbstractAccessControlManager.java
+++ b/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/AbstractAccessControlManager.java
@@ -28,12 +28,12 @@ import org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfigu
import org.apache.jackrabbit.oak.spi.security.authorization.permission.PermissionAware;
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.privilege.PrivilegeBits;
import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBitsProvider;
import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConfiguration;
import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.osgi.annotation.versioning.ProviderType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -53,6 +53,7 @@ import java.util.Set;
* This implementation covers both editing access control content by path and
* by {@code Principal} resulting both in the same content structure.
*/
+@ProviderType
public abstract class AbstractAccessControlManager implements JackrabbitAccessControlManager, AccessControlConstants {
private static final Logger log = LoggerFactory.getLogger(AbstractAccessControlManager.class);
@@ -127,7 +128,7 @@ public abstract class AbstractAccessControlManager implements JackrabbitAccessCo
@Override
public @NotNull PrivilegeCollection getPrivilegeCollection(@Nullable String absPath) throws RepositoryException {
- return getPrivilegeCollection(absPath, getPermissionProvider(), Permissions.NO_PERMISSION);
+ return getPrivilegeCollection(getPrivilegeNames(absPath, getPermissionProvider(), Permissions.NO_PERMISSION));
}
@Override
@@ -136,10 +137,15 @@ public abstract class AbstractAccessControlManager implements JackrabbitAccessCo
return getPrivilegeCollection(absPath);
} else {
PermissionProvider provider = config.getPermissionProvider(root, workspaceName, principals);
- return getPrivilegeCollection(absPath, provider, Permissions.READ_ACCESS_CONTROL);
+ return getPrivilegeCollection(getPrivilegeNames(absPath, provider, Permissions.READ_ACCESS_CONTROL));
}
}
+ @Override
+ public @NotNull PrivilegeCollection privilegeCollectionFromNames(@NotNull String... privilegeNames) throws RepositoryException {
+ return getPrivilegeCollection(PrivilegeUtil.getOakNames(privilegeNames, namePathMapper));
+ }
+
//----------------------------------------------------------< protected >---
@NotNull
protected AuthorizationConfiguration getConfig() {
@@ -295,28 +301,23 @@ public abstract class AbstractAccessControlManager implements JackrabbitAccessCo
return provider.hasPrivileges(tree, privilegeNames.toArray(new String[0]));
}
}
-
+
@NotNull
- private PrivilegeCollection getPrivilegeCollection(@Nullable String absPath, @NotNull PermissionProvider provider, long permissions) throws RepositoryException {
- Set<String> pNames = getPrivilegeNames(absPath, provider, permissions);
- return new PrivilegeCollection() {
+ private PrivilegeCollection getPrivilegeCollection(@NotNull Set<String> pNames) {
+ return new AbstractPrivilegeCollection(getPrivilegeBitsProvider().getBits(pNames)) {
@Override
public Privilege[] getPrivileges() throws RepositoryException {
return AbstractAccessControlManager.this.getPrivileges(pNames);
}
@Override
- public boolean includes(@NotNull String... privilegeNames) throws RepositoryException {
- if (privilegeNames.length == 0) {
- return true;
- }
- if (pNames.isEmpty()) {
- return false;
- }
- PrivilegeBitsProvider pbp = getPrivilegeBitsProvider();
- PrivilegeBits toTest = pbp.getBits(PrivilegeUtil.getOakNames(privilegeNames, getNamePathMapper()), true);
- PrivilegeBits bits = pbp.getBits(pNames);
- return bits.includes(toTest);
+ @NotNull PrivilegeBitsProvider getPrivilegeBitsProvider() {
+ return AbstractAccessControlManager.this.getPrivilegeBitsProvider();
+ }
+
+ @Override
+ @NotNull NamePathMapper getNamePathMapper() {
+ return AbstractAccessControlManager.this.getNamePathMapper();
}
};
}
diff --git a/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/AbstractPrivilegeCollection.java b/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/AbstractPrivilegeCollection.java
new file mode 100644
index 0000000..a25c3dd
--- /dev/null
+++ b/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/AbstractPrivilegeCollection.java
@@ -0,0 +1,68 @@
+/*
+ * 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.spi.security.authorization.accesscontrol;
+
+import org.apache.jackrabbit.api.security.authorization.PrivilegeCollection;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBits;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBitsProvider;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeUtil;
+import org.jetbrains.annotations.NotNull;
+
+import javax.jcr.RepositoryException;
+import java.util.Objects;
+
+abstract class AbstractPrivilegeCollection implements PrivilegeCollection {
+
+ private final PrivilegeBits privilegeBits;
+
+ AbstractPrivilegeCollection(@NotNull PrivilegeBits privilegeBits) {
+ this.privilegeBits = privilegeBits;
+ }
+
+ abstract @NotNull PrivilegeBitsProvider getPrivilegeBitsProvider();
+ abstract @NotNull NamePathMapper getNamePathMapper();
+
+ @Override
+ public boolean includes(@NotNull String... privilegeNames) throws RepositoryException {
+ if (privilegeNames.length == 0) {
+ return true;
+ }
+ if (privilegeBits.isEmpty()) {
+ return false;
+ }
+ PrivilegeBits toTest = getPrivilegeBitsProvider().getBits(PrivilegeUtil.getOakNames(privilegeNames, getNamePathMapper()), true);
+ return privilegeBits.includes(toTest);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(privilegeBits);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (obj instanceof AbstractPrivilegeCollection) {
+ AbstractPrivilegeCollection other = (AbstractPrivilegeCollection) obj;
+ return privilegeBits.equals(other.privilegeBits);
+ }
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/package-info.java b/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/package-info.java
index 8bdef7e..a4f2ad2 100644
--- a/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/package-info.java
+++ b/oak-security-spi/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/package-info.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-@Version("1.8.0")
+@Version("1.9.0")
package org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol;
import org.osgi.annotation.versioning.Version;
diff --git a/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ACETest.java b/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ACETest.java
index 5132242..67a4c07 100644
--- a/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ACETest.java
+++ b/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/ACETest.java
@@ -21,6 +21,7 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import org.apache.jackrabbit.api.security.JackrabbitAccessControlEntry;
+import org.apache.jackrabbit.api.security.authorization.PrivilegeCollection;
import org.apache.jackrabbit.oak.api.Root;
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.plugins.memory.PropertyStates;
@@ -29,7 +30,10 @@ import org.apache.jackrabbit.oak.spi.security.authorization.restriction.Restrict
import org.apache.jackrabbit.oak.spi.security.authorization.restriction.RestrictionImpl;
import org.apache.jackrabbit.oak.spi.security.principal.EveryonePrincipal;
import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBits;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBitsProvider;
import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.junit.Before;
import org.junit.Test;
@@ -40,9 +44,14 @@ import javax.jcr.ValueFactory;
import javax.jcr.ValueFormatException;
import javax.jcr.security.AccessControlException;
import javax.jcr.security.Privilege;
+import java.security.Principal;
import java.util.Collections;
import java.util.Set;
+import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_READ;
+import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_WRITE;
+import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.REP_READ_NODES;
+import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.REP_READ_PROPERTIES;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -52,7 +61,12 @@ import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.CALLS_REAL_METHODS;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.withSettings;
/**
* Tests for {@link ACE}
@@ -73,9 +87,15 @@ public class ACETest extends AbstractAccessControlTest {
valueFactory.createValue("nt:file", PropertyType.NAME)
};
}
+
+ private ACE mockACE(@NotNull Principal principal, @NotNull PrivilegeBits bits, boolean isAllow, @Nullable Set<Restriction> rest) {
+ ACE ace = mock(ACE.class, withSettings().useConstructor(principal, bits, isAllow, rest, getNamePathMapper()).defaultAnswer(CALLS_REAL_METHODS));
+ when(ace.getPrivilegeBitsProvider()).thenReturn(getBitsProvider());
+ return ace;
+ }
private ACE createEntry(Restriction... restrictions) throws Exception {
- return createEntry(testPrincipal, PrivilegeBits.BUILT_IN.get(PrivilegeConstants.JCR_READ), true, restrictions);
+ return createEntry(testPrincipal, PrivilegeBits.BUILT_IN.get(JCR_READ), true, restrictions);
}
private Restriction createRestriction(String name, String value) {
@@ -92,16 +112,16 @@ public class ACETest extends AbstractAccessControlTest {
@Test
public void testIsAllow() throws RepositoryException {
- ACE ace = createEntry(true, PrivilegeConstants.JCR_READ);
+ ACE ace = createEntry(true, JCR_READ);
assertTrue(ace.isAllow());
- ace = createEntry(false, PrivilegeConstants.JCR_READ);
+ ace = createEntry(false, JCR_READ);
assertFalse(ace.isAllow());
}
@Test
public void testGetPrincipal() throws RepositoryException {
- ACE tmpl = createEntry(true, PrivilegeConstants.JCR_READ);
+ ACE tmpl = createEntry(true, JCR_READ);
assertNotNull(tmpl.getPrincipal());
assertEquals(testPrincipal.getName(), tmpl.getPrincipal().getName());
assertSame(testPrincipal, tmpl.getPrincipal());
@@ -109,7 +129,7 @@ public class ACETest extends AbstractAccessControlTest {
@Test(expected = AccessControlException.class)
public void testNullPrincipal() throws Exception {
- createEntry(null, PrivilegeBits.BUILT_IN.get(PrivilegeConstants.JCR_READ), true);
+ createEntry(null, PrivilegeBits.BUILT_IN.get(JCR_READ), true);
}
@Test(expected = AccessControlException.class)
@@ -124,11 +144,11 @@ public class ACETest extends AbstractAccessControlTest {
@Test
public void testGetPrivilegeBits() throws RepositoryException {
- ACE entry = createEntry(true, PrivilegeConstants.JCR_READ);
+ ACE entry = createEntry(true, JCR_READ);
PrivilegeBits bits = entry.getPrivilegeBits();
assertNotNull(bits);
- assertEquals(PrivilegeBits.BUILT_IN.get(PrivilegeConstants.JCR_READ), bits);
+ assertEquals(PrivilegeBits.BUILT_IN.get(JCR_READ), bits);
entry = createEntry(true, PrivilegeConstants.REP_WRITE);
bits = entry.getPrivilegeBits();
@@ -148,46 +168,59 @@ public class ACETest extends AbstractAccessControlTest {
@Test(expected = AccessControlException.class)
public void testNullPrivileges() throws Exception {
- new ACE(testPrincipal, null, true, Collections.emptySet(), getNamePathMapper()) {
- @Override
- public Privilege[] getPrivileges() {
- return new Privilege[0];
- }
- };
+ createEmptyEntry(null);
}
@Test(expected = AccessControlException.class)
public void testEmptyPrivileges() throws Exception {
- new ACE(testPrincipal, PrivilegeBits.EMPTY, true, null, getNamePathMapper()) {
+ createEmptyEntry(PrivilegeBits.EMPTY);
+ }
+
+ @NotNull
+ private ACE createEmptyEntry(@Nullable PrivilegeBits bits) throws AccessControlException {
+ return new ACE(testPrincipal, bits, true, Collections.emptySet(), getNamePathMapper()) {
@Override
- public Privilege[] getPrivileges() {
- return new Privilege[0];
+ protected @NotNull PrivilegeBitsProvider getPrivilegeBitsProvider() {
+ return getBitsProvider();
}
- };
- }
- @Test
- public void testNullRestrictions() throws Exception {
- ACE ace = new ACE(testPrincipal, PrivilegeBits.BUILT_IN.get(PrivilegeConstants.JCR_READ), true, null, getNamePathMapper()) {
@Override
public Privilege[] getPrivileges() {
return new Privilege[0];
}
};
+ }
+
+ @Test
+ public void testGetPrivilegeCollection() throws RepositoryException {
+ ACE entry = mockACE(testPrincipal,PrivilegeBits.BUILT_IN.get(JCR_READ), true, null);
+
+ PrivilegeCollection pc = entry.getPrivilegeCollection();
+ assertTrue(pc instanceof AbstractPrivilegeCollection);
+
+ assertArrayEquals(entry.getPrivileges(), pc.getPrivileges());
+ verify(entry, times(2)).getPrivileges();
+
+ assertTrue(pc.includes(JCR_READ));
+ assertTrue(pc.includes(REP_READ_NODES));
+ assertTrue(pc.includes(REP_READ_PROPERTIES));
+ assertFalse(pc.includes(JCR_READ, JCR_WRITE));
+
+ assertEquals(pc, entry.getPrivilegeCollection());
+ }
+
+ @Test
+ public void testNullRestrictions() {
+ ACE ace = mockACE(testPrincipal, PrivilegeBits.BUILT_IN.get(JCR_READ), true, null);
assertTrue(ace.getRestrictions().isEmpty());
}
@Test
- public void testRestrictions() throws Exception {
+ public void testRestrictions() {
Restriction r = new RestrictionImpl(PropertyStates.createProperty("r", "v"), false);
Restriction r2 = new RestrictionImpl(PropertyStates.createProperty("r2", ImmutableList.of("v"), Type.STRINGS), false);
Set<Restriction> restrictions = Sets.newHashSet(r, r2);
- ACE ace = new ACE(testPrincipal, PrivilegeBits.BUILT_IN.get(PrivilegeConstants.JCR_READ), true, restrictions, getNamePathMapper()) {
- @Override
- public Privilege[] getPrivileges() {
- return new Privilege[0];
- }
- };
+ ACE ace = mockACE(testPrincipal, PrivilegeBits.BUILT_IN.get(JCR_READ), true, restrictions);
assertFalse(ace.getRestrictions().isEmpty());
assertNotSame(restrictions, ace.getRestrictions());
assertTrue(Iterables.elementsEqual(restrictions, ace.getRestrictions()));
@@ -333,52 +366,52 @@ public class ACETest extends AbstractAccessControlTest {
@Test
public void testGetRestrictionsNone() throws Exception {
- ACE ace = createEntry(testPrincipal, PrivilegeBits.BUILT_IN.get(PrivilegeConstants.JCR_READ), true);
+ ACE ace = createEntry(testPrincipal, PrivilegeBits.BUILT_IN.get(JCR_READ), true);
assertTrue(ace.getRestrictions().isEmpty());
}
@Test
public void testEqualsSameACE() throws Exception {
- ACE ace = createEntry(testPrincipal, PrivilegeBits.BUILT_IN.get(PrivilegeConstants.JCR_READ), true);
+ ACE ace = createEntry(testPrincipal, PrivilegeBits.BUILT_IN.get(JCR_READ), true);
assertEquals(ace, ace);
}
@Test
public void testEqualsACE() throws Exception {
- ACE ace = createEntry(testPrincipal, PrivilegeBits.BUILT_IN.get(PrivilegeConstants.JCR_READ), true);
- ACE ace2 = createEntry(testPrincipal, PrivilegeBits.BUILT_IN.get(PrivilegeConstants.JCR_READ), true);
+ ACE ace = createEntry(testPrincipal, PrivilegeBits.BUILT_IN.get(JCR_READ), true);
+ ACE ace2 = createEntry(testPrincipal, PrivilegeBits.BUILT_IN.get(JCR_READ), true);
assertEquals(ace, ace2);
}
@Test
public void testEqualsOtherEntryImpl() throws Exception {
- ACE ace = createEntry(testPrincipal, PrivilegeBits.BUILT_IN.get(PrivilegeConstants.JCR_READ), true);
+ ACE ace = createEntry(testPrincipal, PrivilegeBits.BUILT_IN.get(JCR_READ), true);
assertNotEquals(ace, mock(JackrabbitAccessControlEntry.class));
}
@Test
public void testEqualsDifferentAllow() throws Exception {
- ACE ace = createEntry(testPrincipal, PrivilegeBits.BUILT_IN.get(PrivilegeConstants.JCR_READ), true);
- ACE ace2 = createEntry(testPrincipal, PrivilegeBits.BUILT_IN.get(PrivilegeConstants.JCR_READ), false);
+ ACE ace = createEntry(testPrincipal, PrivilegeBits.BUILT_IN.get(JCR_READ), true);
+ ACE ace2 = createEntry(testPrincipal, PrivilegeBits.BUILT_IN.get(JCR_READ), false);
assertNotEquals(ace, ace2);
}
@Test
public void testEqualsDifferentPrincipal() throws Exception {
- ACE ace = createEntry(testPrincipal, PrivilegeBits.BUILT_IN.get(PrivilegeConstants.JCR_READ), true);
- ACE ace2 = createEntry(EveryonePrincipal.getInstance(), PrivilegeBits.BUILT_IN.get(PrivilegeConstants.JCR_READ), true);
+ ACE ace = createEntry(testPrincipal, PrivilegeBits.BUILT_IN.get(JCR_READ), true);
+ ACE ace2 = createEntry(EveryonePrincipal.getInstance(), PrivilegeBits.BUILT_IN.get(JCR_READ), true);
assertNotEquals(ace, ace2);
}
@Test
public void testEqualsDifferentPrivs() throws Exception {
- ACE ace = createEntry(testPrincipal, PrivilegeBits.BUILT_IN.get(PrivilegeConstants.JCR_READ), true);
+ ACE ace = createEntry(testPrincipal, PrivilegeBits.BUILT_IN.get(JCR_READ), true);
ACE ace2 = createEntry(testPrincipal, PrivilegeBits.BUILT_IN.get(PrivilegeConstants.JCR_ADD_CHILD_NODES), true);
assertNotEquals(ace, ace2);
@@ -386,16 +419,16 @@ public class ACETest extends AbstractAccessControlTest {
@Test
public void testEqualsDifferentRestrictions() throws Exception {
- ACE ace = createEntry(testPrincipal, PrivilegeBits.BUILT_IN.get(PrivilegeConstants.JCR_READ), true, createRestriction("name2", "val"));
- ACE ace2 = createEntry(testPrincipal, PrivilegeBits.BUILT_IN.get(PrivilegeConstants.JCR_READ), true, createRestriction("name", "val"));
+ ACE ace = createEntry(testPrincipal, PrivilegeBits.BUILT_IN.get(JCR_READ), true, createRestriction("name2", "val"));
+ ACE ace2 = createEntry(testPrincipal, PrivilegeBits.BUILT_IN.get(JCR_READ), true, createRestriction("name", "val"));
assertNotEquals(ace, ace2);
}
@Test
public void testEqualsDifferentRestrictionValue() throws Exception {
- ACE ace = createEntry(testPrincipal, PrivilegeBits.BUILT_IN.get(PrivilegeConstants.JCR_READ), true, createRestriction("name", "val"));
- ACE ace2 = createEntry(testPrincipal, PrivilegeBits.BUILT_IN.get(PrivilegeConstants.JCR_READ), true, createRestriction("name", "val2"));
+ ACE ace = createEntry(testPrincipal, PrivilegeBits.BUILT_IN.get(JCR_READ), true, createRestriction("name", "val"));
+ ACE ace2 = createEntry(testPrincipal, PrivilegeBits.BUILT_IN.get(JCR_READ), true, createRestriction("name", "val2"));
assertNotEquals(ace, ace2);
}
diff --git a/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/AbstractAccessControlManagerTest.java b/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/AbstractAccessControlManagerTest.java
index bd0515d..012bbfa 100644
--- a/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/AbstractAccessControlManagerTest.java
+++ b/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/AbstractAccessControlManagerTest.java
@@ -514,4 +514,15 @@ public class AbstractAccessControlManagerTest extends AbstractAccessControlTest
verify(acMgr).getPrivilegeCollection(testPath, getEveryonePrincipalSet());
verify(acMgr, never()).getPrivilegeCollection(testPath);
}
+
+ @Test
+ public void testPrivilegeCollectionFromNames() throws Exception {
+ PrivilegeCollection pc = acMgr.privilegeCollectionFromNames();
+ assertTrue(pc instanceof AbstractPrivilegeCollection);
+ assertArrayEquals(new Privilege[0], pc.getPrivileges());
+
+ pc = acMgr.privilegeCollectionFromNames(JCR_READ);
+ assertTrue(pc instanceof AbstractPrivilegeCollection);
+ assertArrayEquals(new Privilege[] {acMgr.privilegeFromName(JCR_READ)}, pc.getPrivileges());
+ }
}
diff --git a/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/AbstractAccessControlTest.java b/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/AbstractAccessControlTest.java
index d4abfaa..c5de49b 100644
--- a/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/AbstractAccessControlTest.java
+++ b/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/AbstractAccessControlTest.java
@@ -16,12 +16,6 @@
*/
package org.apache.jackrabbit.oak.spi.security.authorization.accesscontrol;
-import java.security.Principal;
-import java.util.Set;
-import javax.jcr.RepositoryException;
-import javax.jcr.security.AccessControlException;
-import javax.jcr.security.Privilege;
-
import com.google.common.collect.ImmutableSet;
import org.apache.jackrabbit.oak.api.Root;
import org.apache.jackrabbit.oak.namepath.NamePathMapper;
@@ -29,22 +23,30 @@ import org.apache.jackrabbit.oak.spi.security.authorization.restriction.Restrict
import org.apache.jackrabbit.oak.spi.security.principal.PrincipalImpl;
import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBits;
import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBitsProvider;
-import org.mockito.Mockito;
+import org.jetbrains.annotations.NotNull;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.security.AccessControlException;
+import javax.jcr.security.Privilege;
+import java.security.Principal;
+import java.util.Set;
+
+import static org.mockito.Mockito.mock;
public abstract class AbstractAccessControlTest {
- final Root root = Mockito.mock(Root.class);
+ final Root root = mock(Root.class);
Principal testPrincipal = new PrincipalImpl("testPrincipal");
- PrivilegeBitsProvider getBitsProvider() {
+ protected PrivilegeBitsProvider getBitsProvider() {
return new PrivilegeBitsProvider(root);
}
- NamePathMapper getNamePathMapper() {
+ protected NamePathMapper getNamePathMapper() {
return NamePathMapper.DEFAULT;
}
-
+
ACE createEntry(boolean isAllow, String... privilegeName)
throws RepositoryException {
if (privilegeName.length == 1) {
@@ -73,5 +75,10 @@ public abstract class AbstractAccessControlTest {
public Privilege[] getPrivileges() {
throw new UnsupportedOperationException();
}
+
+ @Override
+ protected @NotNull PrivilegeBitsProvider getPrivilegeBitsProvider() {
+ return getBitsProvider();
+ }
}
}
diff --git a/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/AbstractPrivilegeCollectionTest.java b/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/AbstractPrivilegeCollectionTest.java
new file mode 100644
index 0000000..050b2f7
--- /dev/null
+++ b/oak-security-spi/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/accesscontrol/AbstractPrivilegeCollectionTest.java
@@ -0,0 +1,130 @@
+/*
+ * 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.spi.security.authorization.accesscontrol;
+
+import org.apache.jackrabbit.api.security.authorization.PrivilegeCollection;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBits;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBitsProvider;
+import org.jetbrains.annotations.NotNull;
+import org.junit.Test;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.security.Privilege;
+
+import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_ADD_CHILD_NODES;
+import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_MODIFY_ACCESS_CONTROL;
+import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_MODIFY_PROPERTIES;
+import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_READ;
+import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_READ_ACCESS_CONTROL;
+import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_WRITE;
+import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.REP_READ_NODES;
+import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.REP_READ_PROPERTIES;
+import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.REP_WRITE;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+
+public class AbstractPrivilegeCollectionTest extends AbstractAccessControlTest {
+
+ private @NotNull AbstractPrivilegeCollection createPrivilegeCollection(@NotNull String... privilegeNames) {
+ return new AbstractPrivilegeCollection(getBitsProvider().getBits(privilegeNames)) {
+ @Override
+ @NotNull PrivilegeBitsProvider getPrivilegeBitsProvider() {
+ return AbstractPrivilegeCollectionTest.this.getBitsProvider();
+ }
+
+ @Override
+ @NotNull NamePathMapper getNamePathMapper() {
+ return AbstractPrivilegeCollectionTest.this.getNamePathMapper();
+ }
+
+ @Override
+ public Privilege[] getPrivileges() throws RepositoryException {
+ throw new RepositoryException("not implemented");
+ }
+ };
+ }
+
+ @Test
+ public void testIncludes() throws Exception {
+ AbstractPrivilegeCollection apc = createPrivilegeCollection(JCR_WRITE, JCR_READ);
+
+ assertTrue(apc.includes());
+ assertTrue(apc.includes(JCR_WRITE, JCR_READ));
+ assertTrue(apc.includes(JCR_WRITE));
+ assertTrue(apc.includes(JCR_READ));
+ assertTrue(apc.includes(REP_READ_NODES, REP_READ_NODES));
+
+ assertFalse(apc.includes(JCR_MODIFY_ACCESS_CONTROL));
+ assertFalse(apc.includes(REP_WRITE));
+ }
+
+ @Test
+ public void testEquals() {
+ PrivilegeCollection apc = createPrivilegeCollection(JCR_READ_ACCESS_CONTROL, JCR_READ);
+
+ assertEquals(apc, createPrivilegeCollection(JCR_READ, JCR_READ_ACCESS_CONTROL));
+ assertEquals(apc, createPrivilegeCollection(REP_READ_PROPERTIES, REP_READ_NODES, JCR_READ_ACCESS_CONTROL));
+ assertEquals(apc, createPrivilegeCollection(REP_READ_PROPERTIES, REP_READ_NODES, JCR_READ, JCR_READ_ACCESS_CONTROL));
+ assertEquals(apc, apc);
+
+ assertNotEquals(apc, createPrivilegeCollection(JCR_READ_ACCESS_CONTROL));
+ assertNotEquals(apc, createPrivilegeCollection(JCR_READ));
+ assertNotEquals(apc, createPrivilegeCollection(JCR_READ_ACCESS_CONTROL, JCR_READ, JCR_MODIFY_PROPERTIES));
+ // different impl
+ assertNotEquals(apc, new PrivilegeCollection() {
+ @Override
+ public Privilege[] getPrivileges() {
+ return new Privilege[0];
+ }
+
+ @Override
+ public boolean includes(@NotNull String... privilegeNames) {
+ return false;
+ }
+ });
+ }
+
+ @Test
+ public void testHashCode() {
+ AbstractPrivilegeCollection apc = createPrivilegeCollection(JCR_ADD_CHILD_NODES, JCR_MODIFY_PROPERTIES);
+
+ assertEquals(getBitsProvider().getBits(JCR_ADD_CHILD_NODES, JCR_MODIFY_PROPERTIES).hashCode(), apc.hashCode());
+ assertEquals(apc.hashCode(), createPrivilegeCollection(JCR_ADD_CHILD_NODES, JCR_MODIFY_PROPERTIES).hashCode());
+
+ assertNotEquals(apc.hashCode(), createPrivilegeCollection(JCR_ADD_CHILD_NODES).hashCode());
+ assertNotEquals(apc.hashCode(), createPrivilegeCollection(JCR_MODIFY_PROPERTIES).hashCode());
+ assertNotEquals(apc.hashCode(), createPrivilegeCollection(JCR_READ).hashCode());
+ }
+
+ @Test
+ public void testEmpty() throws RepositoryException {
+ AbstractPrivilegeCollection apc = createPrivilegeCollection();
+
+ assertTrue(apc.includes());
+ assertFalse(apc.includes(REP_READ_NODES));
+
+ assertEquals(PrivilegeBits.EMPTY.hashCode(), apc.hashCode());
+
+ assertEquals(apc, createPrivilegeCollection());
+ assertNotEquals(apc, createPrivilegeCollection(JCR_READ));
+
+ }
+
+}
\ No newline at end of file