You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by si...@apache.org on 2019/04/30 21:36:11 UTC
[sling-org-apache-sling-feature-cpconverter] 15/29: SLING-8371 -
[cp2fm] map rep:ACL JCR nodes to repoinit Feature extension
This is an automated email from the ASF dual-hosted git repository.
simonetripodi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature-cpconverter.git
commit 8e6b9097328d9fe5d9c62beae0460e02a8d4269c
Author: stripodi <st...@192.168.1.111>
AuthorDate: Wed Apr 24 15:51:45 2019 +0200
SLING-8371 - [cp2fm] map rep:ACL JCR nodes to repoinit Feature extension
initial implementation
old System User refactored in order to use the new ACL Manager
---
.../ContentPackage2FeatureModelConverter.java | 31 ++--
.../apache/sling/feature/cpconverter/acl/Acl.java | 59 ++++++++
.../sling/feature/cpconverter/acl/AclManager.java | 84 +++++++++++
.../feature/cpconverter/acl/package-info.java | 21 +++
.../handlers/AbstractJcrNodeParser.java | 6 +-
.../handlers/RepPolicyEntryHandler.java | 143 ++++++++++++++++++
.../handlers/SystemUsersEntryHandler.java | 9 +-
.../handlers/XmlConfigurationEntryHandler.java | 13 +-
...ache.sling.feature.cpconverter.spi.EntryHandler | 1 +
.../handlers/RepPolicyEntryHandlerTest.java | 161 +++++++++++++++++++++
.../handlers/SystemUsersEntryHandlerTest.java | 5 +-
.../vltpkg/VaultPackageAssemblerTest.java | 1 -
.../handlers/jcr_root/asd/public/_rep_policy.xml | 38 ++++-
13 files changed, 532 insertions(+), 40 deletions(-)
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/ContentPackage2FeatureModelConverter.java b/src/main/java/org/apache/sling/feature/cpconverter/ContentPackage2FeatureModelConverter.java
index 9cf9b1e..378ac20 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/ContentPackage2FeatureModelConverter.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/ContentPackage2FeatureModelConverter.java
@@ -41,6 +41,7 @@ import org.apache.sling.feature.Extension;
import org.apache.sling.feature.ExtensionType;
import org.apache.sling.feature.Extensions;
import org.apache.sling.feature.Feature;
+import org.apache.sling.feature.cpconverter.acl.AclManager;
import org.apache.sling.feature.cpconverter.spi.BundlesDeployer;
import org.apache.sling.feature.cpconverter.spi.EntryHandler;
import org.apache.sling.feature.cpconverter.vltpkg.VaultPackageAssembler;
@@ -66,8 +67,6 @@ public class ContentPackage2FeatureModelConverter {
private static final String DEFEAULT_VERSION = "0.0.0";
- private static final String REPOINIT = "repoinit";
-
private final Logger logger = LoggerFactory.getLogger(getClass());
private final PackageManager packageManager = new PackageManagerImpl();
@@ -76,6 +75,8 @@ public class ContentPackage2FeatureModelConverter {
private final Map<String, Feature> runModes = new HashMap<>();
+ private final AclManager aclManager = new AclManager();
+
private final RegexBasedResourceFilter filter = new RegexBasedResourceFilter();
private BundlesDeployer artifactDeployer;
@@ -95,7 +96,7 @@ public class ContentPackage2FeatureModelConverter {
private VaultPackageAssembler mainPackageAssembler = null;
private String id;
-
+
private String idOverride;
public ContentPackage2FeatureModelConverter setStrictValidation(boolean strictValidation) {
@@ -152,12 +153,15 @@ public class ContentPackage2FeatureModelConverter {
this.id = id;
return this;
}
-
+
public ContentPackage2FeatureModelConverter setIdOverride(String id) {
this.idOverride = id;
return this;
}
+ public AclManager getAclManager() {
+ return aclManager;
+ }
public Feature getRunMode(String runMode) {
if (getTargetFeature() == null) {
@@ -305,7 +309,9 @@ public class ContentPackage2FeatureModelConverter {
// finally serialize the Feature Model(s) file(s)
- seralize(targetFeature, null);
+ aclManager.addRepoinitExtension(getTargetFeature());
+
+ seralize(getTargetFeature(), null);
if (!runModes.isEmpty()) {
for (java.util.Map.Entry<String, Feature> runmodeEntry : runModes.entrySet()) {
@@ -315,21 +321,6 @@ public class ContentPackage2FeatureModelConverter {
}
}
- public void addRepoinitStatement(String format, Object...args) {
- Extension repoInitExtension = getTargetFeature().getExtensions().getByName(REPOINIT);
- if (repoInitExtension == null) {
- repoInitExtension = new Extension(ExtensionType.TEXT, REPOINIT, true);
- getTargetFeature().getExtensions().add(repoInitExtension);
- }
-
- String statement = String.format(format, args);
- if (repoInitExtension.getText() == null) {
- repoInitExtension.setText(statement);
- } else {
- repoInitExtension.setText(repoInitExtension.getText() + '\n' + statement);
- }
- }
-
public void addConfiguration(String runMode, String pid, Dictionary<String, Object> configurationProperties) {
if (!mergeConfigurations) {
checkConfigurationExist(getTargetFeature(), pid);
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/acl/Acl.java b/src/main/java/org/apache/sling/feature/cpconverter/acl/Acl.java
new file mode 100644
index 0000000..0f483ff
--- /dev/null
+++ b/src/main/java/org/apache/sling/feature/cpconverter/acl/Acl.java
@@ -0,0 +1,59 @@
+/*
+ * 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.feature.cpconverter.acl;
+
+import java.util.Formatter;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Simple single ACL statement representation.
+ */
+public final class Acl {
+
+ private final String operation;
+
+ private final String privileges;
+
+ private final String path;
+
+ private final List<String> restrictions = new LinkedList<>();
+
+ protected Acl(String operation, String privileges, String path) {
+ this.operation = operation;
+ this.privileges = privileges;
+ this.path = path;
+ }
+
+ public void addRestriction(String restriction) {
+ if (restriction != null && !restriction.isEmpty()) {
+ restrictions.add(restriction);
+ }
+ }
+
+ protected void addAclStatement(Formatter formatter) {
+ formatter.format("%s %s on %s", operation, privileges, path);
+
+ if (!restrictions.isEmpty()) {
+ formatter.format(" restriction(%s)", restrictions.stream().collect(Collectors.joining(",")));
+ }
+
+ formatter.format("%n");
+ }
+
+}
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/acl/AclManager.java b/src/main/java/org/apache/sling/feature/cpconverter/acl/AclManager.java
new file mode 100644
index 0000000..54564c9
--- /dev/null
+++ b/src/main/java/org/apache/sling/feature/cpconverter/acl/AclManager.java
@@ -0,0 +1,84 @@
+/*
+ * 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.feature.cpconverter.acl;
+
+import java.util.Formatter;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.sling.feature.Extension;
+import org.apache.sling.feature.ExtensionType;
+import org.apache.sling.feature.Feature;
+
+/**
+ * The Manager able to collect and build System Users and related ACL policies.
+ */
+public final class AclManager {
+
+ private final Set<String> systemUsers = new LinkedHashSet<>();
+
+ private final Map<String, List<Acl>> acls = new HashMap<>();
+
+ public boolean addSystemUser(String systemUser) {
+ if (systemUser != null && !systemUser.isEmpty()) {
+ return systemUsers.add(systemUser);
+ }
+ return false;
+ }
+
+ public Acl addAcl(String systemUser, String operation, String privileges, String path) {
+ Acl acl = new Acl(operation, privileges, path);
+ acls.computeIfAbsent(systemUser, k -> new LinkedList<>()).add(acl);
+ return acl;
+ }
+
+ public void addRepoinitExtension(Feature feature) {
+ if (systemUsers.isEmpty()) {
+ return;
+ }
+
+ Extension repoInitExtension = new Extension(ExtensionType.TEXT, Extension.EXTENSION_NAME_REPOINIT, true);
+
+ Formatter formatter = new Formatter();
+
+ for (String systemUser : systemUsers) {
+ formatter.format("create service user %s%n", systemUser);
+
+ List<Acl> authorizations = acls.get(systemUser);
+ if (authorizations != null && !authorizations.isEmpty()) {
+ formatter.format("set ACL for %s%n", systemUser);
+
+ for (Acl authorization : authorizations) {
+ authorization.addAclStatement(formatter);
+ }
+
+ formatter.format("end%n");
+ }
+ }
+
+ String text = formatter.toString();
+ formatter.close();
+ repoInitExtension.setText(text);
+
+ feature.getExtensions().add(repoInitExtension);
+ }
+
+}
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/acl/package-info.java b/src/main/java/org/apache/sling/feature/cpconverter/acl/package-info.java
new file mode 100644
index 0000000..0ef4e34
--- /dev/null
+++ b/src/main/java/org/apache/sling/feature/cpconverter/acl/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+/**
+ * Small utility set to handle System Users and related ACL policies.
+ */
+package org.apache.sling.feature.cpconverter.acl;
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/handlers/AbstractJcrNodeParser.java b/src/main/java/org/apache/sling/feature/cpconverter/handlers/AbstractJcrNodeParser.java
index 12e3089..e346ff3 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/handlers/AbstractJcrNodeParser.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/handlers/AbstractJcrNodeParser.java
@@ -27,7 +27,7 @@ import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
-abstract class AbstractJcrNodeParser extends DefaultHandler {
+abstract class AbstractJcrNodeParser<O> extends DefaultHandler {
private static final String JCR_ROOT = "jcr:root";
@@ -45,7 +45,7 @@ abstract class AbstractJcrNodeParser extends DefaultHandler {
}
@Override
- public final void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+ public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
String primaryType = attributes.getValue(JCR_PRIMARYTYPE);
if (JCR_ROOT.equals(qName) && this.primaryType.equals(primaryType)) {
@@ -55,4 +55,6 @@ abstract class AbstractJcrNodeParser extends DefaultHandler {
protected abstract void onJcrRootElement(String uri, String localName, String qName, Attributes attributes) throws SAXException;
+ protected abstract O getParsingResult();
+
}
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/handlers/RepPolicyEntryHandler.java b/src/main/java/org/apache/sling/feature/cpconverter/handlers/RepPolicyEntryHandler.java
new file mode 100644
index 0000000..6dad716
--- /dev/null
+++ b/src/main/java/org/apache/sling/feature/cpconverter/handlers/RepPolicyEntryHandler.java
@@ -0,0 +1,143 @@
+/*
+ * 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.feature.cpconverter.handlers;
+
+import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
+
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Stack;
+import java.util.regex.Matcher;
+
+import org.apache.jackrabbit.vault.fs.io.Archive;
+import org.apache.jackrabbit.vault.fs.io.Archive.Entry;
+import org.apache.sling.feature.cpconverter.ContentPackage2FeatureModelConverter;
+import org.apache.sling.feature.cpconverter.acl.Acl;
+import org.apache.sling.feature.cpconverter.acl.AclManager;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+public final class RepPolicyEntryHandler extends AbstractRegexEntryHandler {
+
+ public RepPolicyEntryHandler() {
+ super("(jcr_root)?(/.+)/_rep_policy.xml");
+ }
+
+ @Override
+ public void handle(String path, Archive archive, Entry entry, ContentPackage2FeatureModelConverter converter)
+ throws Exception {
+ Matcher matcher = getPattern().matcher(path);
+ // we are pretty sure it matches, here
+ if (matcher.matches()) {
+ path = matcher.group(2);
+ } else {
+ throw new IllegalStateException("Something went terribly wrong: pattern '"
+ + getPattern().pattern()
+ + "' should have matched already with path '"
+ + path
+ + "' but it does not, currently");
+ }
+
+ RepPolicyParser systemUserParser = new RepPolicyParser(path, converter.getAclManager());
+ try (InputStream input = archive.openInputStream(entry)) {
+ systemUserParser.parse(input);
+ }
+ }
+
+ private static final class RepPolicyParser extends AbstractJcrNodeParser<Void> {
+
+ private static final String REP_ACL = "rep:ACL";
+
+ private static final String REP_GRANT_ACE = "rep:GrantACE";
+
+ private static final String REP_DENY_ACE = "rep:DenyACE";
+
+ private static final String REP_RESTRICTIONS = "rep:Restrictions";
+
+ private static final String REP_PRINCIPAL_NAME = "rep:principalName";
+
+ private static final String REP_PRIVILEGES = "rep:privileges";
+
+ private static final String REP_GLOB = "rep:glob";
+
+ private static final Map<String, String> operations = new HashMap<>();
+
+ static {
+ operations.put(REP_GRANT_ACE, "allow");
+ operations.put(REP_DENY_ACE, "deny");
+ }
+
+ private final Stack<Acl> acls = new Stack<>();
+
+ private final String path;
+
+ private final AclManager aclManager;
+
+ private boolean onRepAclNode = false;
+
+ public RepPolicyParser(String path, AclManager aclManager) {
+ super(REP_ACL);
+ this.path = path;
+ this.aclManager = aclManager;
+ }
+
+ @Override
+ public void startElement(String uri, String localName, String qName, Attributes attributes)
+ throws SAXException {
+ if (onRepAclNode) {
+ String primaryType = attributes.getValue(JCR_PRIMARYTYPE);
+ if (REP_GRANT_ACE.equals(primaryType) || REP_DENY_ACE.equals(primaryType)) {
+ String principalName = attributes.getValue(REP_PRINCIPAL_NAME);
+
+ String operation = operations.get(primaryType);
+
+ String privileges = attributes.getValue(REP_PRIVILEGES);
+ int beginIndex = privileges.indexOf('[') + 1;
+ int endIndex = privileges.indexOf(']');
+ privileges = privileges.substring(beginIndex, endIndex);
+
+ acls.add(aclManager.addAcl(principalName, operation, privileges, path));
+ } else if (REP_RESTRICTIONS.equals(primaryType) && !acls.isEmpty()) {
+ String restriction = attributes.getValue(REP_GLOB);
+ acls.peek().addRestriction(restriction);
+ }
+ } else {
+ super.startElement(uri, localName, qName, attributes);
+ }
+ }
+
+ @Override
+ public void endElement(String uri, String localName, String qName) throws SAXException {
+ if (onRepAclNode && !acls.isEmpty()) {
+ acls.pop();
+ }
+ }
+
+ @Override
+ protected void onJcrRootElement(String uri, String localName, String qName, Attributes attributes) {
+ onRepAclNode = true;
+ }
+
+ @Override
+ protected Void getParsingResult() {
+ return null;
+ }
+
+ }
+
+}
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/handlers/SystemUsersEntryHandler.java b/src/main/java/org/apache/sling/feature/cpconverter/handlers/SystemUsersEntryHandler.java
index b451e8b..7fe64aa 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/handlers/SystemUsersEntryHandler.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/handlers/SystemUsersEntryHandler.java
@@ -38,7 +38,7 @@ public final class SystemUsersEntryHandler extends AbstractRegexEntryHandler {
}
}
- private static final class SystemUserParser extends AbstractJcrNodeParser {
+ private static final class SystemUserParser extends AbstractJcrNodeParser<Void> {
private final static String REP_SYSTEM_USER = "rep:SystemUser";
@@ -55,10 +55,15 @@ public final class SystemUsersEntryHandler extends AbstractRegexEntryHandler {
protected void onJcrRootElement(String uri, String localName, String qName, Attributes attributes) {
String authorizableId = attributes.getValue(REP_AUTHORIZABLE_ID);
if (authorizableId != null && !authorizableId.isEmpty()) {
- converter.addRepoinitStatement("create service user %s", authorizableId);
+ converter.getAclManager().addSystemUser(authorizableId);
}
}
+ @Override
+ protected Void getParsingResult() {
+ return null;
+ }
+
}
}
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/handlers/XmlConfigurationEntryHandler.java b/src/main/java/org/apache/sling/feature/cpconverter/handlers/XmlConfigurationEntryHandler.java
index 5188b24..d1b1919 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/handlers/XmlConfigurationEntryHandler.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/handlers/XmlConfigurationEntryHandler.java
@@ -34,19 +34,15 @@ public final class XmlConfigurationEntryHandler extends AbstractConfigurationEnt
protected Dictionary<String, Object> parseConfiguration(String name, InputStream input) throws Exception {
JcrConfigurationHandler configurationHandler = new JcrConfigurationHandler();
configurationHandler.parse(input);
- return configurationHandler.getConfiguration();
+ return configurationHandler.getParsingResult();
}
- private static final class JcrConfigurationHandler extends AbstractJcrNodeParser {
+ private static final class JcrConfigurationHandler extends AbstractJcrNodeParser<Dictionary<String, Object>> {
private static final String SLING_OSGICONFIG = "sling:OsgiConfig";
private final Dictionary<String, Object> configuration = new Hashtable<>();
- public Dictionary<String, Object> getConfiguration() {
- return configuration;
- }
-
public JcrConfigurationHandler() {
super(SLING_OSGICONFIG);
}
@@ -75,6 +71,11 @@ public final class XmlConfigurationEntryHandler extends AbstractConfigurationEnt
}
}
+ @Override
+ protected Dictionary<String, Object> getParsingResult() {
+ return configuration;
+ }
+
}
}
diff --git a/src/main/resources/META-INF/services/org.apache.sling.feature.cpconverter.spi.EntryHandler b/src/main/resources/META-INF/services/org.apache.sling.feature.cpconverter.spi.EntryHandler
index b4b9ec0..53e84b4 100644
--- a/src/main/resources/META-INF/services/org.apache.sling.feature.cpconverter.spi.EntryHandler
+++ b/src/main/resources/META-INF/services/org.apache.sling.feature.cpconverter.spi.EntryHandler
@@ -3,5 +3,6 @@ org.apache.sling.feature.cpconverter.handlers.ConfigurationEntryHandler
org.apache.sling.feature.cpconverter.handlers.ContentPackageEntryHandler
org.apache.sling.feature.cpconverter.handlers.JsonConfigurationEntryHandler
org.apache.sling.feature.cpconverter.handlers.PropertiesConfigurationEntryHandler
+org.apache.sling.feature.cpconverter.handlers.RepPolicyEntryHandler
org.apache.sling.feature.cpconverter.handlers.SystemUsersEntryHandler
org.apache.sling.feature.cpconverter.handlers.XmlConfigurationEntryHandler
diff --git a/src/test/java/org/apache/sling/feature/cpconverter/handlers/RepPolicyEntryHandlerTest.java b/src/test/java/org/apache/sling/feature/cpconverter/handlers/RepPolicyEntryHandlerTest.java
new file mode 100644
index 0000000..ecf5419
--- /dev/null
+++ b/src/test/java/org/apache/sling/feature/cpconverter/handlers/RepPolicyEntryHandlerTest.java
@@ -0,0 +1,161 @@
+/*
+ * 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.feature.cpconverter.handlers;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import org.apache.jackrabbit.vault.fs.io.Archive;
+import org.apache.jackrabbit.vault.fs.io.Archive.Entry;
+import org.apache.sling.feature.ArtifactId;
+import org.apache.sling.feature.Extension;
+import org.apache.sling.feature.ExtensionType;
+import org.apache.sling.feature.Feature;
+import org.apache.sling.feature.cpconverter.ContentPackage2FeatureModelConverter;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public final class RepPolicyEntryHandlerTest {
+
+ private RepPolicyEntryHandler handler;
+
+ @Before
+ public void setUp() {
+ handler = new RepPolicyEntryHandler();
+ }
+
+ @After
+ public void tearDown() {
+ handler = null;
+ }
+
+ @Test
+ public void doesNotMatch() {
+ assertFalse(handler.matches("/this/is/a/path/not/pointing/to/a/valid/policy.xml"));
+ }
+
+ @Test
+ public void matches() {
+ assertTrue(handler.matches("/home/users/system/asd-share-commons/asd-index-definition-reader/_rep_policy.xml"));
+ assertTrue(handler.matches("jcr_root/home/users/system/asd-share-commons/asd-index-definition-reader/_rep_policy.xml"));
+ }
+
+ @Test
+ public void parseAcl() throws Exception {
+ Extension repoinitExtension = parseAndSetRepoinit("acs-commons-ensure-oak-index-service",
+ "acs-commons-dispatcher-flush-service",
+ "acs-commons-package-replication-status-event-service",
+ "acs-commons-ensure-service-user-service",
+ "acs-commons-automatic-package-replicator-service",
+ "acs-commons-on-deploy-scripts-service");
+ assertNotNull(repoinitExtension);
+ assertEquals(ExtensionType.TEXT, repoinitExtension.getType());
+
+ String expected = "create service user acs-commons-ensure-oak-index-service\n" +
+ "set ACL for acs-commons-ensure-oak-index-service\n" +
+ "allow jcr:read,rep:write,rep:indexDefinitionManagement on /asd/public restriction(*/oak:index/*)\n" +
+ "end\n" +
+ "create service user acs-commons-dispatcher-flush-service\n" +
+ "set ACL for acs-commons-dispatcher-flush-service\n" +
+ "allow jcr:read,crx:replicate,jcr:removeNode on /asd/public\n" +
+ "end\n" +
+ "create service user acs-commons-package-replication-status-event-service\n" +
+ "set ACL for acs-commons-package-replication-status-event-service\n" +
+ "allow jcr:read,rep:write,jcr:readAccessControl,jcr:modifyAccessControl on /asd/public\n" +
+ "end\n" +
+ "create service user acs-commons-ensure-service-user-service\n" +
+ "set ACL for acs-commons-ensure-service-user-service\n" +
+ "allow jcr:read,rep:write,jcr:readAccessControl,jcr:modifyAccessControl on /asd/public\n" +
+ "end\n" +
+ "create service user acs-commons-automatic-package-replicator-service\n" +
+ "set ACL for acs-commons-automatic-package-replicator-service\n" +
+ "allow jcr:read on /asd/public\n" +
+ "end\n" +
+ "create service user acs-commons-on-deploy-scripts-service\n" +
+ "set ACL for acs-commons-on-deploy-scripts-service\n" +
+ "allow jcr:read on /asd/public\n" +
+ "end\n";
+ String actual = repoinitExtension.getText();
+ assertEquals(expected, actual);
+ }
+
+ @Test
+ public void notDeclaredSystemUsersWontHaveAclSettings() throws Exception {
+ Extension repoinitExtension = parseAndSetRepoinit("acs-commons-package-replication-status-event-service",
+ "acs-commons-ensure-service-user-service",
+ "acs-commons-automatic-package-replicator-service",
+ "acs-commons-on-deploy-scripts-service");
+ assertNotNull(repoinitExtension);
+ assertEquals(ExtensionType.TEXT, repoinitExtension.getType());
+
+ String expected = "create service user acs-commons-package-replication-status-event-service\n" +
+ "set ACL for acs-commons-package-replication-status-event-service\n" +
+ "allow jcr:read,rep:write,jcr:readAccessControl,jcr:modifyAccessControl on /asd/public\n" +
+ "end\n" +
+ "create service user acs-commons-ensure-service-user-service\n" +
+ "set ACL for acs-commons-ensure-service-user-service\n" +
+ "allow jcr:read,rep:write,jcr:readAccessControl,jcr:modifyAccessControl on /asd/public\n" +
+ "end\n" +
+ "create service user acs-commons-automatic-package-replicator-service\n" +
+ "set ACL for acs-commons-automatic-package-replicator-service\n" +
+ "allow jcr:read on /asd/public\n" +
+ "end\n" +
+ "create service user acs-commons-on-deploy-scripts-service\n" +
+ "set ACL for acs-commons-on-deploy-scripts-service\n" +
+ "allow jcr:read on /asd/public\n" +
+ "end\n";
+ String actual = repoinitExtension.getText();
+ assertEquals(expected, actual);
+ }
+
+ @Test
+ public void parseEmptyAcl() throws Exception {
+ Extension repoinitExtension = parseAndSetRepoinit();
+ assertNull(repoinitExtension);
+ }
+
+ private Extension parseAndSetRepoinit(String...systemUsers) throws Exception {
+ String path = "jcr_root/asd/public/_rep_policy.xml";
+ Archive archive = mock(Archive.class);
+ Entry entry = mock(Entry.class);
+
+ when(archive.openInputStream(entry)).thenReturn(getClass().getResourceAsStream(path));
+
+ Feature feature = new Feature(new ArtifactId("org.apache.sling", "org.apache.sling.cp2fm", "0.0.1", null, null));
+ ContentPackage2FeatureModelConverter converter = spy(ContentPackage2FeatureModelConverter.class);
+ when(converter.getTargetFeature()).thenReturn(feature);
+
+ handler.handle(path, archive, entry, converter);
+
+ if (systemUsers != null) {
+ for (String systemUser : systemUsers) {
+ converter.getAclManager().addSystemUser(systemUser);
+ }
+ }
+
+ converter.getAclManager().addRepoinitExtension(feature);
+ return feature.getExtensions().getByName(Extension.EXTENSION_NAME_REPOINIT);
+ }
+
+}
diff --git a/src/test/java/org/apache/sling/feature/cpconverter/handlers/SystemUsersEntryHandlerTest.java b/src/test/java/org/apache/sling/feature/cpconverter/handlers/SystemUsersEntryHandlerTest.java
index 5126e0f..70270d0 100644
--- a/src/test/java/org/apache/sling/feature/cpconverter/handlers/SystemUsersEntryHandlerTest.java
+++ b/src/test/java/org/apache/sling/feature/cpconverter/handlers/SystemUsersEntryHandlerTest.java
@@ -67,7 +67,7 @@ public class SystemUsersEntryHandlerTest {
assertNotNull(repoinitExtension);
assertEquals(ExtensionType.TEXT, repoinitExtension.getType());
assertTrue(repoinitExtension.isRequired());
- assertEquals("create service user asd-share-commons-asd-index-definition-reader-service", repoinitExtension.getText());
+ assertEquals("create service user asd-share-commons-asd-index-definition-reader-service\n", repoinitExtension.getText());
}
@Test
@@ -89,7 +89,8 @@ public class SystemUsersEntryHandlerTest {
systemUsersEntryHandler.handle(path, archive, entry, converter);
- return feature.getExtensions().getByName("repoinit");
+ converter.getAclManager().addRepoinitExtension(feature);
+ return feature.getExtensions().getByName(Extension.EXTENSION_NAME_REPOINIT);
}
}
diff --git a/src/test/java/org/apache/sling/feature/cpconverter/vltpkg/VaultPackageAssemblerTest.java b/src/test/java/org/apache/sling/feature/cpconverter/vltpkg/VaultPackageAssemblerTest.java
index d2aa3cc..011a516 100644
--- a/src/test/java/org/apache/sling/feature/cpconverter/vltpkg/VaultPackageAssemblerTest.java
+++ b/src/test/java/org/apache/sling/feature/cpconverter/vltpkg/VaultPackageAssemblerTest.java
@@ -81,7 +81,6 @@ public class VaultPackageAssemblerTest {
return Arrays.asList(new Object[][] {
{ "jcr_root/.content.xml", assembler },
{ "jcr_root/asd/.content.xml", assembler },
- { "jcr_root/asd/public/_rep_policy.xml", assembler },
{ "jcr_root/asd/public/license.txt", assembler }
});
}
diff --git a/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/asd/public/_rep_policy.xml b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/asd/public/_rep_policy.xml
index 2b1119a..8b639bb 100644
--- a/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/asd/public/_rep_policy.xml
+++ b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/asd/public/_rep_policy.xml
@@ -15,10 +15,34 @@
License for the specific language governing permissions and limitations under
the License.
-->
-<jcr:root xmlns:crx="http://www.day.com/crx/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:rep="internal"
- jcr:primaryType="rep:ACL">
- <allow
- jcr:primaryType="rep:GrantACE"
- rep:principalName="everyone"
- rep:privileges="{Name}[jcr:read]"/>
-</jcr:root>
\ No newline at end of file
+<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:rep="internal"
+ jcr:primaryType="rep:ACL">
+ <allow0
+ jcr:primaryType="rep:GrantACE"
+ rep:principalName="acs-commons-ensure-oak-index-service"
+ rep:privileges="{Name}[jcr:read,rep:write,rep:indexDefinitionManagement]">
+ <rep:restrictions
+ jcr:primaryType="rep:Restrictions"
+ rep:glob="*/oak:index/*"/>
+ </allow0>
+ <allow1
+ jcr:primaryType="rep:GrantACE"
+ rep:principalName="acs-commons-dispatcher-flush-service"
+ rep:privileges="{Name}[jcr:read,crx:replicate,jcr:removeNode]"/>
+ <allow2
+ jcr:primaryType="rep:GrantACE"
+ rep:principalName="acs-commons-package-replication-status-event-service"
+ rep:privileges="{Name}[jcr:read,rep:write,jcr:readAccessControl,jcr:modifyAccessControl]"/>
+ <allow3
+ jcr:primaryType="rep:GrantACE"
+ rep:principalName="acs-commons-ensure-service-user-service"
+ rep:privileges="{Name}[jcr:read,rep:write,jcr:readAccessControl,jcr:modifyAccessControl]"/>
+ <allow4
+ jcr:primaryType="rep:GrantACE"
+ rep:principalName="acs-commons-automatic-package-replicator-service"
+ rep:privileges="{Name}[jcr:read]"/>
+ <allow5
+ jcr:primaryType="rep:GrantACE"
+ rep:principalName="acs-commons-on-deploy-scripts-service"
+ rep:privileges="{Name}[jcr:read]"/>
+</jcr:root>