Skip to content
Snippets Groups Projects

Product/801 refactor file metadata

Merged Marcel Nellesen requested to merge Product/801-refactorFileMetadata into Sprint/2020-12
3 files
+ 65
260
Compare changes
  • Side-by-side
  • Inline
Files
3
using Coscine.Database.Models;
using Coscine.ApiCommons;
using Coscine.ApiCommons;
using Coscine.ApiCommons.Exceptions;
using Coscine.ApiCommons.Factories;
using Coscine.Database.Models;
using Coscine.Database.Util;
using Coscine.Metadata;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
using System;
using System.Linq;
using VDS.RDF.Writing;
using VDS.RDF.Parsing;
using VDS.RDF;
using Coscine.Metadata;
using System.Web;
using Microsoft.AspNetCore.Authorization;
using Coscine.Database.Util;
using Coscine.Logging;
using Microsoft.Extensions.Logging;
using Coscine.Database.DataModel;
using VDS.RDF;
using VDS.RDF.Parsing;
using VDS.RDF.Writing;
namespace Coscine.Api.Metadata.Controllers
{
[Authorize]
public class MetadataController : Controller
{
private readonly Authenticator _authenticator;
private readonly MetadataModel _metadataModel;
private readonly ResourceModel _resourceModel;
private readonly ProjectModel _projectModel;
private readonly Util _util;
private readonly ProjectRoleModel _projectRoleModel;
private readonly ProjectResourceModel _projectResourceModel;
private readonly CoscineLogger _coscineLogger;
private readonly AnalyticsLogObject _analyticsLogObject;
private readonly string ApplicationProfileUrl = "https://purl.org/coscine/ap/";
public MetadataController(ILogger<MetadataController> logger)
public MetadataController()
{
_authenticator = new Authenticator(this, Program.Configuration);
_metadataModel = new MetadataModel();
_resourceModel = new ResourceModel();
_projectModel = new ProjectModel();
_util = new Util(Program.Configuration.GetStringAndWait("coscine/local/virtuoso/additional/url"));
_projectRoleModel = new ProjectRoleModel();
_projectResourceModel = new ProjectResourceModel();
_coscineLogger = new CoscineLogger(logger);
_analyticsLogObject = new AnalyticsLogObject();
}
[Route("[controller]")]
public IActionResult Index()
[HttpGet("[controller]/profiles/")]
public IActionResult GetProfiles()
{
return NoContent();
var graphUris = _util.ListGraphs();
return Json(new JArray(graphUris.Select(x => x.ToString()).Where(x => x.StartsWith(ApplicationProfileUrl))));
}
// returns the basic application profile
[HttpGet("[controller]/resource/{projectId}/ap/{applicationProfileId}")]
public IActionResult GetApplicationProfile(Guid projectId, string applicationProfileId)
[HttpGet("[controller]/profiles/{profile}")]
public IActionResult GetProfile(string profile)
{
var user = _authenticator.GetUser();
string profileUrl = profile.StartsWith("http") ? HttpUtility.UrlDecode(profile) : $"{ApplicationProfileUrl}{profile}/";
if (_projectModel.HasAccess(user, _projectModel.GetById(projectId), UserRoles.Owner, UserRoles.Member))
{
var graph = _util.GetGraph(HttpUtility.UrlDecode(applicationProfileId));
var graph = _util.GetGraph(profileUrl);
var json = JToken.Parse(VDS.RDF.Writing.StringWriter.Write(graph, new RdfJsonWriter()));
return Json(json);
}
else
{
throw new NotAuthorizedException("User is no project member!");
}
var json = JToken.Parse(VDS.RDF.Writing.StringWriter.Write(graph, new RdfJsonWriter()));
return Ok(json);
}
// returns the application profile with the fixed values
[HttpGet("[controller]/resource/{resourceId}/apc/{applicationProfileId}")]
public IActionResult GetApplicationProfileComplete(string resourceId, string applicationProfileId)
[HttpGet("[controller]/profiles/{profile}/{resourceId}")]
public IActionResult GetApplicationProfileComplete(string profile, string resourceId)
{
var user = _authenticator.GetUser();
var resource = _resourceModel.GetById(Guid.Parse(resourceId));
if (_resourceModel.HasAccess(user, resource, UserRoles.Owner, UserRoles.Member) && applicationProfileId != null)
if (user == null || !_resourceModel.HasAccess(user, resource, UserRoles.Owner, UserRoles.Member))
{
var graph = _util.GetGraph(HttpUtility.UrlDecode(applicationProfileId));
var fixedValuesGraph = new Graph();
return Forbid("User is no project member!");
}
fixedValuesGraph.LoadFromString(resource.FixedValues, new RdfJsonParser());
string profileUrl = profile.StartsWith("http") ? HttpUtility.UrlDecode(profile) : $"{ApplicationProfileUrl}{profile}/";
graph.Merge(fixedValuesGraph);
var graph = _util.GetGraph(profileUrl);
var fixedValuesGraph = new Graph();
var json = JToken.Parse(VDS.RDF.Writing.StringWriter.Write(graph, new RdfJsonWriter()));
fixedValuesGraph.LoadFromString(resource.FixedValues, new RdfJsonParser());
return Ok(json);
}
else
{
throw new NotAuthorizedException("User is no project member!");
}
graph.Merge(fixedValuesGraph);
}
var json = JToken.Parse(VDS.RDF.Writing.StringWriter.Write(graph, new RdfJsonWriter()));
[HttpGet("[controller]/project/{projectId}/aplist/")]
public IActionResult ListAllApplicationProfiles(Guid projectId)
{
var user = _authenticator.GetUser();
if (_projectModel.HasAccess(user, _projectModel.GetById(projectId), UserRoles.Owner, UserRoles.Member))
{
var graphUris = _util.ListGraphs();
return Ok(json);
return Json(new JArray(graphUris.Select(x => x.ToString()).Where(x => x.StartsWith("https://purl.org/coscine/ap/"))));
}
else
{
throw new NotAuthorizedException("User is no project member!");
}
}
[HttpGet("[controller]/resource/{resourceId}/filename/{filename}/ver/{version}")]
public IActionResult GetMetadataForFile(string resourceId, string filename, string version)
[HttpGet("[controller]/vocabularies/")]
public IActionResult GetVocabularies()
{
var user = _authenticator.GetUser();
var resource = _resourceModel.GetById(Guid.Parse(resourceId));
if (_resourceModel.HasAccess(user, resource, UserRoles.Owner, UserRoles.Member))
{
var id = _metadataModel.GenerateId(resourceId, filename, version);
var uri = _metadataModel.CreateUri(id);
var graph = _util.GetGraph(uri);
LogAnalytics("View MD", resourceId, filename, user);
return Json(JToken.Parse(VDS.RDF.Writing.StringWriter.Write(graph, new RdfJsonWriter())).ToString());
}
else
{
throw new NotAuthorizedException("User is no project member!");
}
throw new NotImplementedException();
}
[HttpPut("[controller]/resource/{resourceId}/filename/{filename}/ver/{version}")]
public IActionResult StoreMetadataForFile(string resourceId, string filename, string version)
[HttpGet("[controller]/vocabularies/{path}")]
public IActionResult GetVocabulary(string path)
{
var innerBlock = ObjectFactory<JToken>.DeserializeFromStream(Request.Body);
var graphName = _metadataModel.GenerateId(resourceId, filename, version);
var graphNameUri = _metadataModel.CreateUri(graphName);
var json = new JObject
{
[graphName] = innerBlock
};
var user = _authenticator.GetUser();
var resource = _resourceModel.GetById(Guid.Parse(resourceId));
var graph = _util.GetGraph(HttpUtility.UrlDecode(path));
if (_resourceModel.HasAccess(user, resource, UserRoles.Owner, UserRoles.Member))
var de = new JArray();
foreach (var kv in _util.GetVocabularyLabels(graph, "de"))
{
if(resource.ApplicationProfile[resource.ApplicationProfile.Length - 1] != '/')
JObject obj = new JObject
{
resource.ApplicationProfile += '/';
}
json[graphName]["http://www.w3.org/1999/02/22-rdf-syntax-ns#type"] = new JArray
{
new JObject
{
["value"] = resource.ApplicationProfile,
["type"] = "uri"
}
["value"] = kv.Key,
["name"] = kv.Value
};
// throw bad request if empty node value is detected
JToken root = json.First.First;
foreach (var node in root)
{
string nodeValue = node.First.First["value"].ToString().ToLower();
if (String.IsNullOrEmpty(nodeValue))
{
throw new ArgumentException("Empty values in application profile are not accepted.");
}
}
var graph = new Graph();
graph.LoadFromString(json.ToString(), new RdfJsonParser());
var fixedValuesGraph = new Graph();
fixedValuesGraph.LoadFromString(resource.FixedValues, new RdfJsonParser());
var shapesGraph = (Graph) _util.GetGraph(resource.ApplicationProfile);
foreach (var triple in fixedValuesGraph.Triples.Where(x => x.Predicate.ToString() == "https://purl.org/coscine/fixedValue"))
{
var shapeTriples = shapesGraph.Triples.Where((shapeTriple) =>
shapeTriple.Subject.ToString() == triple.Subject.ToString()
&& shapeTriple.Predicate.ToString() == "http://www.w3.org/ns/shacl#path");
var entry = shapeTriples.First();
// Remove any existing triples
foreach (var triple2 in graph.GetTriplesWithSubjectPredicate(graph.CreateUriNode(graphNameUri), entry.Object).ToList())
{
graph.Retract(triple2);
}
var tripleObject = triple.Object;
var tripleObjectString = tripleObject.ToString();
if (tripleObjectString == "{ME}")
{
tripleObjectString = tripleObjectString.Replace("{ME}", user.DisplayName);
tripleObject = graph.CreateLiteralNode(tripleObjectString, new Uri(XmlSpecsHelper.XmlSchemaDataTypeString));
}
else if(tripleObjectString == "{TODAY}")
{
tripleObjectString = tripleObjectString.Replace("{TODAY}", DateTime.Today.ToString("yyyy-MM-dd"));
tripleObject = graph.CreateLiteralNode(tripleObjectString, new Uri(XmlSpecsHelper.XmlSchemaDataTypeDate));
}
graph.Assert(graph.CreateUriNode(graphNameUri), entry.Object, tripleObject);
}
// Default values is not checked or added
// validate the data
if (_util.ValidateShacl(graph, graphNameUri))
{
// store the data
if (_util.HasGraph(graphNameUri))
{
_util.ClearGraph(graphNameUri);
LogAnalytics("Update MD", resourceId, filename, user);
}
else
{
_util.CreateNamedGraph(graphNameUri);
LogAnalytics("Upload MD", resourceId, filename, user);
}
// BaseUri must be set for the sparql query
graph.BaseUri = graphNameUri;
_util.AddGraph(graph);
de.Add(obj);
}
return NoContent();
}
else
var en = new JArray();
foreach (var kv in _util.GetVocabularyLabels(graph, "en"))
{
JObject obj = new JObject
{
throw new NotAuthorizedException("Data has the wrong format!");
}
["value"] = kv.Key,
["name"] = kv.Value
};
en.Add(obj);
}
else
JObject json = new JObject
{
throw new NotAuthorizedException("User is no project member!");
}
["de"] = de,
["en"] = en
};
return Json(json);
}
[HttpGet("[controller]/instances/{projectId}/{className}")]
public IActionResult GetClassInstances(Guid projectId, string className)
{
var user = _authenticator.GetUser();
if (_projectModel.HasAccess(user, _projectModel.GetById(projectId), UserRoles.Owner, UserRoles.Member))
ProjectModel projectModel = new ProjectModel();
if (projectModel.HasAccess(user, projectModel.GetById(projectId), UserRoles.Owner, UserRoles.Member))
{
if (!Uri.TryCreate(HttpUtility.UrlDecode(className), UriKind.Absolute, out Uri uri))
{
@@ -295,64 +169,5 @@ namespace Coscine.Api.Metadata.Controllers
throw new NotAuthorizedException("User is no project member!");
}
}
[HttpGet("[controller]/vocabulary/{projectId}/{path}")]
public IActionResult GetVocabulary(Guid projectId, string path)
{
var user = _authenticator.GetUser();
if (_projectModel.HasAccess(user, _projectModel.GetById(projectId), UserRoles.Owner, UserRoles.Member))
{
var graph = _util.GetGraph(HttpUtility.UrlDecode(path));
var de = new JArray();
foreach (var kv in _util.GetVocabularyLabels(graph, "de"))
{
JObject obj = new JObject
{
["value"] = kv.Key,
["name"] = kv.Value
};
de.Add(obj);
}
var en = new JArray();
foreach (var kv in _util.GetVocabularyLabels(graph, "en"))
{
JObject obj = new JObject
{
["value"] = kv.Key,
["name"] = kv.Value
};
en.Add(obj);
}
JObject json = new JObject
{
["de"] = de,
["en"] = en
};
return Json(json);
}
else
{
throw new NotAuthorizedException("User is no project member!");
}
}
private void LogAnalytics(string operation, string resourceId, string filename, User user)
{
if (CoscineLoggerConfiguration.IsLogLevelActivated(LogType.Analytics))
{
_analyticsLogObject.Type = "Action";
_analyticsLogObject.Operation = operation;
_analyticsLogObject.FileId = resourceId + "/" + HttpUtility.UrlDecode(filename).Substring(1);
_analyticsLogObject.ResourceId = resourceId;
_analyticsLogObject.ProjectId = _projectResourceModel.GetProjectForResource(new Guid(resourceId)).ToString();
_analyticsLogObject.RoleId = _projectRoleModel.GetGetUserRoleForProject(new Guid(_analyticsLogObject.ProjectId), user.Id).ToString();
_coscineLogger.AnalyticsLog(_analyticsLogObject);
}
}
}
}
Loading