Skip to content

Commit

Permalink
Web interface for policies to suppress individual by type, by type no…
Browse files Browse the repository at this point in the history
…t related; suppress not related property
  • Loading branch information
litvinovg committed Jan 8, 2024
1 parent 25e11ce commit 7090a4b
Show file tree
Hide file tree
Showing 17 changed files with 383 additions and 95 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

package edu.cornell.mannlib.vedit.controller;

import static edu.cornell.mannlib.vitro.webapp.auth.attributes.NamedKeyComponent.NOT_RELATED;
import static edu.cornell.mannlib.vitro.webapp.auth.attributes.NamedKeyComponent.PROPERTY_EXCLUSION;
import static edu.cornell.mannlib.vitro.webapp.auth.attributes.NamedKeyComponent.TYPE_EXCLUSION;
import static edu.cornell.mannlib.vitro.webapp.auth.attributes.NamedKeyComponent.URI_EXCLUSION;
import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.ReasoningOption.ASSERTIONS_ONLY;

import java.text.Collator;
Expand All @@ -12,13 +16,11 @@
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

Expand All @@ -27,6 +29,7 @@
import edu.cornell.mannlib.vedit.util.FormUtils;
import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessObjectType;
import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessOperation;
import edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionSets;
import edu.cornell.mannlib.vitro.webapp.auth.policy.EntityPolicyController;
import edu.cornell.mannlib.vitro.webapp.beans.PermissionSet;
import edu.cornell.mannlib.vitro.webapp.controller.Controllers;
Expand All @@ -41,6 +44,7 @@
public class BaseEditController extends VitroHttpServlet {

public static final String ENTITY_URI_ATTRIBUTE_NAME = "_permissionsEntityURI";

public static final String ENTITY_TYPE_ATTRIBUTE_NAME = "_permissionsEntityType";

public static final boolean FORCE_NEW = true; // when you know you're starting a new edit process
Expand Down Expand Up @@ -215,15 +219,13 @@ public String getDefaultLandingPage(HttpServletRequest request) {
protected static void addAccessAttributes(HttpServletRequest req, String entityURI, AccessObjectType aot) {
// Add the permissionsEntityURI (if we are creating a new property, this will be empty)
req.setAttribute(ENTITY_URI_ATTRIBUTE_NAME, entityURI);

String[] namedKeys = new String[0];
// Get the available permission sets
List<PermissionSet> permissionSets = buildListOfSelectableRoles(ModelAccess.on(req).getWebappDaoFactory());
List<RoleInfo> roles = new ArrayList<>();
List<String> roleUris = new ArrayList<>();

for (PermissionSet permissionSet : permissionSets) {
roles.add(new RoleInfo(permissionSet));
roleUris.add(permissionSet.getUri());
}
List<AccessOperation> accessOperations = AccessOperation.getOperations(aot);
// Operation, list of roles>
Expand All @@ -242,16 +244,109 @@ protected static void addAccessAttributes(HttpServletRequest req, String entityU
}
}
}
if (!StringUtils.isEmpty(entityURI)) {
for (RoleInfo roleInfo : roleInfos) {
if (roleInfo.isEnabled()) {
roleInfo.setGranted(
EntityPolicyController.isGranted(entityURI, aot, operation, roleInfo.getUri()));
}
getRolePolicyInformation(entityURI, aot, namedKeys, operation, roleInfos);
}
req.setAttribute("operationsToRoles", operationsToRoles);
}

private static void getRolePolicyInformation(String entityURI, AccessObjectType aot, String[] namedKeys,
AccessOperation operation, List<RoleInfo> roleInfos) {
if (!StringUtils.isEmpty(entityURI)) {
for (RoleInfo roleInfo : roleInfos) {
if (roleInfo.isEnabled()) {
roleInfo.setGranted(
EntityPolicyController.isGranted(entityURI, aot, operation, roleInfo.getUri(), namedKeys));
}
}
}
req.setAttribute("operationsToRoles", operationsToRoles);
}

protected static void addUriSuppressions(HttpServletRequest req, String entityURI, AccessObjectType aot) {
AccessOperation operation = AccessOperation.DISPLAY;
String[] namedKeys = new String[1];
namedKeys[0] = URI_EXCLUSION.toString();
// Get the available permission sets
List<PermissionSet> permissionSets = buildListOfSelectableRoles(ModelAccess.on(req).getWebappDaoFactory());
List<RoleInfo> roles = new ArrayList<>();

for (PermissionSet permissionSet : permissionSets) {
roles.add(new RoleInfo(permissionSet));
}
Map<String, List<RoleInfo>> uriSuppressionsToRoles = new LinkedHashMap<>();
List<RoleInfo> roleInfos = new LinkedList<>();
String operationName = StringUtils.capitalize(operation.toString().toLowerCase());
uriSuppressionsToRoles.put(operationName, roleInfos);
for (RoleInfo role : roles) {
RoleInfo roleCopy = role.clone();
roleInfos.add(roleCopy);
}
getRolePolicyInformation(entityURI, aot, namedKeys, operation, roleInfos);
req.setAttribute("uriSuppressions", uriSuppressionsToRoles);
}

protected static void addTypeSuppressions(HttpServletRequest req, String entityURI, AccessObjectType aot) {
AccessOperation operation = AccessOperation.DISPLAY;
String[] namedKeys = new String[1];
namedKeys[0] = TYPE_EXCLUSION.toString();
// Get the available permission sets
List<PermissionSet> permissionSets = buildListOfSelectableRoles(ModelAccess.on(req).getWebappDaoFactory());
List<RoleInfo> roles = new ArrayList<>();

for (PermissionSet permissionSet : permissionSets) {
roles.add(new RoleInfo(permissionSet));
}
Map<String, List<RoleInfo>> typeSuppressionsToRoles = new LinkedHashMap<>();
List<RoleInfo> roleInfos = new LinkedList<>();
String operationName = StringUtils.capitalize(operation.toString().toLowerCase());
typeSuppressionsToRoles.put(operationName, roleInfos);
for (RoleInfo role : roles) {
RoleInfo roleCopy = role.clone();
roleInfos.add(roleCopy);
}
getRolePolicyInformation(entityURI, aot, namedKeys, operation, roleInfos);
req.setAttribute("typeSuppressions", typeSuppressionsToRoles);
}

protected static void addNotRelatedTypeSuppressions(HttpServletRequest req, String entityURI, AccessObjectType aot) {
AccessOperation operation = AccessOperation.DISPLAY;
String[] namedKeys = new String[2];
namedKeys[0] = TYPE_EXCLUSION.toString();
namedKeys[1] = NOT_RELATED.toString();

RoleInfo role = getSelfEditorRole(req);
Map<String, List<RoleInfo>> typeSuppressionsToRoles = new LinkedHashMap<>();
List<RoleInfo> roleInfos = new LinkedList<>();
String operationName = StringUtils.capitalize(operation.toString().toLowerCase());
typeSuppressionsToRoles.put(operationName, roleInfos);
roleInfos.add(role);

getRolePolicyInformation(entityURI, aot, namedKeys, operation, roleInfos);
req.setAttribute("typeSuppressionsNotRelated", typeSuppressionsToRoles);
}

protected static RoleInfo getSelfEditorRole(HttpServletRequest req) {
PermissionSet permissionSet = ModelAccess.on(req).getWebappDaoFactory().getUserAccountsDao()
.getPermissionSetByUri(PermissionSets.URI_SELF_EDITOR);
RoleInfo role = new RoleInfo(permissionSet);
return role;
}

protected static void addNotRelatedPropertySuppressions(HttpServletRequest req, String entityURI,
AccessObjectType aot) {
AccessOperation operation = AccessOperation.DISPLAY;
String[] namedKeys = new String[2];
namedKeys[0] = PROPERTY_EXCLUSION.toString();
namedKeys[1] = NOT_RELATED.toString();

RoleInfo role = getSelfEditorRole(req);
Map<String, List<RoleInfo>> propertySuppressionsToRoles = new LinkedHashMap<>();
List<RoleInfo> roleInfos = new LinkedList<>();
String operationName = StringUtils.capitalize(operation.toString().toLowerCase());
propertySuppressionsToRoles.put(operationName, roleInfos);
roleInfos.add(role);

getRolePolicyInformation(entityURI, aot, namedKeys, operation, roleInfos);
req.setAttribute("propertySuppressionsNotRelated", propertySuppressionsToRoles);
}

static boolean isPublicForbiddenOperation(AccessOperation operation) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@

package edu.cornell.mannlib.vedit.controller;

import static edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessObjectType.CLASS;
import static edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessObjectType.INDIVIDUAL;
import static edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessOperation.DISPLAY;
import static edu.cornell.mannlib.vitro.webapp.auth.attributes.NamedKeyComponent.NOT_RELATED;
import static edu.cornell.mannlib.vitro.webapp.auth.attributes.NamedKeyComponent.PROPERTY_EXCLUSION;
import static edu.cornell.mannlib.vitro.webapp.auth.attributes.NamedKeyComponent.TYPE_EXCLUSION;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
Expand All @@ -19,19 +25,7 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessObjectType;
import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessOperation;
import edu.cornell.mannlib.vitro.webapp.auth.attributes.OperationGroup;
import edu.cornell.mannlib.vitro.webapp.auth.policy.EntityPolicyController;
import edu.cornell.mannlib.vitro.webapp.beans.PermissionSet;
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
import org.apache.commons.lang3.EnumUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import edu.cornell.mannlib.vedit.beans.EditProcessObject;
import edu.cornell.mannlib.vedit.controller.BaseEditController.RoleInfo;
import edu.cornell.mannlib.vedit.forwarder.PageForwarder;
import edu.cornell.mannlib.vedit.listener.ChangeListener;
import edu.cornell.mannlib.vedit.listener.EditPreProcessor;
Expand All @@ -40,6 +34,15 @@
import edu.cornell.mannlib.vedit.util.OperationUtils;
import edu.cornell.mannlib.vedit.validator.ValidationObject;
import edu.cornell.mannlib.vedit.validator.Validator;
import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessObjectType;
import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessOperation;
import edu.cornell.mannlib.vitro.webapp.auth.policy.EntityPolicyController;
import edu.cornell.mannlib.vitro.webapp.beans.PermissionSet;
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
import org.apache.commons.lang3.EnumUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

@WebServlet(name = "OperationController", urlPatterns = {"/doEdit"} )
public class OperationController extends BaseEditController {
Expand Down Expand Up @@ -138,39 +141,7 @@ public void doPost (HttpServletRequest request, HttpServletResponse response) {

// If contains restrictions
if (request.getParameter("_permissions") != null) {
// Get the namespace that we are editing
String entityUri = request.getParameter(ENTITY_URI_ATTRIBUTE_NAME);
if (StringUtils.isEmpty(entityUri)) {
// If we don't have a namespace set, we are creating a new entity so use that namespace
if (!StringUtils.isEmpty(request.getParameter("Namespace")) && !StringUtils.isEmpty(request.getParameter("LocalName"))) {
entityUri = "" + request.getParameter("Namespace") + request.getParameter("LocalName");
}
}
String entityType = request.getParameter(ENTITY_TYPE_ATTRIBUTE_NAME);
List<PermissionSet> permissionSets = buildListOfSelectableRoles(ModelAccess.on(request).getWebappDaoFactory());
Set<RoleInfo> roles = new HashSet<>();
for (PermissionSet permissionSet : permissionSets) {
roles.add(new RoleInfo(permissionSet));
}
AccessObjectType aot = getAccessObjectType(entityUri, entityType);
if (aot != null) {
List<AccessOperation> operations = AccessOperation.getOperations(aot);
for (AccessOperation ao : operations) {
String operationGroupName = ao.toString().toLowerCase().split("_")[0];
Set<String> selectedRoles = getSelectedRoles(request, operationGroupName);
for (RoleInfo role : roles) {
if (role.isPublic() && isPublicForbiddenOperation(ao)) {
continue;
}
if (selectedRoles.contains(role.getUri())) {
EntityPolicyController.grantAccess(entityUri, aot, ao, role.getUri());
} else {
EntityPolicyController.revokeAccess(entityUri, aot, ao, role.getUri());
}

}
}
}
updatePermissions(request);
}

/* put request parameters and attributes into epo where the listeners can see */
Expand Down Expand Up @@ -230,6 +201,119 @@ public void doPost (HttpServletRequest request, HttpServletResponse response) {
}
}

private void updatePermissions(HttpServletRequest request) {
// Get the namespace that we are editing
String entityUri = request.getParameter(ENTITY_URI_ATTRIBUTE_NAME);
if (StringUtils.isEmpty(entityUri)) {
// If we don't have a namespace set, we are creating a new entity so use that namespace
if (!StringUtils.isEmpty(request.getParameter("Namespace")) && !StringUtils.isEmpty(request.getParameter("LocalName"))) {
entityUri = "" + request.getParameter("Namespace") + request.getParameter("LocalName");
}
}
String entityType = request.getParameter(ENTITY_TYPE_ATTRIBUTE_NAME);
AccessObjectType aot = getAccessObjectType(entityUri, entityType);
if (aot == null) {
return;
}
updateEntityPermissions(request, entityUri, aot);
updateTypeSuppressions(request, aot, entityUri);
updateNotRelatedTypeSuppressions(request, aot, entityUri);
updateNotRelatedPropertySuppressions(request, aot, entityUri);
}

private void updateEntityPermissions(HttpServletRequest request, String entityUri, AccessObjectType aot) {
Set<RoleInfo> roles = getAllRoles(request);
List<AccessOperation> operations = AccessOperation.getOperations(aot);
for (AccessOperation ao : operations) {
String operationGroupName = ao.toString().toLowerCase();
Set<String> selectedRoles = getSelectedRoles(request, operationGroupName);
for (RoleInfo role : roles) {
if (role.isPublic() && isPublicForbiddenOperation(ao)) {
continue;
}
if (selectedRoles.contains(role.getUri())) {
EntityPolicyController.grantAccess(entityUri, aot, ao, role.getUri());
} else {
EntityPolicyController.revokeAccess(entityUri, aot, ao, role.getUri());
}
}
}
}

private Set<RoleInfo> getAllRoles(HttpServletRequest request) {
List<PermissionSet> permissionSets = buildListOfSelectableRoles(ModelAccess.on(request).getWebappDaoFactory());
Set<RoleInfo> roles = new HashSet<>();
for (PermissionSet permissionSet : permissionSets) {
roles.add(new RoleInfo(permissionSet));
}
return roles;
}

private void updateTypeSuppressions(HttpServletRequest request, AccessObjectType aot, String entityUri) {
if (!isTypeSuppressionsPresent(request) || !AccessObjectType.CLASS.equals(aot)) {
return;
}
String[] namedKeys = new String[1];
namedKeys[0] = TYPE_EXCLUSION.toString();
Set<RoleInfo> roles = getAllRoles(request);
String operationGroupName = "typeSuppression" + DISPLAY.toString().toLowerCase();
Set<String> selectedRoles = getSelectedRoles(request, operationGroupName);
for (RoleInfo role : roles) {
if (selectedRoles.contains(role.getUri())) {
EntityPolicyController.grantAccess(entityUri, INDIVIDUAL, DISPLAY, role.getUri(), namedKeys);
} else {
EntityPolicyController.revokeAccess(entityUri, INDIVIDUAL, DISPLAY, role.getUri(), namedKeys);
}
}
}

private void updateNotRelatedTypeSuppressions(HttpServletRequest request, AccessObjectType aot, String entityUri) {
if (!isNotRelatedTypeSuppressionsPresent(request) || !CLASS.equals(aot)) {
return;
}
String[] namedKeys = new String[2];
namedKeys[0] = TYPE_EXCLUSION.toString();
namedKeys[1] = NOT_RELATED.toString();
RoleInfo role = getSelfEditorRole(request);
String operationGroupName = "typeSuppressionNotRelated" + DISPLAY.toString().toLowerCase();
Set<String> selectedRoles = getSelectedRoles(request, operationGroupName);
if (selectedRoles.contains(role.getUri())) {
EntityPolicyController.grantAccess(entityUri, INDIVIDUAL, DISPLAY, role.getUri(), namedKeys);
} else {
EntityPolicyController.revokeAccess(entityUri, INDIVIDUAL, DISPLAY, role.getUri(), namedKeys);
}
}

private void updateNotRelatedPropertySuppressions(HttpServletRequest request, AccessObjectType aot,
String entityUri) {
if (!isNotRelatedPropertySuppressionsPresent(request)) {
return;
}
String[] namedKeys = new String[2];
namedKeys[0] = PROPERTY_EXCLUSION.toString();
namedKeys[1] = NOT_RELATED.toString();
RoleInfo role = getSelfEditorRole(request);
String operationGroupName = "propertySuppressionNotRelated" + DISPLAY.toString().toLowerCase();
Set<String> selectedRoles = getSelectedRoles(request, operationGroupName);
if (selectedRoles.contains(role.getUri())) {
EntityPolicyController.grantAccess(entityUri, aot, DISPLAY, role.getUri(), namedKeys);
} else {
EntityPolicyController.revokeAccess(entityUri, aot, DISPLAY, role.getUri(), namedKeys);
}
}

private boolean isNotRelatedPropertySuppressionsPresent(HttpServletRequest request) {
return request.getParameter("_propertySuppressionsNotRelated") != null;
}

private boolean isTypeSuppressionsPresent(HttpServletRequest request) {
return request.getParameter("_typeSuppressions") != null;
}

private boolean isNotRelatedTypeSuppressionsPresent(HttpServletRequest request) {
return request.getParameter("_typeSuppressionsNotRelated") != null;
}

private Set<String> getSelectedRoles(HttpServletRequest request, String operationGroupName) {
String[] selectedRoles = request.getParameterValues(operationGroupName + "Roles");
if (selectedRoles == null) {
Expand Down
Loading

0 comments on commit 7090a4b

Please sign in to comment.