Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
Loading items

Target

Select target project
  • coscine/backend/apis/project
1 result
Select Git revision
Loading items
Show changes
Commits on Source (3)
Showing
with 357 additions and 83 deletions
......@@ -56,17 +56,17 @@
<Reference Include="Consul, Version=0.7.2.6, Culture=neutral, PublicKeyToken=20a6ad9a81df1d95, processorArchitecture=MSIL">
<HintPath>..\packages\Consul.0.7.2.6\lib\net45\Consul.dll</HintPath>
</Reference>
<Reference Include="Coscine.Action, Version=1.3.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Coscine.Action.1.3.1\lib\net461\Coscine.Action.dll</HintPath>
<Reference Include="Coscine.Action, Version=1.4.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Coscine.Action.1.4.0\lib\net461\Coscine.Action.dll</HintPath>
</Reference>
<Reference Include="Coscine.ApiCommons, Version=1.2.1.0, Culture=neutral, PublicKeyToken=af4c1345df96546b, processorArchitecture=MSIL">
<HintPath>..\packages\Coscine.ApiCommons.1.2.1\lib\net461\Coscine.ApiCommons.dll</HintPath>
<Reference Include="Coscine.ApiCommons, Version=1.2.2.0, Culture=neutral, PublicKeyToken=af4c1345df96546b, processorArchitecture=MSIL">
<HintPath>..\packages\Coscine.ApiCommons.1.2.2\lib\net461\Coscine.ApiCommons.dll</HintPath>
</Reference>
<Reference Include="Coscine.Configuration, Version=1.4.0.0, Culture=neutral, PublicKeyToken=ce3d7a32d7dc1e5a, processorArchitecture=MSIL">
<HintPath>..\packages\Coscine.Configuration.1.4.0\lib\net461\Coscine.Configuration.dll</HintPath>
</Reference>
<Reference Include="Coscine.Database, Version=1.6.0.0, Culture=neutral, PublicKeyToken=767d77427707b70a, processorArchitecture=MSIL">
<HintPath>..\packages\Coscine.Database.1.6.0\lib\net461\Coscine.Database.dll</HintPath>
<Reference Include="Coscine.Database, Version=1.7.0.0, Culture=neutral, PublicKeyToken=767d77427707b70a, processorArchitecture=MSIL">
<HintPath>..\packages\Coscine.Database.1.7.0\lib\net461\Coscine.Database.dll</HintPath>
</Reference>
<Reference Include="Coscine.ProxyApi, Version=1.2.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Coscine.ProxyApi.1.2.0\lib\net461\Coscine.ProxyApi.dll</HintPath>
......
......@@ -9,8 +9,8 @@ using System.Reflection;
[assembly: AssemblyDescription("Project.Tests is a part of the CoScInE group.")]
[assembly: AssemblyCompany("IT Center, RWTH Aachen University")]
[assembly: AssemblyProduct("Project.Tests")]
[assembly: AssemblyVersion("1.4.1.0")]
[assembly: AssemblyFileVersion("1.4.1.0")]
[assembly: AssemblyInformationalVersion("1.4.1.0")]
[assembly: AssemblyVersion("1.5.0.0")]
[assembly: AssemblyFileVersion("1.5.0.0")]
[assembly: AssemblyInformationalVersion("1.5.0.0")]
[assembly: AssemblyCopyright("2019 IT Center, RWTH Aachen University")]
......@@ -90,6 +90,7 @@ namespace Coscine.Api.Project.Tests
Guid.NewGuid(),
"Test",
"testR",
"testD",
"keys",
"usageR",
new ResourceTypeObject(Resources[0].Type.Id, Resources[0].Type.DisplayName),
......
......@@ -88,7 +88,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Coscine.Database" publicKeyToken="767d77427707b70a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.6.0.0" newVersion="1.6.0.0" />
<bindingRedirect oldVersion="0.0.0.0-1.7.0.0" newVersion="1.7.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.IdentityModel.Tokens.Jwt" publicKeyToken="31bf3856ad364e35" culture="neutral" />
......
......@@ -4,10 +4,10 @@
<package id="AutoMapper.Extensions.Microsoft.DependencyInjection" version="6.0.0" targetFramework="net472" />
<package id="Castle.Core" version="4.4.0" targetFramework="net472" />
<package id="Consul" version="0.7.2.6" targetFramework="net472" />
<package id="Coscine.Action" version="1.3.1" targetFramework="net472" />
<package id="Coscine.ApiCommons" version="1.2.1" targetFramework="net472" />
<package id="Coscine.Action" version="1.4.0" targetFramework="net472" />
<package id="Coscine.ApiCommons" version="1.2.2" targetFramework="net472" />
<package id="Coscine.Configuration" version="1.4.0" targetFramework="net472" />
<package id="Coscine.Database" version="1.6.0" targetFramework="net472" />
<package id="Coscine.Database" version="1.7.0" targetFramework="net472" />
<package id="Coscine.ProxyApi" version="1.2.0" targetFramework="net472" />
<package id="Coscine.SharePoint.Webparts.Vue" version="1.4.0" targetFramework="net472" />
<package id="EntityFramework" version="6.2.0" targetFramework="net472" />
......
......@@ -91,7 +91,7 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Coscine.Database" publicKeyToken="767d77427707b70a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.6.0.0" newVersion="1.6.0.0" />
<bindingRedirect oldVersion="0.0.0.0-1.7.0.0" newVersion="1.7.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.IdentityModel.Tokens.Jwt" publicKeyToken="31bf3856ad364e35" culture="neutral" />
......
......@@ -9,10 +9,15 @@ using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web;
#region DupFinder Exclusion
namespace Coscine.Api.Project.Controllers
{
......@@ -20,10 +25,19 @@ namespace Coscine.Api.Project.Controllers
{
private readonly IConfiguration _configuration;
private readonly JWTHandler _jwtHandler;
private static readonly HttpClient Client = new HttpClient();
// make to lazy property
private static readonly HttpClient Client;
private readonly Authenticator _authenticator;
private readonly ResourceModel _resourceModel;
static DataSourceController()
{
Client = new HttpClient
{
Timeout = TimeSpan.FromMinutes(30)
};
}
public DataSourceController()
{
_configuration = Program.Configuration;
......@@ -32,86 +46,221 @@ namespace Coscine.Api.Project.Controllers
_resourceModel = new ResourceModel();
}
// inferring a ../ (urlencoded) can manipulate the url.
// However the constructed signature for s3 won't match and it will not be resolved.
// This may be a problem for other provider!
[HttpGet("[controller]/{resourceId}/{path}")]
public async Task<IActionResult> GetWaterButlerFolder(string resourceId, string path)
{
if (!string.IsNullOrWhiteSpace(path))
{
path = HttpUtility.UrlDecode(path);
}
var check = CheckResourceIdAndPath(resourceId, path, out Resource resource);
if (check != null)
{
return check;
}
var authHeader = BuildAuthHeader(resource);
if (authHeader == null)
{
return BadRequest($"No provider for: \"{resource.Type.DisplayName}\".");
}
else
{
// If the path is null, an empty string is added.
string url = $"{_configuration.GetString("coscine/global/waterbutler_url")}{resource.Type.DisplayName.ToLower()}{path}";
var request = new HttpRequestMessage(HttpMethod.Get, url);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authHeader);
// Thread safe according to msdn and HttpCompletionOption sets it to get only headers first.
var response = await Client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
if (response.IsSuccessStatusCode)
{
if (response.Content.Headers.Contains("Content-Disposition"))
{
return File(await response.Content.ReadAsStreamAsync(),
response.Content.Headers.GetValues("Content-Type").First());
}
else
{
var data = JObject.Parse(await response.Content.ReadAsStringAsync())["data"];
return Ok(new WaterbutlerObject(path, data));
}
}
else
{
return FailedRequeset(response, path);
}
}
}
// inferring a ../ (urlencoded) can manipulate the url.
// However the constructed signature for s3 won't match and it will not be resolved.
// This may be a problem for other provider!
[HttpGet("[controller]/{resourceId}/{*path}")]
public async Task<IActionResult> Get(string resourceId, string path)
[HttpPut("[controller]/{resourceId}/{path}")]
[DisableRequestSizeLimit]
public async Task<IActionResult> PutUploadFile(string resourceId, string path)
{
if (!string.IsNullOrWhiteSpace(path))
{
path = HttpUtility.UrlDecode(path);
}
if (!Guid.TryParse(resourceId, out Guid resouceGuid))
var check = CheckResourceIdAndPath(resourceId, path, out Resource resource);
if (check != null)
{
return BadRequest($"{resourceId} is not a guid.");
return check;
}
Resource resource;
var authHeader = BuildAuthHeader(resource, new string[] { "gitlab" });
if (authHeader == null)
{
return BadRequest($"No provider for: \"{resource.Type.DisplayName}\".");
}
else
{
// If the path is null, an empty string is added.
string url = $"{_configuration.GetString("coscine/global/waterbutler_url")}{resource.Type.DisplayName.ToLower()}/?kind=file&name={path}";
try
{
resource = _resourceModel.GetById(resouceGuid);
if (resource == null)
var response = await UploadFile(url, authHeader, Request.Body);
if (response.IsSuccessStatusCode)
{
return NotFound($"Could not find resource with id: {resourceId}");
return NoContent();
}
else
{
return FailedRequeset(response, path);
}
catch (Exception)
}
catch (Exception e)
{
return NotFound($"Could not find resource with id: {resourceId}");
Console.WriteLine(e);
return BadRequest(e);
}
}
}
var user = _authenticator.GetUserFromToken();
if (!_resourceModel.OwnsResource(user, resource))
// inferring a ../ (urlencoded) can manipulate the url.
// However the constructed signature for s3 won't match and it will not be resolved.
// This may be a problem for other provider!
[HttpPut("[controller]/{resourceId}/{path}/update")]
[DisableRequestSizeLimit]
public async Task<IActionResult> PutUpdateFile(string resourceId, string path)
{
return Forbid($"The user does not own the resource {resourceId}");
if (!string.IsNullOrWhiteSpace(path))
{
path = HttpUtility.UrlDecode(path);
}
if (resource.Type == null)
var check = CheckResourceIdAndPath(resourceId, path, out Resource resource);
if (check != null)
{
ResourceTypeModel resourceTypeModel = new ResourceTypeModel();
resource.Type = resourceTypeModel.GetById(resource.TypeId);
return check;
}
string authHeader = null;
var authHeader = BuildAuthHeader(resource, new string[] { "gitlab" });
if (resource.Type.DisplayName.ToLower() == "rds")
if (authHeader == null)
{
RDSResourceTypeModel rdsResourceTypeModel = new RDSResourceTypeModel();
var rdsResourceType = rdsResourceTypeModel.GetById(resource.ResourceTypeOptionId.Value);
return BadRequest($"No provider for: \"{resource.Type.DisplayName}\".");
}
else
{
// If the path is null, an empty string is added.
string url = $"{_configuration.GetString("coscine/global/waterbutler_url")}{resource.Type.DisplayName.ToLower()}/{path}?kind=file";
authHeader = BuildRdsAuthHeader(rdsResourceType);
try
{
var response = await UploadFile(url, authHeader, Request.Body);
if (response.IsSuccessStatusCode)
{
return NoContent();
}
else if (resource.Type.DisplayName.ToLower() == "gitlab")
else
{
return FailedRequeset(response, path);
}
}
catch (Exception e)
{
GitlabResourceTypeModel gitlabResourceTypeModel = new GitlabResourceTypeModel();
var gitlabResourceType = gitlabResourceTypeModel.GetById(resource.ResourceTypeOptionId.Value);
authHeader = BuildGitlabAuthHeader(gitlabResourceType);
Console.WriteLine(e);
return BadRequest(e);
}
}
}
if (authHeader != null)
public async Task<HttpResponseMessage> UploadFile(string url, string authHeader, Stream stream)
{
var request = new HttpRequestMessage(HttpMethod.Put, url);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authHeader);
request.Content = new StreamContent(stream);
return await Client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
}
[HttpDelete("[controller]/{resourceId}/{path}")]
public async Task<IActionResult> Delete(string resourceId, string path)
{
if (!string.IsNullOrWhiteSpace(path))
{
path = HttpUtility.UrlDecode(path);
}
var check = CheckResourceIdAndPath(resourceId, path, out Resource resource);
if (check != null)
{
return check;
}
var authHeader = BuildAuthHeader(resource, new string[] { "gitlab" });
if (authHeader == null)
{
return BadRequest($"No provider for: \"{resource.Type.DisplayName}\".");
}
else
{
// If the path is null, an empty string is added.
string url = $"{_configuration.GetString("coscine/global/waterbutler_url")}{resource.Type.DisplayName.ToLower()}/{path}";
var request = new HttpRequestMessage(HttpMethod.Get, url);
var request = new HttpRequestMessage(HttpMethod.Delete, url);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authHeader);
// Thread safe according to msdn and HttpCompletionOption sets it to get only headers first.
try
{
var response = await Client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
if (response.IsSuccessStatusCode)
{
if (response.Content.Headers.Contains("Content-Disposition"))
{
return File(await response.Content.ReadAsStreamAsync(),
response.Content.Headers.GetValues("Content-Type").First());
return NoContent();
}
else
{
var data = JObject.Parse(await response.Content.ReadAsStringAsync())["data"];
return Ok(new WaterbutlerObject(path, data));
return FailedRequeset(response, path);
}
}
else
catch (Exception e)
{
Console.WriteLine(e);
return BadRequest(e);
}
}
}
private IActionResult FailedRequeset(HttpResponseMessage response, string path)
{
if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
{
......@@ -127,11 +276,55 @@ namespace Coscine.Api.Project.Controllers
return BadRequest($"Error in communication with waterbutler: {response.StatusCode}");
}
}
private IActionResult CheckResourceIdAndPath(string resourceId, string path, out Resource resource)
{
resource = null;
if (string.IsNullOrWhiteSpace(path))
{
return BadRequest($"Your path \"{path}\" is empty.");
}
else
Regex rgx = new Regex(@"^[0-9a-zA-Z_\-/. ]+$");
if (!rgx.IsMatch(path))
{
return BadRequest($"No provider for: \"{resource.Type.DisplayName}\".");
return BadRequest($"Your path \"{path}\" contains bad chars. Only {@"^[0-9a-zA-Z_\-./ ]+"} are allowed as chars.");
}
if (!Guid.TryParse(resourceId, out Guid resouceGuid))
{
return BadRequest($"{resourceId} is not a guid.");
}
#if! DEBUG
var user = _authenticator.GetUserFromToken();
if (!_resourceModel.OwnsResource(user, resource))
{
return Forbid($"The user does not own the resource {resourceId}");
}
#endif
try
{
resource = _resourceModel.GetById(resouceGuid);
if (resource == null)
{
return NotFound($"Could not find resource with id: {resourceId}");
}
}
catch (Exception)
{
return NotFound($"Could not find resource with id: {resourceId}");
}
if (resource.Type == null)
{
ResourceTypeModel resourceTypeModel = new ResourceTypeModel();
resource.Type = resourceTypeModel.GetById(resource.TypeId);
}
// All good
return null;
}
private string BuildWaterbutlerPayload(Dictionary<string, object> auth, Dictionary<string, object> credentials, Dictionary<string, object> settings)
......@@ -152,6 +345,32 @@ namespace Coscine.Api.Project.Controllers
return _jwtHandler.GenerateJwtToken(payload);
}
private string BuildAuthHeader(Resource resource, IEnumerable<string> exclude = null)
{
if (exclude != null && exclude.Contains(resource.Type.DisplayName.ToLower()))
{
return null;
}
string authHeader = null;
if (resource.Type.DisplayName.ToLower() == "rds")
{
RDSResourceTypeModel rdsResourceTypeModel = new RDSResourceTypeModel();
var rdsResourceType = rdsResourceTypeModel.GetById(resource.ResourceTypeOptionId.Value);
authHeader = BuildRdsAuthHeader(rdsResourceType);
}
else if (resource.Type.DisplayName.ToLower() == "gitlab")
{
GitlabResourceTypeModel gitlabResourceTypeModel = new GitlabResourceTypeModel();
var gitlabResourceType = gitlabResourceTypeModel.GetById(resource.ResourceTypeOptionId.Value);
authHeader = BuildGitlabAuthHeader(gitlabResourceType);
}
return authHeader;
}
private string BuildRdsAuthHeader(RDSResourceType rdsResourceType)
{
var auth = new Dictionary<string, object>();
......@@ -192,3 +411,4 @@ namespace Coscine.Api.Project.Controllers
}
}
}
#endregion
using Coscine.Api.Project.Models;
using Coscine.Api.Project.ReturnObjects;
using Coscine.ApiCommons;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Coscine.Api.Project.Controllers
{
public class LicenseController : Controller
{
private readonly Authenticator _authenticator;
private readonly LicenseModel _licenseModel;
public LicenseController()
{
_authenticator = new Authenticator(this, Program.Configuration);
_licenseModel = new LicenseModel();
}
[Route("[controller]")]
public IActionResult Index()
{
return Ok(_authenticator.ValidateAndExecute((user) =>
{
return _licenseModel.GetAll().Select((license) => new LicenseObject(license.Id, license.DisplayName));
}));
}
}
}
......@@ -28,13 +28,18 @@ namespace Coscine.Api.Project.Models
{
DisplayName = resourceObject.DisplayName,
ResourceName = resourceObject.ResourceName,
Description = resourceObject.Description,
Keywords = resourceObject.Keywords,
UsageRights = resourceObject.UsageRights,
TypeId = resourceObject.Type.Id,
Type = new ResourceTypeModel().GetById(resourceObject.Type.Id),
VisibilityId = resourceObject.Visibility.Id,
LicenseId = resourceObject.License.Id
};
if(resourceObject.License != null)
{
resource.LicenseId = resourceObject.License.Id;
}
Insert(resource);
try
......@@ -177,12 +182,17 @@ namespace Coscine.Api.Project.Models
resource.DisplayName = resourceObject.DisplayName;
resource.ResourceName = resourceObject.ResourceName;
resource.Description = resourceObject.Description;
resource.Keywords = resourceObject.Keywords;
resource.UsageRights = resourceObject.UsageRights;
resource.TypeId = resourceObject.Type.Id;
resource.Type = new ResourceTypeModel().GetById(resourceObject.Type.Id);
resource.VisibilityId = resourceObject.Visibility.Id;
if(resourceObject.License != null)
{
resource.LicenseId = resourceObject.License.Id;
}
SetDisciplines(resource, resourceObject.Disciplines);
SetResourceTypeObject(resource, resourceObject.ResourceTypeOption);
......@@ -256,6 +266,7 @@ namespace Coscine.Api.Project.Models
resource.Id,
resource.DisplayName,
resource.ResourceName,
resource.Description,
resource.Keywords,
resource.UsageRights,
new ResourceTypeObject(resource.Type.Id, resource.Type.DisplayName),
......
......@@ -45,17 +45,17 @@
<Reference Include="Consul, Version=0.7.2.6, Culture=neutral, PublicKeyToken=20a6ad9a81df1d95, processorArchitecture=MSIL">
<HintPath>..\packages\Consul.0.7.2.6\lib\net45\Consul.dll</HintPath>
</Reference>
<Reference Include="Coscine.Action, Version=1.3.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Coscine.Action.1.3.1\lib\net461\Coscine.Action.dll</HintPath>
<Reference Include="Coscine.Action, Version=1.4.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Coscine.Action.1.4.0\lib\net461\Coscine.Action.dll</HintPath>
</Reference>
<Reference Include="Coscine.ApiCommons, Version=1.2.1.0, Culture=neutral, PublicKeyToken=af4c1345df96546b, processorArchitecture=MSIL">
<HintPath>..\packages\Coscine.ApiCommons.1.2.1\lib\net461\Coscine.ApiCommons.dll</HintPath>
<Reference Include="Coscine.ApiCommons, Version=1.2.2.0, Culture=neutral, PublicKeyToken=af4c1345df96546b, processorArchitecture=MSIL">
<HintPath>..\packages\Coscine.ApiCommons.1.2.2\lib\net461\Coscine.ApiCommons.dll</HintPath>
</Reference>
<Reference Include="Coscine.Configuration, Version=1.4.0.0, Culture=neutral, PublicKeyToken=ce3d7a32d7dc1e5a, processorArchitecture=MSIL">
<HintPath>..\packages\Coscine.Configuration.1.4.0\lib\net461\Coscine.Configuration.dll</HintPath>
</Reference>
<Reference Include="Coscine.Database, Version=1.6.0.0, Culture=neutral, PublicKeyToken=767d77427707b70a, processorArchitecture=MSIL">
<HintPath>..\packages\Coscine.Database.1.6.0\lib\net461\Coscine.Database.dll</HintPath>
<Reference Include="Coscine.Database, Version=1.7.0.0, Culture=neutral, PublicKeyToken=767d77427707b70a, processorArchitecture=MSIL">
<HintPath>..\packages\Coscine.Database.1.7.0\lib\net461\Coscine.Database.dll</HintPath>
</Reference>
<Reference Include="Coscine.ProxyApi, Version=1.2.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Coscine.ProxyApi.1.2.0\lib\net461\Coscine.ProxyApi.dll</HintPath>
......@@ -567,6 +567,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Controllers\DataSourceController.cs" />
<Compile Include="Controllers\LicenseController.cs" />
<Compile Include="Controllers\VisibilityController.cs" />
<Compile Include="Controllers\InstituteController.cs" />
<Compile Include="Controllers\DisciplineController.cs" />
......
......@@ -9,8 +9,8 @@ using System.Reflection;
[assembly: AssemblyDescription("Project is a part of the CoScInE group.")]
[assembly: AssemblyCompany("IT Center, RWTH Aachen University")]
[assembly: AssemblyProduct("Project")]
[assembly: AssemblyVersion("1.4.1.0")]
[assembly: AssemblyFileVersion("1.4.1.0")]
[assembly: AssemblyInformationalVersion("1.4.1.0")]
[assembly: AssemblyVersion("1.5.0.0")]
[assembly: AssemblyFileVersion("1.5.0.0")]
[assembly: AssemblyInformationalVersion("1.5.0.0")]
[assembly: AssemblyCopyright("2019 IT Center, RWTH Aachen University")]
......@@ -11,6 +11,7 @@ namespace Coscine.Api.Project.ReturnObjects
public Guid Id { get; set; }
public string DisplayName { get; set; }
public string ResourceName { get; set; }
public string Description { get; set; }
public string Keywords { get; set; }
public string UsageRights { get; set; }
public ResourceTypeObject Type { get; set; }
......@@ -19,12 +20,13 @@ namespace Coscine.Api.Project.ReturnObjects
public LicenseObject License { get; set; }
public JObject ResourceTypeOption { get; set; }
public ResourceObject(Guid id, string displayName, string resourceName, string keywords, string usageRights, ResourceTypeObject type, IEnumerable<DisciplineObject> disciplines, VisibilityObject visibility, LicenseObject license, JObject resourceTypeOption)
public ResourceObject(Guid id, string displayName, string resourceName, string description, string keywords, string usageRights, ResourceTypeObject type, IEnumerable<DisciplineObject> disciplines, VisibilityObject visibility, LicenseObject license, JObject resourceTypeOption)
{
Id = id;
DisplayName = displayName;
ResourceName = resourceName;
Description = description;
Keywords = keywords;
UsageRights = usageRights;
......
......@@ -9,6 +9,9 @@ namespace Coscine.Api.Project.ReturnObjects
public bool IsFolder { get; set; } = false;
public string Absolutepath { get; set; } = null;
public string Name { get; set; } = null;
public string LastModified { get; set; }
public string Created { get; set; }
public string Size { get; set; }
// Shallow! Only one level deep.
// Should the folder contain additional folders, they will be empty/null.
public List<WaterbutlerObject> Content { get; set; } = null;
......@@ -20,7 +23,7 @@ namespace Coscine.Api.Project.ReturnObjects
public WaterbutlerObject(string path, JToken data)
{
Absolutepath = string.IsNullOrWhiteSpace(path) ? "/" : $"/{path}";
Absolutepath = path;
Content = new List<WaterbutlerObject>();
IsFolder = true;
......@@ -37,7 +40,10 @@ namespace Coscine.Api.Project.ReturnObjects
{
IsFolder = obj["attributes"]["kind"].ToObject<string>() == "folder",
Absolutepath = obj["attributes"]["path"].ToObject<string>(),
Name = obj["attributes"]["name"].ToObject<string>()
Name = obj["attributes"]["name"].ToObject<string>(),
Created = obj["attributes"]["modified_utc"]?.ToObject<string>(),
LastModified = obj["attributes"]["LastModified_utc"]?.ToObject<string>(),
Size = obj["attributes"]["size"]?.ToObject<string>(),
});
}
}
......
......@@ -3,10 +3,10 @@
<package id="AutoMapper" version="8.0.0" targetFramework="net472" />
<package id="AutoMapper.Extensions.Microsoft.DependencyInjection" version="6.0.0" targetFramework="net472" />
<package id="Consul" version="0.7.2.6" targetFramework="net472" />
<package id="Coscine.Action" version="1.3.1" targetFramework="net472" />
<package id="Coscine.ApiCommons" version="1.2.1" targetFramework="net472" />
<package id="Coscine.Action" version="1.4.0" targetFramework="net472" />
<package id="Coscine.ApiCommons" version="1.2.2" targetFramework="net472" />
<package id="Coscine.Configuration" version="1.4.0" targetFramework="net472" />
<package id="Coscine.Database" version="1.6.0" targetFramework="net472" />
<package id="Coscine.Database" version="1.7.0" targetFramework="net472" />
<package id="Coscine.ProxyApi" version="1.2.0" targetFramework="net472" />
<package id="Coscine.SharePoint.Webparts.Vue" version="1.4.0" targetFramework="net472" />
<package id="EntityFramework" version="6.2.0" targetFramework="net472" />
......