Skip to content

Commit

Permalink
Merge pull request #395 from wttech/custom-restrictions
Browse files Browse the repository at this point in the history
added custom restrictions
  • Loading branch information
dprzybyl committed Jul 5, 2023
2 parents 3bb322e + a1bec69 commit 566e977
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -51,25 +52,25 @@ public class Allow implements Action {
private final boolean ignoreNonExistingPaths;

public Allow(String path, List<String> permissions,
String glob, List<String> ntNames,
List<String> itemNames, boolean ignoreNonExistingPaths) {
String glob, List<String> ntNames, List<String> itemNames, Map<String, Object> 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();
Expand All @@ -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));
Expand All @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -51,9 +52,10 @@ public Action create(
@Required(value = "permissions", description = "e.g.: [READ, 'jcr:all']") List<String> 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<String> types,
@Named(value = "properties", description = "list of properties which will be affected ") List<String> items,
@Named(value = "properties", description = "list of properties which will be affected") List<String> items,
@Named(value = "restrictions", description = "map of custom restrictions") Map<String, Object> 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(
Expand All @@ -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<String> types,
@Named(value = "properties", description = "list of properties which will be affected ") List<String> items,
@Named(value = "properties", description = "list of properties which will be affected") List<String> items,
@Named(value = "restrictions", description = "map of custom restrictions") Map<String, Object> 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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -50,26 +51,26 @@ public class Deny implements Action {

private final boolean ignoreNonExistingPaths;

public Deny(final String path, final List<String> permissions,
final String glob, List<String> ntNames, final List<String> itemNames,
final boolean ignoreNonExistingPaths) {
public Deny(String path, List<String> permissions,
String glob, List<String> ntNames, List<String> itemNames, Map<String, Object> 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();
Expand All @@ -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));
Expand All @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -51,9 +52,10 @@ public Action create(
@Required(value = "permissions", description = "e.g.: [READ, 'jcr:all']") List<String> 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<String> types,
@Named(value = "properties", description = "list of properties which will be affected ") List<String> items,
@Named(value = "properties", description = "list of properties which will be affected") List<String> items,
@Named(value = "restrictions", description = "map of custom restrictions") Map<String, Object> 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(
Expand All @@ -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<String> types,
@Named(value = "properties", description = "list of properties which will be affected ") List<String> items,
@Named(value = "properties", description = "list of properties which will be affected") List<String> items,
@Named(value = "restrictions", description = "map of custom restrictions") Map<String, Object> 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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -40,54 +41,75 @@ public class Restrictions {
private static final String STRICT = "STRICT";

private final String glob;

private final List<String> ntNames;

private final List<String> itemNames;

public Restrictions(String glob, List<String> ntNames, List<String> itemNames) {
private final Map<String, Object> customRestrictions;

public Restrictions(String glob, List<String> ntNames, List<String> itemNames, Map<String, Object> customRestrictions) {
this.glob = glob;
this.ntNames = notNullCopy(ntNames);
this.itemNames = notNullCopy(itemNames);
this.customRestrictions = notNullCopy(customRestrictions);
}

private List<String> notNullCopy(List<String> strings) {
return strings != null ? ImmutableList.copyOf(strings) : Collections.emptyList();
}

public Map<String, Value> getSingleValueRestrictions(ValueFactory valueFactory) {
private Map<String, Object> notNullCopy(Map<String, Object> items) {
return items != null ? ImmutableMap.copyOf(items) : Collections.emptyMap();
}

public Map<String, Value> getSingleValueRestrictions(ValueFactory valueFactory) throws ValueFormatException {
Map<String, Value> result = new HashMap<>();
if (StringUtils.isNotBlank(glob)) {
result.put("rep:glob", normalizeGlob(valueFactory));
addRestriction(valueFactory, result, "rep:glob", glob);
for (Map.Entry<String, Object> entry : customRestrictions.entrySet()) {
if (entry.getValue() instanceof String) {
addRestriction(valueFactory, result, entry.getKey(), (String) entry.getValue());
}
}
return result;
}

private void addRestriction(ValueFactory valueFactory, Map<String, Value> 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);
}
return valueFactory.createValue(glob);
}

public Map<String, Value[]> getMultiValueRestrictions(ValueFactory valueFactory)
throws ValueFormatException {

public Map<String, Value[]> getMultiValueRestrictions(ValueFactory valueFactory) throws ValueFormatException {
Map<String, Value[]> result = new HashMap<>();
addRestrictions(valueFactory, result, "rep:ntNames", ntNames);
addRestrictions(valueFactory, result, "rep:itemNames", itemNames);
for (Map.Entry<String, Object> entry : customRestrictions.entrySet()) {
if (entry.getValue() instanceof List) {
addRestrictions(valueFactory, result, entry.getKey(), (List<String>) entry.getValue());
}
}
return result;
}

private void addRestrictions(ValueFactory valueFactory, Map<String, Value[]> result, String key, List<String> names)
throws ValueFormatException {

private void addRestrictions(ValueFactory valueFactory, Map<String, Value[]> result, String key, List<String> names) throws ValueFormatException {
if (names != null && !names.isEmpty()) {
result.put(key, createRestrictions(valueFactory, names));
}
}

private Value[] createRestrictions(ValueFactory valueFactory, List<String> names)
throws ValueFormatException {

private Value[] createRestrictions(ValueFactory valueFactory, List<String> 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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 {
Expand All @@ -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<MappingDescriptor> mappingDescriptors = Lists.newArrayList();
Object mapper = createInstance(mapperClass);
String name = mapperAnnotation.value();
String group = mapperAnnotation.group();
List<MappingDescriptor> mappingDescriptors = Lists.newArrayList();
for (Method method : mapperClass.getDeclaredMethods()) {
create(mapperAnnotation, method).ifPresent(mappingDescriptors::add);
}
Expand Down Expand Up @@ -138,6 +140,8 @@ private Class<? extends ApmType> 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;
Expand Down

0 comments on commit 566e977

Please sign in to comment.