You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by dk...@apache.org on 2021/12/01 00:14:21 UTC
[sling-org-apache-sling-repoinit-parser] 01/01: SLING-10952 - Adding support for whitespace characters in group names
This is an automated email from the ASF dual-hosted git repository.
dklco pushed a commit to branch SLING-10952-whitespace-group-names
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-repoinit-parser.git
commit 1e8953e5d8f9d16cd10e5a7f9641fbac7a815e42
Author: Dan Klco <kl...@adobe.com>
AuthorDate: Tue Nov 30 19:14:10 2021 -0500
SLING-10952 - Adding support for whitespace characters in group names
---
.../repoinit/parser/impl/AuthorizableIdUtil.java | 49 ++++++++++++++++++++++
.../repoinit/parser/operations/AclGroupBase.java | 6 ++-
.../parser/operations/AddGroupMembers.java | 4 +-
.../repoinit/parser/operations/CreateGroup.java | 3 +-
.../repoinit/parser/operations/DeleteGroup.java | 3 +-
.../repoinit/parser/operations/Operation.java | 4 ++
.../parser/operations/RemoveGroupMembers.java | 4 +-
.../repoinit/parser/operations/SetAclPaths.java | 1 +
.../parser/operations/SetAclPrincipalBased.java | 7 +++-
.../parser/operations/SetAclPrincipals.java | 10 +++--
src/main/javacc/RepoInitGrammar.jjt | 22 ++++++----
src/test/resources/testcases/test-71-output.txt | 20 +++++++++
src/test/resources/testcases/test-71.txt | 28 +++++++++++++
13 files changed, 143 insertions(+), 18 deletions(-)
diff --git a/src/main/java/org/apache/sling/repoinit/parser/impl/AuthorizableIdUtil.java b/src/main/java/org/apache/sling/repoinit/parser/impl/AuthorizableIdUtil.java
new file mode 100644
index 0000000..09b958a
--- /dev/null
+++ b/src/main/java/org/apache/sling/repoinit/parser/impl/AuthorizableIdUtil.java
@@ -0,0 +1,49 @@
+/*
+ * 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.sling.repoinit.parser.impl;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class AuthorizableIdUtil {
+
+ private AuthorizableIdUtil() {
+ // hidden
+ }
+
+ /**
+ * Gets the authorizable ID handling cases where the value should be quoted
+ * (e.g. the authorizable id is not just an alphanumeric string)
+ *
+ * @param authorizableId the authorizable ID to get
+ * @return the (potentially quoted) authorizable id
+ */
+ public static final String forRepoInitString(String authorizableId) {
+ return !authorizableId.matches(".*\\s.*") ? authorizableId : "\"" + authorizableId + "\"";
+ }
+
+ /**
+ * Gets the authorizable IDs handling cases where the value should be quoted
+ * (e.g. the authorizable id is not just an alphanumeric string)
+ *
+ * @param authorizableIds the authorizable IDs to get
+ * @return the list of (potentially quoted) authorizable ids
+ */
+ public static final List<String> forRepoInitString(List<String> authorizableIds) {
+ return authorizableIds.stream().map(AuthorizableIdUtil::forRepoInitString).collect(Collectors.toList());
+ }
+}
diff --git a/src/main/java/org/apache/sling/repoinit/parser/operations/AclGroupBase.java b/src/main/java/org/apache/sling/repoinit/parser/operations/AclGroupBase.java
index 12e02a3..bcd013a 100644
--- a/src/main/java/org/apache/sling/repoinit/parser/operations/AclGroupBase.java
+++ b/src/main/java/org/apache/sling/repoinit/parser/operations/AclGroupBase.java
@@ -23,6 +23,7 @@ import java.util.Collections;
import java.util.Formatter;
import java.util.List;
+import org.apache.sling.repoinit.parser.impl.AuthorizableIdUtil;
import org.apache.sling.repoinit.parser.operations.AclLine.Action;
import org.jetbrains.annotations.NotNull;
import org.osgi.annotation.versioning.ProviderType;
@@ -40,7 +41,7 @@ abstract class AclGroupBase extends Operation {
private final List<String> aclOptions;
protected AclGroupBase(List<AclLine> lines) {
- this(lines,new ArrayList<String>());
+ this(lines,new ArrayList<>());
}
protected AclGroupBase(List<AclLine> lines, List<String> aclOptions) {
this.lines = Collections.unmodifiableList(lines);
@@ -74,7 +75,8 @@ abstract class AclGroupBase extends Operation {
String pathStr = pathsToString(line.getProperty(AclLine.PROP_PATHS));
onOrFor = (pathStr.isEmpty()) ? "" : " on " + pathStr;
} else {
- onOrFor = " for " + listToString(line.getProperty(AclLine.PROP_PRINCIPALS));
+ onOrFor = " for " + listToString(
+ AuthorizableIdUtil.forRepoInitString(line.getProperty(AclLine.PROP_PRINCIPALS)));
}
formatter.format(" %s %s%s%s%s%n", action, privileges, onOrFor,
nodetypesToString(line.getProperty(AclLine.PROP_NODETYPES)),
diff --git a/src/main/java/org/apache/sling/repoinit/parser/operations/AddGroupMembers.java b/src/main/java/org/apache/sling/repoinit/parser/operations/AddGroupMembers.java
index 5ccb49f..7572aef 100644
--- a/src/main/java/org/apache/sling/repoinit/parser/operations/AddGroupMembers.java
+++ b/src/main/java/org/apache/sling/repoinit/parser/operations/AddGroupMembers.java
@@ -19,6 +19,7 @@ package org.apache.sling.repoinit.parser.operations;
import java.util.List;
+import org.apache.sling.repoinit.parser.impl.AuthorizableIdUtil;
import org.jetbrains.annotations.NotNull;
import org.osgi.annotation.versioning.ProviderType;
@@ -55,7 +56,8 @@ public class AddGroupMembers extends Operation {
@NotNull
@Override
public String asRepoInitString() {
- return String.format("add %s to group %s%n", listToString(members), groupname);
+ return String.format("add %s to group %s%n", listToString(AuthorizableIdUtil.forRepoInitString(members)),
+ AuthorizableIdUtil.forRepoInitString(groupname));
}
public String getGroupname() {
diff --git a/src/main/java/org/apache/sling/repoinit/parser/operations/CreateGroup.java b/src/main/java/org/apache/sling/repoinit/parser/operations/CreateGroup.java
index 3384c46..40db1e7 100644
--- a/src/main/java/org/apache/sling/repoinit/parser/operations/CreateGroup.java
+++ b/src/main/java/org/apache/sling/repoinit/parser/operations/CreateGroup.java
@@ -17,6 +17,7 @@
package org.apache.sling.repoinit.parser.operations;
+import org.apache.sling.repoinit.parser.impl.AuthorizableIdUtil;
import org.apache.sling.repoinit.parser.impl.WithPathOptions;
import org.jetbrains.annotations.NotNull;
import org.osgi.annotation.versioning.ProviderType;
@@ -63,7 +64,7 @@ public class CreateGroup extends OperationWithPathOptions {
@NotNull
@Override
public String asRepoInitString() {
- return asRepoInitString("group", groupname);
+ return asRepoInitString("group", AuthorizableIdUtil.forRepoInitString(groupname));
}
public String getGroupname() {
diff --git a/src/main/java/org/apache/sling/repoinit/parser/operations/DeleteGroup.java b/src/main/java/org/apache/sling/repoinit/parser/operations/DeleteGroup.java
index 1fcb807..fba5ab0 100644
--- a/src/main/java/org/apache/sling/repoinit/parser/operations/DeleteGroup.java
+++ b/src/main/java/org/apache/sling/repoinit/parser/operations/DeleteGroup.java
@@ -17,6 +17,7 @@
package org.apache.sling.repoinit.parser.operations;
+import org.apache.sling.repoinit.parser.impl.AuthorizableIdUtil;
import org.jetbrains.annotations.NotNull;
import org.osgi.annotation.versioning.ProviderType;
@@ -46,7 +47,7 @@ public class DeleteGroup extends Operation {
@NotNull
@Override
public String asRepoInitString() {
- return String.format("delete group %s%n", groupname);
+ return String.format("delete group %s", AuthorizableIdUtil.forRepoInitString(groupname));
}
public String getGroupname() {
diff --git a/src/main/java/org/apache/sling/repoinit/parser/operations/Operation.java b/src/main/java/org/apache/sling/repoinit/parser/operations/Operation.java
index e1b1d80..37f2c30 100644
--- a/src/main/java/org/apache/sling/repoinit/parser/operations/Operation.java
+++ b/src/main/java/org/apache/sling/repoinit/parser/operations/Operation.java
@@ -17,6 +17,7 @@
package org.apache.sling.repoinit.parser.operations;
+import org.apache.sling.repoinit.parser.impl.AuthorizableIdUtil;
import org.jetbrains.annotations.NotNull;
import org.osgi.annotation.versioning.ProviderType;
@@ -72,6 +73,9 @@ public abstract class Operation {
if (s.startsWith(":") && s.contains("#")) {
String func = s.substring(1, s.indexOf(":",1));
String s2 = s.substring(func.length()+2, s.lastIndexOf('#'));
+ if ("authorizable".equals(func)) {
+ s2 = AuthorizableIdUtil.forRepoInitString(s2);
+ }
String trailingPath = (s.endsWith("#")) ? "" : s.substring(s.indexOf("#")+1);
return func + "(" + s2 +")" + trailingPath;
} else {
diff --git a/src/main/java/org/apache/sling/repoinit/parser/operations/RemoveGroupMembers.java b/src/main/java/org/apache/sling/repoinit/parser/operations/RemoveGroupMembers.java
index 320e647..a72b482 100644
--- a/src/main/java/org/apache/sling/repoinit/parser/operations/RemoveGroupMembers.java
+++ b/src/main/java/org/apache/sling/repoinit/parser/operations/RemoveGroupMembers.java
@@ -19,6 +19,7 @@ package org.apache.sling.repoinit.parser.operations;
import java.util.List;
+import org.apache.sling.repoinit.parser.impl.AuthorizableIdUtil;
import org.jetbrains.annotations.NotNull;
import org.osgi.annotation.versioning.ProviderType;
@@ -55,7 +56,8 @@ public class RemoveGroupMembers extends Operation {
@NotNull
@Override
public String asRepoInitString() {
- return String.format("remove %s from group %s%n", listToString(members), groupname);
+ return String.format("remove %s from group %s%n", listToString(AuthorizableIdUtil.forRepoInitString(members)),
+ AuthorizableIdUtil.forRepoInitString(groupname));
}
public String getGroupname() {
diff --git a/src/main/java/org/apache/sling/repoinit/parser/operations/SetAclPaths.java b/src/main/java/org/apache/sling/repoinit/parser/operations/SetAclPaths.java
index e43aed7..9195039 100644
--- a/src/main/java/org/apache/sling/repoinit/parser/operations/SetAclPaths.java
+++ b/src/main/java/org/apache/sling/repoinit/parser/operations/SetAclPaths.java
@@ -41,6 +41,7 @@ public class SetAclPaths extends AclGroupBase {
this.paths = Collections.unmodifiableList(paths);
}
+ @Override
protected String getParametersDescription() {
final StringBuilder sb = new StringBuilder();
sb.append(paths);
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 c8d8538..5d83b99 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
@@ -21,6 +21,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import org.apache.sling.repoinit.parser.impl.AuthorizableIdUtil;
import org.jetbrains.annotations.NotNull;
import org.osgi.annotation.versioning.ProviderType;
@@ -33,7 +34,7 @@ public class SetAclPrincipalBased extends AclGroupBase {
private final List<String> principals;
public SetAclPrincipalBased(List<String> principals, List<AclLine> lines) {
- this(principals,lines,new ArrayList<String>());
+ this(principals,lines,new ArrayList<>());
}
public SetAclPrincipalBased(List<String> principals, List<AclLine> lines, List<String> aclOptions) {
@@ -41,6 +42,7 @@ public class SetAclPrincipalBased extends AclGroupBase {
this.principals = Collections.unmodifiableList(principals);
}
+ @Override
protected String getParametersDescription() {
final StringBuilder sb = new StringBuilder();
sb.append(principals);
@@ -51,7 +53,8 @@ public class SetAclPrincipalBased extends AclGroupBase {
@NotNull
@Override
public String asRepoInitString() {
- String topline = String.format("set principal ACL for %s%s%n", listToString(principals), getAclOptionsString());
+ String topline = String.format("set principal ACL for %s%s%n",
+ listToString(AuthorizableIdUtil.forRepoInitString(principals)), getAclOptionsString());
return asRepoInit(topline, true);
}
diff --git a/src/main/java/org/apache/sling/repoinit/parser/operations/SetAclPrincipals.java b/src/main/java/org/apache/sling/repoinit/parser/operations/SetAclPrincipals.java
index 2c8c1b1..4556a8a 100644
--- a/src/main/java/org/apache/sling/repoinit/parser/operations/SetAclPrincipals.java
+++ b/src/main/java/org/apache/sling/repoinit/parser/operations/SetAclPrincipals.java
@@ -21,6 +21,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import org.apache.sling.repoinit.parser.impl.AuthorizableIdUtil;
import org.jetbrains.annotations.NotNull;
import org.osgi.annotation.versioning.ProviderType;
@@ -33,7 +34,7 @@ public class SetAclPrincipals extends AclGroupBase {
private final List<String> principals;
public SetAclPrincipals(List<String> principals, List<AclLine> lines) {
- this(principals,lines,new ArrayList<String>());
+ this(principals,lines,new ArrayList<>());
}
public SetAclPrincipals(List<String> principals,List<AclLine> lines, List<String> aclOptions) {
@@ -41,6 +42,7 @@ public class SetAclPrincipals extends AclGroupBase {
this.principals = Collections.unmodifiableList(principals);
}
+ @Override
protected String getParametersDescription() {
final StringBuilder sb = new StringBuilder();
sb.append(principals);
@@ -55,10 +57,12 @@ public class SetAclPrincipals extends AclGroupBase {
List<String> paths = line.getProperty(AclLine.PROP_PATHS);
return paths == null || paths.isEmpty();
})) {
- String topline = String.format("set repository ACL for %s%s%n", listToString(principals), getAclOptionsString());
+ String topline = String.format("set repository ACL for %s%s%n",
+ listToString(AuthorizableIdUtil.forRepoInitString(principals)), getAclOptionsString());
return asRepoInit(topline, true);
} else {
- String topline = String.format("set ACL for %s%s%n", listToString(principals), getAclOptionsString());
+ String topline = String.format("set ACL for %s%s%n",
+ listToString(AuthorizableIdUtil.forRepoInitString(principals)), getAclOptionsString());
return asRepoInit(topline, true);
}
}
diff --git a/src/main/javacc/RepoInitGrammar.jjt b/src/main/javacc/RepoInitGrammar.jjt
index 1e4236d..d8f93cd 100644
--- a/src/main/javacc/RepoInitGrammar.jjt
+++ b/src/main/javacc/RepoInitGrammar.jjt
@@ -178,8 +178,8 @@ List<String> principalsList() :
List<String> principals = new ArrayList<String>();
}
{
- t = <STRING> { principals.add(t.image); }
- ( <COMMA> t = <STRING> { principals.add(t.image); } )*
+ t = authorizableId() { principals.add(t.image); }
+ ( <COMMA> t = authorizableId() { principals.add(t.image); } )*
{ return principals; }
}
@@ -247,7 +247,7 @@ String usernameList() :
Token t = null;
}
{
- ( t = <STRING> ) { names.add(t.image); }
+ ( t = authorizableId() ) { names.add(t.image); }
// disable lists for now, not supported downstream
// ( <COMMA> t = <STRING> { names.add(t.image); }) *
@@ -654,7 +654,7 @@ void createGroupStatement(List<Operation> result) :
}
{
<CREATE> <GROUP>
- ( group = <STRING> )
+ ( group = authorizableId() )
( wpopt = withPathStatement() ) ?
{
@@ -668,7 +668,7 @@ void deleteGroupStatement(List<Operation> result) :
}
{
<DELETE> <GROUP>
- ( group = <STRING> )
+ ( group = authorizableId() )
{
result.add(new DeleteGroup(group.image));
@@ -754,7 +754,7 @@ void addToGroupStatement(List<Operation> result) :
<ADD>
members = principalsList()
<TO> <GROUP>
- group = <STRING>
+ group = authorizableId()
{
result.add(new AddGroupMembers(members, group.image));
@@ -771,13 +771,21 @@ void removeFromGroupStatement(List<Operation> result) :
<REMOVE>
members = principalsList()
<FROM> <GROUP>
- group = <STRING>
+ group = authorizableId()
{
result.add(new RemoveGroupMembers(members, group.image));
}
}
+Token authorizableId() :
+{
+ Token t = null;
+}
+{
+ (t = <STRING> | t = quotedString() ) { return t; }
+}
+
Token propertyValue() :
{
Token t = null;
diff --git a/src/test/resources/testcases/test-71-output.txt b/src/test/resources/testcases/test-71-output.txt
new file mode 100644
index 0000000..daabab9
--- /dev/null
+++ b/src/test/resources/testcases/test-71-output.txt
@@ -0,0 +1,20 @@
+CreateGroup Test Group
+CreateGroup Test Group With Spaces with path /thePathF
+DeleteGroup Test Group
+SetAclPaths on /content
+ AclLine ALLOW {principals=[Test Group, user1], privileges=[jcr:read]}
+SetAclPaths on /content
+ AclLine ALLOW {principals=[Test Group- Cool People, Test Group, user1], privileges=[jcr:read]}
+SetAclPrincipals for user1 Test Group u2
+ AclLine ALLOW {paths=[/content], privileges=[jcr:read]}
+SetAclPrincipalBased for user1 Test Group ACLOptions=[mergePreserve]
+ AclLine REMOVE_ALL {paths=[/libs, /apps]}
+ AclLine ALLOW {paths=[/content], privileges=[jcr:read]}
+SetAclPaths on /test ACLOptions=[merge]
+ AclLine REMOVE_ALL {principals=[user1, Test Group, user2]}
+SetProperties on :authorizable:bob# :authorizable:Test Group#
+ PropertyLine stringProp{String}=[{String}hello, you again!]
+SetProperties on :authorizable:bob#/nested :authorizable:Test Group#/nested
+ PropertyLine stringProp{String}=[{String}hello, you nested again!]
+AddGroupMembers user1 Test Group 2000 user2 in group Parent Group
+RemoveGroupMembers user1 Test Group 2000 user2 in group Parent Group
\ No newline at end of file
diff --git a/src/test/resources/testcases/test-71.txt b/src/test/resources/testcases/test-71.txt
new file mode 100644
index 0000000..0114a21
--- /dev/null
+++ b/src/test/resources/testcases/test-71.txt
@@ -0,0 +1,28 @@
+# Support quoted Group IDs
+create group "Test Group"
+create group "Test Group With Spaces" with path /thePathF
+delete group "Test Group"
+set ACL on /content
+ allow jcr:read for "Test Group",user1
+end
+set ACL on /content
+ allow jcr:read for "Test Group- Cool People","Test Group",user1
+end
+set ACL for user1,"Test Group",u2
+ allow jcr:read on /content
+end
+set principal ACL for user1,"Test Group" (ACLOptions=mergePreserve)
+ remove * on /libs,/apps
+ allow jcr:read on /content
+end
+set ACL on /test (ACLOptions=merge)
+ remove * for user1,"Test Group",user2
+end
+set properties on authorizable(bob), authorizable("Test Group")
+ set stringProp to "hello, you again!"
+end
+set properties on authorizable(bob)/nested, authorizable("Test Group")/nested
+ set stringProp to "hello, you nested again!"
+end
+add user1,"Test Group 2000",user2 to group "Parent Group"
+remove user1,"Test Group 2000",user2 from group "Parent Group"
\ No newline at end of file