Skip to content
Snippets Groups Projects
Select Git revision
  • 8abe8e6a2f8bf5a8a3c093c2441dc44b311caa90
  • main default protected
  • gitkeep
  • dev
  • ipynb
  • 81-add-id-to-figure-file-metadata
  • v0.3.2
  • v0.3.1
  • v0.3.0
  • v0.2.3
  • test_tag
  • v0.2.2
  • v.0.2.1
  • v0.2.1
  • v0.1.2
  • v0.1.1
  • v0.1.0
17 results

conf.py

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    DataSourceController.cs 6.75 KiB
    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}");
                }
    
                var user = _authenticator.GetUserFromToken();
                if (!_resourceModel.OwnsResource(user, resource))
                {
                    return Forbid($"The user does not own the resource {resourceId}");
                }
    
                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(resource.ExternalId, resource.Url);
                }
    
                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 BuildWaterbutlerPayload(Dictionary<string, object> auth, Dictionary<string, object> credentials, Dictionary<string, object> settings)
            {
                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 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 }
                };
    
                return BuildWaterbutlerPayload(auth, credentials, settings);
            }
    
            private string BuildGitlabAuthHeader(string externalId, string url)
            {
    
                var auth = new Dictionary<string, object>();
    
                var credentials = new Dictionary<string, object>
                {
                    { "token", _configuration.GetString("coscine/global/gitlabtoken") }
                };
    
                var settings = new Dictionary<string, object>
                {
                    {"owner", "Tester"},
                    {"repo", url},
                    { "repo_id", externalId},
                    { "host", "https://git.rwth-aachen.de"}
                };
    
                return BuildWaterbutlerPayload(auth, credentials, settings);
            }
        }
    }