This is an automated email from the ASF dual-hosted git repository.
pauls pushed a commit to branch master
in repository
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature-cpconverter.git
The following commit(s) were added to refs/heads/master by this push:
new c338e2c SLING-10070 : Option to enforce principal-based authorization
(wip) (#56)
c338e2c is described below
commit c338e2c2d1713174eaf7acaa1560680a6117417f
Author: anchela <[email protected]>
AuthorDate: Wed Jan 20 13:25:26 2021 +0100
SLING-10070 : Option to enforce principal-based authorization (wip) (#56)
Co-authored-by: angela <[email protected]>
Co-authored-by: Karl Pauls <[email protected]>
---
.../cpconverter/accesscontrol/AclManager.java | 2 +
.../accesscontrol/DefaultAclManager.java | 114 +++++++++++-----
.../feature/cpconverter/accesscontrol/Mapping.java | 130 ++++++++++++++++++
...ntentPackage2FeatureModelConverterLauncher.java | 9 +-
.../AbstractConfigurationEntryHandler.java | 22 ++-
.../accesscontrol/EnforcePrincipalBasedTest.java | 149 +++++++++------------
.../cpconverter/accesscontrol/MappingTest.java | 134 ++++++++++++++++++
.../handlers/ConfigurationEntryHandlerTest.java | 55 +++++---
.../JsonConfigurationEntryHandlerTest.java | 34 +++++
.../feature/cpconverter/handlers/TestUtils.java | 3 +
...ceusermapping.impl.ServiceUserMapperImpl.config | 2 +-
...ceusermapping.impl.ServiceUserMapperImpl.config | 2 +-
...rviceusermapping.impl.ServiceUserMapperImpl.cfg | 2 +-
...usermapping.impl.ServiceUserMapperImpl.cfg.json | 5 +-
...ceusermapping.impl.ServiceUserMapperImpl.config | 2 +-
...ermapping.impl.ServiceUserMapperImpl.config.xml | 2 +-
...sermapping.impl.ServiceUserMapperImpl.typed.xml | 2 +-
...rviceusermapping.impl.ServiceUserMapperImpl.xml | 2 +-
...eusermapping.impl.ServiceUserMapperImpl.xml.cfg | 2 +-
19 files changed, 510 insertions(+), 163 deletions(-)
diff --git
a/src/main/java/org/apache/sling/feature/cpconverter/accesscontrol/AclManager.java
b/src/main/java/org/apache/sling/feature/cpconverter/accesscontrol/AclManager.java
index 8ca506d..95f2f75 100644
---
a/src/main/java/org/apache/sling/feature/cpconverter/accesscontrol/AclManager.java
+++
b/src/main/java/org/apache/sling/feature/cpconverter/accesscontrol/AclManager.java
@@ -34,6 +34,8 @@ public interface AclManager {
boolean addSystemUser(@NotNull SystemUser systemUser);
+ void addMapping(@NotNull Mapping mapping);
+
boolean addAcl(@NotNull String systemUser, @NotNull AccessControlEntry
acl);
void addRepoinitExtension(@NotNull List<VaultPackageAssembler>
packageAssemblers, @NotNull FeaturesManager featureManager);
diff --git
a/src/main/java/org/apache/sling/feature/cpconverter/accesscontrol/DefaultAclManager.java
b/src/main/java/org/apache/sling/feature/cpconverter/accesscontrol/DefaultAclManager.java
index aff08fc..e898d13 100644
---
a/src/main/java/org/apache/sling/feature/cpconverter/accesscontrol/DefaultAclManager.java
+++
b/src/main/java/org/apache/sling/feature/cpconverter/accesscontrol/DefaultAclManager.java
@@ -27,11 +27,15 @@ import org.apache.sling.feature.cpconverter.shared.RepoPath;
import org.apache.sling.feature.cpconverter.vltpkg.VaultPackageAssembler;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import javax.jcr.NamespaceException;
import java.io.File;
import java.io.FileInputStream;
import java.util.Collection;
+import java.util.HashSet;
+import java.util.Optional;
import java.util.Formatter;
import java.util.HashMap;
import java.util.LinkedHashMap;
@@ -41,7 +45,6 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
-import java.util.Optional;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@@ -49,14 +52,17 @@ import java.util.stream.Stream;
public class DefaultAclManager implements AclManager {
+ private static final Logger log =
LoggerFactory.getLogger(DefaultAclManager.class);
+
private static final String CONTENT_XML_FILE_NAME = ".content.xml";
- private final boolean enforcePrincipalBased;
- private final RepoPath supportedPrincipalBasedPath;
+ private final RepoPath enforcePrincipalBasedSupportedPath;
private final Set<SystemUser> systemUsers = new LinkedHashSet<>();
private final Set<Group> groups = new LinkedHashSet<>();
private final Set<User> users = new LinkedHashSet<>();
+ private final Set<Mapping> mappings = new HashSet<>();
+ private final Set<String> mappedById = new HashSet<>();
private final Map<String, List<AccessControlEntry>> acls = new HashMap<>();
@@ -65,11 +71,10 @@ public class DefaultAclManager implements AclManager {
private volatile PrivilegeDefinitions privilegeDefinitions;
public DefaultAclManager() {
- this(false, null);
+ this(null);
}
- public DefaultAclManager(boolean enforcePrincipalBased, @Nullable String
supportedPrincipalBasedPath) {
- this.enforcePrincipalBased = enforcePrincipalBased;
- this.supportedPrincipalBasedPath = (supportedPrincipalBasedPath ==
null) ? null : new RepoPath(supportedPrincipalBasedPath);
+ public DefaultAclManager(@Nullable String
enforcePrincipalBasedSupportedPath) {
+ this.enforcePrincipalBasedSupportedPath =
(enforcePrincipalBasedSupportedPath == null) ? null : new
RepoPath(enforcePrincipalBasedSupportedPath);
}
@Override
@@ -84,7 +89,26 @@ public class DefaultAclManager implements AclManager {
@Override
public boolean addSystemUser(@NotNull SystemUser systemUser) {
- return systemUsers.add(systemUser);
+ if (systemUsers.add(systemUser)) {
+ if (mappings.stream().anyMatch(mapping ->
mapping.mapsUser(systemUser.getId()))) {
+ mappedById.add(systemUser.getId());
+ }
+ return true;
+ } else {
+ return false;
+ }
+
+ }
+
+ @Override
+ public void addMapping(@NotNull Mapping mapping) {
+ if (mappings.add(mapping)) {
+ for (SystemUser user : systemUsers) {
+ if (mapping.mapsUser(user.getId())) {
+ mappedById.add(user.getId());
+ }
+ }
+ }
}
@Override
@@ -128,7 +152,7 @@ public class DefaultAclManager implements AclManager {
private void addUsersAndGroups(@NotNull Formatter formatter) {
for (SystemUser systemUser : systemUsers) {
// make sure all system users are created first
- formatter.format("create service user %s with path %s%n",
systemUser.getId(),
calculateIntermediatePath(systemUser.getIntermediatePath()));
+ formatter.format("create service user %s with path %s%n",
systemUser.getId(), calculateIntermediatePath(systemUser));
if (aclIsBelow(systemUser.getPath())) {
throw new IllegalStateException("Detected policy on subpath of
system-user: " + systemUser);
}
@@ -138,50 +162,53 @@ public class DefaultAclManager implements AclManager {
// created by repo-init statements generated here.
Stream.concat(groups.stream(), users.stream()).forEach(abstractUser ->
{
if (aclStartsWith(abstractUser.getPath())) {
- throw new IllegalStateException("Detected policy on user: " +
abstractUser);
+ throw new IllegalStateException("Detected policy on
user/group: " + abstractUser);
}
});
}
@NotNull
- private String calculateIntermediatePath(@NotNull RepoPath
intermediatePath) {
- if (enforcePrincipalBased && supportedPrincipalBasedPath != null &&
!intermediatePath.startsWith(supportedPrincipalBasedPath)) {
+ private String calculateIntermediatePath(@NotNull SystemUser systemUser) {
+ RepoPath intermediatePath = systemUser.getIntermediatePath();
+ if (enforcePrincipalBased(systemUser) &&
!intermediatePath.startsWith(enforcePrincipalBasedSupportedPath)) {
RepoPath parent = intermediatePath.getParent();
while (parent != null) {
- if (supportedPrincipalBasedPath.startsWith(parent)) {
+ if (enforcePrincipalBasedSupportedPath.startsWith(parent)) {
String relpath =
intermediatePath.toString().substring(parent.toString().length());
- return supportedPrincipalBasedPath.toString() + relpath;
+ return enforcePrincipalBasedSupportedPath.toString() +
relpath;
}
parent = parent.getParent();
}
- throw new IllegalStateException("Cannot calculate intermediate
path for service user. Configured Supported path "
+supportedPrincipalBasedPath+" has no common ancestor with "+intermediatePath);
+ throw new IllegalStateException("Cannot calculate intermediate
path for service user. Configured Supported path "
+enforcePrincipalBasedSupportedPath+" has no common ancestor with
"+intermediatePath);
} else {
return intermediatePath.toString();
}
}
private void addPaths(@NotNull Formatter formatter, @NotNull
List<VaultPackageAssembler> packageAssemblers) {
- if (!enforcePrincipalBased) {
- Set<RepoPath> paths = acls.entrySet().stream()
- .filter(entry -> getSystemUser(entry.getKey()).isPresent())
- .map(Entry::getValue)
- .flatMap(Collection::stream)
- // paths only should/need to be create with resource-based
access control
- .filter(((Predicate<AccessControlEntry>)
AccessControlEntry::isPrincipalBased).negate())
- .map(AccessControlEntry::getRepositoryPath)
- .collect(Collectors.toSet());
-
- paths.stream()
- .filter(path -> paths.stream().noneMatch(other ->
!other.equals(path) && other.startsWith(path)))
-
.filter(((Predicate<RepoPath>)RepoPath::isRepositoryPath).negate())
- .filter(path -> Stream.of(systemUsers, users,
groups).flatMap(Collection::stream)
- .noneMatch(user ->
user.getPath().startsWith(path)))
- .map(path -> computePathWithTypes(path, packageAssemblers))
- .filter(Objects::nonNull)
- .forEach(
- path -> formatter.format("create path %s%n", path)
- );
- }
+ Set<RepoPath> paths = acls.entrySet().stream()
+ // filter paths if service user does not exist or will have
principal-based ac setup enforced
+ .filter(entry -> {
+ Optional<SystemUser> su = getSystemUser(entry.getKey());
+ return su.isPresent() && !enforcePrincipalBased(su.get());
+ })
+ .map(Entry::getValue)
+ .flatMap(Collection::stream)
+ // paths only should/need to be create with resource-based
access control
+ .filter(((Predicate<AccessControlEntry>)
AccessControlEntry::isPrincipalBased).negate())
+ .map(AccessControlEntry::getRepositoryPath)
+ .collect(Collectors.toSet());
+
+ paths.stream()
+ .filter(path -> paths.stream().noneMatch(other ->
!other.equals(path) && other.startsWith(path)))
+
.filter(((Predicate<RepoPath>)RepoPath::isRepositoryPath).negate())
+ .filter(path -> Stream.of(systemUsers, users,
groups).flatMap(Collection::stream)
+ .noneMatch(user -> user.getPath().startsWith(path)))
+ .map(path -> computePathWithTypes(path, packageAssemblers))
+ .filter(Objects::nonNull)
+ .forEach(
+ path -> formatter.format("create path %s%n", path)
+ );
}
private boolean aclStartsWith(@NotNull RepoPath path) {
@@ -200,7 +227,7 @@ public class DefaultAclManager implements AclManager {
authorizations.forEach(entry -> {
String path = getRepoInitPath(entry.getRepositoryPath(),
systemUser);
- if (enforcePrincipalBased || entry.isPrincipalBased()) {
+ if (entry.isPrincipalBased() || enforcePrincipalBased(systemUser))
{
principalEntries.put(entry, path);
} else {
resourceEntries.put(entry, path);
@@ -219,6 +246,19 @@ public class DefaultAclManager implements AclManager {
}
}
+ private boolean enforcePrincipalBased(@NotNull SystemUser systemUser) {
+ if (enforcePrincipalBasedSupportedPath == null) {
+ return false;
+ } else {
+ if (mappedById.contains(systemUser.getId())) {
+ log.warn("Skip enforcing principalbased access control setup
for system user {} due to existing mapping", systemUser.getId());
+ return false;
+ } else {
+ return true;
+ }
+ }
+ }
+
private void writeEntry(@NotNull AccessControlEntry entry, @NotNull String
path, @NotNull Formatter formatter) {
formatter.format("%s %s on %s",
entry.getOperation(),
diff --git
a/src/main/java/org/apache/sling/feature/cpconverter/accesscontrol/Mapping.java
b/src/main/java/org/apache/sling/feature/cpconverter/accesscontrol/Mapping.java
new file mode 100644
index 0000000..9b91372
--- /dev/null
+++
b/src/main/java/org/apache/sling/feature/cpconverter/accesscontrol/Mapping.java
@@ -0,0 +1,130 @@
+/*
+ * 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.accesscontrol;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.LinkedHashSet;
+import java.util.Objects;
+import java.util.Set;
+
+public class Mapping {
+
+ private final String serviceName;
+
+ private final String subServiceName;
+
+ private final String userName;
+
+ private final Set<String> principalNames;
+
+ /**
+ * Copied from
https://github.com/apache/sling-org-apache-sling-serviceusermapper/blob/master/src/main/java/org/apache/sling/serviceusermapping/Mapping.java
+ */
+ public Mapping(@NotNull final String spec) {
+
+ final int colon = spec.indexOf(':');
+ final int equals = spec.indexOf('=');
+
+ if (colon == 0 || equals <= 0) {
+ throw new IllegalArgumentException("serviceName is required");
+ } else if (equals == spec.length() - 1) {
+ throw new IllegalArgumentException("userName or principalNames is
required");
+ } else if (colon + 1 == equals) {
+ throw new IllegalArgumentException("serviceInfo must not be
empty");
+ }
+
+ if (colon < 0 || colon > equals) {
+ this.serviceName = spec.substring(0, equals);
+ this.subServiceName = null;
+ } else {
+ this.serviceName = spec.substring(0, colon);
+ this.subServiceName = spec.substring(colon + 1, equals);
+ }
+
+ String s = spec.substring(equals + 1);
+ if (s.charAt(0) == '[' && s.charAt(s.length()-1) == ']') {
+ this.userName = null;
+ this.principalNames = extractPrincipalNames(s);
+ } else {
+ this.userName = s;
+ this.principalNames = null;
+ }
+ }
+
+ /**
+ * Copied from
https://github.com/apache/sling-org-apache-sling-serviceusermapper/blob/master/src/main/java/org/apache/sling/serviceusermapping/Mapping.java
+ */
+ @NotNull
+ private static Set<String> extractPrincipalNames(@NotNull String s) {
+ String[] sArr = s.substring(1, s.length() - 1).split(",");
+ Set<String> set = new LinkedHashSet<>();
+ for (String name : sArr) {
+ String n = name.trim();
+ if (!n.isEmpty()) {
+ set.add(n);
+ }
+ }
+ return set;
+ }
+
+ public boolean mapsUser(@NotNull String userId) {
+ return userId.equals(this.userName);
+ }
+
+ public boolean mapsPrincipal(@NotNull String principalName) {
+ return this.principalNames != null &&
principalNames.contains(principalName);
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + Objects.hash(serviceName);
+ result = prime * result + Objects.hash(subServiceName);
+ result = prime * result + Objects.hash(userName);
+ result = prime * result + Objects.hash(principalNames);
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+
+ Mapping other = (Mapping) obj;
+ return Objects.equals(serviceName, other.serviceName)
+ && Objects.equals(subServiceName, other.subServiceName)
+ && Objects.equals(userName, other.userName)
+ && Objects.equals(principalNames, other.principalNames);
+ }
+
+ /**
+ * Copied from
https://github.com/apache/sling-org-apache-sling-serviceusermapper/blob/master/src/main/java/org/apache/sling/serviceusermapping/Mapping.java
+ */
+ @Override
+ public String toString() {
+ String name = (userName != null) ? "userName=" + userName :
"principleNames" + principalNames.toString();
+ return "Mapping [serviceName=" + serviceName + ", subServiceName="
+ + subServiceName + ", " + name;
+ }
+}
\ No newline at end of file
diff --git
a/src/main/java/org/apache/sling/feature/cpconverter/cli/ContentPackage2FeatureModelConverterLauncher.java
b/src/main/java/org/apache/sling/feature/cpconverter/cli/ContentPackage2FeatureModelConverterLauncher.java
index 73dd0c2..94332af 100644
---
a/src/main/java/org/apache/sling/feature/cpconverter/cli/ContentPackage2FeatureModelConverterLauncher.java
+++
b/src/main/java/org/apache/sling/feature/cpconverter/cli/ContentPackage2FeatureModelConverterLauncher.java
@@ -96,11 +96,8 @@ public final class
ContentPackage2FeatureModelConverterLauncher implements Runna
@Option(names = { "-Z", "--fail-on-mixed-packages" }, description = "Fail
the conversion if the resulting attached content-package is MIXED type",
required = false)
private boolean failOnMixedPackages = false;
- @Option(names = { "--enforce-principal-based" }, description = "Converts
all service user access control entries to principal-based setup", required =
false)
- private boolean enforcePrincipalBased = false;
-
- @Option(names = { "--supported-principal-based-path" }, description =
"Path supported for principal-based access control setup", required = false)
- private String supportedPrincipalBasedPath = null;
+ @Option(names = { "--enforce-principal-based-supported-path" },
description = "Converts service user access control entries to principal-based
setup using the given supported path.", required = false)
+ private String enforcePrincipalBasedSupportedPath = null;
@Option(names = { "--entry-handler-config" }, description = "Config for
entry handlers that support it (classname:<config-string>", required = false)
private List<String> entryHandlerConfigs = null;
@@ -161,7 +158,7 @@ public final class
ContentPackage2FeatureModelConverterLauncher implements Runna
.setFeaturesManager(featuresManager)
.setBundlesDeployer(new DefaultArtifactsDeployer(artifactsOutputDirectory))
.setEntryHandlersManager(new
DefaultEntryHandlersManager(entryHandlerConfigsMap))
-
.setAclManager(new DefaultAclManager(enforcePrincipalBased,
supportedPrincipalBasedPath))
+
.setAclManager(new DefaultAclManager(enforcePrincipalBasedSupportedPath))
.setEmitter(DefaultPackagesEventsEmitter.open(featureModelsOutputDirectory))
.setFailOnMixedPackages(failOnMixedPackages)
.setDropContent(true);
diff --git
a/src/main/java/org/apache/sling/feature/cpconverter/handlers/AbstractConfigurationEntryHandler.java
b/src/main/java/org/apache/sling/feature/cpconverter/handlers/AbstractConfigurationEntryHandler.java
index 8be1241..4ade6d8 100644
---
a/src/main/java/org/apache/sling/feature/cpconverter/handlers/AbstractConfigurationEntryHandler.java
+++
b/src/main/java/org/apache/sling/feature/cpconverter/handlers/AbstractConfigurationEntryHandler.java
@@ -24,6 +24,9 @@ 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.accesscontrol.AclManager;
+import org.apache.sling.feature.cpconverter.accesscontrol.Mapping;
+import org.apache.sling.feature.cpconverter.features.FeaturesManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.osgi.util.converter.Converters;
@@ -34,6 +37,8 @@ abstract class AbstractConfigurationEntryHandler extends
AbstractRegexEntryHandl
private static final String REPOINIT_PID =
"org.apache.sling.jcr.repoinit.impl.RepositoryInitializer";
+ private static final String SERVICE_USER_MAPPING_PID =
"org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl";
+
public AbstractConfigurationEntryHandler(@NotNull String extension) {
super("/jcr_root/(?:apps|libs)/.+/config(\\.(?<runmode>[^/]+))?/(?<pid>.*)\\."
+ extension);
}
@@ -80,22 +85,31 @@ abstract class AbstractConfigurationEntryHandler extends
AbstractRegexEntryHandl
}
// there is a specified RunMode
runMode = matcher.group("runmode");
-
+
+ FeaturesManager featuresManager =
Objects.requireNonNull(converter.getFeaturesManager());
if (REPOINIT_FACTORY_PID.equals(factoryPid)) {
final String[] scripts =
Converters.standardConverter().convert(configurationProperties.get("scripts")).to(String[].class);
if (scripts != null && scripts.length > 0 ) {
for(final String text : scripts) {
if ( text != null && !text.trim().isEmpty() ) {
-
Objects.requireNonNull(converter.getFeaturesManager()).addOrAppendRepoInitExtension(text,
runMode);
+ featuresManager.addOrAppendRepoInitExtension(text,
runMode);
}
}
}
checkReferences(configurationProperties, pid);
} else if ( REPOINIT_PID.equals(pid) ) {
checkReferences(configurationProperties, pid);
-
+ } else if (pid.startsWith(SERVICE_USER_MAPPING_PID)) {
+ String[] mappings =
Converters.standardConverter().convert(configurationProperties.get("user.mapping")).to(String[].class);
+ if (mappings != null) {
+ AclManager aclManager =
Objects.requireNonNull(converter.getAclManager());
+ for (String usermapping : mappings) {
+ aclManager.addMapping(new Mapping(usermapping));
+ }
+ }
+ featuresManager.addConfiguration(runMode, id,
configurationProperties);
} else {
-
Objects.requireNonNull(converter.getFeaturesManager()).addConfiguration(runMode,
id, configurationProperties);
+ featuresManager.addConfiguration(runMode, id,
configurationProperties);
}
} else {
throw new IllegalStateException("Something went terribly wrong:
pattern '"
diff --git
a/src/test/java/org/apache/sling/feature/cpconverter/accesscontrol/EnforcePrincipalBasedTest.java
b/src/test/java/org/apache/sling/feature/cpconverter/accesscontrol/EnforcePrincipalBasedTest.java
index 33c390f..13955dc 100644
---
a/src/test/java/org/apache/sling/feature/cpconverter/accesscontrol/EnforcePrincipalBasedTest.java
+++
b/src/test/java/org/apache/sling/feature/cpconverter/accesscontrol/EnforcePrincipalBasedTest.java
@@ -53,6 +53,7 @@ import static org.mockito.Mockito.when;
public class EnforcePrincipalBasedTest {
private final SystemUser systemUser = new SystemUser("user1", new
RepoPath("/home/users/system/intermediate/usernode"), new
RepoPath("/home/users/system/intermediate"));
+ private final String remappedIntermediatePath =
"/home/users/system/some/subtree/intermediate";
private AclManager aclManager;
private Path tempDir;
@@ -63,7 +64,7 @@ public class EnforcePrincipalBasedTest {
@Before
public void setUp() throws Exception {
- aclManager = new DefaultAclManager(true,
"/home/users/system/some/subtree");
+ aclManager = new DefaultAclManager("/home/users/system/some/subtree");
tempDir = Files.createTempDirectory(getClass().getSimpleName());
assembler = mock(VaultPackageAssembler.class);
@@ -87,53 +88,29 @@ public class EnforcePrincipalBasedTest {
@Test(expected = IllegalStateException.class)
public void testInvalidSupportedPath() {
- AclManager aclManager = new DefaultAclManager(true,
"/an/invalid/supported/path");
- aclManager.addSystemUser(systemUser);
-
- RepoPath accessControlledPath = new RepoPath("/content/feature");
- aclManager.addAcl(systemUser.getId(), new AccessControlEntry(true,
"jcr:read", accessControlledPath , false));
-
- aclManager.addRepoinitExtension(Collections.singletonList(assembler),
fm);
- }
-
- @Test
- public void testMissingSupportedPath() {
- AclManager aclManager = new DefaultAclManager(true, null);
- aclManager.addSystemUser(systemUser);
-
+ AclManager acMgr = new DefaultAclManager("/an/invalid/supported/path");
RepoPath accessControlledPath = new RepoPath("/content/feature");
- aclManager.addAcl(systemUser.getId(), new AccessControlEntry(true,
"jcr:read", accessControlledPath , false));
-
- aclManager.addRepoinitExtension(Collections.singletonList(assembler),
fm);
- String txt =
feature.getExtensions().getByName(Extension.EXTENSION_NAME_REPOINIT).getText();
- assertFalse(txt.contains("create service user user1 with path
/home/users/system/some/subtree/intermediate"));
- assertTrue(txt.contains("create service user user1 with path " +
systemUser.getIntermediatePath()));
+ getRepoInitExtension(acMgr, accessControlledPath, systemUser, false);
}
@Test
public void testResourceBasedConversionWithoutForce() throws
RepoInitParsingException {
- AclManager aclManager = new DefaultAclManager(false,
"/home/users/system/some/subtree"){
+ AclManager acMgr = new DefaultAclManager(null) {
@Override
protected @Nullable String computePathWithTypes(@NotNull RepoPath
path, @NotNull List<VaultPackageAssembler> packageAssemblers) {
return "/content/feature(sling:Folder)";
}
};
- aclManager.addSystemUser(systemUser);
RepoPath accessControlledPath = new RepoPath("/content/feature");
- aclManager.addAcl(systemUser.getId(), new AccessControlEntry(true,
"jcr:read", accessControlledPath , false));
-
- aclManager.addRepoinitExtension(Collections.singletonList(assembler),
fm);
-
- Extension repoinitExtension =
feature.getExtensions().getByName(Extension.EXTENSION_NAME_REPOINIT);
- assertNotNull(repoinitExtension);
+ Extension repoinitExtension = getRepoInitExtension(acMgr,
accessControlledPath, systemUser, false);
String expected =
"create service user user1 with path " +
systemUser.getIntermediatePath() + System.lineSeparator() +
- "create path /content/feature(sling:Folder)" +
System.lineSeparator() +
- "set ACL for user1" + System.lineSeparator() +
- "allow jcr:read on /content/feature" + System.lineSeparator() +
- "end" + System.lineSeparator();
+ "create path /content/feature(sling:Folder)" +
System.lineSeparator() +
+ "set ACL for user1" + System.lineSeparator() +
+ "allow jcr:read on /content/feature" +
System.lineSeparator() +
+ "end" + System.lineSeparator();
String actual = repoinitExtension.getText();
assertEquals(expected, actual);
@@ -141,46 +118,15 @@ public class EnforcePrincipalBasedTest {
RepoInitParser repoInitParser = new RepoInitParserService();
List<Operation> operations = repoInitParser.parse(new
StringReader(actual));
assertFalse(operations.isEmpty());
-
- aclManager =
EnforcePrincipalBasedTest.this.aclManager;aclManager.addSystemUser(systemUser);
- feature.getExtensions().clear();
-
- accessControlledPath = new RepoPath("/content/feature");
- aclManager.addAcl(systemUser.getId(), new AccessControlEntry(true,
"jcr:read", accessControlledPath , false));
-
- aclManager.addRepoinitExtension(Collections.singletonList(assembler),
fm);
-
- repoinitExtension =
feature.getExtensions().getByName(Extension.EXTENSION_NAME_REPOINIT);
- assertNotNull(repoinitExtension);
-
- expected =
- "create service user user1 with path
/home/users/system/some/subtree/intermediate" + System.lineSeparator() +
- "set principal ACL for user1" + System.lineSeparator()
+
- "allow jcr:read on /content/feature" +
System.lineSeparator() +
- "end" + System.lineSeparator();
-
- actual = repoinitExtension.getText();
- assertEquals(expected, actual);
-
- repoInitParser = new RepoInitParserService();
- operations = repoInitParser.parse(new StringReader(actual));
- assertFalse(operations.isEmpty());
}
@Test
public void testResourceBasedConversion() throws RepoInitParsingException {
- aclManager.addSystemUser(systemUser);
-
RepoPath accessControlledPath = new RepoPath("/content/feature");
- aclManager.addAcl(systemUser.getId(), new AccessControlEntry(true,
"jcr:read", accessControlledPath , false));
-
- aclManager.addRepoinitExtension(Collections.singletonList(assembler),
fm);
-
- Extension repoinitExtension =
feature.getExtensions().getByName(Extension.EXTENSION_NAME_REPOINIT);
- assertNotNull(repoinitExtension);
+ Extension repoinitExtension = getRepoInitExtension(aclManager,
accessControlledPath, systemUser, false);
String expected =
- "create service user user1 with path
/home/users/system/some/subtree/intermediate" + System.lineSeparator() +
+ "create service user user1 with path " +
remappedIntermediatePath + System.lineSeparator() +
"set principal ACL for user1" + System.lineSeparator() +
"allow jcr:read on /content/feature" + System.lineSeparator() +
"end" + System.lineSeparator();
@@ -195,18 +141,11 @@ public class EnforcePrincipalBasedTest {
@Test
public void testPrincipalBased() throws RepoInitParsingException {
- aclManager.addSystemUser(systemUser);
-
RepoPath accessControlledPath = new RepoPath("/content/feature");
- aclManager.addAcl("user1", new AccessControlEntry(true, "jcr:read",
accessControlledPath, true));
-
- aclManager.addRepoinitExtension(Collections.singletonList(assembler),
fm);
-
- Extension repoinitExtension =
feature.getExtensions().getByName(Extension.EXTENSION_NAME_REPOINIT);
- assertNotNull(repoinitExtension);
+ Extension repoinitExtension = getRepoInitExtension(aclManager,
accessControlledPath, systemUser, true);
String expected =
- "create service user user1 with path
/home/users/system/some/subtree/intermediate" + System.lineSeparator() +
+ "create service user user1 with path " +
remappedIntermediatePath + System.lineSeparator() +
"set principal ACL for user1" + System.lineSeparator()
+
"allow jcr:read on /content/feature" +
System.lineSeparator() +
"end" + System.lineSeparator();
@@ -221,19 +160,11 @@ public class EnforcePrincipalBasedTest {
@Test
public void testPrincipalBasedForUserHome() throws
RepoInitParsingException {
- aclManager.addSystemUser(systemUser);
-
RepoPath accessControlledPath = systemUser.getPath();
- AccessControlEntry acl = new AccessControlEntry(true, "jcr:read",
accessControlledPath, true);
- aclManager.addAcl("user1", acl);
-
- aclManager.addRepoinitExtension(Collections.singletonList(assembler),
fm);
-
- Extension repoinitExtension =
feature.getExtensions().getByName(Extension.EXTENSION_NAME_REPOINIT);
- assertNotNull(repoinitExtension);
+ Extension repoinitExtension = getRepoInitExtension(aclManager,
accessControlledPath, systemUser, true);
String expected =
- "create service user user1 with path
/home/users/system/some/subtree/intermediate" + System.lineSeparator() +
+ "create service user user1 with path " +
remappedIntermediatePath + System.lineSeparator() +
"set principal ACL for user1" + System.lineSeparator() +
"allow jcr:read on home(user1)" + System.lineSeparator() +
"end" + System.lineSeparator();
@@ -245,4 +176,52 @@ public class EnforcePrincipalBasedTest {
List<Operation> operations = repoInitParser.parse(new
StringReader(actual));
assertFalse(operations.isEmpty());
}
+
+ @Test
+ public void testSingleUserMapping() {
+ aclManager.addMapping(new
Mapping("org.apache.sling.testbundle:subservice="+systemUser.getId()));
+
+ RepoPath accessControlledPath = new RepoPath("/content/feature");
+ Extension repoinitExtension = getRepoInitExtension(aclManager,
accessControlledPath, systemUser, false);
+
+ String expected =
+ "create service user user1 with path "
+systemUser.getIntermediatePath()+ System.lineSeparator() +
+ "set ACL for user1" + System.lineSeparator() +
+ "allow jcr:read on /content/feature" + System.lineSeparator() +
+ "end" + System.lineSeparator();
+
+ String actual = repoinitExtension.getText();
+ assertEquals(expected, actual);
+ }
+
+ @Test
+ public void testPrincipalMapping() {
+ aclManager.addMapping(new
Mapping("org.apache.sling.testbundle:subservice=["+systemUser.getId()+"]"));
+
+ RepoPath accessControlledPath = new RepoPath("/content/feature");
+ Extension repoinitExtension = getRepoInitExtension(aclManager,
accessControlledPath, systemUser, false);
+
+ String expected =
+ "create service user user1 with path " +
remappedIntermediatePath + System.lineSeparator() +
+ "set principal ACL for user1" + System.lineSeparator() +
+ "allow jcr:read on /content/feature" + System.lineSeparator() +
+ "end" + System.lineSeparator();
+
+ String actual = repoinitExtension.getText();
+ assertEquals(expected, actual);
+ }
+
+ @NotNull
+ private Extension getRepoInitExtension(@NotNull AclManager aclManager,
@NotNull RepoPath accessControlledPath, @NotNull SystemUser systemUser, boolean
isPrincipalBased) {
+ aclManager.addSystemUser(systemUser);
+
+ AccessControlEntry acl = new AccessControlEntry(true, "jcr:read",
accessControlledPath, isPrincipalBased);
+ aclManager.addAcl(systemUser.getId(), acl);
+
+ aclManager.addRepoinitExtension(Collections.singletonList(assembler),
fm);
+
+ Extension repoinitExtension =
feature.getExtensions().getByName(Extension.EXTENSION_NAME_REPOINIT);
+ assertNotNull(repoinitExtension);
+ return repoinitExtension;
+ }
}
diff --git
a/src/test/java/org/apache/sling/feature/cpconverter/accesscontrol/MappingTest.java
b/src/test/java/org/apache/sling/feature/cpconverter/accesscontrol/MappingTest.java
new file mode 100644
index 0000000..96b5242
--- /dev/null
+++
b/src/test/java/org/apache/sling/feature/cpconverter/accesscontrol/MappingTest.java
@@ -0,0 +1,134 @@
+/*
+ * 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.accesscontrol;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+
+public class MappingTest {
+
+ @Test
+ public void testMapUserId() {
+ Mapping m = new
Mapping("org.apache.sling.testbundle:sub-service-1=service1");
+ assertTrue(m.mapsUser("service1"));
+ assertFalse(m.mapsUser("another"));
+ assertFalse(m.mapsPrincipal("service1"));
+ assertFalse(m.mapsPrincipal("another"));
+ }
+
+ @Test
+ public void testMapPrincipalNames() {
+ Mapping m = new
Mapping("org.apache.sling.testbundle:sub-service-1=[service1,service2]");
+ assertFalse(m.mapsUser("service1"));
+ assertFalse(m.mapsUser("another"));
+ assertTrue(m.mapsPrincipal("service1"));
+ assertTrue(m.mapsPrincipal("service2"));
+ assertFalse(m.mapsPrincipal("another"));
+ }
+
+ @Test
+ public void testMapSinglePrincipalName() {
+ Mapping m = new
Mapping("org.apache.sling.testbundle:sub-service-1=[service1]");
+ assertFalse(m.mapsUser("service1"));
+ assertFalse(m.mapsUser("another"));
+ assertTrue(m.mapsPrincipal("service1"));
+ assertFalse(m.mapsPrincipal("service2"));
+ assertFalse(m.mapsPrincipal("another"));
+ }
+
+ @Test
+ public void testMapEmptyPrincipalNames() {
+ Mapping m = new
Mapping("org.apache.sling.testbundle:sub-service-1=[]");
+ assertFalse(m.mapsUser("service1"));
+ assertFalse(m.mapsUser("another"));
+ assertFalse(m.mapsPrincipal("service1"));
+ assertFalse(m.mapsPrincipal("service2"));
+ assertFalse(m.mapsPrincipal("another"));
+ }
+
+ @Test
+ public void testMapMissingSubservice() {
+ Mapping m = new Mapping("org.apache.sling.testbundle=[service1]");
+ assertFalse(m.mapsUser("service1"));
+ assertFalse(m.mapsUser("another"));
+ assertTrue(m.mapsPrincipal("service1"));
+ assertFalse(m.mapsPrincipal("another"));
+ }
+
+ @Test
+ public void testMapIncompleteArray() {
+ Mapping m = new
Mapping("org.apache.sling.testbundle:sub-service=[service1");
+ assertTrue(m.mapsUser("[service1"));
+ assertFalse(m.mapsPrincipal("service1"));
+
+ m = new Mapping("org.apache.sling.testbundle:sub-service=service1]");
+ assertTrue(m.mapsUser("service1]"));
+ assertFalse(m.mapsPrincipal("service1"));
+ }
+
+ @Test
+ public void testColonInUserName() {
+ Mapping m = new Mapping("org.apache.sling.testbundle=sling:service1");
+ assertTrue(m.mapsUser("sling:service1"));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testMissingUser() {
+ new Mapping("org.apache.sling.testbundle:subservice");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testMissingUser2() {
+ new Mapping("org.apache.sling.testbundle:sub-service=");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testMissingBundle() {
+ new Mapping(":sub-service=[service1]");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testMissingSubservice() {
+ new Mapping("org.apache.sling.testbundle:=service1");
+ }
+
+ @Test
+ public void testEquals() {
+ Mapping m = new
Mapping("org.apache.sling.testbundle:sub-service-1=service1");
+ Mapping m2 = new
Mapping("org.apache.sling.testbundle:sub-service-1=[service1,service2]");
+ Mapping m3 = new
Mapping("org.apache.sling.testbundle:sub-service-1=[service1]");
+
+ assertEquals(m, new
Mapping("org.apache.sling.testbundle:sub-service-1=service1"));
+
+ assertNotEquals(m, new
Mapping("org.apache.sling.testbundle=service1"));
+ assertNotEquals(m, new
Mapping("org.apache.sling.testbundle:other-sub-service=service1"));
+ assertNotEquals(m, new
Mapping("org.apache.sling.otherbundle:sub-service1=service1"));
+ assertNotEquals(m, m2);
+ assertNotEquals(m, m3);
+ assertNotEquals(m2, m3);
+ assertNotEquals(m2, new
Mapping("org.apache.sling.testbundle:sub-service-1=[service3,service4]"));
+
+ assertTrue(m.equals(m));
+ assertTrue(m2.equals(m2));
+ assertFalse(m.equals(null));
+ assertFalse(m2.equals(m2.toString()));
+ }
+}
\ No newline at end of file
diff --git
a/src/test/java/org/apache/sling/feature/cpconverter/handlers/ConfigurationEntryHandlerTest.java
b/src/test/java/org/apache/sling/feature/cpconverter/handlers/ConfigurationEntryHandlerTest.java
index b5ddbd4..6107275 100644
---
a/src/test/java/org/apache/sling/feature/cpconverter/handlers/ConfigurationEntryHandlerTest.java
+++
b/src/test/java/org/apache/sling/feature/cpconverter/handlers/ConfigurationEntryHandlerTest.java
@@ -24,12 +24,15 @@ import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doCallRealMethod;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Dictionary;
import org.apache.jackrabbit.vault.fs.io.Archive;
import org.apache.jackrabbit.vault.fs.io.Archive.Entry;
@@ -39,6 +42,8 @@ import org.apache.sling.feature.Configurations;
import org.apache.sling.feature.Extension;
import org.apache.sling.feature.Feature;
import
org.apache.sling.feature.cpconverter.ContentPackage2FeatureModelConverter;
+import org.apache.sling.feature.cpconverter.accesscontrol.AclManager;
+import org.apache.sling.feature.cpconverter.accesscontrol.Mapping;
import org.apache.sling.feature.cpconverter.features.DefaultFeaturesManager;
import org.apache.sling.feature.cpconverter.features.FeaturesManager;
import org.apache.sling.feature.io.json.ConfigurationJSONWriter;
@@ -71,9 +76,10 @@ public class ConfigurationEntryHandlerTest {
" \"test.dateproperty\":1604743842669,\n" +
" \"test.booleanproperty\":true,\n" +
" \"user.mapping\":[\n" +
- " \"com.adobe.acs.acs-aem-samples-bundle=admin\",\n" +
- "
\"com.adobe.acs.acs-aem-samples-bundle:sample-service=oauthservice\"\n" +
- " ]\n" +
+ " \"org.apache.sling.testbundle:sub-service-1=service1\",\n" +
+ "
\"org.apache.sling.testbundle:sub-service-2=[service1,service2]\",\n" +
+ "
\"org.apache.sling.testbundle=[service1,external-service-user]\"\n" +
+ " ]\n" +
" }\n" +
"}";
@@ -81,6 +87,7 @@ public class ConfigurationEntryHandlerTest {
private final int expectedConfigurationsSize;
private final int expectedConfigurationsEntrySize;
+ private final int expectedMappings;
private final AbstractConfigurationEntryHandler configurationEntryHandler;
private final String expectedRunMode;
@@ -88,11 +95,13 @@ public class ConfigurationEntryHandlerTest {
public ConfigurationEntryHandlerTest(String resourceConfiguration,
int expectedConfigurationsSize,
int expectedConfigurationsEntrySize,
+ int expectedMappings,
AbstractConfigurationEntryHandler
configurationEntryHandler,
String expectedRunMode) {
this.resourceConfiguration = resourceConfiguration;
this.expectedConfigurationsSize = expectedConfigurationsSize;
this.expectedConfigurationsEntrySize = expectedConfigurationsEntrySize;
+ this.expectedMappings = expectedMappings;
this.configurationEntryHandler = configurationEntryHandler;
this.expectedRunMode = expectedRunMode;
}
@@ -122,6 +131,8 @@ public class ConfigurationEntryHandlerTest {
when(featuresManager.getRunMode(anyString())).thenReturn(feature);
ContentPackage2FeatureModelConverter converter =
mock(ContentPackage2FeatureModelConverter.class);
when(converter.getFeaturesManager()).thenReturn(featuresManager);
+ AclManager aclManager = mock(AclManager.class);
+ when(converter.getAclManager()).thenReturn(aclManager);
configurationEntryHandler.handle(resourceConfiguration, archive,
entry, converter);
@@ -138,10 +149,12 @@ public class ConfigurationEntryHandlerTest {
assertTrue(configuration.getPid(),
configuration.getPid().startsWith(EXPECTED_PID));
+ Dictionary<String,Object> props = configuration.getProperties();
if (configuration.getPid().contains(".empty")) {
- assertTrue(configuration.getProperties().isEmpty());
+ assertTrue(props.isEmpty());
} else {
- assertEquals("Unmatching size: " +
configuration.getProperties().size(), expectedConfigurationsEntrySize,
configuration.getProperties().size());
+ assertEquals("Unmatching size: " + props.size(),
expectedConfigurationsEntrySize, configuration.getProperties().size());
+ verify(aclManager,
times(expectedMappings)).addMapping(any(Mapping.class));
}
// type & value check for typed configuration
if (this.resourceConfiguration.equals(TYPED_TESTCONFIG_PATH)) {
@@ -157,32 +170,32 @@ public class ConfigurationEntryHandlerTest {
String path = "/jcr_root/apps/asd/config/";
return Arrays.asList(new Object[][] {
- { path + EXPECTED_PID + ".empty.cfg", 1, 2, new
PropertiesConfigurationEntryHandler(), null },
- { path + EXPECTED_PID + ".cfg", 1, 2, new
PropertiesConfigurationEntryHandler(), null },
+ { path + EXPECTED_PID + ".empty.cfg", 1, 2, 0, new
PropertiesConfigurationEntryHandler(), null },
+ { path + EXPECTED_PID + ".cfg", 1, 2, 1, new
PropertiesConfigurationEntryHandler(), null },
- { path + EXPECTED_PID + ".empty.cfg.json", 1, 2, new
JsonConfigurationEntryHandler(), null },
- { path + EXPECTED_PID + ".cfg.json", 1, 2, new
JsonConfigurationEntryHandler(), null },
+ { path + EXPECTED_PID + ".empty.cfg.json", 1, 2, 0, new
JsonConfigurationEntryHandler(), null },
+ { path + EXPECTED_PID + ".cfg.json", 1, 2, 3, new
JsonConfigurationEntryHandler(), null },
- { path + EXPECTED_PID + ".empty.config", 1, 2, new
ConfigurationEntryHandler(), null },
- { path + EXPECTED_PID + ".config", 1, 2, new
ConfigurationEntryHandler(), null },
+ { path + EXPECTED_PID + ".empty.config", 1, 2, 0, new
ConfigurationEntryHandler(), null },
+ { path + EXPECTED_PID + ".config", 1, 2, 3, new
ConfigurationEntryHandler(), null },
- { path + EXPECTED_PID + ".empty.xml", 1, 2, new
XmlConfigurationEntryHandler(), null },
- { path + EXPECTED_PID + ".xml", 1, 2, new
XmlConfigurationEntryHandler(), null },
+ { path + EXPECTED_PID + ".empty.xml", 1, 2, 0, new
XmlConfigurationEntryHandler(), null },
+ { path + EXPECTED_PID + ".xml", 1, 2, 3, new
XmlConfigurationEntryHandler(), null },
- { path + EXPECTED_PID + ".empty.config.xml", 1, 2, new
XmlConfigurationEntryHandler(), null },
- { path + EXPECTED_PID + ".config.xml", 1, 2, new
XmlConfigurationEntryHandler(), null },
+ { path + EXPECTED_PID + ".empty.config.xml", 1, 2, 0, new
XmlConfigurationEntryHandler(), null },
+ { path + EXPECTED_PID + ".config.xml", 1, 2, 3, new
XmlConfigurationEntryHandler(), null },
- { path + EXPECTED_PID + ".empty.xml.cfg", 1, 2, new
PropertiesConfigurationEntryHandler(), null },
- { path + EXPECTED_PID + ".xml.cfg", 1, 2, new
PropertiesConfigurationEntryHandler(), null },
+ { path + EXPECTED_PID + ".empty.xml.cfg", 1, 2, 0, new
PropertiesConfigurationEntryHandler(), null },
+ { path + EXPECTED_PID + ".xml.cfg", 1, 2, 1, new
PropertiesConfigurationEntryHandler(), null },
// runmode aware folders
- { "/jcr_root/apps/asd/config.author/" + EXPECTED_PID + ".config",
1, 2, new ConfigurationEntryHandler(), "author" },
- { REPOINIT_TESTCONFIG_PATH, 0, 2, new ConfigurationEntryHandler()
, "author"},
- { "/jcr_root/apps/asd/config.publish/" + EXPECTED_PID + ".config",
1, 2, new ConfigurationEntryHandler(), "publish" },
+ { "/jcr_root/apps/asd/config.author/" + EXPECTED_PID + ".config",
1, 2, 3, new ConfigurationEntryHandler(), "author" },
+ { REPOINIT_TESTCONFIG_PATH, 0, 2, 1, new
ConfigurationEntryHandler() , "author"},
+ { "/jcr_root/apps/asd/config.publish/" + EXPECTED_PID + ".config",
1, 2, 3, new ConfigurationEntryHandler(), "publish" },
//test typed config
- { TYPED_TESTCONFIG_PATH, 1, 6, new XmlConfigurationEntryHandler(),
null }
+ { TYPED_TESTCONFIG_PATH, 1, 6, 3, new
XmlConfigurationEntryHandler(), null }
});
}
diff --git
a/src/test/java/org/apache/sling/feature/cpconverter/handlers/JsonConfigurationEntryHandlerTest.java
b/src/test/java/org/apache/sling/feature/cpconverter/handlers/JsonConfigurationEntryHandlerTest.java
index 9711ba8..67d2ec9 100644
---
a/src/test/java/org/apache/sling/feature/cpconverter/handlers/JsonConfigurationEntryHandlerTest.java
+++
b/src/test/java/org/apache/sling/feature/cpconverter/handlers/JsonConfigurationEntryHandlerTest.java
@@ -16,14 +16,24 @@
*/
package org.apache.sling.feature.cpconverter.handlers;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.IOException;
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.Feature;
import
org.apache.sling.feature.cpconverter.ContentPackage2FeatureModelConverter;
+import org.apache.sling.feature.cpconverter.accesscontrol.AclManager;
+import org.apache.sling.feature.cpconverter.accesscontrol.Mapping;
+import org.apache.sling.feature.cpconverter.features.DefaultFeaturesManager;
+import org.apache.sling.feature.cpconverter.features.FeaturesManager;
import org.junit.Test;
public class JsonConfigurationEntryHandlerTest {
@@ -43,4 +53,28 @@ public class JsonConfigurationEntryHandlerTest {
new JsonConfigurationEntryHandler().handle(resourceConfiguration,
archive, entry, converter);
}
+ @Test
+ public void validConfigurationThrowsException() throws Exception {
+ String resourceConfiguration =
"/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.cfg.json";
+
+ Archive archive = mock(Archive.class);
+ Entry entry = mock(Entry.class);
+
+
when(entry.getName()).thenReturn(resourceConfiguration.substring(resourceConfiguration.lastIndexOf('/')
+ 1));
+
when(archive.openInputStream(entry)).thenReturn(getClass().getResourceAsStream(resourceConfiguration.substring(1)));
+
+ AclManager aclManager = mock(AclManager.class);
+ Feature feature = new Feature(new ArtifactId("org.apache.sling",
"org.apache.sling.cp2fm", "0.0.1", null, null));
+ FeaturesManager featuresManager = spy(DefaultFeaturesManager.class);
+ when(featuresManager.getTargetFeature()).thenReturn(feature);
+
+ ContentPackage2FeatureModelConverter converter =
mock(ContentPackage2FeatureModelConverter.class);
+ when(converter.getAclManager()).thenReturn(aclManager);
+ when(converter.getFeaturesManager()).thenReturn(featuresManager);
+
+ new JsonConfigurationEntryHandler().handle(resourceConfiguration,
archive, entry, converter);
+
+ verify(aclManager, times(3)).addMapping(any(Mapping.class));
+ }
+
}
diff --git
a/src/test/java/org/apache/sling/feature/cpconverter/handlers/TestUtils.java
b/src/test/java/org/apache/sling/feature/cpconverter/handlers/TestUtils.java
index a950260..737a777 100644
--- a/src/test/java/org/apache/sling/feature/cpconverter/handlers/TestUtils.java
+++ b/src/test/java/org/apache/sling/feature/cpconverter/handlers/TestUtils.java
@@ -31,8 +31,10 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
+import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.security.acl.Acl;
import java.util.Collections;
import static org.mockito.ArgumentMatchers.anyString;
@@ -49,6 +51,7 @@ class TestUtils {
static Extension createRepoInitExtension(@NotNull EntryHandler handler,
@NotNull AclManager aclManager, @NotNull String path, @NotNull InputStream is)
throws Exception {
return createRepoInitExtension(handler, aclManager, path, is, null);
}
+
static Extension createRepoInitExtension(@NotNull EntryHandler handler,
@NotNull AclManager aclManager, @NotNull String path, @NotNull InputStream is,
@Nullable OutputStream out) throws Exception {
Archive archive = mock(Archive.class);
Archive.Entry entry = mock(Archive.Entry.class);
diff --git
a/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config.author/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.config
b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config.author/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.config
index 4c50ea3..d8884c9 100644
---
a/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config.author/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.config
+++
b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config.author/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.config
@@ -14,4 +14,4 @@
# the License.
user.default="admin"
-user.mapping=["com.adobe.acs.acs-aem-samples-bundle\=admin","com.adobe.acs.acs-aem-samples-bundle:sample-service\=oauthservice"]
+user.mapping=["org.apache.sling.testbundle:sub-service-1\=service1","org.apache.sling.testbundle:sub-service-2\=[service1,service2]","org.apache.sling.testbundle\=[service1,external-service-user]"]
diff --git
a/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config.publish/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.config
b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config.publish/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.config
index 4c50ea3..fc60138 100644
---
a/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config.publish/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.config
+++
b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config.publish/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.config
@@ -14,4 +14,4 @@
# the License.
user.default="admin"
-user.mapping=["com.adobe.acs.acs-aem-samples-bundle\=admin","com.adobe.acs.acs-aem-samples-bundle:sample-service\=oauthservice"]
+user.mapping=["org.apache.sling.testbundle:sub-service-1\=service1","org.apache.sling.testbundle:sub-service-2\=[service1,service2]","org.apache.sling.testbundle\=org.apache.sling.testbundle\=[service1,external-service-user]"]
diff --git
a/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.cfg
b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.cfg
index bf91183..712f4e7 100644
---
a/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.cfg
+++
b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.cfg
@@ -14,4 +14,4 @@
# the License.
user.default=admin
-user.mapping=[com.adobe.acs.acs-aem-samples-bundle=admin,com.adobe.acs.acs-aem-samples-bundle:sample-service=oauthservice]
+user.mapping=org.apache.sling.testbundle:sub-service-1=service-1
diff --git
a/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.cfg.json
b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.cfg.json
index 98e506c..3b80428 100644
---
a/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.cfg.json
+++
b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.cfg.json
@@ -1,7 +1,8 @@
{
"user.default":"admin",
"user.mapping": [
- "com.adobe.acs.acs-aem-samples-bundle=admin",
- "com.adobe.acs.acs-aem-samples-bundle:sample-service=oauthservice"
+ "org.apache.sling.testbundle:sub-service-1=service1",
+ "org.apache.sling.testbundle:sub-service-2=[service1,service2]",
+ "org.apache.sling.testbundle=[service1,external-service-user]"
]
}
diff --git
a/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.config
b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.config
index 4c50ea3..d8884c9 100644
---
a/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.config
+++
b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.config
@@ -14,4 +14,4 @@
# the License.
user.default="admin"
-user.mapping=["com.adobe.acs.acs-aem-samples-bundle\=admin","com.adobe.acs.acs-aem-samples-bundle:sample-service\=oauthservice"]
+user.mapping=["org.apache.sling.testbundle:sub-service-1\=service1","org.apache.sling.testbundle:sub-service-2\=[service1,service2]","org.apache.sling.testbundle\=[service1,external-service-user]"]
diff --git
a/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.config.xml
b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.config.xml
index f23afc9..7b8c6ca 100644
---
a/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.config.xml
+++
b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.config.xml
@@ -18,4 +18,4 @@
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="sling:OsgiConfig"
user.default="admin"
-
user.mapping="[com.adobe.acs.acs-aem-samples-bundle=admin,com.adobe.acs.acs-aem-samples-bundle:sample-service=oauthservice]"/>
+
user.mapping="[org.apache.sling.testbundle:sub-service-1=service1,org.apache.sling.testbundle:sub-service-2=\[service1\,service2\],org.apache.sling.testbundle=\[service1\,external-service-user\]]"/>
diff --git
a/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.typed.xml
b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.typed.xml
index 91ed2cf..0f3e3c8 100644
---
a/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.typed.xml
+++
b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.typed.xml
@@ -22,4 +22,4 @@
test.doubleproperty="{Double}1.23"
test.dateproperty="{Date}2020-11-07T10:10:42.669"
test.booleanproperty="{Boolean}true"
-
user.mapping="[com.adobe.acs.acs-aem-samples-bundle=admin,com.adobe.acs.acs-aem-samples-bundle:sample-service=oauthservice]"/>
+
user.mapping="[org.apache.sling.testbundle:sub-service-1=service1,org.apache.sling.testbundle:sub-service-2=\[service1\,service2\],org.apache.sling.testbundle=\[service1\,external-service-user\]]"/>
diff --git
a/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.xml
b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.xml
index f23afc9..7b8c6ca 100644
---
a/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.xml
+++
b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.xml
@@ -18,4 +18,4 @@
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="sling:OsgiConfig"
user.default="admin"
-
user.mapping="[com.adobe.acs.acs-aem-samples-bundle=admin,com.adobe.acs.acs-aem-samples-bundle:sample-service=oauthservice]"/>
+
user.mapping="[org.apache.sling.testbundle:sub-service-1=service1,org.apache.sling.testbundle:sub-service-2=\[service1\,service2\],org.apache.sling.testbundle=\[service1\,external-service-user\]]"/>
diff --git
a/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.xml.cfg
b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.xml.cfg
index 05ce515..7dd338f 100644
---
a/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.xml.cfg
+++
b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/config/org.apache.sling.serviceusermapping.impl.ServiceUserMapperImpl.xml.cfg
@@ -18,5 +18,5 @@
-->
<properties>
<entry key="user.default">admin</entry>
- <entry
key="user.mapping">[com.adobe.acs.acs-aem-samples-bundle=admin,com.adobe.acs.acs-aem-samples-bundle:sample-service=oauthservice]</entry>
+ <entry
key="user.mapping">org.apache.sling.testbundle:sub-service-1=service1</entry>
</properties>