Skip to content

Commit

Permalink
Merge branch 'main' into feature/jquery-update
Browse files Browse the repository at this point in the history
  • Loading branch information
gneissone committed Jun 4, 2024
2 parents 22a835f + f20881e commit 04db538
Show file tree
Hide file tree
Showing 142 changed files with 2,585 additions and 21,387 deletions.
36 changes: 32 additions & 4 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,39 @@ A description of what steps someone could take to:
Any additional information that you think would be helpful when reviewing this PR.

Example:
* Does this change require documentation to be updated?
* Does this change add any new dependencies?
* Does this change require any other modifications to be made to the repository?
* Does this change require documentation to be updated?
* Does this change add any new dependencies?
* Does this change require any other modifications to be made to the repository?
* Could this change impact execution of existing code?
* Large pull requests should be avoided. If this PR is large (more than 1,000 lines of codes), please provide short explanation why your contribution can't be decoupled in smaller PRs.
* Large pull requests should be avoided. If this PR is large (more than 1,000 lines of codes), please provide short explanation why your contribution can't be decoupled in smaller PRs.

# Interested parties
Tag (@ mention) interested parties or, if unsure, @VIVO-project/vivo-committers

# Reviewers' expertise
**Please add any new expertise in the list which might be needed for reviewing your PR or remove any of the listed if it is not needed.**

Candidates for reviewing this PR should have some of the following expertises:
1. Java
1. HTML, CSS, JavaScript
1. FreeMarker
1. SPARQL
1. Ontologies
1. Docker
1. Natural language knowledge
1. English
2. German
3. Spanish
4. French
5. Portuguese
6. Russian
7. Serbian

# Reviewers' report template
**Please update the following template which should be used by reviewers.**
## General comment
A reviewer should provide here comments and suggestions for requested changes if any.
## Testing
A reviewer should briefly describe here how it was tested
## Code reviewing
A reviewer should briefly describe here which part was code reviewed
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ utilities/sdb_to_tdb/.work
**/overlays
*~

**/.DS_Store

# Eclipse artifacts
**/.settings
**/.classpath
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

package edu.cornell.mannlib.vedit.beans;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

