<commit_before>/* $This file is distributed under the terms of the license in /doc/license.txt$ */

package edu.cornell.mannlib.vivo.auth.policy;

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

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.hp.hpl.jena.ontology.OntModel;

import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasAssociatedIndividual;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ServletPolicyList;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface;
import edu.cornell.mannlib.vitro.webapp.auth.policy.specialrelationships.AbstractRelationshipPolicy;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractDataPropertyStatementAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractObjectPropertyStatementAction;

/**
 * Permit self-editors to edit the properties of classes with which they share a
 * special relationship. So for example:
 * 
 * A self-editor may edit properties of an InformationResource for which he is
 * an author, an editor, or in which he is featured.
 * 
 * A self-editor may edit properties of a Project in which he plays a clinical
 * role.
 * 
 * Etc.
 * 
 * NOTE: properties or resources which are restricted by namespace or by access
 * setting will still not be editable, even if this special relationship
 * applies.
 * 
 * NOTE: This could be further generalized by building a list of authorizing
 * relationships, where each relationship may specify a type of object, a
 * relating property (or chain of properties), and a text message describing the
 * relationship (to be used in the decision). We could go even farther and drive
 * this from an XML config file, so site administrators could configure it
 * themselves. A great tool for this is the one used to process the Tomcat
 * server.xml file, see http://commons.apache.org/digester/
 */
