Skip to content

Commit

Permalink
Add option to allow mutable install hooks for local AEM SDK developme…
Browse files Browse the repository at this point in the history
…nt. Used for example by accesscontroltool
  • Loading branch information
Roy Teeuwen authored and kwin committed May 8, 2023
1 parent 76175d6 commit 17737f2
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 8 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ The following options are supported apart from the default settings mentioned in
Option | Mandatory | Description | Default Value | Since Version
--- | --- | --- | --- | ---
`allowReadOnlyMutablePaths` (or `allowVarNodeOutsideContainer` deprecated) | no | `true` means read-only paths (i.e. paths to which the service session used for mutable package installation on publish does not have write permission) should be allowed. Otherwise those will only be allowed in author-only packages included in a container package. | `false` | 1.2.0
`allowLibsNode` | no | `true` means that `libs` nodes are allowed in content packages. *Only set this to `true` when building packages which are part of the AEM product.* | `false` | 1.2.0
`allowLibsNode` | no | `true` means that `libs` nodes are allowed in content packages. *Only set this to `true` when building packages which are part of the AEM product.* | `false` | 1.2.0
`allowHooksInMutableContent` | no | `true` means that JCR Install Hooks are allowed in content packages. *Only set this to `true` when building packages for local AEM SDK development, where install hooks are supported for mutable content.* | `false` | 1.3.0

# Included Checks

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ public class AemCloudValidator implements NodePathValidator, MetaInfPathValidato
private boolean hasMutableNodes;
private final boolean allowReadOnlyMutablePaths;
private final boolean allowLibsNode;
private final boolean allowHooksInMutableContent;
private boolean hasInstallHooks;
private boolean hasImmutableNodes;

Expand All @@ -72,11 +73,12 @@ public class AemCloudValidator implements NodePathValidator, MetaInfPathValidato
private int numLibNodeViolations = 0;
private int numMutableNodeViolations = 0;

