Skip to content

Commit

Permalink
Role based search results filtering (vivo-project#434)
Browse files Browse the repository at this point in the history
* refact: moved Role URIs to VitroVocabulary

* remove mistakenly commited settings

* Replaced search:defaultPublic data property with isDefaultForRole to apply default filters not only to public role, but to any role.

* use VITRO_AUTH prefix in VitroVocabulary role URIs

---------

Co-authored-by: Georgy Litvinov <[email protected]>
  • Loading branch information
litvinovg and litvinovg authored Dec 22, 2023
1 parent d37e594 commit d3903af
Show file tree
Hide file tree
Showing 10 changed files with 73 additions and 1,068 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -261,4 +261,10 @@ public enum Precision {
}
public String uri(){return URI;}
}

public static final String ROLE_PUBLIC_URI = VITRO_AUTH + "PUBLIC";
public static final String ROLE_SELF_EDITOR_URI = VITRO_AUTH + "SELF_EDITOR";
public static final String ROLE_EDITOR_URI = VITRO_AUTH + "EDITOR";
public static final String ROLE_CURATOR_URI = VITRO_AUTH + "CURATOR";
public static final String ROLE_ADMIN_URI = VITRO_AUTH + "ADMIN";
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package edu.cornell.mannlib.vitro.webapp.migration.auth;

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;
import static edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary.ROLE_PUBLIC_URI;
import static edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary.ROLE_SELF_EDITOR_URI;
import static edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary.VITRO_AUTH;
import static edu.cornell.mannlib.vitro.webapp.migration.auth.AuthMigrator.ALL_ROLES;
import static edu.cornell.mannlib.vitro.webapp.migration.auth.AuthMigrator.ROLE_ADMIN_URI;
import static edu.cornell.mannlib.vitro.webapp.migration.auth.AuthMigrator.ROLE_CURATOR_URI;
import static edu.cornell.mannlib.vitro.webapp.migration.auth.AuthMigrator.ROLE_EDITOR_URI;
import static edu.cornell.mannlib.vitro.webapp.migration.auth.AuthMigrator.ROLE_PUBLIC_URI;
import static edu.cornell.mannlib.vitro.webapp.migration.auth.AuthMigrator.ROLE_SELF_EDITOR_URI;

import java.util.Arrays;
import java.util.Collections;
Expand All @@ -31,10 +32,7 @@