public class SelfEditorRelationshipPolicy extends AbstractRelationshipPolicy
		implements PolicyIface {
	private static final Log log = LogFactory
			.getLog(SelfEditorRelationshipPolicy.class);

	private static final String NS_CORE = "http://vivoweb.org/ontology/core#";
	private static final String URI_INFORMATION_RESOURCE_TYPE = NS_CORE
			+ "InformationResource";
	private static final String URI_EDITOR_PROPERTY = "http://purl.org/ontology/bibo/editor";
	private static final String URI_FEATURES_PROPERTY = NS_CORE + "features";
	private static final String URI_IN_AUTHORSHIP_PROPERTY = NS_CORE
			+ "informationResourceInAuthorship";
	private static final String URI_LINKED_AUTHOR_PROPERTY = NS_CORE
			+ "linkedAuthor";

	private static final String URI_GRANT_TYPE = NS_CORE + "Grant";
	private static final String URI_RELATED_ROLE_PROPERTY = NS_CORE
			+ "relatedRole";
	private static final String URI_PRINCIPAL_INVESTIGATOR_OF_PROPERTY = NS_CORE
			+ "principalInvestigatorRoleOf";
	private static final String URI_CO_PRINCIPAL_INVESTIGATOR_OF_PROPERTY = NS_CORE
			+ "co-PrincipalInvestigatorRoleOf";

	private static final String URI_PROJECT_TYPE = NS_CORE + "Project";
	private static final String URI_SERVICE_TYPE = NS_CORE + "Service";
	private static final String URI_CLINICAL_ROLE_OF_PROPERTY = NS_CORE
			+ "clinicalRoleOf";

	private static final String URI_PRESENTATION_TYPE = NS_CORE
			+ "Presentation";
	private static final String URI_PRESENTER_ROLE_OF_PROPERTY = NS_CORE
			+ "presenterRoleOf";

	private static final String URI_COURSE_TYPE = NS_CORE + "Course";
	private static final String URI_TEACHER_ROLE_OF_PROPERTY = NS_CORE
			+ "teacherRoleOf";

	private static final String URI_ADVISING_RELATIONSHIP_TYPE = NS_CORE
			+ "AdvisingRelationship";
	private static final String URI_ADVISOR_PROPERTY = NS_CORE + "advisor";

	public SelfEditorRelationshipPolicy(ServletContext ctx, OntModel model) {
		super(ctx, model);
	}

	@Override
	public PolicyDecision isAuthorized(IdentifierBundle whoToAuth,
			RequestedAction whatToAuth) {
		PolicyDecision decision = null;

		if (whatToAuth == null) {
			decision = inconclusiveDecision("whatToAuth was null");
		} else if (whatToAuth instanceof AbstractDataPropertyStatementAction) {
			decision = isAuthorized(whoToAuth,
					distill((AbstractDataPropertyStatementAction) whatToAuth));
		} else if (whatToAuth instanceof AbstractObjectPropertyStatementAction) {
			decision = isAuthorized(whoToAuth,
					distill((AbstractObjectPropertyStatementAction) whatToAuth));
		} else {
			decision = inconclusiveDecision("Does not authorize "
					+ whatToAuth.getClass().getSimpleName() + " actions");
		}

		if (decision == null) {
			return userNotAuthorizedToStatement();
		} else {
			return decision;
		}
	}

	private DistilledAction distill(AbstractDataPropertyStatementAction action) {
		return new DistilledAction(action.getPredicateUri(),
				action.getSubjectUri());
	}

	private DistilledAction distill(AbstractObjectPropertyStatementAction action) {
		return new DistilledAction(action.getUriOfPredicate(),
				action.getUriOfSubject(), action.getUriOfObject());
	}

	private PolicyDecision isAuthorized(IdentifierBundle ids,
			DistilledAction action) {
		List<String> userUris = new ArrayList<String>(
				HasAssociatedIndividual.getIndividualUris(ids));

		if (userUris.isEmpty()) {
			return inconclusiveDecision("Not self-editing.");<commit_msg>NIHVIVO-3404 Rename accessor methods on AbstractObjectPropertyStatementAction to be consistent with those on AbstractDataPropertyStatementAction.<commit_after>/* $This file is distributed under the terms of the license in /doc/license.txt$ */

package edu.cornell.mannlib.vivo.auth.policy;

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

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.hp.hpl.jena.ontology.OntModel;

import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasAssociatedIndividual;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ServletPolicyList;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision;
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface;
import edu.cornell.mannlib.vitro.webapp.auth.policy.specialrelationships.AbstractRelationshipPolicy;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractDataPropertyStatementAction;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractObjectPropertyStatementAction;

/**
 * Permit self-editors to edit the properties of classes with which they share a
 * special relationship. So for example:
 * 
 * A self-editor may edit properties of an InformationResource for which he is
 * an author, an editor, or in which he is featured.
 * 
 * A self-editor may edit properties of a Project in which he plays a clinical
 * role.
 * 
 * Etc.
 * 
 * NOTE: properties or resources which are restricted by namespace or by access
 * setting will still not be editable, even if this special relationship
 * applies.
 * 
 * NOTE: This could be further generalized by building a list of authorizing
 * relationships, where each relationship may specify a type of object, a
 * relating property (or chain of properties), and a text message describing the
 * relationship (to be used in the decision). We could go even farther and drive
 * this from an XML config file, so site administrators could configure it
 * themselves. A great tool for this is the one used to process the Tomcat
 * server.xml file, see http://commons.apache.org/digester/
 */
public class SelfEditorRelationshipPolicy extends AbstractRelationshipPolicy
		implements PolicyIface {
	private static final Log log = LogFactory
			.getLog(SelfEditorRelationshipPolicy.class);

	private static final String NS_CORE = "http://vivoweb.org/ontology/core#";
	private static final String URI_INFORMATION_RESOURCE_TYPE = NS_CORE
			+ "InformationResource";
	private static final String URI_EDITOR_PROPERTY = "http://purl.org/ontology/bibo/editor";
	private static final String URI_FEATURES_PROPERTY = NS_CORE + "features";
	private static final String URI_IN_AUTHORSHIP_PROPERTY = NS_CORE
			+ "informationResourceInAuthorship";
	private static final String URI_LINKED_AUTHOR_PROPERTY = NS_CORE
			+ "linkedAuthor";

	private static final String URI_GRANT_TYPE = NS_CORE + "Grant";
	private static final String URI_RELATED_ROLE_PROPERTY = NS_CORE
			+ "relatedRole";
	private static final String URI_PRINCIPAL_INVESTIGATOR_OF_PROPERTY = NS_CORE
			+ "principalInvestigatorRoleOf";
	private static final String URI_CO_PRINCIPAL_INVESTIGATOR_OF_PROPERTY = NS_CORE
			+ "co-PrincipalInvestigatorRoleOf";

	private static final String URI_PROJECT_TYPE = NS_CORE + "Project";
	private static final String URI_SERVICE_TYPE = NS_CORE + "Service";
	private static final String URI_CLINICAL_ROLE_OF_PROPERTY = NS_CORE
			+ "clinicalRoleOf";

	private static final String URI_PRESENTATION_TYPE = NS_CORE
			+ "Presentation";
	private static final String URI_PRESENTER_ROLE_OF_PROPERTY = NS_CORE
			+ "presenterRoleOf";

	private static final String URI_COURSE_TYPE = NS_CORE + "Course";
	private static final String URI_TEACHER_ROLE_OF_PROPERTY = NS_CORE
			+ "teacherRoleOf";

	private static final String URI_ADVISING_RELATIONSHIP_TYPE = NS_CORE
			+ "AdvisingRelationship";
	private static final String URI_ADVISOR_PROPERTY = NS_CORE + "advisor";

	public SelfEditorRelationshipPolicy(ServletContext ctx, OntModel model) {
		super(ctx, model);
	}

	@Override
	public PolicyDecision isAuthorized(IdentifierBundle whoToAuth,
			RequestedAction whatToAuth) {
		PolicyDecision decision = null;

		if (whatToAuth == null) {
			decision = inconclusiveDecision("whatToAuth was null");
		} else if (whatToAuth instanceof AbstractDataPropertyStatementAction) {
			decision = isAuthorized(whoToAuth,
					distill((AbstractDataPropertyStatementAction) whatToAuth));
		} else if (whatToAuth instanceof AbstractObjectPropertyStatementAction) {
			decision = isAuthorized(whoToAuth,
					distill((AbstractObjectPropertyStatementAction) whatToAuth));
		} else {
			decision = inconclusiveDecision("Does not authorize "
					+ whatToAuth.getClass().getSimpleName() + " actions");
		}

		if (decision == null) {
			return userNotAuthorizedToStatement();
		} else {
			return decision;
		}
	}

	private DistilledAction distill(AbstractDataPropertyStatementAction action) {
		return new DistilledAction(action.getPredicateUri(),
				action.getSubjectUri());
	}

	private DistilledAction distill(AbstractObjectPropertyStatementAction action) {
		return new DistilledAction(action.getPredicateUri(),
				action.getSubjectUri(), action.getObjectUri());
	}

	private PolicyDecision isAuthorized(IdentifierBundle ids,
			DistilledAction action) {
		List<String> userUris = new ArrayList<String>(
				HasAssociatedIndividual.getIndividualUris(ids));

		if (userUris.isEmpty()) {
			return inconclusiveDecision("Not self-editing.");
{'fraction_non_alphanumeric': 0.0774939592682085, 'fraction_numerical': 0.00034518467380048324, 'mean_word_length': 5.492436974789916, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2017636', 'n_tokens_mistral': 3579, 'n_tokens_neox': 3311, 'n_words': 897}