This is an automated email from the ASF dual-hosted git repository. kwin pushed a commit to branch feature/ensure-principal-acl in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-repoinit-parser.git
commit 4ffa22f1048d821a36c0be6748447c0b42f7c6e7 Author: Konrad Windszus <[email protected]> AuthorDate: Tue Dec 20 17:46:25 2022 +0100 SLING-10281 add "ensure principal ACL" with stricter semantics --- ...ipalBased.java => EnsureAclPrincipalBased.java} | 12 +++-- .../parser/operations/OperationVisitor.java | 2 + .../parser/operations/SetAclPrincipalBased.java | 2 + .../repoinit/parser/operations/package-info.java | 2 +- src/main/javacc/RepoInitGrammar.jjt | 19 ++++++++ .../parser/test/OperationToStringVisitor.java | 18 ++++++- src/test/resources/testcases/test-74-output.txt | 23 +++++++++ src/test/resources/testcases/test-74.txt | 55 ++++++++++++++++++++++ 8 files changed, 126 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/apache/sling/repoinit/parser/operations/SetAclPrincipalBased.java b/src/main/java/org/apache/sling/repoinit/parser/operations/EnsureAclPrincipalBased.java similarity index 81% copy from src/main/java/org/apache/sling/repoinit/parser/operations/SetAclPrincipalBased.java copy to src/main/java/org/apache/sling/repoinit/parser/operations/EnsureAclPrincipalBased.java index 5f8b937..552ce0c 100644 --- a/src/main/java/org/apache/sling/repoinit/parser/operations/SetAclPrincipalBased.java +++ b/src/main/java/org/apache/sling/repoinit/parser/operations/EnsureAclPrincipalBased.java @@ -27,17 +27,19 @@ import org.osgi.annotation.versioning.ProviderType; /** Set ACL statement that groups a set of AclLines * that all refer to the same set of principals. + * Fails in case the principal ACLs cannot be applied for some reason. + * @see SetAclPrincipalBased */ @ProviderType -public class SetAclPrincipalBased extends AclGroupBase { +public class EnsureAclPrincipalBased extends AclGroupBase { private final List<String> principals; - public SetAclPrincipalBased(List<String> principals, List<AclLine> lines) { + public EnsureAclPrincipalBased(List<String> principals, List<AclLine> lines) { this(principals,lines,new ArrayList<>()); } - public SetAclPrincipalBased(List<String> principals, List<AclLine> lines, List<String> aclOptions) { + public EnsureAclPrincipalBased(List<String> principals, List<AclLine> lines, List<String> aclOptions) { super(lines,aclOptions); this.principals = Collections.unmodifiableList(principals); } @@ -53,7 +55,7 @@ public class SetAclPrincipalBased extends AclGroupBase { @NotNull @Override public String asRepoInitString() { - String topline = String.format("set principal ACL for %s%s%n", + String topline = String.format("ensure principal ACL for %s%s%n", listToString(QuotableStringUtil.forRepoInitString(principals)), getAclOptionsString()); return asRepoInit(topline, true); } @@ -64,6 +66,6 @@ public class SetAclPrincipalBased extends AclGroupBase { @Override public void accept(OperationVisitor v) { - v.visitSetAclPrincipalBased(this); + v.visitEnsureAclPrincipalBased(this); } } diff --git a/src/main/java/org/apache/sling/repoinit/parser/operations/OperationVisitor.java b/src/main/java/org/apache/sling/repoinit/parser/operations/OperationVisitor.java index f2a3919..b009434 100644 --- a/src/main/java/org/apache/sling/repoinit/parser/operations/OperationVisitor.java +++ b/src/main/java/org/apache/sling/repoinit/parser/operations/OperationVisitor.java @@ -29,7 +29,9 @@ public interface OperationVisitor { void visitDeleteServiceUser(DeleteServiceUser s); void visitSetAclPrincipal(SetAclPrincipals s); void visitSetAclPaths(SetAclPaths s); + @Deprecated void visitSetAclPrincipalBased(SetAclPrincipalBased s); + default void visitEnsureAclPrincipalBased(EnsureAclPrincipalBased ensureAclPrincipalBased) { throw new UnsupportedOperationException(); } default void visitRemoveAcePrincipal(RemoveAcePrincipals s) { throw new UnsupportedOperationException(); } default void visitRemoveAcePaths(RemoveAcePaths s) { throw new UnsupportedOperationException(); } default void visitRemoveAcePrincipalBased(RemoveAcePrincipalBased s) { throw new UnsupportedOperationException(); } diff --git a/src/main/java/org/apache/sling/repoinit/parser/operations/SetAclPrincipalBased.java b/src/main/java/org/apache/sling/repoinit/parser/operations/SetAclPrincipalBased.java index 5f8b937..db21d9d 100644 --- a/src/main/java/org/apache/sling/repoinit/parser/operations/SetAclPrincipalBased.java +++ b/src/main/java/org/apache/sling/repoinit/parser/operations/SetAclPrincipalBased.java @@ -27,7 +27,9 @@ import org.osgi.annotation.versioning.ProviderType; /** Set ACL statement that groups a set of AclLines * that all refer to the same set of principals. + * @deprecated Use {@link EnsureAclPrincipalBased} based with stricter semantics */ +@Deprecated @ProviderType public class SetAclPrincipalBased extends AclGroupBase { diff --git a/src/main/java/org/apache/sling/repoinit/parser/operations/package-info.java b/src/main/java/org/apache/sling/repoinit/parser/operations/package-info.java index 3904b7c..8e43410 100644 --- a/src/main/java/org/apache/sling/repoinit/parser/operations/package-info.java +++ b/src/main/java/org/apache/sling/repoinit/parser/operations/package-info.java @@ -15,6 +15,6 @@ * limitations under the License. ******************************************************************************/ [email protected]("6.1.0") [email protected]("6.2.0") package org.apache.sling.repoinit.parser.operations; diff --git a/src/main/javacc/RepoInitGrammar.jjt b/src/main/javacc/RepoInitGrammar.jjt index d068f57..c2b9181 100644 --- a/src/main/javacc/RepoInitGrammar.jjt +++ b/src/main/javacc/RepoInitGrammar.jjt @@ -68,6 +68,7 @@ TOKEN: | < FOR: "for" > | < CREATE: "create" > | < DELETE: "delete" > +| < ENSURE: "ensure" > | < DISABLE: "disable" > | < SERVICE: "service" > | < ADD: "add" > @@ -144,6 +145,7 @@ List<Operation> parse() : | setAclPaths(result) | setAclPrincipals(result) | setAclPrincipalBased(result) + | ensureAclPrincipalBased(result) | setAclRepository(result) | deleteAclPaths(result) | deleteAclPrincipals(result) @@ -607,6 +609,23 @@ void setAclPrincipalBased(List<Operation> result) : } } +void ensureAclPrincipalBased(List<Operation> result) : +{ + List <String> principals; + List<AclLine> lines = new ArrayList<AclLine>(); + List<String> aclOptions; +} +{ + <ENSURE> <PRINCIPAL> <ACL> <FOR> principals = principalsList() aclOptions=aclOptions() <EOL> + ( removeStarLine(lines) | pathPrivilegesLine(lines, true) | blankLine() ) + + <END> + ( <EOL> | <EOF> ) + + { + result.add(new EnsureAclPrincipalBased(principals, lines, aclOptions)); + } +} + void removeAcePaths(List<Operation> result) : { List<String> paths; diff --git a/src/test/java/org/apache/sling/repoinit/parser/test/OperationToStringVisitor.java b/src/test/java/org/apache/sling/repoinit/parser/test/OperationToStringVisitor.java index 0a17b17..419fa0d 100644 --- a/src/test/java/org/apache/sling/repoinit/parser/test/OperationToStringVisitor.java +++ b/src/test/java/org/apache/sling/repoinit/parser/test/OperationToStringVisitor.java @@ -32,6 +32,7 @@ import org.apache.sling.repoinit.parser.operations.DeleteGroup; import org.apache.sling.repoinit.parser.operations.DeleteServiceUser; import org.apache.sling.repoinit.parser.operations.DeleteUser; import org.apache.sling.repoinit.parser.operations.DisableServiceUser; +import org.apache.sling.repoinit.parser.operations.EnsureAclPrincipalBased; import org.apache.sling.repoinit.parser.operations.RegisterNodetypes; import org.apache.sling.repoinit.parser.operations.OperationVisitor; import org.apache.sling.repoinit.parser.operations.RegisterNamespace; @@ -103,7 +104,7 @@ class OperationToStringVisitor implements OperationVisitor { out.println(); dumpAclLines(s.getLines()); } - + @Override public void visitSetAclPaths(SetAclPaths s) { out.print(s.getClass().getSimpleName()); @@ -134,6 +135,21 @@ class OperationToStringVisitor implements OperationVisitor { dumpAclLines(s.getLines()); } + @Override + public void visitEnsureAclPrincipalBased(EnsureAclPrincipalBased s) { + out.print(s.getClass().getSimpleName()); + out.print(" for "); + for(String p : s.getPrincipals()) { + out.print(p); + out.print(' '); + } + + dumpAclOptions(s.getOptions()); + + out.println(); + dumpAclLines(s.getLines()); + } + @Override public void visitRemoveAcePrincipal(RemoveAcePrincipals s) { out.print(s.getClass().getSimpleName()); diff --git a/src/test/resources/testcases/test-74-output.txt b/src/test/resources/testcases/test-74-output.txt new file mode 100644 index 0000000..9349807 --- /dev/null +++ b/src/test/resources/testcases/test-74-output.txt @@ -0,0 +1,23 @@ +EnsureAclPrincipalBased for principal1 principal2 + AclLine REMOVE_ALL {paths=[/libs, /apps]} + AclLine ALLOW {paths=[/content], privileges=[jcr:read]} + AclLine DENY {paths=[/apps], privileges=[jcr:write]} + AclLine DENY {nodetypes=[sling:Folder, nt:unstructured], paths=[/apps, /content], privileges=[jcr:lockManagement]} + AclLine DENY {nodetypes=[sling:Folder, nt:unstructured], paths=[/apps, /content], privileges=[jcr:modifyProperties]} restrictions=[rep:itemNames=[prop1, prop2]] + AclLine REMOVE {paths=[/apps], privileges=[jcr:understand, some:other]} + AclLine ALLOW {paths=[/apps], privileges=[jcr:addChildNodes]} restrictions=[rep:ntNames=[sling:Folder, nt:unstructured]] + AclLine ALLOW {paths=[/apps], privileges=[jcr:modifyProperties]} restrictions=[rep:ntNames=[sling:Folder, nt:unstructured], rep:itemNames=[prop1, prop2]] + AclLine ALLOW {paths=[/apps, /content], privileges=[jcr:addChildNodes]} restrictions=[rep:glob=[/cat, /cat/, cat]] + AclLine ALLOW {paths=[/apps, /content], privileges=[jcr:addChildNodes]} restrictions=[rep:glob=[cat/, *, *cat]] + AclLine ALLOW {paths=[/apps, /content], privileges=[jcr:addChildNodes]} restrictions=[rep:glob=[/cat/*, */cat, *cat/*]] + AclLine ALLOW {paths=[/], privileges=[jcr:something]} restrictions=[rep:glob=[]] +EnsureAclPrincipalBased for principal1 principal2 ACLOptions=[mergePreserve] + AclLine REMOVE_ALL {paths=[/libs, /apps]} + AclLine ALLOW {paths=[/content], privileges=[jcr:read]} +EnsureAclPrincipalBased for principal1 principal2 ACLOptions=[mergePreserve, someOtherOption, someOther123, namespaced:option] + AclLine REMOVE_ALL {paths=[/libs, /apps]} + AclLine ALLOW {paths=[/content], privileges=[jcr:read]} +EnsureAclPrincipalBased for principal1 principal2 + AclLine ALLOW {paths=[:repository], privileges=[jcr:namespaceManagement]} +EnsureAclPrincipalBased for principal1 + AclLine ALLOW {paths=[:repository, /content], privileges=[jcr:all]} \ No newline at end of file diff --git a/src/test/resources/testcases/test-74.txt b/src/test/resources/testcases/test-74.txt new file mode 100644 index 0000000..5170e58 --- /dev/null +++ b/src/test/resources/testcases/test-74.txt @@ -0,0 +1,55 @@ +# Set principal-based access control (see SLING-8602), requires +# o.a.s.repoinit.parser 1.2.8 and +# o.a.s.jcr.repoinit 1.1.14 +# precondition for o.a.s.jcr.repoinit: +# repository needs to support 'o.a.j.api.security.authorization.PrincipalAccessControlList' +# Also, this only works for users selected by the Jackrabbit/Oak FilterProvider, see +# https://jackrabbit.apache.org/oak/docs/security/authorization/principalbased.html#configuration +# mostly a copy of test-33 but with "ensure" prefix instead of "set" + +ensure principal ACL for principal1,principal2 + remove * on /libs,/apps + allow jcr:read on /content + + deny jcr:write on /apps + + # Optional nodetypes clause + deny jcr:lockManagement on /apps, /content nodetypes sling:Folder, nt:unstructured + # nodetypes clause with restriction clause + deny jcr:modifyProperties on /apps, /content nodetypes sling:Folder, nt:unstructured restriction(rep:itemNames,prop1,prop2) + remove jcr:understand,some:other on /apps + + # multi value restriction + allow jcr:addChildNodes on /apps restriction(rep:ntNames,sling:Folder,nt:unstructured) + + # multiple restrictions + allow jcr:modifyProperties on /apps restriction(rep:ntNames,sling:Folder,nt:unstructured) restriction(rep:itemNames,prop1,prop2) + + # restrictions with glob patterns + allow jcr:addChildNodes on /apps,/content restriction(rep:glob,/cat,/cat/,cat) + allow jcr:addChildNodes on /apps,/content restriction(rep:glob,cat/,*,*cat) + allow jcr:addChildNodes on /apps,/content restriction(rep:glob,/cat/*,*/cat,*cat/*) + + allow jcr:something on / restriction(rep:glob) +end + +# Principal-based ACL syntax with options (SLING-6423) +ensure principal ACL for principal1,principal2 (ACLOptions=mergePreserve) + remove * on /libs,/apps + allow jcr:read on /content +end + +# With multiple options +ensure principal ACL for principal1,principal2 (ACLOptions=mergePreserve,someOtherOption,someOther123,namespaced:option) + remove * on /libs,/apps + allow jcr:read on /content +end + +# repository level +ensure principal ACL for principal1,principal2 + allow jcr:namespaceManagement on :repository +end + +ensure principal ACL for principal1 + allow jcr:all on :repository,/content +end \ No newline at end of file