public class AnnotationMigrator {

private static final String ROLE_PREFIX = "http://vitro.mannlib.cornell.edu/ns/vitro/authorization#";

private static final Log log = LogFactory.getLog(AnnotationMigrator.class);

private static final String PREFIX = "http://vitro.mannlib.cornell.edu/ns/vitro/role#";
private static final String OLD_ROLE_PUBLIC = PREFIX + "public";
private static final String OLD_ROLE_SELF = PREFIX + "selfEditor";
Expand Down Expand Up @@ -219,8 +217,8 @@ private static Object rolesToString(Set<String> roles) {
String result = "";
for (String roleUri : roles) {
String roleName = roleUri;
if (roleName.startsWith(ROLE_PREFIX)) {
roleName = roleName.substring(ROLE_PREFIX.length());
if (roleName.startsWith(VITRO_AUTH)) {
roleName = roleName.substring(VITRO_AUTH.length());
}
if (!result.isEmpty()) {
result += ", ";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
package edu.cornell.mannlib.vitro.webapp.migration.auth;

import static edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary.LABEL;
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;
import static edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary.ROLE_PUBLIC_URI;
import static edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary.ROLE_SELF_EDITOR_URI;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
Expand All @@ -14,7 +21,6 @@
import edu.cornell.mannlib.vitro.webapp.auth.policy.EntityPolicyController;
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyLoader;
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyTemplateController;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils;
Expand Down Expand Up @@ -79,11 +85,11 @@ public ArmMigrator(RDFService contentRdfService, RDFService configurationRdfServ
operationMap.put(PUBLISH, OperationGroup.PUBLISH_GROUP);

roleMap = new HashMap<>();
roleMap.put(ARM_ADMIN, AuthMigrator.ROLE_ADMIN_URI);
roleMap.put(ARM_CURATOR, AuthMigrator.ROLE_CURATOR_URI);
roleMap.put(ARM_EDITOR, AuthMigrator.ROLE_EDITOR_URI);
roleMap.put(ARM_SELF_EDITOR, AuthMigrator.ROLE_SELF_EDITOR_URI);
roleMap.put(ARM_PUBLIC, AuthMigrator.ROLE_PUBLIC_URI);
roleMap.put(ARM_ADMIN, ROLE_ADMIN_URI);
roleMap.put(ARM_CURATOR, ROLE_CURATOR_URI);
roleMap.put(ARM_EDITOR, ROLE_EDITOR_URI);
roleMap.put(ARM_SELF_EDITOR, ROLE_SELF_EDITOR_URI);
roleMap.put(ARM_PUBLIC, ROLE_PUBLIC_URI);
Set<String> actualRoles = getPermissionSets();
for (String role : actualRoles) {
if (!roleMap.values().contains(role)) {
Expand Down Expand Up @@ -223,7 +229,7 @@ private void getRoleOperationObjectTypedStatementsToAdd(Map<AccessObjectType, Se
//Allow any role to display/update/publish rdfs:label
//with exception to public role and update/publish operations groups
if (!(ARM_PUBLIC.equals(role) && !OperationGroup.DISPLAY_GROUP.equals(og))) {
intersectionEntities.add(VitroVocabulary.LABEL);
intersectionEntities.add(LABEL);
}
}
if (AccessObjectType.FAUX_OBJECT_PROPERTY.equals(type)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

package edu.cornell.mannlib.vitro.webapp.migration.auth;

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;
import static edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary.ROLE_PUBLIC_URI;
import static edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary.ROLE_SELF_EDITOR_URI;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
Expand All @@ -27,11 +33,6 @@
public class AuthMigrator implements ServletContextListener {

private static final Log log = LogFactory.getLog(AuthMigrator.class);
protected static final String ROLE_ADMIN_URI = "http://vitro.mannlib.cornell.edu/ns/vitro/authorization#ADMIN";
protected static final String ROLE_CURATOR_URI = "http://vitro.mannlib.cornell.edu/ns/vitro/authorization#CURATOR";
protected static final String ROLE_EDITOR_URI = "http://vitro.mannlib.cornell.edu/ns/vitro/authorization#EDITOR";
protected static final String ROLE_SELF_EDITOR_URI = "http://vitro.mannlib.cornell.edu/ns/vitro/authorization#SELF_EDITOR";
protected static final String ROLE_PUBLIC_URI = "http://vitro.mannlib.cornell.edu/ns/vitro/authorization#PUBLIC";
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
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package edu.cornell.mannlib.vitro.webapp.migration.auth;

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;
import static edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary.ROLE_PUBLIC_URI;
import static edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary.ROLE_SELF_EDITOR_URI;
import static edu.cornell.mannlib.vitro.webapp.migration.auth.AuthMigrator.ALL_ROLES;
import static edu.cornell.mannlib.vitro.webapp.migration.auth.AuthMigrator.ROLE_ADMIN_URI;
import static edu.cornell.mannlib.vitro.webapp.migration.auth.AuthMigrator.ROLE_CURATOR_URI;
import static edu.cornell.mannlib.vitro.webapp.migration.auth.AuthMigrator.ROLE_EDITOR_URI;
import static edu.cornell.mannlib.vitro.webapp.migration.auth.AuthMigrator.ROLE_PUBLIC_URI;
import static edu.cornell.mannlib.vitro.webapp.migration.auth.AuthMigrator.ROLE_SELF_EDITOR_URI;

import java.util.Arrays;
import java.util.HashMap;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class FilterValue {

private boolean selected = false;

private boolean defaultPublic;
private boolean isDefaultValue;

private boolean publiclyAvailable = true;

Expand All @@ -32,8 +32,8 @@ public FilterValue(String id) {
this.id = id;
}

public boolean isDefaultPublic() {
return defaultPublic;
public boolean isDefault() {
return isDefaultValue;
}

public String getName() {
Expand Down Expand Up @@ -80,7 +80,7 @@ public boolean getSelected() {
return selected;
}

public void setDefaultPublic(boolean b) {
defaultPublic = b;
public void setDefault(boolean b) {
isDefaultValue = b;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package edu.cornell.mannlib.vitro.webapp.search.controller;

import static edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary.ROLE_PUBLIC_URI;

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
Expand All @@ -10,6 +13,7 @@
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -45,11 +49,10 @@ public class SearchFiltering {

private static final String FILTER_QUERY = ""
+ "PREFIX search: <https://vivoweb.org/ontology/vitro-search#>\n"
+ "PREFIX gesah: <http://ontology.tib.eu/gesah/>\n"
+ "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n"
+ "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n"
+ "SELECT ?filter_id ?filter_type ?filter_label ?value_label ?value_id ?field_name ?public ?filter_order "
+ "?value_order (STR(?isUriReq) as ?isUri ) ?multivalued ?input ?regex ?facet ?min ?max ?public_default "
+ "?value_order (STR(?isUriReq) as ?isUri ) ?multivalued ?input ?regex ?facet ?min ?max ?role "
+ "?value_public ?more_limit \n"
+ "WHERE {\n"
+ " ?filter rdf:type search:Filter .\n"
Expand All @@ -58,15 +61,16 @@ public class SearchFiltering {
+ " ?filter a ?filter_type .\n"
+ " ?filter search:filterField ?field .\n"
+ " ?field search:indexField ?field_name .\n"
+ " OPTIONAL {?filter search:hasKnownValue ?value . \n"
+ " OPTIONAL {\n"
+ " ?filter search:hasKnownValue ?value . \n"
+ " ?value rdfs:label ?value_label .\n"
+ " ?value search:id ?value_id .\n"
+ " OPTIONAL {"
+ " ?value search:order ?v_order .\n"
+ " bind(?v_order as ?value_order_found).\n"
+ " }\n"
+ " OPTIONAL {\n"
+ " ?value search:defaultPublic ?public_default .\n"
+ " ?value search:isDefaultForRole ?role .\n"
+ " }\n"
+ " OPTIONAL {\n"
+ " ?value search:public ?value_public .\n"
Expand All @@ -92,7 +96,6 @@ public class SearchFiltering {
private static final String FILTER_GROUPS_QUERY = ""
+ "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n"
+ "PREFIX search: <https://vivoweb.org/ontology/vitro-search#>\n"
+ "PREFIX gesah: <http://ontology.tib.eu/gesah/>\n"
+ "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n"
+ "SELECT ?group_id (STR(?group_l) AS ?group_label) ?filter_id ?order ?filter_order ?public\n"
+ "WHERE {\n"
Expand All @@ -119,8 +122,7 @@ public class SearchFiltering {
private static final String SORT_QUERY = ""
+ "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n"
+ "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n"
+ "PREFIX gesah: <http://ontology.tib.eu/gesah/>\n"
+ "Prefix search: <https://vivoweb.org/ontology/vitro-search#> \n"
+ "PREFIX search: <https://vivoweb.org/ontology/vitro-search#> \n"
+ "SELECT ( STR(?sort_label) as ?label ) ?id ?searchField ?multilingual ?isAsc ?sort_order \n"
+ "WHERE {\n"
+ " ?sort rdf:type search:Sort . \n"
Expand Down Expand Up @@ -176,7 +178,7 @@ public static void addFiltersToQuery(VitroRequest vreq, SearchQuery query, Map<S
SearchFiltering.addRangeFilter(query, searchFilter);
}
for (FilterValue fv : searchFilter.getValues().values()) {
if (fv.isDefaultPublic()) {
if (fv.isDefault()) {
query.addFilterQuery(searchFilter.getField() + ":\"" + fv.getId() + "\"");
}
}
Expand Down Expand Up @@ -240,15 +242,21 @@ public static Map<String, SearchFilter> readFilterConfigurations(VitroRequest vr
continue;
}
String valueId = solution.get("value_id").toString();
FilterValue value;
if (!filter.contains(valueId)) {
FilterValue value = new FilterValue(valueId);
value = new FilterValue(valueId);
value.setName(solution.get("value_label"));
value.setOrder(solution.get("value_order"));
value.setPubliclyAvailable(solution.get("value_public"));
filter.addValue(value);
RDFNode pubDefault = solution.get("public_default");
if (pubDefault != null && pubDefault.asLiteral().getBoolean() && isNotLoggedIn(vreq)) {
value.setDefaultPublic(true);
}
value = filter.getValue(valueId);
RDFNode role = solution.get("role");
if (role != null && role.isResource()) {
String roleUri = role.asResource().getURI();
Set<String> currentRoles = getCurrentUserRoles(vreq);
if (currentRoles.contains(roleUri)) {
value.setDefault(true);
}
}
}
Expand Down Expand Up @@ -489,9 +497,12 @@ private static void setSelectedFilters(Map<String, SearchFilter> filtersByField,
}
}

private static boolean isNotLoggedIn(VitroRequest vreq) {
private static Set<String> getCurrentUserRoles(VitroRequest vreq) {
UserAccount user = LoginStatusBean.getCurrentUser(vreq);
return user == null;
if (user == null) {
return Collections.singleton(ROLE_PUBLIC_URI);
}
return user.getPermissionSetUris();
}

static boolean isEmptyValues(List<String> requestedValues) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ search:facetResults rdfs:label "Show facet results"@en-US .
search:Sort rdfs:label "Sort"@en-US .
search:hasKnownValue rdfs:label "hasKnownValue"@en-US .
search:public rdfs:label "public"@en-US .
search:defaultPublic rdfs:label "Is default public value"@en-US .
search:isDefaultForRole rdfs:label "Is default for role"@en-US .
search:moreLimit rdfs:label "initial facet limit"@en-US .
8 changes: 4 additions & 4 deletions home/src/main/resources/rdf/tbox/filegraph/search_ontology.n3
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
@prefix ro: <http://purl.obolibrary.org/obo/ro.owl#> .
@prefix obo: <http://purl.obolibrary.org/obo/> .
@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix auth: <http://vitro.mannlib.cornell.edu/ns/vitro/authorization#> .

<https://vivoweb.org/ontology/vitro-search>
a owl:Ontology ;
Expand Down Expand Up @@ -129,11 +130,10 @@ search:public a owl:DatatypeProperty , owl:FunctionalPrope
rdfs:domain search:PublicParameter ;
rdfs:range xsd:boolean .

search:defaultPublic
a <http://www.w3.org/2002/07/owl#DatatypeProperty> , <http://www.w3.org/2002/07/owl#FunctionalProperty> ;
search:isDefaultForRole
a <http://www.w3.org/2002/07/owl#ObjectProperty> ;
rdfs:domain <https://vivoweb.org/ontology/vitro-search#FilterValue> ;
rdfs:range <http://www.w3.org/2001/XMLSchema#boolean> ;
rdfs:subPropertyOf <http://www.w3.org/2002/07/owl#topDataProperty> .
rdfs:range auth:PermissionSet .

search:moreLimit
a <http://www.w3.org/2002/07/owl#DatatypeProperty> , <http://www.w3.org/2002/07/owl#FunctionalProperty> ;
Expand Down
Loading

0 comments on commit d3903af

Please sign in to comment.