From a1bec69ab29744934db0bd28552e558ea47d5148 Mon Sep 17 00:00:00 2001 From: Dominik Przybyl Date: Thu, 13 Apr 2023 13:46:31 +0200 Subject: [PATCH] added custom restrictions --- .../apm/main/actions/allow/Allow.java | 18 +++---- .../apm/main/actions/allow/AllowMapper.java | 11 +++-- .../cognifide/apm/main/actions/deny/Deny.java | 23 ++++----- .../apm/main/actions/deny/DenyMapper.java | 11 +++-- .../apm/main/permissions/Restrictions.java | 48 ++++++++++++++----- .../core/actions/MapperDescriptorFactory.java | 12 +++-- 6 files changed, 79 insertions(+), 44 deletions(-) diff --git a/app/aem/actions.main/src/main/java/com/cognifide/apm/main/actions/allow/Allow.java b/app/aem/actions.main/src/main/java/com/cognifide/apm/main/actions/allow/Allow.java index 5bb5c849c..e6fd77e3e 100644 --- a/app/aem/actions.main/src/main/java/com/cognifide/apm/main/actions/allow/Allow.java +++ b/app/aem/actions.main/src/main/java/com/cognifide/apm/main/actions/allow/Allow.java @@ -31,6 +31,7 @@ import com.cognifide.apm.main.utils.PathUtils; import java.util.Collections; import java.util.List; +import java.util.Map; import javax.jcr.PathNotFoundException; import javax.jcr.RepositoryException; import org.apache.commons.lang3.StringUtils; @@ -51,25 +52,25 @@ public class Allow implements Action { private final boolean ignoreNonExistingPaths; public Allow(String path, List permissions, - String glob, List ntNames, - List itemNames, boolean ignoreNonExistingPaths) { + String glob, List ntNames, List itemNames, Map customRestrictions, + boolean ignoreNonExistingPaths) { this.path = path; this.permissions = permissions; - this.restrictions = new Restrictions(glob, ntNames, itemNames); + this.restrictions = new Restrictions(glob, ntNames, itemNames, customRestrictions); this.ignoreNonExistingPaths = ignoreNonExistingPaths; } @Override - public ActionResult simulate(final Context context) { + public ActionResult simulate(Context context) { return process(context, true); } @Override - public ActionResult execute(final Context context) { + public ActionResult execute(Context context) { return process(context, false); } - private ActionResult process(final Context context, boolean simulate) { + private ActionResult process(Context context, boolean simulate) { ActionResult actionResult = context.createActionResult(); try { Authorizable authorizable = context.getCurrentAuthorizable(); @@ -78,7 +79,7 @@ private ActionResult process(final Context context, boolean simulate) { actionResult.changeStatus(Status.SKIPPED, "Skipped adding allow privilege for " + authorizable.getID() + " on " + path); } else { context.getSession().getNode(path); - final PermissionActionHelper permissionActionHelper = new PermissionActionHelper( + PermissionActionHelper permissionActionHelper = new PermissionActionHelper( context.getValueFactory(), path, permissions, restrictions); LOGGER.info(String.format("Adding permissions %s for authorizable with id = %s for path = %s %s", permissions.toString(), context.getCurrentAuthorizable().getID(), path, restrictions)); @@ -92,11 +93,12 @@ private ActionResult process(final Context context, boolean simulate) { String preparedGlob = recalculateGlob(restrictions.getGlob()); new Allow(path, Collections.singletonList("MODIFY_PAGE"), preparedGlob + "*/jcr:content*", restrictions.getNtNames(), restrictions.getItemNames(), + restrictions.getCustomRestrictions(), ignoreNonExistingPaths ).process(context, simulate); } } - } catch (final PathNotFoundException e) { + } catch (PathNotFoundException e) { if (ignoreNonExistingPaths) { actionResult.logWarning("Path " + path + " not found"); } else { diff --git a/app/aem/actions.main/src/main/java/com/cognifide/apm/main/actions/allow/AllowMapper.java b/app/aem/actions.main/src/main/java/com/cognifide/apm/main/actions/allow/AllowMapper.java index 7589de79d..aac7f78f4 100644 --- a/app/aem/actions.main/src/main/java/com/cognifide/apm/main/actions/allow/AllowMapper.java +++ b/app/aem/actions.main/src/main/java/com/cognifide/apm/main/actions/allow/AllowMapper.java @@ -29,6 +29,7 @@ import com.cognifide.apm.api.actions.annotations.Required; import com.cognifide.apm.main.actions.ActionGroup; import java.util.List; +import java.util.Map; @Mapper(value = "ALLOW", group = ActionGroup.CORE) public class AllowMapper { @@ -51,9 +52,10 @@ public Action create( @Required(value = "permissions", description = "e.g.: [READ, 'jcr:all']") List permissions, @Named(value = "glob", description = "regular expression to narrow set of paths") String glob, @Named(value = "types", description = "list of jcr types which will be affected") List types, - @Named(value = "properties", description = "list of properties which will be affected ") List items, + @Named(value = "properties", description = "list of properties which will be affected") List items, + @Named(value = "restrictions", description = "map of custom restrictions") Map restrictions, @Flag(value = IF_EXISTS, description = "script doesn't fail if path doesn't exist") boolean ifExists) { - return new Allow(path, permissions, glob, types, items, ifExists); + return new Allow(path, permissions, glob, types, items, restrictions, ifExists); } @Mapping( @@ -71,8 +73,9 @@ public Action create( @Required(value = "path", description = "e.g.: '/content/dam'") String path, @Named(value = "glob", description = "regular expression to narrow set of paths") String glob, @Named(value = "types", description = "list of jcr types which will be affected") List types, - @Named(value = "properties", description = "list of properties which will be affected ") List items, + @Named(value = "properties", description = "list of properties which will be affected") List items, + @Named(value = "restrictions", description = "map of custom restrictions") Map restrictions, @Flag(value = IF_EXISTS, description = "script doesn't fail if path doesn't exist") boolean ifExists) { - return new Allow(path, permissions, glob, types, items, ifExists); + return new Allow(path, permissions, glob, types, items, restrictions, ifExists); } } diff --git a/app/aem/actions.main/src/main/java/com/cognifide/apm/main/actions/deny/Deny.java b/app/aem/actions.main/src/main/java/com/cognifide/apm/main/actions/deny/Deny.java index a7be3e53a..5e37dbabf 100644 --- a/app/aem/actions.main/src/main/java/com/cognifide/apm/main/actions/deny/Deny.java +++ b/app/aem/actions.main/src/main/java/com/cognifide/apm/main/actions/deny/Deny.java @@ -31,6 +31,7 @@ import com.cognifide.apm.main.utils.PathUtils; import java.util.ArrayList; import java.util.List; +import java.util.Map; import javax.jcr.PathNotFoundException; import javax.jcr.RepositoryException; import org.apache.commons.lang3.StringUtils; @@ -50,26 +51,26 @@ public class Deny implements Action { private final boolean ignoreNonExistingPaths; - public Deny(final String path, final List permissions, - final String glob, List ntNames, final List itemNames, - final boolean ignoreNonExistingPaths) { + public Deny(String path, List permissions, + String glob, List ntNames, List itemNames, Map customRestrictions, + boolean ignoreNonExistingPaths) { this.path = path; this.permissions = permissions; - this.restrictions = new Restrictions(glob, ntNames, itemNames); + this.restrictions = new Restrictions(glob, ntNames, itemNames, customRestrictions); this.ignoreNonExistingPaths = ignoreNonExistingPaths; } @Override - public ActionResult simulate(final Context context) { + public ActionResult simulate(Context context) { return process(context, true); } @Override - public ActionResult execute(final Context context) { + public ActionResult execute(Context context) { return process(context, false); } - private ActionResult process(final Context context, boolean simulate) { + private ActionResult process(Context context, boolean simulate) { ActionResult actionResult = context.createActionResult(); try { Authorizable authorizable = context.getCurrentAuthorizable(); @@ -78,7 +79,7 @@ private ActionResult process(final Context context, boolean simulate) { actionResult.changeStatus(Status.SKIPPED, "Skipped adding deny privilege for " + authorizable.getID() + " on " + path); } else { context.getSession().getNode(path); - final PermissionActionHelper permissionActionHelper = new PermissionActionHelper( + PermissionActionHelper permissionActionHelper = new PermissionActionHelper( context.getValueFactory(), path, permissions, restrictions); LOGGER.info(String.format("Denying permissions %s for authorizable with id = %s for path = %s %s", permissions.toString(), context.getCurrentAuthorizable().getID(), path, restrictions)); @@ -93,18 +94,18 @@ private ActionResult process(final Context context, boolean simulate) { globModifyPermission.add("MODIFY_PAGE"); String preparedGlob = recalculateGlob(restrictions.getGlob()); new Deny(path, globModifyPermission, - preparedGlob + "*/jcr:content*", restrictions.getNtNames(), restrictions.getItemNames(), + preparedGlob + "*/jcr:content*", restrictions.getNtNames(), restrictions.getItemNames(), restrictions.getCustomRestrictions(), ignoreNonExistingPaths) .process(context, simulate); } } - } catch (final PathNotFoundException e) { + } catch (PathNotFoundException e) { if (ignoreNonExistingPaths) { actionResult.logWarning("Path " + path + " not found"); } else { actionResult.logError("Path " + path + " not found"); } - } catch (final RepositoryException | PermissionException | ActionExecutionException e) { + } catch (RepositoryException | PermissionException | ActionExecutionException e) { actionResult.logError(MessagingUtils.createMessage(e)); } return actionResult; diff --git a/app/aem/actions.main/src/main/java/com/cognifide/apm/main/actions/deny/DenyMapper.java b/app/aem/actions.main/src/main/java/com/cognifide/apm/main/actions/deny/DenyMapper.java index 27c7fee89..1f48c14bb 100644 --- a/app/aem/actions.main/src/main/java/com/cognifide/apm/main/actions/deny/DenyMapper.java +++ b/app/aem/actions.main/src/main/java/com/cognifide/apm/main/actions/deny/DenyMapper.java @@ -29,6 +29,7 @@ import com.cognifide.apm.api.actions.annotations.Required; import com.cognifide.apm.main.actions.ActionGroup; import java.util.List; +import java.util.Map; @Mapper(value = "DENY", group = ActionGroup.CORE) public class DenyMapper { @@ -51,9 +52,10 @@ public Action create( @Required(value = "permissions", description = "e.g.: [READ, 'jcr:all']") List permissions, @Named(value = "glob", description = "regular expression to narrow set of paths") String glob, @Named(value = "types", description = "list of jcr types which will be affected") List types, - @Named(value = "properties", description = "list of properties which will be affected ") List items, + @Named(value = "properties", description = "list of properties which will be affected") List items, + @Named(value = "restrictions", description = "map of custom restrictions") Map restrictions, @Flag(value = IF_EXISTS, description = "script doesn't fail if path doesn't exist") boolean ifExists) { - return new Deny(path, permissions, glob, types, items, ifExists); + return new Deny(path, permissions, glob, types, items, restrictions, ifExists); } @Mapping( @@ -71,8 +73,9 @@ public Action create( @Required(value = "path", description = "e.g.: '/content/dam'") String path, @Named(value = "glob", description = "regular expression to narrow set of paths") String glob, @Named(value = "types", description = "list of jcr types which will be affected") List types, - @Named(value = "properties", description = "list of properties which will be affected ") List items, + @Named(value = "properties", description = "list of properties which will be affected") List items, + @Named(value = "restrictions", description = "map of custom restrictions") Map restrictions, @Flag(value = IF_EXISTS, description = "script doesn't fail if path doesn't exist") boolean ifExists) { - return new Deny(path, permissions, glob, types, items, ifExists); + return new Deny(path, permissions, glob, types, items, restrictions, ifExists); } } diff --git a/app/aem/actions.main/src/main/java/com/cognifide/apm/main/permissions/Restrictions.java b/app/aem/actions.main/src/main/java/com/cognifide/apm/main/permissions/Restrictions.java index 4d70e075a..e219e32c7 100644 --- a/app/aem/actions.main/src/main/java/com/cognifide/apm/main/permissions/Restrictions.java +++ b/app/aem/actions.main/src/main/java/com/cognifide/apm/main/permissions/Restrictions.java @@ -21,6 +21,7 @@ package com.cognifide.apm.main.permissions; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -40,27 +41,49 @@ public class Restrictions { private static final String STRICT = "STRICT"; private final String glob; + private final List ntNames; + private final List itemNames; - public Restrictions(String glob, List ntNames, List itemNames) { + private final Map customRestrictions; + + public Restrictions(String glob, List ntNames, List itemNames, Map customRestrictions) { this.glob = glob; this.ntNames = notNullCopy(ntNames); this.itemNames = notNullCopy(itemNames); + this.customRestrictions = notNullCopy(customRestrictions); } private List notNullCopy(List strings) { return strings != null ? ImmutableList.copyOf(strings) : Collections.emptyList(); } - public Map getSingleValueRestrictions(ValueFactory valueFactory) { + private Map notNullCopy(Map items) { + return items != null ? ImmutableMap.copyOf(items) : Collections.emptyMap(); + } + + public Map getSingleValueRestrictions(ValueFactory valueFactory) throws ValueFormatException { Map result = new HashMap<>(); - if (StringUtils.isNotBlank(glob)) { - result.put("rep:glob", normalizeGlob(valueFactory)); + addRestriction(valueFactory, result, "rep:glob", glob); + for (Map.Entry entry : customRestrictions.entrySet()) { + if (entry.getValue() instanceof String) { + addRestriction(valueFactory, result, entry.getKey(), (String) entry.getValue()); + } } return result; } + private void addRestriction(ValueFactory valueFactory, Map result, String key, String value) throws ValueFormatException { + if (StringUtils.isNotBlank(value)) { + if (key.equals("rep:glob")) { + result.put(key, normalizeGlob(valueFactory)); + } else { + result.put(key, valueFactory.createValue(value, PropertyType.NAME)); + } + } + } + private Value normalizeGlob(ValueFactory valueFactory) { if (STRICT.equalsIgnoreCase(glob)) { return valueFactory.createValue(StringUtils.EMPTY); @@ -68,26 +91,25 @@ private Value normalizeGlob(ValueFactory valueFactory) { return valueFactory.createValue(glob); } - public Map getMultiValueRestrictions(ValueFactory valueFactory) - throws ValueFormatException { - + public Map getMultiValueRestrictions(ValueFactory valueFactory) throws ValueFormatException { Map result = new HashMap<>(); addRestrictions(valueFactory, result, "rep:ntNames", ntNames); addRestrictions(valueFactory, result, "rep:itemNames", itemNames); + for (Map.Entry entry : customRestrictions.entrySet()) { + if (entry.getValue() instanceof List) { + addRestrictions(valueFactory, result, entry.getKey(), (List) entry.getValue()); + } + } return result; } - private void addRestrictions(ValueFactory valueFactory, Map result, String key, List names) - throws ValueFormatException { - + private void addRestrictions(ValueFactory valueFactory, Map result, String key, List names) throws ValueFormatException { if (names != null && !names.isEmpty()) { result.put(key, createRestrictions(valueFactory, names)); } } - private Value[] createRestrictions(ValueFactory valueFactory, List names) - throws ValueFormatException { - + private Value[] createRestrictions(ValueFactory valueFactory, List names) throws ValueFormatException { Value[] values = new Value[names.size()]; for (int index = 0; index < names.size(); index++) { values[index] = valueFactory.createValue(names.get(index), PropertyType.NAME); diff --git a/app/aem/core/src/main/java/com/cognifide/apm/core/actions/MapperDescriptorFactory.java b/app/aem/core/src/main/java/com/cognifide/apm/core/actions/MapperDescriptorFactory.java index 1c336c03d..d0822fa0e 100644 --- a/app/aem/core/src/main/java/com/cognifide/apm/core/actions/MapperDescriptorFactory.java +++ b/app/aem/core/src/main/java/com/cognifide/apm/core/actions/MapperDescriptorFactory.java @@ -34,6 +34,7 @@ import com.cognifide.apm.core.actions.ParameterDescriptor.RequiredParameterDescriptor; import com.cognifide.apm.core.grammar.ApmInteger; import com.cognifide.apm.core.grammar.ApmList; +import com.cognifide.apm.core.grammar.ApmMap; import com.cognifide.apm.core.grammar.ApmString; import com.cognifide.apm.core.grammar.ApmType; import com.google.common.collect.ImmutableList; @@ -43,6 +44,7 @@ import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.List; +import java.util.Map; import java.util.Optional; public class MapperDescriptorFactory { @@ -53,10 +55,10 @@ public MapperDescriptor create(Class mapperClass) { throw new InvalidActionMapperException("Mapper must be annotated with " + Mapper.class.getName()); } - final Object mapper = createInstance(mapperClass); - final String name = mapperAnnotation.value(); - final String group = mapperAnnotation.group(); - final List mappingDescriptors = Lists.newArrayList(); + Object mapper = createInstance(mapperClass); + String name = mapperAnnotation.value(); + String group = mapperAnnotation.group(); + List mappingDescriptors = Lists.newArrayList(); for (Method method : mapperClass.getDeclaredMethods()) { create(mapperAnnotation, method).ifPresent(mappingDescriptors::add); } @@ -138,6 +140,8 @@ private Class getApmType(Type type) { Class rawType = (Class) parameterizedType.getRawType(); if (List.class.equals(rawType)) { return ApmList.class; + } else if (Map.class.equals(rawType)) { + return ApmMap.class; } } return null;