public AemCloudValidator(boolean allowReadOnlyMutablePaths, boolean allowLibsNode, @Nullable PackageType packageType,
@Nullable ValidationContext containerValidationContext, @NotNull ValidationMessageSeverity defaultSeverity) {
public AemCloudValidator(boolean allowReadOnlyMutablePaths, boolean allowLibsNode, boolean allowHooksInMutableContent, @Nullable PackageType packageType,
@Nullable ValidationContext containerValidationContext, @NotNull ValidationMessageSeverity defaultSeverity) {
super();
this.allowReadOnlyMutablePaths = allowReadOnlyMutablePaths;
this.allowLibsNode = allowLibsNode;
this.allowHooksInMutableContent = allowHooksInMutableContent;
this.packageType = packageType;
this.containerValidationContext = containerValidationContext;
this.defaultSeverity = defaultSeverity;
Expand Down Expand Up @@ -165,7 +167,7 @@ static boolean isPackagePathInstalledConditionally(String runMode, Path packageR
@Override
public @Nullable Collection<ValidationMessage> done() {
Collection<ValidationMessage> messages = new ArrayList<>();
if (hasInstallHooks && hasMutableNodes) {
if (hasInstallHooks && hasMutableNodes && !allowHooksInMutableContent) {
messages.add(new ValidationMessage(defaultSeverity, VIOLATION_MESSAGE_INSTALL_HOOK_IN_MUTABLE_PACKAGE));
}
// for non-set package types usually the package type is determined by cp2fm, but it will be MIXED in case both mutable and immutable nodes are contained
Expand All @@ -181,7 +183,10 @@ static boolean isPackagePathInstalledConditionally(String runMode, Path packageR
if (filePath.startsWith(INSTALL_HOOK_PATH) && filePath.toString().endsWith(".jar")) {
// is it mutable content package?
if (PackageType.CONTENT.equals(packageType)) {
return Collections.singleton(new ValidationMessage(defaultSeverity, VIOLATION_MESSAGE_INSTALL_HOOK_IN_MUTABLE_PACKAGE));
hasInstallHooks = true;
if (!allowHooksInMutableContent) {
return Collections.singleton(new ValidationMessage(defaultSeverity, VIOLATION_MESSAGE_INSTALL_HOOK_IN_MUTABLE_PACKAGE));
}
} else if (packageType == null) {
// defer checking until one is sure that the package has mutable content
hasInstallHooks = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public class AemCloudValidatorFactory implements ValidatorFactory {
private static final String OPTION_ALLOW_VAR_NODE_OUTSIDE_CONTAINERS = "allowVarNodeOutsideContainer";
private static final String OPTION_ALLOW_READONLY_MUTABLE_PATHS = "allowReadOnlyMutablePaths";
private static final String OPTION_ALLOW_LIBS_NODE = "allowLibsNode";
private static final String OPTION_ALLOW_HOOKS_IN_MUTABLE_CONTENT = "allowHooksInMutableContent";

private static final Logger LOGGER = LoggerFactory.getLogger(AemCloudValidatorFactory.class);

Expand All @@ -43,10 +44,14 @@ public Validator createValidator(@NotNull ValidationContext context, @NotNull Va
LOGGER.warn("Using deprecated option 'allowVarNodeOutsideContainer', please use 'allowReadOnlyMutablePaths' instead");
}
boolean allowLibsNode = false;
boolean allowHooksInMutableContent = false;
if (settings.getOptions().containsKey(OPTION_ALLOW_LIBS_NODE)) {
allowLibsNode = Boolean.parseBoolean(settings.getOptions().get(OPTION_ALLOW_LIBS_NODE));
}
return new AemCloudValidator(allowReadOnlyMutablePaths, allowLibsNode, context.getProperties().getPackageType(), context.getContainerValidationContext(), settings.getDefaultSeverity());
if (settings.getOptions().containsKey(OPTION_ALLOW_HOOKS_IN_MUTABLE_CONTENT)) {
allowHooksInMutableContent = Boolean.parseBoolean(settings.getOptions().get(OPTION_ALLOW_HOOKS_IN_MUTABLE_CONTENT));
}
return new AemCloudValidator(allowReadOnlyMutablePaths, allowLibsNode, allowHooksInMutableContent, context.getProperties().getPackageType(), context.getContainerValidationContext(), settings.getDefaultSeverity());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,18 @@
*/

import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Optional;

import org.apache.jackrabbit.vault.packaging.PackageType;
import org.apache.jackrabbit.vault.validation.spi.ValidationMessage;
import org.apache.jackrabbit.vault.validation.spi.ValidationMessageSeverity;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import static biz.netcentric.filevault.validator.aem.cloud.AemCloudValidator.VIOLATION_MESSAGE_INSTALL_HOOK_IN_MUTABLE_PACKAGE;

class AemCloudValidatorTest {

@Test
Expand Down Expand Up @@ -53,16 +57,31 @@ void testIsPathWritableByDistributionJournalImporter() {

@Test
void testMutablePaths(){
AemCloudValidator validator = new AemCloudValidator(false, false, PackageType.CONTENT, null, ValidationMessageSeverity.ERROR);
AemCloudValidator validator = new AemCloudValidator(false, false, false, PackageType.CONTENT, null, ValidationMessageSeverity.ERROR);
Collection<ValidationMessage> messages = validator.validate("/var/subnode");
Assertions.assertFalse(messages.isEmpty());
}

@Test
void testAllowReadOnlyMutablePaths(){
AemCloudValidator validator = new AemCloudValidator(true, false, PackageType.CONTENT, null, ValidationMessageSeverity.ERROR);
AemCloudValidator validator = new AemCloudValidator(true, false, false, PackageType.CONTENT, null, ValidationMessageSeverity.ERROR);
Collection<ValidationMessage> messages = validator.validate("/var/subnode");
Assertions.assertTrue(messages.isEmpty());
}

@Test
void testAllowHooksInMutableContent() {
AemCloudValidator validator = new AemCloudValidator(true, false, false, PackageType.CONTENT, null, ValidationMessageSeverity.ERROR);
Collection<ValidationMessage> messages = new ArrayList<>();
Optional.ofNullable(validator.validateMetaInfPath(Paths.get("vault/hooks/install-hook.jar"))).ifPresent(messages::addAll);
Optional.ofNullable(validator.done()).ifPresent(messages::addAll);
Assertions.assertTrue(messages.stream().anyMatch(message -> message.getMessage().equals(VIOLATION_MESSAGE_INSTALL_HOOK_IN_MUTABLE_PACKAGE)));

validator = new AemCloudValidator(true, false, true, PackageType.CONTENT, null, ValidationMessageSeverity.ERROR);
messages = new ArrayList<>();
Optional.ofNullable(validator.validateMetaInfPath(Paths.get("vault/hooks/install-hook.jar"))).ifPresent(messages::addAll);
Optional.ofNullable(validator.done()).ifPresent(messages::addAll);
Assertions.assertTrue(messages.isEmpty());
}

}

0 comments on commit 17737f2

Please sign in to comment.