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 2012/11/20 11:10:00 UTC
svn commit: r1411605 - in /jackrabbit/oak/trunk:
oak-core/src/main/java/org/apache/jackrabbit/oak/core/
oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/
oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/privilege/
oak-co...
Author: angela
Date: Tue Nov 20 10:09:59 2012
New Revision: 1411605
URL: http://svn.apache.org/viewvc?rev=1411605&view=rev
Log:
OAK-64 : Privilege Management (WIP)
Removed:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/ReadOnlyPrivilegeManager.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/RootImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeConfigurationImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeManagerImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/privilege/PrivilegeConfiguration.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/core/RootImplTest.java
jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/RootImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/RootImpl.java?rev=1411605&r1=1411604&r2=1411605&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/RootImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/RootImpl.java Tue Nov 20 10:09:59 2012
@@ -118,6 +118,26 @@ public class RootImpl implements Root {
refresh();
}
+ /**
+ * Oak level variant of {@link org.apache.jackrabbit.oak.api.ContentSession#getLatestRoot()}
+ * to be used when no {@code ContentSession} is available.
+ *
+ * @return A new Root instance.
+ * @see org.apache.jackrabbit.oak.api.ContentSession#getLatestRoot()
+ */
+ public Root getLatest() {
+ checkLive();
+ RootImpl root = new RootImpl(store, null, subject, accConfiguration, indexProvider) {
+ protected void checkLive() {
+ RootImpl.this.checkLive();
+ }
+ };
+ if (conflictHandler != null) {
+ root.setConflictHandler(conflictHandler);
+ }
+ return root;
+ }
+
void setConflictHandler(ConflictHandler conflictHandler) {
this.conflictHandler = conflictHandler;
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeConfigurationImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeConfigurationImpl.java?rev=1411605&r1=1411604&r2=1411605&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeConfigurationImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeConfigurationImpl.java Tue Nov 20 10:09:59 2012
@@ -21,7 +21,6 @@ import java.util.List;
import javax.annotation.Nonnull;
import org.apache.jackrabbit.api.security.authorization.PrivilegeManager;
-import org.apache.jackrabbit.oak.api.ContentSession;
import org.apache.jackrabbit.oak.api.Root;
import org.apache.jackrabbit.oak.namepath.NamePathMapper;
import org.apache.jackrabbit.oak.spi.commit.ValidatorProvider;
@@ -37,13 +36,7 @@ public class PrivilegeConfigurationImpl
@Nonnull
@Override
public PrivilegeManager getPrivilegeManager(Root root, NamePathMapper namePathMapper) {
- return new ReadOnlyPrivilegeManager(root, namePathMapper);
- }
-
- @Nonnull
- @Override
- public PrivilegeManager getPrivilegeManager(ContentSession contentSession, Root root, NamePathMapper namePathMapper) {
- return new PrivilegeManagerImpl(root, namePathMapper, contentSession);
+ return new PrivilegeManagerImpl(root, namePathMapper);
}
@Nonnull
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeManagerImpl.java?rev=1411605&r1=1411604&r2=1411605&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeManagerImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/privilege/PrivilegeManagerImpl.java Tue Nov 20 10:09:59 2012
@@ -16,17 +16,25 @@
*/
package org.apache.jackrabbit.oak.security.privilege;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
import javax.jcr.InvalidItemStateException;
import javax.jcr.NamespaceException;
import javax.jcr.RepositoryException;
+import javax.jcr.UnsupportedRepositoryOperationException;
+import javax.jcr.security.AccessControlException;
import javax.jcr.security.Privilege;
-import org.apache.jackrabbit.oak.api.ContentSession;
+import org.apache.jackrabbit.api.security.authorization.PrivilegeManager;
import org.apache.jackrabbit.oak.api.Root;
+import org.apache.jackrabbit.oak.core.RootImpl;
import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants;
import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeDefinition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -34,19 +42,41 @@ import org.slf4j.LoggerFactory;
/**
* {@code PrivilegeManager} implementation reading from and storing privileges
* into the repository.
+ *
+ * TODO: review if jcr:all should be present in the content as well (updated in the privilege commit validator)
*/
-public class PrivilegeManagerImpl extends ReadOnlyPrivilegeManager {
+public class PrivilegeManagerImpl implements PrivilegeManager {
/**
* logger instance
*/
private static final Logger log = LoggerFactory.getLogger(PrivilegeManagerImpl.class);
- private final ContentSession contentSession;
+ final Root root;
+ final NamePathMapper namePathMapper;
- public PrivilegeManagerImpl(Root root, NamePathMapper namePathMapper, ContentSession contentSession) {
- super(root, namePathMapper);
- this.contentSession = contentSession;
+ public PrivilegeManagerImpl(Root root, NamePathMapper namePathMapper) {
+ this.root = root;
+ this.namePathMapper = namePathMapper;
+ }
+
+ @Override
+ public Privilege[] getRegisteredPrivileges() throws RepositoryException {
+ Set<Privilege> privileges = new HashSet<Privilege>();
+ for (PrivilegeDefinition def : getPrivilegeDefinitions()) {
+ privileges.add(getPrivilege(def));
+ }
+ return privileges.toArray(new Privilege[privileges.size()]);
+ }
+
+ @Override
+ public Privilege getPrivilege(String privilegeName) throws RepositoryException {
+ PrivilegeDefinition def = getPrivilegeDefinition(getOakName(privilegeName));
+ if (def == null) {
+ throw new AccessControlException("No such privilege " + privilegeName);
+ } else {
+ return getPrivilege(def);
+ }
}
@Override
@@ -64,7 +94,7 @@ public class PrivilegeManagerImpl extend
}
PrivilegeDefinition definition = new PrivilegeDefinitionImpl(oakName, isAbstract, getOakNames(declaredAggregateNames));
- PrivilegeDefinitionWriter writer = new PrivilegeDefinitionWriter(contentSession.getLatestRoot());
+ PrivilegeDefinitionWriter writer = new PrivilegeDefinitionWriter(getWriteRoot());
writer.writeDefinition(definition);
// refresh the current root to make sure the definition is visible
@@ -73,6 +103,14 @@ public class PrivilegeManagerImpl extend
}
//------------------------------------------------------------< private >---
+ private Root getWriteRoot() throws UnsupportedRepositoryOperationException {
+ if (root instanceof RootImpl) {
+ return ((RootImpl) root).getLatest();
+ } else {
+ throw new UnsupportedRepositoryOperationException("Privilege registration not supported");
+ }
+ }
+
private Set<String> getOakNames(String[] jcrNames) throws RepositoryException {
Set<String> oakNames;
if (jcrNames == null || jcrNames.length == 0) {
@@ -89,4 +127,124 @@ public class PrivilegeManagerImpl extend
}
return oakNames;
}
+
+ @CheckForNull
+ String getOakName(String jcrName) {
+ return namePathMapper.getOakName(jcrName);
+ }
+
+ @Nonnull
+ Privilege getPrivilege(PrivilegeDefinition definition) {
+ return new PrivilegeImpl(definition);
+ }
+
+ @Nonnull
+ private PrivilegeDefinition[] getPrivilegeDefinitions() {
+ Map<String, PrivilegeDefinition> definitions = getReader().readDefinitions();
+ definitions.put(PrivilegeConstants.JCR_ALL, getJcrAllDefinition(definitions));
+ return definitions.values().toArray(new PrivilegeDefinition[definitions.size()]);
+ }
+
+ @CheckForNull
+ private PrivilegeDefinition getPrivilegeDefinition(String oakName) {
+ if (PrivilegeConstants.JCR_ALL.equals(oakName)) {
+ return getJcrAllDefinition(getReader().readDefinitions());
+ } else {
+ return getReader().readDefinition(oakName);
+ }
+ }
+
+ @Nonnull
+ private PrivilegeDefinitionReader getReader() {
+ return new PrivilegeDefinitionReader(root);
+ }
+
+ @Nonnull
+ private static PrivilegeDefinition getJcrAllDefinition(Map<String, PrivilegeDefinition> definitions) {
+ return new PrivilegeDefinitionImpl(PrivilegeConstants.JCR_ALL, false, definitions.keySet());
+ }
+
+ //--------------------------------------------------------------------------
+ /**
+ * Privilege implementation based on a {@link org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeDefinition}.
+ */
+ private class PrivilegeImpl implements Privilege {
+
+ private final PrivilegeDefinition definition;
+
+ private PrivilegeImpl(PrivilegeDefinition definition) {
+ this.definition = definition;
+ }
+
+ //------------------------------------------------------< Privilege >---
+ @Override
+ public String getName() {
+ return namePathMapper.getJcrName(definition.getName());
+ }
+
+ @Override
+ public boolean isAbstract() {
+ return definition.isAbstract();
+ }
+
+ @Override
+ public boolean isAggregate() {
+ return !definition.getDeclaredAggregateNames().isEmpty();
+ }
+
+ @Override
+ public Privilege[] getDeclaredAggregatePrivileges() {
+ Set<String> declaredAggregateNames = definition.getDeclaredAggregateNames();
+ Set<Privilege> declaredAggregates = new HashSet<Privilege>(declaredAggregateNames.size());
+ for (String oakName : declaredAggregateNames) {
+ if (oakName.equals(definition.getName())) {
+ log.warn("Found cyclic privilege aggregation -> ignore declared aggregate " + oakName);
+ continue;
+ }
+ PrivilegeDefinition def = getPrivilegeDefinition(oakName);
+ if (def != null) {
+ declaredAggregates.add(getPrivilege(def));
+ } else {
+ log.warn("Invalid privilege '{}' in declared aggregates of '{}'", oakName, getName());
+ }
+ }
+ return declaredAggregates.toArray(new Privilege[declaredAggregates.size()]);
+ }
+
+ @Override
+ public Privilege[] getAggregatePrivileges() {
+ Set<Privilege> aggr = new HashSet<Privilege>();
+ for (Privilege decl : getDeclaredAggregatePrivileges()) {
+ aggr.add(decl);
+ if (decl.isAggregate()) {
+ // TODO: defensive check to prevent circular aggregation that might occur with inconsistent repositories
+ aggr.addAll(Arrays.asList(decl.getAggregatePrivileges()));
+ }
+ }
+ return aggr.toArray(new Privilege[aggr.size()]);
+ }
+
+ //---------------------------------------------------------< Object >---
+ @Override
+ public int hashCode() {
+ return definition.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == this) {
+ return true;
+ }
+ if (o instanceof PrivilegeImpl) {
+ return definition.equals(((PrivilegeImpl) o).definition);
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "Privilege " + definition.getName();
+ }
+ }
}
\ No newline at end of file
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/privilege/PrivilegeConfiguration.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/privilege/PrivilegeConfiguration.java?rev=1411605&r1=1411604&r2=1411605&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/privilege/PrivilegeConfiguration.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/privilege/PrivilegeConfiguration.java Tue Nov 20 10:09:59 2012
@@ -19,7 +19,6 @@ package org.apache.jackrabbit.oak.spi.se
import javax.annotation.Nonnull;
import org.apache.jackrabbit.api.security.authorization.PrivilegeManager;
-import org.apache.jackrabbit.oak.api.ContentSession;
import org.apache.jackrabbit.oak.api.Root;
import org.apache.jackrabbit.oak.namepath.NamePathMapper;
import org.apache.jackrabbit.oak.spi.security.SecurityConfiguration;
@@ -31,7 +30,4 @@ public interface PrivilegeConfiguration
@Nonnull
PrivilegeManager getPrivilegeManager(Root root, NamePathMapper namePathMapper);
-
- @Nonnull
- PrivilegeManager getPrivilegeManager(ContentSession contentSession, Root root, NamePathMapper namePathMapper);
}
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/core/RootImplTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/core/RootImplTest.java?rev=1411605&r1=1411604&r2=1411605&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/core/RootImplTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/core/RootImplTest.java Tue Nov 20 10:09:59 2012
@@ -34,8 +34,10 @@ import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
public class RootImplTest {
@@ -218,6 +220,28 @@ public class RootImplTest {
checkEqual(root1.getTree("/"), (root2.getTree("/")));
}
+ @Test
+ public void testGetLatest() throws Exception {
+ RootImpl root = (RootImpl) session.getLatestRoot();
+ Root root2 = root.getLatest();
+ assertNotSame(root, root2);
+
+ session.close();
+ try {
+ root.getLatest();
+ fail();
+ } catch (IllegalStateException e) {
+ // success
+ }
+
+ try {
+ ((RootImpl) root2).checkLive();
+ fail();
+ } catch (IllegalStateException e) {
+ // success
+ }
+ }
+
private static void checkEqual(Tree tree1, Tree tree2) {
assertEquals(tree1.getChildrenCount(), tree2.getChildrenCount());
assertEquals(tree1.getPropertyCount(), tree2.getPropertyCount());
Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java?rev=1411605&r1=1411604&r2=1411605&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java Tue Nov 20 10:09:59 2012
@@ -515,7 +515,7 @@ public class SessionDelegate {
PrivilegeManager getPrivilegeManager() throws UnsupportedRepositoryOperationException {
if (privilegeManager == null) {
if (securityProvider != null) {
- privilegeManager = securityProvider.getPrivilegeConfiguration().getPrivilegeManager(contentSession, root, getNamePathMapper());
+ privilegeManager = securityProvider.getPrivilegeConfiguration().getPrivilegeManager(root, getNamePathMapper());
} else {
throw new UnsupportedRepositoryOperationException("Privilege management not supported.");
}