diff --git a/src/site/markdown/filter.md b/src/site/markdown/filter.md index 45adab5ab..3dce8b9f0 100644 --- a/src/site/markdown/filter.md +++ b/src/site/markdown/filter.md @@ -121,15 +121,17 @@ The exact rules are outlined below Item covered by filter rule | Item contained in the Content Package | Item contained in the Repository (prior to Import/Installation) | State of Item in Repository after Import/Installation --- | --- | --- | --- -no | yes | yes | not touched -no | no | yes | not touched -no | yes | no | *nodes which are ancestors of covered rules*: deserialized from content package (for backwards compatibility reasons), *nodes which are not ancestors of covered rules*: not touched. One should not rely on this behaviour, i.e. all items in the content package should always be covered by some filter rule to make the behaviour more explicit. +no | yes | yes | not touched(*) +no | no | yes | not touched(*) +no | yes | no | *nodes which are ancestors of covered rules*: deserialized from content package (for backwards compatibility reasons), *nodes which are not ancestors of covered rules*: not touched. One should not rely on this behaviour, i.e. all items in the content package should always be covered by some filter rule to make the behaviour more explicit.(*) no | no | no | not existing (not touched) yes | yes | yes | overwritten yes | no | yes | removed yes | yes | no | deserialized from content package yes | no | no | not existing +Mostly for historical reason both authorizable nodes and access control lists behave differently. + ### Uncovered ancestor nodes All *uncovered* ancestor nodes are either @@ -138,6 +140,10 @@ All *uncovered* ancestor nodes are either 1. since version 3.4.4 ([JCRVLT-417](https://issues.apache.org/jira/browse/JCRVLT-417)) created with the ancestor node type's default child type or if that is not set or prior to version 3.4.4 created with node type `nt:folder` (in case the the node type is *not* given with a `.content.xml` at the right location and the node does not yet exist in the repo) or 1. not touched at all (in case they are already existing in the repo, no matter which node type is given with a `.content.xml` at the according location) +### Effect on Access Control Lists (ACLs) + +In order for ACLs to be installed the [ACL serialization node path](vaultfs.html#Authorization_Serialization) must be contained in the filter as well. + ### Example Content Package Filter diff --git a/src/site/markdown/vaultfs.md b/src/site/markdown/vaultfs.md index ef16e5155..ce87dd092 100644 --- a/src/site/markdown/vaultfs.md +++ b/src/site/markdown/vaultfs.md @@ -291,6 +291,16 @@ The serialization of the artifacts is defined by the **serializer** that is prov 1. a direct data serialization for the contents of file or binary artifacts and 2. an enhanced _docview_ serialization for the rest. The [_enhanced docview_ serialization][enhanceddocview] that is used allows multi-value properties and explicit types in contrast to regular [document view XML defined by JCR 2.0][docview]. +### Authorization Serialization + +As JCR 2.0 does not define if/how access control information is stored in the repository, FileVault only supports the Oak-specific implementation leveraging its internal repository format. It support the following node names: + +1. `rep:policy` or `repo:policy` (for repository-level ACLs) with structure as defined in +1. `rep:cugPolicy` with structure as defined in +1. `rep:principalPolicy` with structure as defined in + +Those are serialized as [enhanced docview][enhanceddocview]. + Deserialization --------------- Although for exporting only 2 serialization types are used this is a bit different for importing. The importer analyzes the provided input sources and determines the following serialization types: @@ -310,6 +320,9 @@ Depending on the configuration those input sources can be handled differently. C **generic data** produces a `nt:file` having the data as `nt:resource` content. +### Authorization Deserialization + +Only the Oak-specific serializations as defined above are deserialized leveraging the [JCR 2.0 API defined in chapter 16][authorization]. Terminology ----------- @@ -332,4 +345,5 @@ Terminology [enhanceddocview]: docview.html [docview]: https://s.apache.org/jcr-2.0-spec/7_Export.html#7.3%20Document%20View -[sysview]: https://s.apache.org/jcr-2.0-spec/7_Export.html#7.2%20System%20View \ No newline at end of file +[sysview]: https://s.apache.org/jcr-2.0-spec/7_Export.html#7.2%20System%20View +[authorization]: https://s.apache.org/jcr-2.0-spec/16_Access_Control_Management.html \ No newline at end of file diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/io/Importer.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/io/Importer.java index 1b2c6dd6f..aaaedcf33 100644 --- a/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/io/Importer.java +++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/io/Importer.java @@ -522,12 +522,14 @@ public void run(Archive archive, Session session, String parentPath) } } + /** + * This discards artifacts from the tree which are not contained in the filter + * @param root the (sub)tree + * @return the modified (sub)tree + */ private TxInfo postFilter(TxInfo root) { TxInfo modifierRoot = root; - if (filter.contains(modifierRoot.path)){ - return modifierRoot; - } - if (filter.isAncestor(modifierRoot.path)) { + if (filter.isAncestor(modifierRoot.path) || filter.contains(modifierRoot.path)) { for (String k : modifierRoot.children().keySet()) { TxInfo child = modifierRoot.children().get(k); modifierRoot.children().put(k, postFilter(child)); diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/spi/impl/jcr20/JcrACLManagement.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/spi/impl/jcr20/JcrACLManagement.java index bd2ab7822..0c4a68318 100644 --- a/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/spi/impl/jcr20/JcrACLManagement.java +++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/spi/impl/jcr20/JcrACLManagement.java @@ -34,6 +34,7 @@ public class JcrACLManagement implements ACLManagement { * {@inheritDoc} */ public boolean isACLNodeType(String name) { + // all those inherit from rep:Policy return name.equals("rep:ACL") || name.equals("rep:CugPolicy") || name.equals("rep:PrincipalPolicy"); } diff --git a/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/integration/ACLAndMergeIT.java b/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/integration/ACLAndMergeIT.java index 90f22f244..d8e47dbd8 100644 --- a/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/integration/ACLAndMergeIT.java +++ b/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/integration/ACLAndMergeIT.java @@ -24,9 +24,11 @@ import javax.jcr.RepositoryException; +import org.apache.jackrabbit.JcrConstants; import org.apache.jackrabbit.api.JackrabbitSession; import org.apache.jackrabbit.api.security.user.Authorizable; import org.apache.jackrabbit.api.security.user.UserManager; +import org.apache.jackrabbit.commons.JcrUtils; import org.apache.jackrabbit.vault.fs.io.AccessControlHandling; import org.apache.jackrabbit.vault.fs.io.ImportOptions; import org.apache.jackrabbit.vault.packaging.JcrPackage; @@ -416,7 +418,7 @@ public void testRepoACL() throws RepositoryException, IOException, PackageExcept } /** - * Installs a package with repository level acl and then installs another that removes them again. + * Installs a package with repository level acl with AccessControlHandling.MERGE. */ @Test public void testRepoACLMerge() throws RepositoryException, IOException, PackageException { @@ -437,7 +439,7 @@ public void testRepoACLMerge() throws RepositoryException, IOException, PackageE } /** - * Installs a package with repository level acl and then installs another that removes them again. + * Installs a package with repository level acl with AccessControlHandling.MERGE_PRESERVE. */ @Test public void testRepoACLMergePreserve() throws RepositoryException, IOException, PackageException { @@ -458,7 +460,7 @@ public void testRepoACLMergePreserve() throws RepositoryException, IOException, } /** - * Installs a package a the root level (JCRVLT-75) + * Installs a package at the root level (JCRVLT-75) */ @Test public void testRootACL() throws RepositoryException, IOException, PackageException { @@ -469,4 +471,18 @@ public void testRootACL() throws RepositoryException, IOException, PackageExcept // test if nodes and ACLs of first package exist assertPermission("/", true, new String[]{"jcr:all"}, "everyone", null); } + + /** Check effect of filter definitions */ + @Test + public void testACLsOutsideFilter() throws IOException, PackageException, RepositoryException { + extractVaultPackageStrict("/test-packages/ac_outside_filter.zip"); + assertNodeExists("/testroot/node_a"); + + // this ACL is not contained in the filter neither is its direct ancestor (node whose privileges are set) + // still nodes contained in the filter would be affected by the ACL + assertPermissionMissing("/testroot", false, new String[]{"jcr:all"}, "everyone", null); + + // this ACL is not contained in the filter but its direct ancestor (the node whose privileges are set) is + assertPermissionMissing("/testroot/secured", false, new String[]{"jcr:all"}, "everyone", null); + } } \ No newline at end of file diff --git a/vault-core/src/test/resources/test-packages/ac_outside_filter.zip/META-INF/vault/filter.xml b/vault-core/src/test/resources/test-packages/ac_outside_filter.zip/META-INF/vault/filter.xml new file mode 100644 index 000000000..84ea8ffff --- /dev/null +++ b/vault-core/src/test/resources/test-packages/ac_outside_filter.zip/META-INF/vault/filter.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/vault-core/src/test/resources/test-packages/ac_outside_filter.zip/META-INF/vault/nodetypes.cnd b/vault-core/src/test/resources/test-packages/ac_outside_filter.zip/META-INF/vault/nodetypes.cnd new file mode 100644 index 000000000..5afdfb71b --- /dev/null +++ b/vault-core/src/test/resources/test-packages/ac_outside_filter.zip/META-INF/vault/nodetypes.cnd @@ -0,0 +1,8 @@ +<'sling'='http://sling.apache.org/jcr/sling/1.0'> +<'nt'='http://www.jcp.org/jcr/nt/1.0'> + +[sling:Folder] > nt:folder + - * (undefined) + - * (undefined) multiple + + * (nt:base) = sling:Folder version + diff --git a/vault-core/src/test/resources/test-packages/ac_outside_filter.zip/META-INF/vault/properties.xml b/vault-core/src/test/resources/test-packages/ac_outside_filter.zip/META-INF/vault/properties.xml new file mode 100644 index 000000000..70a8f65f5 --- /dev/null +++ b/vault-core/src/test/resources/test-packages/ac_outside_filter.zip/META-INF/vault/properties.xml @@ -0,0 +1,36 @@ + + + + + +FileVault Package Properties +admin +mode_ac_test_a +2011-11-15T09:43:22.972+01:00 +admin +2011-11-15T09:43:22.993+01:00 +1 + + +2 + +2011-11-15T09:43:22.972+01:00 + +admin +overwrite + diff --git a/vault-core/src/test/resources/test-packages/ac_outside_filter.zip/jcr_root/.content.xml b/vault-core/src/test/resources/test-packages/ac_outside_filter.zip/jcr_root/.content.xml new file mode 100644 index 000000000..d412a30db --- /dev/null +++ b/vault-core/src/test/resources/test-packages/ac_outside_filter.zip/jcr_root/.content.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + diff --git a/vault-core/src/test/resources/test-packages/ac_outside_filter.zip/jcr_root/testroot/_rep_policy.xml b/vault-core/src/test/resources/test-packages/ac_outside_filter.zip/jcr_root/testroot/_rep_policy.xml new file mode 100644 index 000000000..8a415d585 --- /dev/null +++ b/vault-core/src/test/resources/test-packages/ac_outside_filter.zip/jcr_root/testroot/_rep_policy.xml @@ -0,0 +1,9 @@ + + + + diff --git a/vault-core/src/test/resources/test-packages/ac_outside_filter.zip/jcr_root/testroot/node_a/.content.xml b/vault-core/src/test/resources/test-packages/ac_outside_filter.zip/jcr_root/testroot/node_a/.content.xml new file mode 100644 index 000000000..61b37c823 --- /dev/null +++ b/vault-core/src/test/resources/test-packages/ac_outside_filter.zip/jcr_root/testroot/node_a/.content.xml @@ -0,0 +1,4 @@ + + diff --git a/vault-core/src/test/resources/test-packages/ac_outside_filter.zip/jcr_root/testroot/secured/.content.xml b/vault-core/src/test/resources/test-packages/ac_outside_filter.zip/jcr_root/testroot/secured/.content.xml new file mode 100644 index 000000000..1e519aa0b --- /dev/null +++ b/vault-core/src/test/resources/test-packages/ac_outside_filter.zip/jcr_root/testroot/secured/.content.xml @@ -0,0 +1,21 @@ + + + + diff --git a/vault-core/src/test/resources/test-packages/ac_outside_filter.zip/jcr_root/testroot/secured/_rep_policy.xml b/vault-core/src/test/resources/test-packages/ac_outside_filter.zip/jcr_root/testroot/secured/_rep_policy.xml new file mode 100644 index 000000000..8a415d585 --- /dev/null +++ b/vault-core/src/test/resources/test-packages/ac_outside_filter.zip/jcr_root/testroot/secured/_rep_policy.xml @@ -0,0 +1,9 @@ + + + +