using Coscine.Configuration; using Coscine.Database.DataModel; using Coscine.Database.Models; using System; using System.Collections.Generic; using System.Linq; using VDS.RDF; namespace Coscine.Metadata.Models { public class OrganizationModel { private readonly IConfiguration _configuration; private const string _uriStringOpenIdPredicate = "http://xmlns.com/foaf/0.1/#openId"; private const string _uriStringLabelPredicate = "http://www.w3.org/2000/01/rdf-schema#label"; private const string _uriStringOrgIdentifierPredicate = "http://www.w3.org/ns/org#identifier"; private const string _uriStringOrgHasMemberPredicate = "http://www.w3.org/ns/org#hasMember"; private const string _uriStringOrgMembershipPredicate = "http://www.w3.org/ns/org#Membership"; private const string _uriStringOrgPersonPredicate = "http://xmlns.com/foaf/0.1/#Person"; public OrganizationModel(IConfiguration configuration) { _configuration = configuration; } private List<string> AdaptExternalIds(IEnumerable<ExternalId> externalIds) { List<string> adaptedIds = new List<string>(); var externalAuthenticatorModel = new ExternalAuthenticatorModel(); var orcid = externalAuthenticatorModel.GetWhere((exAuth) => exAuth.DisplayName == "ORCiD"); foreach (var externalId in externalIds) { var exId = externalId.ExternalId_Column; if (externalId.ExternalAuthenticatorId == orcid.Id) { exId = "https://orcid.org/" + exId; } adaptedIds.Add(exId); } return adaptedIds; } private bool IsMemberFilteringActivated() { var memberFilterOption = _configuration.GetStringAndWait("coscine/local/organizations/memberfiltering"); var parseable = int.TryParse(memberFilterOption, out int memberFiltering); return memberFilterOption == null || (parseable && memberFiltering == 1); } public bool IsMember(IEnumerable<ExternalId> externalIds, IGraph graph) { if (IsMemberFilteringActivated()) { bool access = false; var adaptedIds = AdaptExternalIds(externalIds); foreach (var externalIdObject in graph.GetTriplesWithPredicate(new Uri(_uriStringOpenIdPredicate)) .Select((triple) => triple.Object.ToString())) { if (adaptedIds.Any((externalId) => externalId == externalIdObject)) { access = true; break; } } return access; } else { return true; } } public bool HasLabel(string query, IGraph graph) { var labelUri = new Uri(_uriStringLabelPredicate); var transformedQuery = query.ToLower(); return graph.GetTriplesWithPredicate(labelUri).Any((triple) => triple.Object.ToString().ToLower().Contains(transformedQuery)); } public void RemoveBySubject(IGraph graph, INode subject) { foreach (var triple in graph.GetTriplesWithSubject(subject).ToList()) { graph.Retract(triple); } } public IGraph FilterByMember(IGraph organizationGraph, IEnumerable<ExternalId> externalIds) { if (IsMemberFilteringActivated()) { var identifierPredicateUri = new Uri(_uriStringOrgIdentifierPredicate); var hasMemberPredicateUri = new Uri(_uriStringOrgHasMemberPredicate); var hasMemberPredicateNode = organizationGraph.CreateUriNode(hasMemberPredicateUri); var adaptedIds = AdaptExternalIds(externalIds); var removedSubOrganisations = organizationGraph.GetTriplesWithPredicate(identifierPredicateUri) .Select((triple) => triple.Subject); foreach (var externalIdTriple in organizationGraph.GetTriplesWithPredicate(new Uri(_uriStringOpenIdPredicate))) { var externalIdObject = externalIdTriple.Object.ToString(); if (adaptedIds.Any((externalId) => externalId == externalIdObject)) { foreach (var subOrganisation in organizationGraph.GetTriplesWithPredicateObject(hasMemberPredicateNode, externalIdTriple.Subject)) { removedSubOrganisations = removedSubOrganisations.Where((entry) => entry.ToString() != subOrganisation.Subject.ToString()); } } } foreach (var removedSubOrganisation in removedSubOrganisations.ToList()) { RemoveBySubject(organizationGraph, removedSubOrganisation); } } return organizationGraph; } public IGraph FilterByQuery(IGraph organizationGraph, string query) { var identifierPredicateUri = new Uri(_uriStringOrgIdentifierPredicate); var labelUri = new Uri(_uriStringLabelPredicate); var removedSubOrganisations = organizationGraph.GetTriplesWithPredicate(identifierPredicateUri) .Select((triple) => triple.Subject); foreach (var externalIdTriple in organizationGraph.GetTriplesWithPredicate(labelUri)) { var label = externalIdTriple.Object.ToString(); if (label.Contains(query)) { removedSubOrganisations = removedSubOrganisations.Where((entry) => entry.ToString() != externalIdTriple.Subject.ToString()); } } foreach (var removedSubOrganisation in removedSubOrganisations.ToList()) { RemoveBySubject(organizationGraph, removedSubOrganisation); } return organizationGraph; } public void RemoveMembershipTriples(IGraph graph) { var membershipObject = _uriStringOrgMembershipPredicate; var personObject = _uriStringOrgPersonPredicate; var memberShipSubjects = graph.GetTriplesWithObject(new Uri(membershipObject)).Select((triple) => triple.Subject); foreach (var memberShibSubject in memberShipSubjects.ToList()) { RemoveBySubject(graph, memberShibSubject); } var personSubjects = graph.GetTriplesWithObject(new Uri(personObject)).Select((triple) => triple.Subject); foreach (var personSubject in personSubjects.ToList()) { RemoveBySubject(graph, personSubject); } var hasMember = _uriStringOrgHasMemberPredicate; foreach (var membershipLink in graph.GetTriplesWithPredicate(new Uri(hasMember)).ToList()) { graph.Retract(membershipLink); } } public IEnumerable<Triple> GetTriplesByPredicate(IGraph graph, Uri predicate) { INode predicateNode = graph.GetUriNode(predicate); IEnumerable<Triple> filteredTriples = graph.GetTriplesWithPredicate(predicateNode); return filteredTriples; } } }