Commits (3)
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28803.156
# Visual Studio Version 17
VisualStudioVersion = 17.0.32112.339
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tree", "Tree\Tree.csproj", "{AC8882D4-3F0C-4BBF-83CE-22A5B05ED3FB}"
EndProject
......
......@@ -7,12 +7,12 @@ using Coscine.Database.Models;
using Coscine.Database.Util;
using Coscine.Logging;
using Coscine.Metadata;
using Coscine.ResourceLoader;
using Coscine.ResourceTypeBase;
using Coscine.ResourceTypes;
using Coscine.ResourceTypes.Base;
using Coscine.ResourceTypes.Base.Models;
using Coscine.WaterbutlerHelper;
using Coscine.WaterbutlerHelper.ReturnObjects;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
......@@ -75,6 +75,11 @@ namespace Coscine.Api.Tree.Controllers
/// <returns> Uri </returns>
public Uri GenerateId(string resourceId, string path)
{
if (!path.StartsWith("/"))
{
path = "/" + path;
}
return new CustomUri($"https://hdl.handle.net/{_prefix}/{resourceId}@path={Uri.EscapeDataString(path)}");
}
......@@ -98,7 +103,7 @@ namespace Coscine.Api.Tree.Controllers
/// <param name="path">Path to the file</param>
/// <returns> JSON Object with the metadata if OK, otherwise status code 400 or 401 or 404</returns>
[HttpGet("[controller]/{resourceId}/")]
public async Task<IActionResult> GetMetadataWithParameter(string resourceId, [System.Web.Http.FromUri] string path = "")
public async Task<IActionResult> GetMetadataWithParameter(string resourceId, [FromQuery] string path = "")
{
// Strip the first slash, to reuse the previous implementation.
if (path.StartsWith("/"))
......@@ -117,15 +122,13 @@ namespace Coscine.Api.Tree.Controllers
/// <returns> JSON Object with the metadata if OK, otherwise status code 400 or 401 or 404</returns>
public async Task<IActionResult> GetMetadata(string resourceId, string path = "")
{
var rawPath = path;
path = $"/{path}";
if (path.Contains("%2F") || path.Contains("%2f"))
{
return BadRequest("Path can not contain the sequence %2F.");
}
var user = _authenticator.GetUser();
var check = CheckResourceIdAndPath(resourceId, path, out Resource resource);
var check = CheckResourceIdAndPath(resourceId, $"/{path}", out Resource resource);
if (check != null)
{
return check;
......@@ -143,20 +146,15 @@ namespace Coscine.Api.Tree.Controllers
try
{
var resourceTypeOptions = _resourceModel.GetResourceTypeOptions(resource.Id);
var resourceTypeDefinition = ResourceTypeFactory.CreateResourceTypeObject(resource.Type.DisplayName, _configuration);
var resourceTypeDefinition = ResourceTypeFactory.Instance.GetResourceType(resource);
if (resourceTypeDefinition == null)
{
return BadRequest($"No provider for: \"{resource.Type.DisplayName}\".");
}
var fileInfos = await resourceTypeDefinition.ListEntries(resourceId, path, resourceTypeOptions);
var fileInfos = await resourceTypeDefinition.ListEntries(resourceId, path);
var resourceTypeInformation = resourceTypeDefinition.GetResourceTypeInformation().Result;
var metadataInfos = new List<ResourceEntry>(fileInfos);
if (path.EndsWith("/"))
{
metadataInfos.Insert(0, new ResourceEntry(path, false, 0, null, null, new DateTime(), new DateTime()));
}
var graphs = new List<JToken>();
int metadataCount = 0;
......@@ -167,14 +165,15 @@ namespace Coscine.Api.Tree.Controllers
{
var graph = _rdfStoreConnector.GetGraph(id);
metadataCount = graph.Triples.Count;
graphs.Add(JToken.Parse(VDS.RDF.Writing.StringWriter.Write(graph, new RdfJsonWriter())));
graphs.Add(JToken.Parse(StringWriter.Write(graph, new RdfJsonWriter())));
}
}
var jObject = new JObject(
new JProperty("data", new JObject(
new JProperty("metadataStorage", JToken.FromObject(graphs)),
new JProperty("fileStorage", JToken.FromObject(fileInfos.Select(x =>
new JProperty("fileStorage",
JToken.FromObject(fileInfos.Select(x =>
{
var objectMetaInfo = new ObjectMetaInfo
{
......@@ -185,7 +184,7 @@ namespace Coscine.Api.Tree.Controllers
Provider = resource.Type.DisplayName
};
var objectMetaInfoReturnObject = new ObjectMetaInfoReturnObject(objectMetaInfo, _blobApiLink, resource.Id.ToString());
var result = new JObject
var obj = new JObject
{
["Name"] = objectMetaInfoReturnObject.Name,
["Path"] = objectMetaInfoReturnObject.Path,
......@@ -196,33 +195,39 @@ namespace Coscine.Api.Tree.Controllers
["Provider"] = objectMetaInfoReturnObject.Provider,
["IsFolder"] = !x.HasBody,
["IsFile"] = x.HasBody,
["Action"] = new JObject
["Action"] = new JObject()
};
if (resourceTypeInformation.CanCreateLinks)
{
obj["Action"] = new JObject
{
["Delete"] = new JObject
{
["Method"] = "DELETE",
["Url"] = objectMetaInfoReturnObject.DeleteLink
["Url"] = resourceTypeDefinition?.GetPresignedUrl(resource.Id.ToString(), objectMetaInfoReturnObject.Path, CoscineHttpVerb.DELETE).Result?.ToString()
},
["Download"] = new JObject
{
["Method"] = "GET",
["Url"] = resourceTypeDefinition?.GetEntryDownloadUrl(rawPath, null, resourceTypeOptions).Result?.ToString()
["Url"] = resourceTypeDefinition?.GetPresignedUrl(resource.Id.ToString(), objectMetaInfoReturnObject.Path, CoscineHttpVerb.GET).Result?.ToString()
},
["Upload"] = new JObject
{
["Method"] = "PUT",
["Url"] = resourceTypeDefinition?.GetEntryStoreUrl(rawPath, null, resourceTypeOptions).Result?.ToString()
["Url"] = resourceTypeDefinition?.GetPresignedUrl(resource.Id.ToString(), objectMetaInfoReturnObject.Path, CoscineHttpVerb.DELETE).Result?.ToString()
}
}
};
return result;
};
}
return obj;
})))
))
);
if (CoscineLoggerConfiguration.IsLogLevelActivated(LogType.Analytics) && path != "/")
{
LogAnalyticsViewMd(_projectResourceModel.GetProjectForResource(resource.Id).Value, resource.Id, path, user, GetMetadataCompleteness(metadataCount, resource));
LogAnalyticsViewMd(_projectResourceModel.GetProjectForResource(resource.Id).Value, resource.Id, $"/{path}", user, GetMetadataCompleteness(metadataCount, resource));
}
return Json(jObject);
......@@ -245,7 +250,7 @@ namespace Coscine.Api.Tree.Controllers
if (name?.Length == 0)
{
var tempPath = x.Key[..(lastSlash - 1)];
if (tempPath.Contains("/"))
if (tempPath.Contains('/'))
{
tempPath = tempPath[(tempPath.IndexOf("/") + 1)..];
}
......@@ -275,7 +280,7 @@ namespace Coscine.Api.Tree.Controllers
/// <param name="path">Path to the file</param>
/// <returns>If OK status code 204, otherwise status code 400 or 401</returns>
[HttpPut("[controller]/{resourceId}/")]
public IActionResult StoreMetadataForFileWithParameter(string resourceId, [System.Web.Http.FromUri] string path = "")
public IActionResult StoreMetadataForFileWithParameter(string resourceId, [FromQuery] string path = "")
{
// Strip the first slash, to reuse the previous implementation.
if (path.StartsWith("/"))
......@@ -336,8 +341,7 @@ namespace Coscine.Api.Tree.Controllers
};
// throw bad request if empty node value is detected
JToken root = json.First.First;
foreach (var node in root)
foreach (var node in json.First.First)
{
string nodeValue = node.First.First["value"].ToString().ToLower();
if (string.IsNullOrEmpty(nodeValue))
......@@ -407,8 +411,10 @@ namespace Coscine.Api.Tree.Controllers
try
{
_rdfStoreConnector.CreateNamedGraph(graphNameUri);
}
}
#pragma warning disable RCS1075 // Avoid empty catch clause that catches System.Exception.
catch (Exception)
#pragma warning restore RCS1075 // Avoid empty catch clause that catches System.Exception.
{
// Graph creation failed because it has been created before, skip this for now
}
......@@ -442,7 +448,7 @@ namespace Coscine.Api.Tree.Controllers
return BadRequest($"Your path \"{path}\" is empty.");
}
Regex rgx = new Regex(@"[\:?*<>|]+");
var rgx = new Regex(@"[\:?*<>|]+");
if (rgx.IsMatch(path))
{
return BadRequest($"Your path \"{path}\" contains bad characters. The following characters are not permissible: {@"\/:?*<>|"}.");
......@@ -468,7 +474,7 @@ namespace Coscine.Api.Tree.Controllers
if (resource.Type == null)
{
ResourceTypeModel resourceTypeModel = new ResourceTypeModel();
var resourceTypeModel = new ResourceTypeModel();
resource.Type = resourceTypeModel.GetById(resource.TypeId);
}
......
......@@ -5,7 +5,7 @@
<AssemblyName>Coscine.Api.Tree</AssemblyName>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<TargetFramework>net6.0</TargetFramework>
<Version>2.6.4</Version>
<Version>2.7.0</Version>
</PropertyGroup>
<PropertyGroup>
<Authors>RWTH Aachen University</Authors>
......@@ -21,9 +21,7 @@
<PackageReference Include="Coscine.Database" Version="2.*-*" />
<PackageReference Include="Coscine.Logging" Version="2.*-*" />
<PackageReference Include="Coscine.Metadata" Version="2.*-*" />
<PackageReference Include="Coscine.ResourceLoader" Version="2.*-*" />
<PackageReference Include="Coscine.ResourceTypeBase" Version="2.*-*" />
<PackageReference Include="Coscine.ResourceTypes" Version="*-*" />
<PackageReference Include="Coscine.WaterbutlerHelper" Version="2.*-*" />
<PackageReference Include="Microsoft.AspNet.WebApi.Core" Version="5.2.7" />
</ItemGroup>
</Project>