Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VIVO-4030 #482

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -246,12 +246,6 @@ protected static void addAccessAttributes(HttpServletRequest req, String entityU
for (RoleInfo role : roles) {
RoleInfo roleCopy = role.clone();
roleInfos.add(roleCopy);
if (isPublicForbiddenOperation(operation)) {
if (roleCopy.isPublic) {
roleCopy.setEnabled(false);
roleCopy.setGranted(false);
}
}
}
getRolePolicyInformation(entityURI, aot, namedKeys, operation, roleInfos);
}
Expand Down Expand Up @@ -359,10 +353,6 @@ protected static void addNotRelatedPropertySuppressions(HttpServletRequest req,
req.setAttribute(PROPERTY_SUPPRESSIONS_NOT_RELATED, propertySuppressionsToRoles);
}

static boolean isPublicForbiddenOperation(AccessOperation operation) {
return operation.equals(AccessOperation.PUBLISH);
}

public static class RoleInfo {
String uri;
String label;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,9 +244,6 @@ private void updateEntityPermissions(HttpServletRequest request, String entityUr
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 {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
package edu.cornell.mannlib.vitro.webapp.migration.auth;

import static edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessObjectType.CLASS;
import static edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessObjectType.DATA_PROPERTY;
import static edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessObjectType.FAUX_DATA_PROPERTY;
import static edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessObjectType.FAUX_OBJECT_PROPERTY;
import static edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessObjectType.OBJECT_PROPERTY;
import static edu.cornell.mannlib.vitro.webapp.auth.attributes.OperationGroup.PUBLISH_GROUP;
import static edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary.ROLE_ADMIN_URI;
import static edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary.ROLE_CURATOR_URI;
import static edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary.ROLE_EDITOR_URI;
Expand Down Expand Up @@ -89,6 +95,34 @@ protected void migrateConfiguration() {
PolicyLoader.getInstance().loadPolicies();
}

protected void updatePublicPublishPermissions() {
Set<OperationGroup> group = Collections.singleton(PUBLISH_GROUP);
Set<String> role = Collections.singleton(ROLE_PUBLIC_URI);

log.info("Started annotation configuration conversion");
Map<String, Map<OperationGroup, Set<String>>> opConfigs = getObjectPropertyAnnotations();
log.info(String.format("Found %s object property annotation configurations", opConfigs.size()));
Map<String, Map<OperationGroup, Set<String>>> dpConfigs = getDataPropertyAnnotations();
log.info(String.format("Found %s data property annotation configurations", dpConfigs.size()));
Map<String, Map<OperationGroup, Set<String>>> classConfigs = getClassAnnotations();
log.info(String.format("Found %s class annotation configurations", classConfigs.size()));
Map<String, Map<OperationGroup, Set<String>>> fopConfigs = getFauxObjectPropertyAnnotations(opConfigs.keySet());
log.info(String.format("Found %s faux object property annotation configurations", fopConfigs.size()));
Map<String, Map<OperationGroup, Set<String>>> fdpConfigs = getFauxDataPropertyAnnotations(dpConfigs.keySet());
log.info(String.format("Found %s faux data property annotation configurations", fdpConfigs.size()));

Long values = updatePolicyDatasets(OBJECT_PROPERTY, group, role, opConfigs);
log.info(String.format("Added %d values in object property datasets.", values));
values = updatePolicyDatasets(DATA_PROPERTY, group, role, dpConfigs);
log.info(String.format("Added %d values in data property datasets.", values));
values = updatePolicyDatasets(CLASS, group, role, classConfigs);
log.info(String.format("Added %d values in class property datasets.", values));
values = updatePolicyDatasets(FAUX_OBJECT_PROPERTY, group, role, fopConfigs);
log.info(String.format("Added %d values in faux object property datasets.", values));
values = updatePolicyDatasets(FAUX_DATA_PROPERTY, group, role, fdpConfigs);
log.info(String.format("Added %d values in faux data property datasets.", values));
}

protected Map<String, Map<OperationGroup, Set<String>>> getFauxDataPropertyAnnotations(Set<String> dataProperties) {
String queryText = getAnnotationQuery(fauxTypeSpecificPatterns);
return getFauxConfigurations(queryText, configurationRdfService, dataProperties);
Expand Down Expand Up @@ -162,7 +196,6 @@ private void collectConfiguration(Map<String, Map<OperationGroup, Set<String>>>

String publishAnnotation = qs.getResource("publish").getURI();
Set<String> publishRoles = new HashSet<>(showMap.get(publishAnnotation));
publishRoles.remove(ROLE_PUBLIC_URI);

String updateAnnotation = qs.getResource("update").getURI();
Set<String> updateRoles = new HashSet<>(showMap.get(updateAnnotation));
Expand Down Expand Up @@ -191,10 +224,7 @@ private static Long[] updatePolicyDatasets(AccessObjectType aot,
EntityPolicyController.getDataValueStatements(entityUri, aot, ao, rolesToAdd, additions);
Set<String> rolesToRemove = new HashSet<>(ALL_ROLES);
rolesToRemove.removeAll(rolesToAdd);
// Don't remove public publish and update data sets, as there are no public policies for that
// operation
// groups
if (OperationGroup.PUBLISH_GROUP.equals(og) || OperationGroup.UPDATE_GROUP.equals(og)) {
if (OperationGroup.UPDATE_GROUP.equals(og)) {
rolesToRemove.remove(ROLE_PUBLIC_URI);
}
if (!rolesToRemove.isEmpty()) {
Expand All @@ -213,6 +243,33 @@ private static Long[] updatePolicyDatasets(AccessObjectType aot,
return new Long[] { getLineCount(additions.toString()), getLineCount(removals.toString()) };
}


private static long updatePolicyDatasets(AccessObjectType aot, Set<OperationGroup> ogs, Set<String> roles,
Map<String, Map<OperationGroup, Set<String>>> configs) {
StringBuilder additions = new StringBuilder();
for (String entityUri : configs.keySet()) {
Map<OperationGroup, Set<String>> groupMap = configs.get(entityUri);
Set<OperationGroup> currentOperationGroups = new HashSet<OperationGroup>(groupMap.keySet());
currentOperationGroups.retainAll(ogs);
for (OperationGroup og : currentOperationGroups) {
for (AccessOperation ao : OperationGroup.getOperations(og)) {
Set<String> rolesToAdd = new HashSet<String>(groupMap.get(og));
rolesToAdd.retainAll(roles);
if (!rolesToAdd.isEmpty()) {
log.info(String.format("Granted access to %s %s %s for roles %s", ao, aot, entityUri,
rolesToString(rolesToAdd)));
}
EntityPolicyController.getDataValueStatements(entityUri, aot, ao, rolesToAdd, additions);
log.debug(String.format(
"Updated entity %s dataset for operation group %s access object type %s roles %s",
entityUri, og, aot, rolesToAdd));
}
}
}
PolicyLoader.getInstance().updateAccessControlModel(additions.toString(), true);
return getLineCount(additions.toString());
}

private static Object rolesToString(Set<String> roles) {
String result = "";
for (String roleUri : roles) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

public class AuthMigrator implements ServletContextListener {

private static final long CURRENT_VERSION = 2;
private static final Log log = LogFactory.getLog(AuthMigrator.class);
protected static final Set<String> ALL_ROLES = new HashSet<String>(
Arrays.asList(ROLE_ADMIN_URI, ROLE_CURATOR_URI, ROLE_EDITOR_URI, ROLE_SELF_EDITOR_URI, ROLE_PUBLIC_URI));
Expand Down Expand Up @@ -72,6 +73,33 @@ public void contextInitialized(ServletContextEvent sce) {
if (!isMigrationRequired()) {
return;
}
long currentVersion = getVersion();
if (currentVersion == 0) {
runCompleteMigration(sce, begin);
} else if (currentVersion == 1) {
migratePublishPublicPermissions(sce, begin);
}
}

private void migratePublishPublicPermissions(ServletContextEvent sce, long begin) {
ServletContext ctx = sce.getServletContext();
StartupStatus ss = StartupStatus.getBean(ctx);
log.info("Started publish permissions authorization reconfiguration for public role");
convertPublicPublishPermissions();
ss.info(this, secondsSince(begin) + " seconds spent to reconfigure publish permissions for public role");
removeVersion(getVersion());
setVersion(CURRENT_VERSION);
log.info(String.format("Updated access control configuration to version %d", CURRENT_VERSION));
PolicyLoader.getInstance().loadPolicies();
log.info("Reloaded all policies after migration");
}

private void convertPublicPublishPermissions() {
AnnotationMigrator annotationMigrator = new AnnotationMigrator(contentRdfService, configurationRdfService);
annotationMigrator.updatePublicPublishPermissions();
}

private void runCompleteMigration(ServletContextEvent sce, long begin) {
ServletContext ctx = sce.getServletContext();
StartupStatus ss = StartupStatus.getBean(ctx);
log.info("Started authorization configuration update");
Expand All @@ -97,7 +125,8 @@ protected void convertAuthorizationConfiguration() {
}
migrateSimplePermissions();
removeVersion(getVersion());
setVersion(1L);
setVersion(CURRENT_VERSION);
log.info(String.format("Updated access control configuration to version %d", CURRENT_VERSION));
}

private void migrateSimplePermissions() {
Expand All @@ -112,15 +141,14 @@ private void migrateAnnotationConfiguation() {
}

private boolean isMigrationRequired() {
if (getVersion() == 0L) {
if (getVersion() < CURRENT_VERSION) {
return true;
}
return false;
}

protected long getVersion() {
long version = 0L;

try {
ResultSet rs = RDFServiceUtils.sparqlSelectQuery(VERSION_QUERY, configurationRdfService);
while (rs.hasNext()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
access:hasDataSet :CuratorUpdateClassDataSet ;
access:hasDataSet :AdminUpdateClassDataSet ;

access:hasDataSet :PublicPublishClassDataSet ;
access:hasDataSet :SelfEditorPublishClassDataSet ;
access:hasDataSet :EditorPublishClassDataSet ;
access:hasDataSet :CuratorPublishClassDataSet ;
Expand Down Expand Up @@ -251,6 +252,20 @@
access:hasKeyComponent access-individual:AdminRoleUri ;
access:hasKeyComponent access-individual:UpdateOperation .

### Public publish class uri data sets

:PublicPublishClassDataSet a access:DataSet ;
access:hasDataSetKey :PublicPublishClassDataSetKey ;
access:hasRelatedValueSet access-individual:PublicRoleValueSet ;
access:hasRelatedValueSet access-individual:ClassValueSet ;
access:hasRelatedValueSet access-individual:PublishOperationValueSet ;
access:hasRelatedValueSet :PublicPublishClassValueSet .

:PublicPublishClassDataSetKey a access:DataSetKey ;
access:hasKeyComponent access-individual:Class ;
access:hasKeyComponent access-individual:PublicRoleUri ;
access:hasKeyComponent access-individual:PublishOperation .

### Self editor publish class uri data sets

:SelfEditorPublishClassDataSet a access:DataSet ;
Expand Down Expand Up @@ -348,6 +363,7 @@
access:values :EditorPublishClassValueSet ;
access:values :EditorDisplayClassValueSet ;
access:values :EditorUpdateClassValueSet ;
access:values :PublicPublishClassValueSet ;
access:values :SelfEditorPublishClassValueSet ;
access:values :SelfEditorDisplayClassValueSet ;
access:values :SelfEditorUpdateClassValueSet ;
Expand Down Expand Up @@ -382,6 +398,9 @@
:EditorUpdateClassValueSet a access:ValueSet ;
access:containsElementsOfType access-individual:Class .

:PublicPublishClassValueSet a access:ValueSet ;
access:containsElementsOfType access-individual:Class .

:SelfEditorPublishClassValueSet a access:ValueSet ;
access:containsElementsOfType access-individual:Class .

Expand Down
Loading
Loading