From 126c2cd91df97d23ab49b04904d9e857108dbda8 Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Thu, 26 Oct 2023 11:49:34 +0200 Subject: [PATCH] simple permission migration. Query user accounts model via OntModelSelector --- .../auth/permissions/SimplePermission.java | 8 +- .../auth/policy/EntityPolicyController.java | 4 +- .../webapp/auth/policy/PolicyLoader.java | 8 +- .../migration/auth/AnnotationMigrator.java | 9 +- .../webapp/migration/auth/ArmMigrator.java | 78 +++++++----- .../webapp/migration/auth/AuthMigrator.java | 58 +++++---- .../auth/SimplePermissionMigrator.java | 115 ++++++++++++++++++ .../policy/SimplePermissionTemplateTest.java | 3 +- .../migration/auth/ArmMigratorTest.java | 9 +- .../auth/SimplePermissionMigratorTest.java | 104 ++++++++++++++++ .../firsttime/template_simple_permissions.n3 | 6 + 11 files changed, 337 insertions(+), 65 deletions(-) create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/migration/auth/SimplePermissionMigrator.java create mode 100644 api/src/test/java/edu/cornell/mannlib/vitro/webapp/migration/auth/SimplePermissionMigratorTest.java diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/SimplePermission.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/SimplePermission.java index e11e6cc7c4..ebe992491a 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/SimplePermission.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/SimplePermission.java @@ -65,10 +65,16 @@ public class SimplePermission { public SimpleAuthorizationRequest ACTION; + private String uri; + + public String getUri() { + return uri; + } + public static final String NS = "java:edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission#"; private SimplePermission(String uri) { - uri = SimplePermission.NS + uri; + this.uri = SimplePermission.NS + uri; AccessObjectImpl ao = new AccessObjectImpl(uri, AccessObjectType.NAMED_OBJECT); this.ACTION = new SimpleAuthorizationRequest(ao, AccessOperation.EXECUTE); } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/EntityPolicyController.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/EntityPolicyController.java index d6cde6d3f5..edf390d411 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/EntityPolicyController.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/EntityPolicyController.java @@ -107,8 +107,8 @@ public static void insertedEntityEvent(Property newObj) { log.debug("Nothing to do " + newObj); } - private static boolean isUriInTestDataset(String entityUri, AccessOperation og, AccessObjectType aot, String role) { - Set values = PolicyLoader.getInstance().getDataSetValues(og, aot, role); + private static boolean isUriInTestDataset(String entityUri, AccessOperation ao, AccessObjectType aot, String role) { + Set values = PolicyLoader.getInstance().getDataSetValues(ao, aot, role); return values.contains(entityUri); } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/PolicyLoader.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/PolicyLoader.java index 022e07a4cb..b7532448cf 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/PolicyLoader.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/PolicyLoader.java @@ -797,12 +797,12 @@ private static void debug(String template, Object... objects) { } } - public void addEntityToPolicyDataSet(String entityUri, AccessObjectType aot, AccessOperation og, String role) { - modifyPolicyDataSetValue(entityUri, og, aot, role, true); + public void addEntityToPolicyDataSet(String entityUri, AccessObjectType aot, AccessOperation ao, String role) { + modifyPolicyDataSetValue(entityUri, ao, aot, role, true); } - public void removeEntityFromPolicyDataSet(String entityUri, AccessObjectType aot, AccessOperation og, String role) { - modifyPolicyDataSetValue(entityUri, og, aot, role, false); + public void removeEntityFromPolicyDataSet(String entityUri, AccessObjectType aot, AccessOperation ao, String role) { + modifyPolicyDataSetValue(entityUri, ao, aot, role, false); } private ChangeSet makeChangeSet() { diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/migration/auth/AnnotationMigrator.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/migration/auth/AnnotationMigrator.java index 000579352e..b62d7e2c0d 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/migration/auth/AnnotationMigrator.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/migration/auth/AnnotationMigrator.java @@ -206,10 +206,13 @@ private static Long[] updatePolicyDatasets(AccessObjectType aot, } private static String getAnnotationQuery(String typeSpecificPatterns) { - return "" + "PREFIX vitro: \n" + return "" + + "PREFIX vitro: \n" + "PREFIX rdf: \n" - + "PREFIX owl: \n" + "SELECT ?base ?uri ?update ?display ?publish\n" - + "WHERE {\n" + typeSpecificPatterns + + "PREFIX owl: \n" + + "SELECT ?base ?uri ?update ?display ?publish\n" + + "WHERE {\n" + + typeSpecificPatterns + "{OPTIONAL { ?uri vitro:hiddenFromDisplayBelowRoleLevelAnnot ?displayAssigned . }\n" + "BIND (COALESCE(?displayAssigned, ) AS ?display)\n" + "OPTIONAL { ?uri vitro:prohibitedFromUpdateBelowRoleLevelAnnot ?updateAssigned . }\n" diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/migration/auth/ArmMigrator.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/migration/auth/ArmMigrator.java index 633cda1f51..495e26fd60 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/migration/auth/ArmMigrator.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/migration/auth/ArmMigrator.java @@ -16,11 +16,13 @@ import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyTemplateController; import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; -import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.jena.ontology.OntModel; import org.apache.jena.query.ParameterizedSparqlString; +import org.apache.jena.query.QueryExecution; +import org.apache.jena.query.QueryExecutionFactory; import org.apache.jena.query.QuerySolution; import org.apache.jena.query.ResultSet; @@ -46,30 +48,28 @@ public class ArmMigrator { private RDFService contentRdfService; private RDFService configurationRdfService; + private OntModel userAccountsModel; private String VALUE_QUERY = "" + "SELECT ?uri \n" + "WHERE {\n" - + " GRAPH <" + ModelNames.USER_ACCOUNTS + "> {\n" + " ?permission ?uri . \n" - + " }\n" + "}"; private String PERMISSION_SETS_QUERY = "" + "prefix auth: \n" + "SELECT ?uri \n" + "WHERE {\n" - + " GRAPH <" + ModelNames.USER_ACCOUNTS + "> {\n" + " ?uri a auth:PermissionSet . \n" - + " }\n" + "}"; private static Map roleMap; private static Map operationMap; - public ArmMigrator(RDFService contentRdfService, RDFService configurationRdfService) { + public ArmMigrator(RDFService contentRdfService, RDFService configurationRdfService, OntModel userAccountsModel) { this.contentRdfService = contentRdfService; this.configurationRdfService = configurationRdfService; + this.userAccountsModel = userAccountsModel; operationMap = new HashMap<>(); operationMap.put(DISPLAY, OperationGroup.DISPLAY_GROUP); operationMap.put(UPDATE, OperationGroup.UPDATE_GROUP); @@ -263,9 +263,12 @@ private String getQueryText(AccessObjectType type) { } private static String getQuery(String typePatterns) { - return "" + "PREFIX vitro: \n" + return "" + + "PREFIX vitro: \n" + "PREFIX rdf: \n" - + "PREFIX owl: \n" + "SELECT ?base ?uri \n" + "WHERE {\n" + + "PREFIX owl: \n" + + "SELECT ?base ?uri \n" + + "WHERE {\n" + typePatterns + "} \n"; } @@ -281,15 +284,21 @@ private Set getArmEntites(String permissionUri) { ParameterizedSparqlString pss = new ParameterizedSparqlString(VALUE_QUERY); pss.setIri("permission", permissionUri); String queryText = pss.toString(); + userAccountsModel.enterCriticalSection(false); try { - ResultSet rs = RDFServiceUtils.sparqlSelectQuery(queryText, configurationRdfService); - while (rs.hasNext()) { - QuerySolution qs = rs.next(); - String entity = qs.getResource("uri").getURI(); - entities.add(entity); + QueryExecution qexec = QueryExecutionFactory.create(queryText, userAccountsModel); + try { + ResultSet results = qexec.execSelect(); + while (results.hasNext()) { + QuerySolution qs = results.next(); + String entity = qs.getResource("uri").getURI(); + entities.add(entity); + } + } finally { + qexec.close(); } - } catch (Exception e) { - log.error(e, e); + } finally { + userAccountsModel.leaveCriticalSection(); } return entities; } @@ -300,16 +309,21 @@ public boolean isArmConfiguation() { private boolean containsAdminDisplayPermission() { boolean result = false; - String query = "" + String queryText = "" + "prefix rdf: \n" + "ASK WHERE {\n" - + " GRAPH {\n" - + " <" - + getArmPermissionSubject(DISPLAY, ARM_ADMIN) + "> ?p ?o .\n" + " }\n" + "}"; + + " <" + + getArmPermissionSubject(DISPLAY, ARM_ADMIN) + "> ?p ?o .\n" + "}"; + userAccountsModel.enterCriticalSection(false); try { - result = configurationRdfService.sparqlAskQuery(query); - } catch (RDFServiceException e) { - log.error(e, e); + QueryExecution qexec = QueryExecutionFactory.create(queryText, userAccountsModel); + try { + result = qexec.execAsk(); + } finally { + qexec.close(); + } + } finally { + userAccountsModel.leaveCriticalSection(); } return result; } @@ -317,15 +331,21 @@ private boolean containsAdminDisplayPermission() { private Set getPermissionSets() { Set permissionSets = new HashSet<>(); String queryText = PERMISSION_SETS_QUERY; + userAccountsModel.enterCriticalSection(false); try { - ResultSet rs = RDFServiceUtils.sparqlSelectQuery(queryText, configurationRdfService); - while (rs.hasNext()) { - QuerySolution qs = rs.next(); - String entity = qs.getResource("uri").getURI(); - permissionSets.add(entity); + QueryExecution qexec = QueryExecutionFactory.create(queryText, userAccountsModel); + try { + ResultSet results = qexec.execSelect(); + while (results.hasNext()) { + QuerySolution qs = results.next(); + String entity = qs.getResource("uri").getURI(); + permissionSets.add(entity); + } + } finally { + qexec.close(); } - } catch (Exception e) { - log.error(e, e); + } finally { + userAccountsModel.leaveCriticalSection(); } return permissionSets; } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/migration/auth/AuthMigrator.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/migration/auth/AuthMigrator.java index 4326a9d458..d785bcb2e4 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/migration/auth/AuthMigrator.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/migration/auth/AuthMigrator.java @@ -19,6 +19,7 @@ import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.jena.ontology.OntModel; import org.apache.jena.query.ParameterizedSparqlString; import org.apache.jena.query.QuerySolution; import org.apache.jena.query.ResultSet; @@ -34,13 +35,37 @@ public class AuthMigrator implements ServletContextListener { protected static final Set ALL_ROLES = new HashSet( Arrays.asList(ROLE_ADMIN_URI, ROLE_CURATOR_URI, ROLE_EDITOR_URI, ROLE_SELF_EDITOR_URI, ROLE_PUBLIC_URI)); + private static final String SET_VERSION_TEMPLATE = "" + + "@prefix rdf: .\n" + + "@prefix ao: .\n" + + " " + + "rdf:type ao:Configuration ;\n" + + "ao:version ?version ."; + + private static final String REMOVE_VERSION_TEMPLATE = "" + + "@prefix rdf: .\n" + + " " + + " ?version ."; + + private static String VERSION_QUERY = "" + + "prefix rdf: \n" + + "prefix ao: \n" + + "SELECT ?version \n" + + "WHERE {\n" + + " GRAPH {\n" + + " ?configuration rdf:type ao:Configuration .\n" + + " ?configuration ao:version ?version .\n" + + " }\n" + + "}"; + private RDFService contentRdfService; private RDFService configurationRdfService; + private ContextModelAccess modelAccess; @Override public void contextInitialized(ServletContextEvent sce) { long begin = System.currentTimeMillis(); - ContextModelAccess modelAccess = ModelAccess.getInstance(); + modelAccess = ModelAccess.getInstance(); initialize(modelAccess.getRDFService(WhichService.CONTENT), modelAccess.getRDFService(WhichService.CONFIGURATION)); if (!isMigrationRequired()) { @@ -71,12 +96,14 @@ protected void convertAuthorizationConfiguration() { } private void migrateSimplePermissions() { - // TODO Auto-generated method stub - + OntModel userAccountsModel = modelAccess.getOntModelSelector().getUserAccountsModel(); + SimplePermissionMigrator spm = new SimplePermissionMigrator(userAccountsModel); + spm.migrateConfiguration(); } private void migrateArmConfiguration() { - ArmMigrator armMigrator = new ArmMigrator(contentRdfService, configurationRdfService); + OntModel userAccountsModel = modelAccess.getOntModelSelector().getUserAccountsModel(); + ArmMigrator armMigrator = new ArmMigrator(contentRdfService, configurationRdfService, userAccountsModel); armMigrator.migrateConfiguration(); } @@ -93,20 +120,16 @@ private boolean isMigrationRequired() { } private boolean isArmConfiguration() { - ArmMigrator armMigrator = new ArmMigrator(contentRdfService, configurationRdfService); + OntModel userAccountsModel = modelAccess.getOntModelSelector().getUserAccountsModel(); + ArmMigrator armMigrator = new ArmMigrator(contentRdfService, configurationRdfService, userAccountsModel); return armMigrator.isArmConfiguation(); } protected long getVersion() { long version = 0L; - String query = "" + "prefix rdf: \n" - + "prefix ao: \n" - + "SELECT ?version \n" + "WHERE {\n" - + " GRAPH {\n" - + " ?configuration rdf:type ao:Configuration .\n" - + " ?configuration ao:version ?version .\n" + " }\n" + "}"; + try { - ResultSet rs = RDFServiceUtils.sparqlSelectQuery(query, configurationRdfService); + ResultSet rs = RDFServiceUtils.sparqlSelectQuery(VERSION_QUERY, configurationRdfService); while (rs.hasNext()) { QuerySolution qs = rs.next(); if (!qs.contains("version") || !qs.get("version").isLiteral()) { @@ -121,20 +144,13 @@ protected long getVersion() { } protected void removeVersion(long version) { - String template = "" + "@prefix rdf: .\n" - + " " - + " " + "?version ."; - ParameterizedSparqlString pss = new ParameterizedSparqlString(template); + ParameterizedSparqlString pss = new ParameterizedSparqlString(REMOVE_VERSION_TEMPLATE); pss.setLiteral("version", version); PolicyLoader.getInstance().updateAccessControlModel(pss.toString(), false); } protected void setVersion(long version) { - String template = "" + "@prefix rdf: .\n" - + "@prefix ao: .\n" - + " " - + "rdf:type ao:Configuration ;\n" + "ao:version ?version ."; - ParameterizedSparqlString pss = new ParameterizedSparqlString(template); + ParameterizedSparqlString pss = new ParameterizedSparqlString(SET_VERSION_TEMPLATE); pss.setLiteral("version", version); PolicyLoader.getInstance().updateAccessControlModel(pss.toString(), true); } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/migration/auth/SimplePermissionMigrator.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/migration/auth/SimplePermissionMigrator.java new file mode 100644 index 0000000000..2561406732 --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/migration/auth/SimplePermissionMigrator.java @@ -0,0 +1,115 @@ +package edu.cornell.mannlib.vitro.webapp.migration.auth; + +import java.util.HashSet; +import java.util.Set; + +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.PolicyLoader; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.jena.ontology.OntModel; +import org.apache.jena.query.ParameterizedSparqlString; +import org.apache.jena.query.QueryExecution; +import org.apache.jena.query.QueryExecutionFactory; +import org.apache.jena.query.QuerySolution; +import org.apache.jena.query.ResultSet; + +public class SimplePermissionMigrator { + + private static final Log log = LogFactory.getLog(SimplePermissionMigrator.class); + + private OntModel userAccountsModel; + + private String PERMISSION_SETS_QUERY = "" + + "prefix auth: \n" + + "SELECT ?uri \n" + + "WHERE {\n" + + " ?uri a auth:PermissionSet . \n" + + "}"; + + private String ROLE_PERMISSIONS_QUERY = "" + + "prefix auth: \n" + + "SELECT ?permission \n" + + "WHERE {\n" + + " ?role a auth:PermissionSet . \n" + + " ?role auth:hasPermission ?permission .\n" + + "}"; + + + public SimplePermissionMigrator(OntModel userAccountsModel) { + this.userAccountsModel = userAccountsModel; + } + + public void migrateConfiguration() { + Set roles = getPermissionSets(); + PolicyLoader policyLoader = PolicyLoader.getInstance(); + for (String role : roles) { + // get all simple permissions for role + Set policyPermissions = + policyLoader.getDataSetValues(AccessOperation.EXECUTE, AccessObjectType.NAMED_OBJECT, role); + // Compare with simple permissions in access control graph + Set userAccountsPermissions = getUserAccountsPermissions(role); + Set toRevoke = new HashSet<>(policyPermissions); + toRevoke.removeAll(userAccountsPermissions); + Set toGrant = new HashSet<>(userAccountsPermissions); + toGrant.removeAll(policyPermissions); + for (String entityUri : toGrant) { + policyLoader.addEntityToPolicyDataSet(entityUri, AccessObjectType.NAMED_OBJECT, AccessOperation.EXECUTE, + role); + log.info(String.format("Granted simple permission %s to role %s ", entityUri, role )); + } + for (String entityUri : toRevoke) { + policyLoader.removeEntityFromPolicyDataSet(entityUri, AccessObjectType.NAMED_OBJECT, + AccessOperation.EXECUTE, role); + log.info(String.format("Revoked simple permission %s from role %s ", entityUri, role )); + } + } + } + + Set getPermissionSets() { + Set permissionSets = new HashSet<>(); + String queryText = PERMISSION_SETS_QUERY; + userAccountsModel.enterCriticalSection(false); + try { + QueryExecution qexec = QueryExecutionFactory.create(queryText, userAccountsModel); + try { + ResultSet results = qexec.execSelect(); + while (results.hasNext()) { + QuerySolution qs = results.next(); + String entity = qs.getResource("uri").getURI(); + permissionSets.add(entity); + } + } finally { + qexec.close(); + } + } finally { + userAccountsModel.leaveCriticalSection(); + } + return permissionSets; + } + + Set getUserAccountsPermissions(String role) { + Set permissions = new HashSet<>(); + ParameterizedSparqlString pss = new ParameterizedSparqlString(ROLE_PERMISSIONS_QUERY); + pss.setIri("role", role); + String queryText = pss.toString(); + userAccountsModel.enterCriticalSection(false); + try { + QueryExecution qexec = QueryExecutionFactory.create(queryText, userAccountsModel); + try { + ResultSet results = qexec.execSelect(); + while (results.hasNext()) { + QuerySolution qs = results.next(); + String entity = qs.getResource("permission").getURI(); + permissions.add(entity); + } + } finally { + qexec.close(); + } + } finally { + userAccountsModel.leaveCriticalSection(); + } + return permissions; + } +} diff --git a/api/src/test/java/edu/cornell/mannlib/vitro/webapp/auth/policy/SimplePermissionTemplateTest.java b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/auth/policy/SimplePermissionTemplateTest.java index 80d687b7e5..c042e0098a 100644 --- a/api/src/test/java/edu/cornell/mannlib/vitro/webapp/auth/policy/SimplePermissionTemplateTest.java +++ b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/auth/policy/SimplePermissionTemplateTest.java @@ -6,6 +6,7 @@ import java.util.Arrays; 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.SimplePermission; import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.DecisionResult; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.SimpleAuthorizationRequest; @@ -134,7 +135,7 @@ public void testCustomRole() { PolicyTemplateController.createRoleDataSets(CUSTOM); // Get data set uri by key: role uri and named object String dataSetUri = loader.getDataSetUriByKey(new String[] { CUSTOM }, - new String[] { AccessObjectType.NAMED_OBJECT.toString() }); + new String[] { AccessObjectType.NAMED_OBJECT.toString(), AccessOperation.EXECUTE.toString() }); assertTrue(dataSetUri != null); DynamicPolicy policy = loader.loadPolicyFromTemplateDataSet(dataSetUri); diff --git a/api/src/test/java/edu/cornell/mannlib/vitro/webapp/migration/auth/ArmMigratorTest.java b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/migration/auth/ArmMigratorTest.java index eb813a4464..de586f9412 100644 --- a/api/src/test/java/edu/cornell/mannlib/vitro/webapp/migration/auth/ArmMigratorTest.java +++ b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/migration/auth/ArmMigratorTest.java @@ -17,7 +17,7 @@ import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames; import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.model.RDFServiceModel; import org.apache.commons.lang3.StringUtils; -import org.apache.jena.rdf.model.Model; +import org.apache.jena.ontology.OntModel; import org.apache.jena.rdf.model.ModelFactory; import org.apache.jena.rdf.model.Statement; import org.apache.jena.rdf.model.impl.PropertyImpl; @@ -33,17 +33,18 @@ public class ArmMigratorTest extends AuthMigratorTest { private static final String DATA_PROPERTY_URI = "http://vivoweb.org/ontology/core#abbreviation"; private static final String CLASS_URI = "http://xmlns.com/foaf/0.1/Organization"; private static final String OBJECT_PROPERTY_URI = "http://purl.obolibrary.org/obo/RO_0000053"; - private Model userAccountsModel; + private OntModel userAccountsModel; private ArmMigrator armMigrator; private String propertyUri = "http://vitro.mannlib.cornell.edu/ns/vitro/authorization#forEntity"; private String dataValue = "https://vivoweb.org/ontology/vitro-application/auth/vocabulary/dataValue"; @Before public void initArmMigration() { - userAccountsModel = ModelFactory.createDefaultModel(); + userAccountsModel = ModelFactory.createOntologyModel(); configurationDataSet.addNamedModel(ModelNames.USER_ACCOUNTS, userAccountsModel); addUserAccountsStatement(PolicyTest.CUSTOM, VitroVocabulary.PERMISSIONSET, VitroVocabulary.RDF_TYPE); - armMigrator = new ArmMigrator(new RDFServiceModel(contentModel), new RDFServiceModel(configurationDataSet)); + armMigrator = new ArmMigrator(new RDFServiceModel(contentModel), new RDFServiceModel(configurationDataSet), + userAccountsModel); } @Test diff --git a/api/src/test/java/edu/cornell/mannlib/vitro/webapp/migration/auth/SimplePermissionMigratorTest.java b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/migration/auth/SimplePermissionMigratorTest.java new file mode 100644 index 0000000000..87a8535500 --- /dev/null +++ b/api/src/test/java/edu/cornell/mannlib/vitro/webapp/migration/auth/SimplePermissionMigratorTest.java @@ -0,0 +1,104 @@ +package edu.cornell.mannlib.vitro.webapp.migration.auth; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Set; + +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.SimplePermission; +import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyLoader; +import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyTemplateController; +import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyTest; +import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames; +import org.apache.jena.ontology.OntModel; +import org.apache.jena.rdf.model.ModelFactory; +import org.apache.jena.rdf.model.Statement; +import org.apache.jena.rdf.model.impl.PropertyImpl; +import org.apache.jena.rdf.model.impl.ResourceImpl; +import org.apache.jena.rdf.model.impl.StatementImpl; +import org.junit.Before; +import org.junit.Test; + +public class SimplePermissionMigratorTest extends AuthMigratorTest { + + private OntModel userAccountsModel; + private SimplePermissionMigrator spm; + private static final String TEMPLATE_PATH = "template_simple_permissions"; + public static final String ADMIN_SIMPLE_PERMISSIONS_PATH = "simple_permissions_admin"; + public static final String CURATOR_SIMPLE_PERMISSIONS_PATH = "simple_permissions_curator"; + public static final String EDITOR_SIMPLE_PERMISSIONS_PATH = "simple_permissions_editor"; + public static final String SELF_EDITOR_SIMPLE_PERMISSIONS_PATH = "simple_permissions_self_editor"; + public static final String PUBLIC_SIMPLE_PERMISSIONS_PATH = "simple_permissions_public"; + + @Before + public void initMigration() { + userAccountsModel = ModelFactory.createOntologyModel(); + configurationDataSet.addNamedModel(ModelNames.USER_ACCOUNTS, userAccountsModel); + spm = new SimplePermissionMigrator(userAccountsModel); + load(PolicyTest.USER_ACCOUNTS_HOME_FIRSTTIME + TEMPLATE_PATH + EXT); + } + + private void addUserAccountsStatement(String subjUri, String pUri, String objUri) { + Statement statement = + new StatementImpl(new ResourceImpl(subjUri), new PropertyImpl(pUri), new ResourceImpl(objUri)); + userAccountsModel.add(statement); + } + + @Test + public void getPermissionSetsTest() { + addUserAccountsStatement(PolicyTest.CUSTOM, VitroVocabulary.RDF_TYPE, VitroVocabulary.PERMISSIONSET); + addUserAccountsStatement(PolicyTest.ADMIN, VitroVocabulary.RDF_TYPE, VitroVocabulary.PERMISSIONSET); + addUserAccountsStatement(PolicyTest.CURATOR, VitroVocabulary.RDF_TYPE, VitroVocabulary.PERMISSIONSET); + addUserAccountsStatement(PolicyTest.EDITOR, VitroVocabulary.RDF_TYPE, VitroVocabulary.PERMISSIONSET); + addUserAccountsStatement(PolicyTest.SELF_EDITOR, VitroVocabulary.RDF_TYPE, VitroVocabulary.PERMISSIONSET); + Set sets = spm.getPermissionSets(); + assertEquals(5, sets.size()); + assertTrue(sets.contains(PolicyTest.CUSTOM)); + assertTrue(sets.contains(PolicyTest.ADMIN)); + assertTrue(sets.contains(PolicyTest.CURATOR)); + assertTrue(sets.contains(PolicyTest.EDITOR)); + assertTrue(sets.contains(PolicyTest.SELF_EDITOR)); + } + + @Test + public void getUserAccountPermissionsTest() { + addUserAccountsStatement(PolicyTest.CUSTOM, VitroVocabulary.RDF_TYPE, VitroVocabulary.PERMISSIONSET); + addUserAccountsStatement(PolicyTest.ADMIN, VitroVocabulary.RDF_TYPE, VitroVocabulary.PERMISSIONSET); + addUserAccountsStatement(PolicyTest.CUSTOM, VitroVocabulary.PERMISSIONSET_HAS_PERMISSION, + SimplePermission.ACCESS_SPECIAL_DATA_MODELS.getUri()); + addUserAccountsStatement(PolicyTest.CUSTOM, VitroVocabulary.PERMISSIONSET_HAS_PERMISSION, + SimplePermission.DO_BACK_END_EDITING.getUri()); + Set permissions = spm.getUserAccountsPermissions(PolicyTest.CUSTOM); + assertEquals(2, permissions.size()); + assertTrue(permissions.contains(SimplePermission.ACCESS_SPECIAL_DATA_MODELS.getUri())); + assertTrue(permissions.contains(SimplePermission.DO_BACK_END_EDITING.getUri())); + permissions = spm.getUserAccountsPermissions(PolicyTest.ADMIN); + assertEquals(0, permissions.size()); + } + + @Test + public void migrateConfigurationTest() { + addUserAccountsStatement(PolicyTest.CUSTOM, VitroVocabulary.RDF_TYPE, VitroVocabulary.PERMISSIONSET); + addUserAccountsStatement(PolicyTest.CUSTOM, VitroVocabulary.PERMISSIONSET_HAS_PERMISSION, + SimplePermission.ACCESS_SPECIAL_DATA_MODELS.getUri()); + addUserAccountsStatement(PolicyTest.PUBLIC, VitroVocabulary.RDF_TYPE, VitroVocabulary.PERMISSIONSET); + addUserAccountsStatement(PolicyTest.PUBLIC, VitroVocabulary.PERMISSIONSET_HAS_PERMISSION, + SimplePermission.ACCESS_SPECIAL_DATA_MODELS.getUri()); + load(USER_ACCOUNTS_HOME_FIRSTTIME + PUBLIC_SIMPLE_PERMISSIONS_PATH + EXT); + PolicyTemplateController.createRoleDataSets(CUSTOM); + spm.migrateConfiguration(); + PolicyLoader policyLoader = PolicyLoader.getInstance(); + Set entities = policyLoader.getDataSetValues(AccessOperation.EXECUTE, AccessObjectType.NAMED_OBJECT, + PolicyTest.CUSTOM); + assertEquals(1, entities.size()); + assertTrue(entities.contains(SimplePermission.ACCESS_SPECIAL_DATA_MODELS.getUri())); + entities = policyLoader.getDataSetValues(AccessOperation.EXECUTE, AccessObjectType.NAMED_OBJECT, + PolicyTest.PUBLIC); + assertEquals(1, entities.size()); + assertTrue(entities.contains(SimplePermission.ACCESS_SPECIAL_DATA_MODELS.getUri())); + } + +} diff --git a/home/src/main/resources/rdf/accessControl/firsttime/template_simple_permissions.n3 b/home/src/main/resources/rdf/accessControl/firsttime/template_simple_permissions.n3 index 227d9edfcf..7c8cdde7cb 100644 --- a/home/src/main/resources/rdf/accessControl/firsttime/template_simple_permissions.n3 +++ b/home/src/main/resources/rdf/accessControl/firsttime/template_simple_permissions.n3 @@ -36,6 +36,7 @@ :RoleDataSetKeyTemplate a ao:DataSetKeyTemplate ; ao:keyComponent ai:NamedObject ; + ao:keyComponent ai:ExecuteOperation ; ao:keyComponentTemplate ai:SubjectRole . :RoleValueContainerTemplate a ao:ValueContainerTemplate ; @@ -58,6 +59,7 @@ :PublicDataSetKey a ao:DataSetKey ; ao:keyComponent ai:NamedObject ; + ao:keyComponent ai:ExecuteOperation ; ao:keyComponent auth:PUBLIC . :SelfEditorDataSet a ao:PolicyDataSet ; @@ -67,6 +69,7 @@ :SelfEditorDataSetKey a ao:DataSetKey ; ao:keyComponent ai:NamedObject ; + ao:keyComponent ai:ExecuteOperation ; ao:keyComponent auth:SELF_EDITOR . :EditorDataSet a ao:PolicyDataSet ; @@ -76,6 +79,7 @@ :EditorDataSetKey a ao:DataSetKey ; ao:keyComponent ai:NamedObject ; + ao:keyComponent ai:ExecuteOperation ; ao:keyComponent auth:EDITOR . :CuratorDataSet a ao:PolicyDataSet ; @@ -85,6 +89,7 @@ :CuratorDataSetKey a ao:DataSetKey ; ao:keyComponent ai:NamedObject ; + ao:keyComponent ai:ExecuteOperation ; ao:keyComponent auth:CURATOR . :AdminDataSet a ao:PolicyDataSet ; @@ -94,6 +99,7 @@ :AdminDataSetKey a ao:DataSetKey ; ao:keyComponent ai:NamedObject ; + ao:keyComponent ai:ExecuteOperation ; ao:keyComponent auth:ADMIN . :RuleSet a ao:Rules ;