Expand Down Expand Up @@ -100,9 +99,7 @@ public static UserAccount getCurrentUser(HttpSession session) {
if (!getBean(session).isLoggedIn()) {
return null;
}

ServletContext ctx = session.getServletContext();
WebappDaoFactory wadf = ModelAccess.on(ctx).getWebappDaoFactory();
WebappDaoFactory wadf = ModelAccess.getInstance().getWebappDaoFactory();
UserAccountsDao userAccountsDao = wadf.getUserAccountsDao();
if (userAccountsDao == null) {
log.error("No UserAccountsDao");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import edu.cornell.mannlib.vitro.webapp.auth.attributes.AttributeValueSet;
import edu.cornell.mannlib.vitro.webapp.auth.objects.AccessObject;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest;
import edu.cornell.mannlib.vitro.webapp.beans.SelfEditingConfiguration;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
Expand All @@ -26,47 +27,77 @@
import org.apache.jena.rdf.model.RDFNode;

public class SparqlSelectQueryResultsChecker {
private static final String PROFILE_URI = "profileUri";
private static final String EXTERNAL_AUTH_ID = "externalAuthId";
private static final String MATCHING_PROPERTY_URI = "matchingPropertyUri";
private static final String OBJECT_URI = "objectUri";
private static final Log log = LogFactory.getLog(SparqlSelectQueryResultsChecker.class);

public static boolean sparqlSelectQueryResultsContain(Check check, AuthorizationRequest ar, String[] inputValues) {
String queryTemplate = check.getConfiguration();
if (StringUtils.isBlank(queryTemplate)) {
queryTemplate = check.getValues().getSingleValue();
}
if (StringUtils.isBlank(queryTemplate)) {
log.error("SparqlQueryContains template is empty");
return false;
String query = check.getConfiguration();
if (StringUtils.isBlank(query)) {
query = check.getValues().getSingleValue();
if (StringUtils.isBlank(query)) {
log.error("Sparql query is empty.");
return false;
}
}

AccessObject ao = ar.getAccessObject();
Model m = ao.getModel();
if (m == null) {
log.debug("SparqlQueryContains model is not provided");
return false;
}
Set<String> profileUris = new HashSet<String>(ar.getEditorUris());
if (profileUris.isEmpty()) {
if (queryTemplate.contains("?profileUri")) {
log.debug("Subject has no person URIs");
return false;
} else {
profileUris.add("");
}
}

Set<String> comparedValues = new HashSet<>();

if (isQueryNotProvidedInConfiguration(check)) {
addRelatedUrisToComparedValues(ao, comparedValues);
} else {
addValuesToComparedValues(check.getValues(), comparedValues);
}

if (isProfileUriRelatedQuery(query)) {
return makeProfileUriMatchQuery(ar, query, m, comparedValues);
}

if (query.contains("?" + EXTERNAL_AUTH_ID) && externalAuthIdIsNotAvailable(ar)) {
logVariableNotAvailable(EXTERNAL_AUTH_ID);
return false;
}

if (query.contains("?" + MATCHING_PROPERTY_URI) && matchingPropertyUriIsNotAvailable()) {
logVariableNotAvailable(MATCHING_PROPERTY_URI);
return false;
}

Set<String> sparqlResults = getSparqlSelectResults(m, "", query, ar);
sparqlResults.retainAll(comparedValues);
if (!sparqlResults.isEmpty()) {
return true;
}

return false;
}

private static boolean makeProfileUriMatchQuery(AuthorizationRequest ar, String queryTemplate, Model m,
Set<String> comparedValues) {
boolean result = false;
Set<String> profileUris = new HashSet<String>(ar.getEditorUris());
if (profileUris.isEmpty()) {
log.debug("Subject has no person Uri, nothing to substitute.");
result = false;
}
for (String profileUri : profileUris) {
Set<String> sparqlSelectResults = getSparqlSelectResults(m, profileUri, queryTemplate, ar);
Set<String> sparqlResults = getSparqlSelectResults(m, profileUri, queryTemplate, ar);
// Return true if intersection is not empty
comparedValues.retainAll(sparqlSelectResults);
if (!comparedValues.isEmpty()) {
return true;
sparqlResults.retainAll(comparedValues);
if (!sparqlResults.isEmpty()) {
result = true;
}
}
return false;
return result;
}

private static void addValuesToComparedValues(AttributeValueSet values, Set<String> comparedValues) {
Expand Down Expand Up @@ -115,11 +146,19 @@ private static Set<String> getSparqlSelectResults(Model model, String profileUri
}

private static void setVariables(String profileUri, AuthorizationRequest ar, ParameterizedSparqlString pss) {
pss.setIri("profileUri", profileUri);
pss.setIri(PROFILE_URI, profileUri);
AccessObject object = ar.getAccessObject();
Optional<String> uri = object.getUri();
if (uri.isPresent()) {
pss.setIri("objectUri", uri.get());
pss.setIri(OBJECT_URI, uri.get());
}
String externalAuthId = ar.getExternalAuthId();
if (!StringUtils.isBlank(externalAuthId)) {
pss.setLiteral(EXTERNAL_AUTH_ID, externalAuthId);
}
String matchingPropertyUri = SelfEditingConfiguration.getInstance().getMatchingPropertyUri();
if (!StringUtils.isBlank(matchingPropertyUri)) {
pss.setIri(MATCHING_PROPERTY_URI, matchingPropertyUri);
}
}

Expand All @@ -144,7 +183,7 @@ private static void debug(String queryText) {

private static String createQueryMapKey(String profileUri, String queryTemplate, AuthorizationRequest ar) {
String mapKey = queryTemplate + "." + profileUri;
if (queryTemplate.contains("?objectUri")) {
if (queryTemplate.contains("?" + OBJECT_URI)) {
AccessObject object = ar.getAccessObject();
Optional<String> uri = object.getUri();
if (uri.isPresent()) {
Expand All @@ -154,4 +193,22 @@ private static String createQueryMapKey(String profileUri, String queryTemplate,
return mapKey;
}

private static void logVariableNotAvailable(String variable) {
if (log.isDebugEnabled()) {
log.debug(String.format("Query contains ?%s, but authorization request doesn't provide it.", variable));
}
}

private static boolean externalAuthIdIsNotAvailable(AuthorizationRequest ar) {
return StringUtils.isBlank(ar.getExternalAuthId());
}

private static boolean matchingPropertyUriIsNotAvailable() {
return StringUtils.isBlank(SelfEditingConfiguration.getInstance().getMatchingPropertyUri());
}

private static boolean isProfileUriRelatedQuery(String queryTemplate) {
return queryTemplate.contains("?" + PROFILE_URI);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

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

import java.util.ArrayList;
import java.util.List;

import edu.cornell.mannlib.vitro.webapp.auth.attributes.Attribute;
import edu.cornell.mannlib.vitro.webapp.auth.attributes.AttributeValueSet;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

Expand All @@ -20,7 +22,10 @@ public SubjectRoleCheck(String uri, AttributeValueSet values) {

@Override
public boolean check(AuthorizationRequest ar) {
final List<String> inputValues = ar.getRoleUris();
List<String> inputValues = new ArrayList<String>(ar.getRoleUris());
if (inputValues.isEmpty()) {
inputValues.add(VitroVocabulary.ROLE_PUBLIC_URI);
}
if (AttributeValueChecker.test(this, ar, inputValues.toArray(new String[0]))) {
log.debug("Attribute match requested '" + inputValues + "'");
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

import edu.cornell.mannlib.vitro.webapp.auth.attributes.Attribute;
import edu.cornell.mannlib.vitro.webapp.auth.attributes.AttributeValueSet;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.IsRootUser;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
Expand All @@ -20,8 +18,7 @@ public SubjectTypeCheck(String uri, AttributeValueSet values) {

@Override
public boolean check(AuthorizationRequest ar) {
IdentifierBundle ac_subject = ar.getIds();
String inputValue = IsRootUser.isRootUser(ac_subject) ? "ROOT_USER" : "";
String inputValue = ar.isRootUser() ? "ROOT_USER" : "";
if (AttributeValueChecker.test(this, ar, inputValue)) {
log.debug("Attribute subject type match requested object type '");
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public static void revokeAccess(String entityUri, AccessObjectType aot, AccessOp
getLoader().updateAccessControlModel(toRemove, false);
}
} else {
reduceInactiveValueSet(entityUri, aot, ao, role);
reduceInactiveValueSet(entityUri, aot, ao, role, namedKeyComponents);
}
}

Expand All @@ -74,9 +74,9 @@ private static PolicyLoader getLoader() {
}

private static void reduceInactiveValueSet(String entityUri, AccessObjectType aot, AccessOperation ao,
String role) {
String role, String... namedKeyComponents) {
StringBuilder removals = new StringBuilder();
getDataValueStatements(entityUri, aot, ao, Collections.singleton(role), removals);
getDataValueStatements(entityUri, aot, ao, Collections.singleton(role), removals, namedKeyComponents);
getLoader().updateAccessControlModel(removals.toString(), false);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
import java.util.regex.Pattern;

import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessOperation;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
import edu.cornell.mannlib.vitro.webapp.auth.objects.AccessObject;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Policy;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest;
import edu.cornell.mannlib.vitro.webapp.beans.UserAccount;
import edu.cornell.mannlib.vitro.webapp.utils.developer.DeveloperSettings;
import edu.cornell.mannlib.vitro.webapp.utils.developer.Key;
import org.apache.commons.logging.Log;
Expand All @@ -33,7 +33,7 @@ public class PolicyDecisionLogger {
private final DeveloperSettings settings;
private final AccessObject object;
private final AccessOperation operation;
private final IdentifierBundle whoToAuth;
private final UserAccount whoToAuth;

private final boolean enabled;

Expand All @@ -43,7 +43,7 @@ public class PolicyDecisionLogger {

public PolicyDecisionLogger(AuthorizationRequest ar) {
this.settings = DeveloperSettings.getInstance();
this.whoToAuth = ar.getIds();
this.whoToAuth = ar.getUserAccount();
this.object = ar.getAccessObject();
this.operation = ar.getAccessOperation();

Expand All @@ -67,7 +67,7 @@ private boolean figureEnabled() {
*/
private boolean passesUserRestriction() {
Pattern userRestriction = compilePatternFromSetting(Key.AUTHORIZATION_LOG_DECISIONS_USER_RESTRICTION);
return userRestriction == null || userRestriction.matcher(String.valueOf(whoToAuth)).find();
return userRestriction == null || userRestriction.matcher(String.valueOf(whoToAuth.getUri())).find();
}

/**
Expand Down Expand Up @@ -126,7 +126,7 @@ public void log(Policy policy, PolicyDecision pd) {
if (passesRestrictions(String.valueOf(policy), pd)) {
if (this.includeIdentifiers) {
log.info(String.format("Decision on %s %s by %s was %s; user is %s", this.operation, this.object,
policy.getShortUri(), pd, this.whoToAuth));
policy.getShortUri(), pd, getUser()));
} else {
log.info(String.format("Decision on %s %s by %s was %s", this.operation, this.object,
policy.getShortUri(), pd));
Expand Down Expand Up @@ -156,10 +156,14 @@ private boolean isInconclusive(PolicyDecision pd) {
public void logNoDecision(PolicyDecision pd) {
if (enabled) {
if (this.includeIdentifiers) {
log.info(pd.getMessage() + "; user is " + this.whoToAuth);
log.info(pd.getMessage() + "; user is " + getUser());
} else {
log.info(pd.getMessage());
}
}
}

private String getUser() {
return whoToAuth.getLastName() + ", " + whoToAuth.getFirstName() + " uri:'" + whoToAuth.getUri() + "'";
}
}
Loading

0 comments on commit 04db538

Please sign in to comment.