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 2013/02/28 19:27:07 UTC
svn commit: r1451277 - in
/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak:
core/ security/authorization/ security/authorization/permission/
spi/security/authorization/
Author: angela
Date: Thu Feb 28 18:27:06 2013
New Revision: 1451277
URL: http://svn.apache.org/r1451277
Log:
OAK-527: permissions (wip)
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/authorization/AccessControlManagerImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionProviderImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/OpenPermissionProvider.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/PermissionProvider.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=1451277&r1=1451276&r2=1451277&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 Thu Feb 28 18:27:06 2013
@@ -78,11 +78,10 @@ public class RootImpl implements Root {
private final Subject subject;
- /**
- * The security provider.
- */
private final SecurityProvider securityProvider;
+ private final QueryIndexProvider indexProvider;
+
/**
* Current branch this root operates on
*/
@@ -99,7 +98,7 @@ public class RootImpl implements Root {
*/
private int modCount;
- private final QueryIndexProvider indexProvider;
+ private PermissionProvider permissionProvider;
/**
* New instance bases on a given {@link NodeStore} and a workspace
@@ -228,6 +227,7 @@ public class RootImpl implements Root {
purgePendingChanges();
branch.rebase();
rootTree = TreeImpl.createRoot(this);
+ permissionProvider = createPermissionProvider();
}
}
@@ -237,6 +237,11 @@ public class RootImpl implements Root {
branch = store.branch();
rootTree = TreeImpl.createRoot(this);
modCount = 0;
+ if (permissionProvider == null) {
+ permissionProvider = createPermissionProvider();
+ } else {
+ permissionProvider.refresh();
+ }
}
@Override
@@ -355,6 +360,7 @@ public class RootImpl implements Root {
};
}
+ @Nonnull
private QueryIndexProvider getIndexProvider() {
if (hasPendingChanges()) {
return new UUIDDiffIndexProviderWrapper(indexProvider,
@@ -375,6 +381,7 @@ public class RootImpl implements Root {
return branch.getBase();
}
+ @Nonnull
NodeBuilder createRootBuilder() {
return branch.getHead().builder();
}
@@ -387,8 +394,9 @@ public class RootImpl implements Root {
}
}
+ @Nonnull
PermissionProvider getPermissionProvider() {
- return securityProvider.getAccessControlConfiguration().getPermissionProvider(this, subject.getPrincipals());
+ return permissionProvider;
}
//------------------------------------------------------------< private >---
@@ -408,4 +416,7 @@ public class RootImpl implements Root {
rootTree.getNodeBuilder().reset(branch.getHead());
}
+ private PermissionProvider createPermissionProvider() {
+ return securityProvider.getAccessControlConfiguration().getPermissionProvider(this, subject.getPrincipals());
+ }
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlManagerImpl.java?rev=1451277&r1=1451276&r2=1451277&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlManagerImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/AccessControlManagerImpl.java Thu Feb 28 18:27:06 2013
@@ -109,7 +109,6 @@ public class AccessControlManagerImpl im
Subject subject = Subject.getSubject(AccessController.getContext());
Set<Principal> principals = (subject != null) ? subject.getPrincipals() : Collections.<Principal>emptySet();
- // FIXME: keep permission provider up to date.
permissionProvider = acConfig.getPermissionProvider(root, principals);
restrictionProvider = acConfig.getRestrictionProvider(namePathMapper);
ntMgr = ReadOnlyNodeTypeManager.getInstance(root, namePathMapper);
@@ -131,12 +130,14 @@ public class AccessControlManagerImpl im
@Override
public boolean hasPrivileges(@Nullable String absPath, @Nonnull Privilege[] privileges) throws RepositoryException {
+ permissionProvider.refresh();
return hasPrivileges(absPath, privileges, permissionProvider);
}
@Nonnull
@Override
public Privilege[] getPrivileges(@Nullable String absPath) throws RepositoryException {
+ permissionProvider.refresh();
return getPrivileges(absPath, permissionProvider);
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImpl.java?rev=1451277&r1=1451276&r2=1451277&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImpl.java Thu Feb 28 18:27:06 2013
@@ -18,9 +18,11 @@ package org.apache.jackrabbit.oak.securi
import java.security.Principal;
import java.security.acl.Group;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -28,6 +30,7 @@ import com.google.common.collect.Immutab
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.core.ReadOnlyRoot;
import org.apache.jackrabbit.oak.core.ReadOnlyTree;
import org.apache.jackrabbit.oak.security.authorization.AccessControlConstants;
import org.apache.jackrabbit.oak.security.privilege.PrivilegeBits;
@@ -35,6 +38,7 @@ import org.apache.jackrabbit.oak.securit
import org.apache.jackrabbit.oak.spi.security.authorization.Permissions;
import org.apache.jackrabbit.util.Text;
+import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
/**
@@ -43,28 +47,29 @@ import static com.google.common.base.Pre
class CompiledPermissionImpl implements CompiledPermissions, AccessControlConstants {
private final Set<Principal> principals;
- private final PrivilegeBitsProvider bitsProvider;
+ private final Map<String, ReadOnlyTree> trees;
- private final Map<Key, Entry> userEntries;
- private final Map<Key, Entry> groupEntries;
+ private PrivilegeBitsProvider bitsProvider;
+ private Map<Key, Entry> userEntries;
+ private Map<Key, Entry> groupEntries;
CompiledPermissionImpl(@Nonnull Set<Principal> principals,
- @Nonnull PrivilegeBitsProvider bitsProvider,
- @Nonnull ReadOnlyTree permissionsTree) {
+ @Nonnull ReadOnlyTree permissionsTree,
+ @Nonnull PrivilegeBitsProvider bitsProvider) {
this.principals = checkNotNull(principals);
- this.bitsProvider = bitsProvider;
+ checkArgument(!principals.isEmpty());
+ this.trees = new HashMap<String, ReadOnlyTree>(principals.size());
+ update(permissionsTree, bitsProvider);
+ }
- EntriesBuilder builder = new EntriesBuilder();
- for (Principal principal : principals) {
- Tree t = permissionsTree.getChild(Text.escapeIllegalJcrChars(principal.getName()));
- if (t != null) {
- builder.addEntry(principal, t);
- }
- }
- userEntries = builder.userEntries.build();
- groupEntries = builder.groupEntries.build();
+ void update(@Nonnull ReadOnlyTree permissionsTree, @Nonnull PrivilegeBitsProvider bitsProvider) {
+ // TODO: determine if entries need to be reloaded due to changes to the
+ // TODO: affected permission-nodes.
+ this.bitsProvider = bitsProvider;
+ buildEntries(permissionsTree);
}
+ //------------------------------------------------< CompiledPermissions >---
@Override
public boolean canRead(Tree tree) {
return isGranted(tree, Permissions.READ_NODE);
@@ -108,6 +113,25 @@ class CompiledPermissionImpl implements
}
//------------------------------------------------------------< private >---
+
+ private void buildEntries(ReadOnlyTree permissionsTree) {
+ EntriesBuilder builder = new EntriesBuilder();
+ for (Principal principal : principals) {
+ ReadOnlyTree t = getPrincipalRoot(permissionsTree, principal);
+ if (t != null) {
+ trees.put(principal.getName(), t);
+ builder.addEntry(principal, t);
+ }
+ }
+ userEntries = builder.userEntries.build();
+ groupEntries = builder.groupEntries.build();
+ }
+
+ @CheckForNull
+ private static ReadOnlyTree getPrincipalRoot(ReadOnlyTree permissionsTree, Principal principal) {
+ return permissionsTree.getChild(Text.escapeIllegalJcrChars(principal.getName()));
+ }
+
private boolean hasPermissions(@Nonnull Tree tree, @Nullable PropertyState property,
long permissions) {
// TODO
@@ -150,6 +174,10 @@ class CompiledPermissionImpl implements
}
}
+ /**
+ * Collects permission entries for different principals and asserts they are
+ * in the correct order for proper and efficient evaluation.
+ */
private static final class EntriesBuilder {
private ImmutableSortedMap.Builder<Key, Entry> userEntries = ImmutableSortedMap.naturalOrder();
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionProviderImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionProviderImpl.java?rev=1451277&r1=1451276&r2=1451277&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionProviderImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/PermissionProviderImpl.java Thu Feb 28 18:27:06 2013
@@ -59,7 +59,7 @@ public class PermissionProviderImpl impl
private static final Logger log = LoggerFactory.getLogger(PermissionProviderImpl.class);
- private final ReadOnlyRoot root;
+ private final Root root;
private final Context acContext;
@@ -69,22 +69,27 @@ public class PermissionProviderImpl impl
public PermissionProviderImpl(@Nonnull Root root, @Nonnull Set<Principal> principals,
@Nonnull SecurityProvider securityProvider) {
- this.root = new ReadOnlyRoot(root);
+ this.root = root;
this.acContext = securityProvider.getAccessControlConfiguration().getContext();
if (principals.contains(SystemPrincipal.INSTANCE) || isAdmin(principals)) {
compiledPermissions = AllPermissions.getInstance();
} else {
- String relativePath = PERMISSIONS_STORE_PATH + '/' + workspaceName;
- ReadOnlyTree rootTree = this.root.getTree("/");
- ReadOnlyTree permissionsTree = getPermissionsRoot(rootTree, relativePath);
- if (permissionsTree == null) {
+ ReadOnlyTree permissionsTree = getPermissionsRoot();
+ if (permissionsTree == null || principals.isEmpty()) {
compiledPermissions = NoPermissions.getInstance();
} else {
- compiledPermissions = new CompiledPermissionImpl(principals, new PrivilegeBitsProvider(this.root), permissionsTree);
+ compiledPermissions = new CompiledPermissionImpl(principals, permissionsTree, getBitsProvider());
}
}
}
+ @Override
+ public void refresh() {
+ if (compiledPermissions instanceof CompiledPermissionImpl) {
+ ((CompiledPermissionImpl) compiledPermissions).update(getPermissionsRoot(), getBitsProvider());
+ }
+ }
+
@Nonnull
@Override
public Set<String> getPrivileges(@Nullable Tree tree) {
@@ -145,7 +150,7 @@ public class PermissionProviderImpl impl
@Override
public boolean hasPermission(@Nonnull String oakPath, @Nonnull String jcrActions) {
- TreeLocation location = root.getLocation(oakPath);
+ TreeLocation location = getReadOnlyRoot().getLocation(oakPath);
long permissions = Permissions.getPermissions(jcrActions, location);
if (!location.exists()) {
// TODO: deal with version content
@@ -173,12 +178,27 @@ public class PermissionProviderImpl impl
return false;
}
+ private ReadOnlyRoot getReadOnlyRoot() {
+ if (root instanceof ReadOnlyRoot) {
+ return (ReadOnlyRoot) root;
+ } else {
+ return new ReadOnlyRoot(root);
+ }
+ }
+
@CheckForNull
- private static ReadOnlyTree getPermissionsRoot(ReadOnlyTree rootTree, String relativePath) {
+ private ReadOnlyTree getPermissionsRoot() {
+ String relativePath = PERMISSIONS_STORE_PATH + '/' + workspaceName;
+ ReadOnlyTree rootTree = checkNotNull(getReadOnlyRoot().getTree("/"));
Tree tree = rootTree.getLocation().getChild(relativePath).getTree();
return (tree == null) ? null : (ReadOnlyTree) tree;
}
+ @Nonnull
+ private PrivilegeBitsProvider getBitsProvider() {
+ return new PrivilegeBitsProvider(getReadOnlyRoot());
+ }
+
private boolean isAccessControlContent(@Nonnull Tree tree) {
return acContext.definesTree(tree);
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/OpenPermissionProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/OpenPermissionProvider.java?rev=1451277&r1=1451276&r2=1451277&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/OpenPermissionProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/OpenPermissionProvider.java Thu Feb 28 18:27:06 2013
@@ -39,6 +39,11 @@ public final class OpenPermissionProvide
return INSTANCE;
}
+ @Override
+ public void refresh() {
+ // nothing to do
+ }
+
@Nonnull
@Override
public Set<String> getPrivileges(@Nullable Tree tree) {
@@ -79,4 +84,4 @@ public final class OpenPermissionProvide
public boolean hasPermission(@Nonnull String oakPath, @Nonnull String jcrActions) {
return true;
}
-}
\ No newline at end of file
+}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/PermissionProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/PermissionProvider.java?rev=1451277&r1=1451276&r2=1451277&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/PermissionProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authorization/PermissionProvider.java Thu Feb 28 18:27:06 2013
@@ -28,6 +28,8 @@ import org.apache.jackrabbit.oak.api.Tre
*/
public interface PermissionProvider {
+ void refresh();
+
@Nonnull
Set<String> getPrivileges(@Nullable Tree tree);