Skip to content
Snippets Groups Projects

Topic/209 connect to rds

Merged David Schimmel requested to merge Topic/209-connectToRds into Product/152-connectToRds
3 files
+ 218
0
Compare changes
  • Side-by-side
  • Inline
Files
3
+ 170
0
using Coscine.Api.Project.Models;
using Coscine.Api.Project.ReturnObjects;
using Coscine.ApiCommons;
using Coscine.ApiCommons.Utils;
using Coscine.Configuration;
using Coscine.Database.Model;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
namespace Coscine.Api.Project.Controllers
{
public class DataSourceController : Controller
{
private readonly IConfiguration _configuration;
private readonly JWTHandler _jwtHandler;
private static readonly HttpClient _client = new HttpClient();
private readonly Authenticator _authenticator;
private readonly ResourceModel _resourceModel;
public DataSourceController()
{
_configuration = Program.Configuration;
_jwtHandler = new JWTHandler(_configuration);
_authenticator = new Authenticator(this, _configuration);
_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> Get(string resourceId, string path)
{
if (!Guid.TryParse(resourceId, out Guid resouceGuid))
{
return BadRequest($"{resourceId} is not a guid.");
}
Resource resource;
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}");
}
// Temporary
#if (!DEBUG)
var user = _authenticator.GetUserFromToken();
if (!_resourceModel.OwnsResource(user, resource))
{
return Forbid($"The user does not own the resource {resourceId}");
}
#endif
if (resource.Type == null)
{
ResourceTypeModel resourceTypeModel = new ResourceTypeModel();
resource.Type = resourceTypeModel.GetById(resource.TypeId);
}
string authHeader = null;
if (resource.Type.DisplayName.ToLower() == "rds")
{
authHeader = BuildRdsAuthHeader(resource.ExternalId);
}
else if (resource.Type.DisplayName.ToLower() == "gitlab")
{
authHeader = BuildGitlabAuthHeader();
}
if (authHeader != null)
{
// 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
{
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}");
}
}
}
else
{
return BadRequest($"No provider for: \"{resource.Type.DisplayName}\".");
}
}
private string BuildRdsAuthHeader(string bucketname)
{
var auth = new Dictionary<string, object>();
var credentials = new Dictionary<string, object>
{
{ "access_key", _configuration.GetString("coscine/global/rds_access_key") },
{ "secret_key", _configuration.GetString("coscine/global/rds_secret_key") }
};
var settings = new Dictionary<string, object>
{
{ "bucket", bucketname }
};
var data = new Dictionary<string, object>
{
{ "auth", auth },
{ "credentials", credentials },
{ "settings", settings },
{ "callback_url", "rwth-aachen.de" }
};
var payload = new JwtPayload
{
{ "data", data }
};
return _jwtHandler.GenerateJwtToken(payload);
}
private string BuildGitlabAuthHeader()
{
return null;
}
}
}
Loading