diff --git a/src/Blob.sln b/src/Blob.sln index 296bd2162ccc065f184ead54a71b89da7a4d7b00..456b4541f48febef3019fc5f7f887f1de3bb037a 100644 --- a/src/Blob.sln +++ b/src/Blob.sln @@ -1,4 +1,4 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.28803.156 diff --git a/src/Blob/App.config b/src/Blob/App.config index 6dcbd11f56fc2901c74017350067f504dfc09a09..1905b168f9900d871d163aac4d628e593df56c88 100644 --- a/src/Blob/App.config +++ b/src/Blob/App.config @@ -165,7 +165,7 @@ </dependentAssembly> <dependentAssembly> <assemblyIdentity name="Coscine.Database" publicKeyToken="767d77427707b70a" culture="neutral" /> - <bindingRedirect oldVersion="0.0.0.0-1.26.0.0" newVersion="1.26.0.0" /> + <bindingRedirect oldVersion="0.0.0.0-1.27.0.0" newVersion="1.27.0.0" /> </dependentAssembly> <dependentAssembly> <assemblyIdentity name="Coscine.ApiCommons" publicKeyToken="af4c1345df96546b" culture="neutral" /> @@ -201,7 +201,7 @@ </dependentAssembly> <dependentAssembly> <assemblyIdentity name="Coscine.Database.T4" publicKeyToken="84b4c404a0696261" culture="neutral" /> - <bindingRedirect oldVersion="0.0.0.0-1.26.0.0" newVersion="1.26.0.0" /> + <bindingRedirect oldVersion="0.0.0.0-1.27.0.0" newVersion="1.27.0.0" /> </dependentAssembly> </assemblyBinding> </runtime> diff --git a/src/Blob/Blob.csproj b/src/Blob/Blob.csproj index 01bbeb17b0c8b3ec5b0101a0f6b9237555f0c9e0..a897c812f7ad39dd02db002ba588f23aedfcfdde 100644 --- a/src/Blob/Blob.csproj +++ b/src/Blob/Blob.csproj @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Import Project="..\packages\EntityFramework.6.4.4\build\EntityFramework.props" Condition="Exists('..\packages\EntityFramework.6.4.4\build\EntityFramework.props')" /> <Import Project="..\packages\NSwag.AspNetCore.13.6.2\build\NSwag.AspNetCore.props" Condition="Exists('..\packages\NSwag.AspNetCore.13.6.2\build\NSwag.AspNetCore.props')" /> @@ -26,7 +26,7 @@ </NuGetPackageImportStamp> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> - <PlatformTarget>AnyCPU</PlatformTarget> + <PlatformTarget>x64</PlatformTarget> <DebugSymbols>true</DebugSymbols> <DebugType>full</DebugType> <Optimize>false</Optimize> @@ -37,21 +37,21 @@ <DocumentationFile>bin\Debug\Coscine.Api.Blob.xml</DocumentationFile> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> - <PlatformTarget>AnyCPU</PlatformTarget> + <PlatformTarget>x64</PlatformTarget> <DebugType>pdbonly</DebugType> <Optimize>true</Optimize> <OutputPath>bin\Release\</OutputPath> <DefineConstants>TRACE</DefineConstants> <ErrorReport>prompt</ErrorReport> <WarningLevel>4</WarningLevel> - <DocumentationFile>bin\Debug\Coscine.Api.Blob.xml</DocumentationFile> + <DocumentationFile>bin\Release\Coscine.Api.Blob.xml</DocumentationFile> </PropertyGroup> <ItemGroup> <Reference Include="AWSSDK.Core, Version=3.3.0.0, Culture=neutral, PublicKeyToken=885c28607f98e604, processorArchitecture=MSIL"> - <HintPath>..\packages\AWSSDK.Core.3.3.107.8\lib\net45\AWSSDK.Core.dll</HintPath> + <HintPath>..\packages\AWSSDK.Core.3.5.1.23\lib\net45\AWSSDK.Core.dll</HintPath> </Reference> <Reference Include="AWSSDK.S3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=885c28607f98e604, processorArchitecture=MSIL"> - <HintPath>..\packages\AWSSDK.S3.3.3.111.9\lib\net45\AWSSDK.S3.dll</HintPath> + <HintPath>..\packages\AWSSDK.S3.3.5.3.1\lib\net45\AWSSDK.S3.dll</HintPath> </Reference> <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> @@ -62,11 +62,11 @@ <Reference Include="Coscine.Configuration, Version=1.5.0.0, Culture=neutral, PublicKeyToken=ce3d7a32d7dc1e5a, processorArchitecture=MSIL"> <HintPath>..\packages\Coscine.Configuration.1.5.0\lib\net461\Coscine.Configuration.dll</HintPath> </Reference> - <Reference Include="Coscine.Database, Version=1.26.0.0, Culture=neutral, PublicKeyToken=767d77427707b70a, processorArchitecture=MSIL"> - <HintPath>..\packages\Coscine.Database.1.26.0\lib\net461\Coscine.Database.dll</HintPath> + <Reference Include="Coscine.Database, Version=1.27.0.0, Culture=neutral, PublicKeyToken=767d77427707b70a, processorArchitecture=MSIL"> + <HintPath>..\packages\Coscine.Database.1.27.0-topic-1159-rtdap0005\lib\net461\Coscine.Database.dll</HintPath> </Reference> - <Reference Include="Coscine.Database.T4, Version=1.26.0.0, Culture=neutral, PublicKeyToken=84b4c404a0696261, processorArchitecture=MSIL"> - <HintPath>..\packages\Coscine.Database.1.26.0\lib\net461\Coscine.Database.T4.dll</HintPath> + <Reference Include="Coscine.Database.T4, Version=1.27.0.0, Culture=neutral, PublicKeyToken=84b4c404a0696261, processorArchitecture=MSIL"> + <HintPath>..\packages\Coscine.Database.1.27.0-topic-1159-rtdap0005\lib\net461\Coscine.Database.T4.dll</HintPath> </Reference> <Reference Include="Coscine.JwtHandler, Version=1.1.0.0, Culture=neutral, processorArchitecture=MSIL"> <HintPath>..\packages\Coscine.JwtHandler.1.1.0\lib\net461\Coscine.JwtHandler.dll</HintPath> @@ -74,6 +74,15 @@ <Reference Include="Coscine.Logging, Version=1.2.0.0, Culture=neutral, PublicKeyToken=e1ed402bc3f6525e, processorArchitecture=MSIL"> <HintPath>..\packages\Coscine.Logging.1.2.0\lib\net461\Coscine.Logging.dll</HintPath> </Reference> + <Reference Include="Coscine.ResourceConfiguration, Version=1.3.0.0, Culture=neutral, processorArchitecture=MSIL"> + <HintPath>..\packages\Coscine.ResourceConfiguration.1.3.0-topic-1159-rtdap0010\lib\net461\Coscine.ResourceConfiguration.dll</HintPath> + </Reference> + <Reference Include="Coscine.ResourceLoader, Version=1.2.0.0, Culture=neutral, processorArchitecture=AMD64"> + <HintPath>..\packages\Coscine.ResourceLoader.1.2.0-topic-1159-rtdap0012\lib\net461\Coscine.ResourceLoader.dll</HintPath> + </Reference> + <Reference Include="Coscine.ResourceTypeBase, Version=1.4.0.0, Culture=neutral, processorArchitecture=MSIL"> + <HintPath>..\packages\Coscine.ResourceTypeBase.1.4.0-topic-1159-rtdap0013\lib\net461\Coscine.ResourceTypeBase.dll</HintPath> + </Reference> <Reference Include="Coscine.WaterbutlerHelper, Version=1.2.1.0, Culture=neutral, processorArchitecture=MSIL"> <HintPath>..\packages\Coscine.WaterbutlerHelper.1.2.1\lib\net461\Coscine.WaterbutlerHelper.dll</HintPath> </Reference> @@ -540,7 +549,7 @@ <None Include="packages.config" /> </ItemGroup> <ItemGroup> - <Analyzer Include="..\packages\AWSSDK.S3.3.3.111.9\analyzers\dotnet\cs\AWSSDK.S3.CodeAnalysis.dll" /> + <Analyzer Include="..\packages\AWSSDK.S3.3.5.3.1\analyzers\dotnet\cs\AWSSDK.S3.CodeAnalysis.dll" /> <Analyzer Include="..\packages\Microsoft.CodeAnalysis.Analyzers.2.9.2\analyzers\dotnet\cs\Microsoft.CodeAnalysis.Analyzers.dll" /> <Analyzer Include="..\packages\Microsoft.CodeAnalysis.Analyzers.2.9.2\analyzers\dotnet\cs\Microsoft.CodeAnalysis.CSharp.Analyzers.dll" /> </ItemGroup> @@ -568,4 +577,4 @@ <Import Project="..\packages\Microsoft.Extensions.ApiDescription.Server.3.0.0\build\Microsoft.Extensions.ApiDescription.Server.targets" Condition="Exists('..\packages\Microsoft.Extensions.ApiDescription.Server.3.0.0\build\Microsoft.Extensions.ApiDescription.Server.targets')" /> <Import Project="..\packages\NSwag.AspNetCore.13.6.2\build\NSwag.AspNetCore.targets" Condition="Exists('..\packages\NSwag.AspNetCore.13.6.2\build\NSwag.AspNetCore.targets')" /> <Import Project="..\packages\EntityFramework.6.4.4\build\EntityFramework.targets" Condition="Exists('..\packages\EntityFramework.6.4.4\build\EntityFramework.targets')" /> -</Project> \ No newline at end of file +</Project> diff --git a/src/Blob/Controllers/BlobController.cs b/src/Blob/Controllers/BlobController.cs index 85a92b13022eff9a0c5abcec5a32d70e9da76c51..e187ee33c11894d2e44df25d2eb79dc4f2ba6c74 100644 --- a/src/Blob/Controllers/BlobController.cs +++ b/src/Blob/Controllers/BlobController.cs @@ -1,25 +1,22 @@ -using Amazon.S3; -using Amazon.S3.Model; -using Coscine.WaterbutlerHelper; -using Coscine.WaterbutlerHelper.Services; -using Coscine.ApiCommons; -using Coscine.ApiCommons.Factories; +using Coscine.ApiCommons; using Coscine.Configuration; using Coscine.Database.DataModel; using Coscine.Database.Models; using Coscine.Database.Util; using Coscine.Logging; +using Coscine.ResourceLoader; +using Coscine.ResourceTypeBase; +using Coscine.WaterbutlerHelper.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.StaticFiles; using Microsoft.Extensions.Logging; using Newtonsoft.Json.Linq; using System; -using System.Linq; +using System.Collections.Generic; using System.Net.Http; using System.Text.RegularExpressions; using System.Threading.Tasks; -using System.Web; -using System.Collections.Generic; namespace Coscine.Api.Blob.Controllers { @@ -27,22 +24,16 @@ namespace Coscine.Api.Blob.Controllers /// This controller represents the actions which can be taken with a Blob object. /// </summary> [Authorize] - + public class BlobController : Controller { private readonly IConfiguration _configuration; private readonly Authenticator _authenticator; private readonly ResourceModel _resourceModel; - private readonly string _accessKey; - private readonly string _secretKey; - private readonly AmazonS3Config _amazonConfig; private readonly ProjectResourceModel _projectResourceModel; private readonly ProjectRoleModel _projectRoleModel; private readonly CoscineLogger _coscineLogger; private readonly AnalyticsLogObject _analyticsLogObject; - private readonly IDataSourceService _dataSourceService; - private readonly string _rdsResourceHost; - private readonly WaterbutlerInterface _waterbutlerInterface; /// <summary> /// Blob controller constructor @@ -57,19 +48,8 @@ namespace Coscine.Api.Blob.Controllers _projectResourceModel = new ProjectResourceModel(); _projectRoleModel = new ProjectRoleModel(); - _accessKey = _configuration.GetStringAndWait("coscine/global/ecs/object_user_name"); - _secretKey = _configuration.GetStringAndWait("coscine/global/ecs/object_user_secretkey"); - _rdsResourceHost = _configuration.GetString("coscine/global/ecs/s3_endpoint"); - _coscineLogger = new CoscineLogger(logger); _analyticsLogObject = new AnalyticsLogObject(); - _amazonConfig = new AmazonS3Config - { - ServiceURL = _rdsResourceHost, - ForcePathStyle = true - }; - _dataSourceService = dataSourceService; - _waterbutlerInterface = new WaterbutlerInterface(_configuration, _dataSourceService); } /// <summary> /// This method returns the amount of allocated space for the given resource @@ -77,7 +57,7 @@ namespace Coscine.Api.Blob.Controllers /// <param name="resourceId">Id of a resource</param> /// <returns>Data, file count and bytesize used or Status Code 400, 404, 401 or 500 </returns> [HttpGet("[controller]/{resourceId}/quota")] - public IActionResult GetQuota (string resourceId) + public IActionResult GetQuota(string resourceId) { if (!Guid.TryParse(resourceId, out Guid resourceGuid)) { @@ -112,37 +92,20 @@ namespace Coscine.Api.Blob.Controllers if (resource.Type.DisplayName.ToLower() == "rds" && resource.ResourceTypeOptionId.HasValue) { - var rdsResourceTypeModel = new RDSResourceTypeModel(); - var rdsResourceType = rdsResourceTypeModel.GetById(resource.ResourceTypeOptionId.Value); - var bucketname = rdsResourceType.BucketName; - - using (var client = new AmazonS3Client(_accessKey, _secretKey, _amazonConfig)) + try { - long totalFileSize = 0; - long fileCount = 0; - ListObjectsRequest listReqeust = new ListObjectsRequest() + var resourceTypeOptions = _resourceModel.GetResourceTypeOptions(resource.Id); + var resourceTypeDefinition = ResourceTypeFactory.CreateResourceTypeObject(resource.Type.DisplayName, _configuration); + if (resourceTypeDefinition == null) { - BucketName = bucketname - }; - - ListObjectsResponse listResponse; - try - { - do - { - listResponse = client.ListObjects(listReqeust); - fileCount += listResponse.S3Objects.Count(); - totalFileSize += listResponse.S3Objects.Sum(x => x.Size); - listReqeust.Marker = listResponse.NextMarker; - - } while (listResponse.IsTruncated); - } - catch (Exception) - { - return StatusCode(500); + return BadRequest($"No provider for: \"{resource.Type.DisplayName}\"."); } - - return Ok($"{{ \"data\": {{ \"fileCount\": {fileCount}, \"usedSizeByte\": {totalFileSize} }}}}"); + var totalFileSize = resourceTypeDefinition.GetResourceQuotaUsed(resourceId, resourceTypeOptions).Result; + return Ok($"{{ \"data\": {{ \"usedSizeByte\": {totalFileSize} }}}}"); + } + catch + { + return BadRequest($"Error in communication with the resource"); } } else @@ -151,10 +114,6 @@ namespace Coscine.Api.Blob.Controllers } } - // 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! - /// <summary> /// This method checks if the given file exists and returns it /// </summary> @@ -184,70 +143,28 @@ namespace Coscine.Api.Blob.Controllers return Forbid("User does not have permission to the resource."); } - var resourceTypeOptions = new Dictionary<string, string>(); - if (resource.Type.DisplayName == "rds") - { - var data = new RDSResourceTypeModel().GetById((Guid)resource.ResourceTypeOptionId); - resourceTypeOptions.Add("bucketname", data.BucketName); - } - else if (resource.Type.DisplayName == "s3") - { - var data = new S3ResourceTypeModel().GetById((Guid)resource.ResourceTypeOptionId); - resourceTypeOptions.Add("accessKey", data.AccessKey); - resourceTypeOptions.Add("secretKey", data.SecretKey); - resourceTypeOptions.Add("bucketname", data.BucketName); - resourceTypeOptions.Add("resourceUrl", data.ResourceUrl); - } - else if (resource.Type.DisplayName == "gitlab") - { - var data = new GitlabResourceTypeModel().GetById((Guid)resource.ResourceTypeOptionId); - resourceTypeOptions.Add("token", data.Token); - resourceTypeOptions.Add("repositoryUrl", data.RepositoryUrl); - resourceTypeOptions.Add("repositoryNumber", data.RepositoryNumber.ToString()); - } - var authHeader = _waterbutlerInterface.BuildAuthHeader(resource.Type.DisplayName, resourceTypeOptions); - - if (authHeader == null) - { - return BadRequest($"No provider for: \"{resource.Type.DisplayName}\"."); - } - - var provider = GetResourceTypeName(resource); - var infos = await _waterbutlerInterface.GetObjectInfoAsync(path, provider, authHeader); - - // Not found - if (infos == null) - { - return NotFound($"Found nothing in waterbutler under \"{path}\"."); - } - - // Not a file - if (infos.Count > 1 || !infos.First().IsFile) + var resourceTypeOptions = _resourceModel.GetResourceTypeOptions(resource.Id); + try { - return NoContent(); - } + var resourceTypeDefinition = ResourceTypeFactory.CreateResourceTypeObject(resource.Type.DisplayName, _configuration); + if (resourceTypeDefinition == null) + { + return BadRequest($"No provider for: \"{resource.Type.DisplayName}\"."); + } - // Do not dispose the response! - // The stream is later accessed by the MVC, to deliver the file. - // When disposed, the stream becomes invalid and can't be read. - var response = await _waterbutlerInterface.DownloadObjectAsync(infos.First(), authHeader); - if (response.IsSuccessStatusCode) - { + var infos = await resourceTypeDefinition.GetEntry(resource.Id.ToString(), path, null, resourceTypeOptions); + var response = await resourceTypeDefinition.LoadEntry(resource.Id.ToString(), path, null, resourceTypeOptions); + new FileExtensionContentTypeProvider().TryGetContentType(path.Substring(path.LastIndexOf("/")), out string contentType); LogAnalytics("Download File", resourceId, path.Substring(1), user); - return File(await response.Content.ReadAsStreamAsync(), - response.Content.Headers.GetValues("Content-Type").First()); + return File(response, contentType); } - else + catch { - return FailedRequest(response, path); + return BadRequest($"Error in communication with the 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! - /// <summary> /// This method uploads a given File /// </summary> @@ -274,77 +191,34 @@ namespace Coscine.Api.Blob.Controllers if (user == null || !_resourceModel.HasAccess(user, resource, UserRoles.Owner, UserRoles.Member)) { - return Forbid("User does not have permission to the resource."); - } - - var resourceTypeOptions = new Dictionary<string, string>(); - if (resource.Type.DisplayName == "rds") - { - var data = new RDSResourceTypeModel().GetById((Guid)resource.ResourceTypeOptionId); - resourceTypeOptions.Add("bucketname", data.BucketName); - } - else if (resource.Type.DisplayName == "s3") - { - var data = new S3ResourceTypeModel().GetById((Guid)resource.ResourceTypeOptionId); - resourceTypeOptions.Add("accessKey", data.AccessKey); - resourceTypeOptions.Add("secretKey", data.SecretKey); - resourceTypeOptions.Add("bucketname", data.BucketName); - resourceTypeOptions.Add("resourceUrl", data.ResourceUrl); + return Forbid("User does not have permission to the resource."); } - var authHeader = _waterbutlerInterface.BuildAuthHeader(resource.Type.DisplayName, resourceTypeOptions); - if (authHeader == null) - { - return BadRequest($"No provider for: \"{resource.Type.DisplayName}\"."); - } - else + try { - var provider = GetResourceTypeName(resource); - var infos = await _waterbutlerInterface.GetObjectInfoAsync(path, provider, authHeader); - - // Not found, upload new - if (infos == null) + var resourceTypeOptions = _resourceModel.GetResourceTypeOptions(resource.Id); + var resourceTypeDefinition = ResourceTypeFactory.CreateResourceTypeObject(resource.Type.DisplayName, _configuration); + if (resourceTypeDefinition == null) { - var filename = path.Substring(path.LastIndexOf("/") + 1); - var rootPath = path.Substring(0, path.Length - filename.Length); - - using (var response = await _waterbutlerInterface.UploadFileAsync(rootPath, filename, provider, authHeader, Request.Body)) - { - if (response.IsSuccessStatusCode) - { - LogAnalytics("Upload File", resourceId, path, user); - return NoContent(); - } - else - { - return FailedRequest(response, path); - } - } + return BadRequest($"No provider for: \"{resource.Type.DisplayName}\"."); } - else - { - // update existing file - // Not a file - if (infos.Count > 1 || !infos.First().IsFile) - { - return BadRequest("Not an updatable or new file."); - } - - using (var response = await _waterbutlerInterface.UploadObjectAsync(infos.First(), authHeader, Request.Body)) - { - if (response.IsSuccessStatusCode) - { - LogAnalytics("Update File", resourceId, path, user); - return NoContent(); - } - else - { - return FailedRequest(response, path); - } - } + ResourceEntry infos = null; + try + { + infos = await resourceTypeDefinition.GetEntry(resource.Id.ToString(), path, null, resourceTypeOptions); } - + catch + { + // do nothing + } + await resourceTypeDefinition.StoreEntry(resource.Id.ToString(), path, Request.Body, resourceTypeOptions); + LogAnalytics(infos == null ? "Upload File" : "Update File", resourceId, path, user); + return NoContent(); + } + catch + { + return BadRequest($"Error in communication with the resource"); } } /// <summary> @@ -375,56 +249,22 @@ namespace Coscine.Api.Blob.Controllers return Forbid("User does not have permission to the resource."); } - var resourceTypeOptions = new Dictionary<string, string>(); - if (resource.Type.DisplayName == "rds") - { - var data = new RDSResourceTypeModel().GetById((Guid)resource.ResourceTypeOptionId); - resourceTypeOptions.Add("bucketname", data.BucketName); - } - else if (resource.Type.DisplayName == "s3") - { - var data = new S3ResourceTypeModel().GetById((Guid)resource.ResourceTypeOptionId); - resourceTypeOptions.Add("accessKey", data.AccessKey); - resourceTypeOptions.Add("secretKey", data.SecretKey); - resourceTypeOptions.Add("bucketname", data.BucketName); - resourceTypeOptions.Add("resourceUrl", data.ResourceUrl); - } - var authHeader = _waterbutlerInterface.BuildAuthHeader(resource.Type.DisplayName, resourceTypeOptions); - - if (authHeader == null) - { - return BadRequest($"No provider for: \"{resource.Type.DisplayName}\"."); - } - else + try { - - var provider = GetResourceTypeName(resource); - var infos = await _waterbutlerInterface.GetObjectInfoAsync(path, provider, authHeader); - - // Not found - if (infos == null) + var resourceTypeOptions = _resourceModel.GetResourceTypeOptions(resource.Id); + var resourceTypeDefinition = ResourceTypeFactory.CreateResourceTypeObject(resource.Type.DisplayName, _configuration); + if (resourceTypeDefinition == null) { - return NotFound($"Found nothing in waterbutler under {path}."); + return BadRequest($"No provider for: \"{resource.Type.DisplayName}\"."); } - // Not a file - if (infos.Count > 1 || !infos.First().IsFile) - { - return BadRequest("Not a file"); - } - - using (var response = await _waterbutlerInterface.DeleteObjectAsync(infos.First(), authHeader)) - { - if (response.IsSuccessStatusCode) - { - LogAnalytics("Delete File", resourceId, path, user); - return NoContent(); - } - else - { - return FailedRequest(response, path); - } - } + await resourceTypeDefinition.DeleteEntry(resource.Id.ToString(), path, resourceTypeOptions); + LogAnalytics("Delete File", resourceId, path, user); + return NoContent(); + } + catch + { + return BadRequest($"Error in communication with the resource"); } } /// <summary> @@ -434,89 +274,40 @@ namespace Coscine.Api.Blob.Controllers [HttpPost("[controller]/validate")] public async Task<IActionResult> IsResourceValid([FromBody] JToken resource) { - var path = "/"; + var displayName = resource["type"]["displayName"].ToString().ToLower(); - string authHeader = null; - if (resource["type"]["displayName"].ToString().ToLower() == "s3") + var resourceTypeOptions = new Dictionary<string, string>(); + if (displayName == "s3") { - authHeader = _waterbutlerInterface.BuildS3AuthHeader( - resource["resourceTypeOption"]["AccessKey"].ToString(), - resource["resourceTypeOption"]["SecretKey"].ToString(), - resource["resourceTypeOption"]["BucketName"].ToString(), - resource["resourceTypeOption"]["ResourceUrl"].ToString()); + resourceTypeOptions.Add("accessKey", resource["resourceTypeOption"]["AccessKey"].ToString()); + resourceTypeOptions.Add("secretKey", resource["resourceTypeOption"]["SecretKey"].ToString()); + resourceTypeOptions.Add("bucketname", resource["resourceTypeOption"]["BucketName"].ToString()); + resourceTypeOptions.Add("resourceUrl", resource["resourceTypeOption"]["ResourceUrl"].ToString()); } - else if (resource["type"]["displayName"].ToString().ToLower() == "gitlab") + else if (displayName == "gitlab") { - authHeader = _waterbutlerInterface.BuildGitlabAuthHeader( - resource["resourceTypeOption"]["Token"].ToString(), - resource["resourceTypeOption"]["RepositoryUrl"].ToString(), - resource["resourceTypeOption"]["RepositoryNumber"].ToString()); + resourceTypeOptions.Add("token", resource["resourceTypeOption"]["Token"].ToString()); + resourceTypeOptions.Add("repositoryUrl", resource["resourceTypeOption"]["RepositoryUrl"].ToString()); + resourceTypeOptions.Add("repositoryNumber", resource["resourceTypeOption"]["RepositoryNumber"].ToString()); } - if (authHeader == null) - { - return BadRequest($"No provider for: \"{resource["type"]["displayName"]}\"."); - } - else + try { - var provider = GetResourceTypeName(resource); - var infos = await _waterbutlerInterface.GetObjectInfoAsync(path, provider, authHeader); - - // Not found - if (infos == null) + var resourceTypeDefinition = ResourceTypeFactory.CreateResourceTypeObject(displayName, _configuration); + if (resourceTypeDefinition == null) { - return NotFound($"Found nothing in waterbutler under {path}."); + return BadRequest($"No provider for: \"{displayName}\"."); } + await resourceTypeDefinition.IsResourceCreated("", resourceTypeOptions); return NoContent(); } - } - /// <summary> - /// Returns the name of the resource - /// </summary> - private string GetResourceTypeName(Resource resource) - { - if (resource.Type.DisplayName.ToLower().Equals("s3")) - { - return "rds"; - } - else + catch { - return resource.Type.DisplayName.ToLower(); - } - } - /// <summary> - /// Returns the name of the resource - /// </summary> - private string GetResourceTypeName(JToken resource) - { - if (resource["type"]["displayName"].ToString().ToLower().Equals("s3")) - { - return "rds"; - } - else - { - return resource["type"]["displayName"].ToString().ToLower(); - } - } - /// <summary> - /// Creates an Action Result that can be returned on error - /// </summary> - private IActionResult FailedRequest(HttpResponseMessage response, string path) - { - if (response.StatusCode == System.Net.HttpStatusCode.NotFound) - { - return NotFound($"Could not find object for: \"{path}\"."); - } - else if (response.StatusCode == System.Net.HttpStatusCode.Forbidden) - { - return Forbid("Not allowed to access the datasource."); - } - else - { - return BadRequest($"Error in communication with waterbutler: {response.StatusCode}"); + return BadRequest($"Error in communication with the resource"); } } + /// <summary> /// Tries to establish connection with resource and validates wether the given file/folder exists /// </summary> diff --git a/src/Blob/packages.config b/src/Blob/packages.config index 71f0a36d4463cf6ddd60308fd6b57b29914a9d54..be535cb117aea27fcc72f346d60fbe45cb8691a0 100644 --- a/src/Blob/packages.config +++ b/src/Blob/packages.config @@ -1,13 +1,16 @@ <?xml version="1.0" encoding="utf-8"?> <packages> - <package id="AWSSDK.Core" version="3.3.107.8" targetFramework="net461" /> - <package id="AWSSDK.S3" version="3.3.111.9" targetFramework="net461" /> + <package id="AWSSDK.Core" version="3.5.1.23" targetFramework="net461" /> + <package id="AWSSDK.S3" version="3.5.3.1" targetFramework="net461" /> <package id="Consul" version="0.7.2.6" targetFramework="net461" /> <package id="Coscine.ApiCommons" version="1.10.0" targetFramework="net461" /> <package id="Coscine.Configuration" version="1.5.0" targetFramework="net461" /> - <package id="Coscine.Database" version="1.26.0" targetFramework="net461" /> + <package id="Coscine.Database" version="1.27.0-topic-1159-rtdap0005" targetFramework="net461" /> <package id="Coscine.JwtHandler" version="1.1.0" targetFramework="net461" /> <package id="Coscine.Logging" version="1.2.0" targetFramework="net461" /> + <package id="Coscine.ResourceConfiguration" version="1.3.0-topic-1159-rtdap0010" targetFramework="net461" /> + <package id="Coscine.ResourceLoader" version="1.2.0-topic-1159-rtdap0012" targetFramework="net461" /> + <package id="Coscine.ResourceTypeBase" version="1.4.0-topic-1159-rtdap0013" targetFramework="net461" /> <package id="Coscine.WaterbutlerHelper" version="1.2.1" targetFramework="net461" /> <package id="EntityFramework" version="6.4.4" targetFramework="net461" /> <package id="linq2db" version="3.1.1" targetFramework="net461" />