Skip to content

Commit

Permalink
Add proxy endpoint for delivering bundles from project portal
Browse files Browse the repository at this point in the history
  • Loading branch information
kjetilhau committed Sep 11, 2024
1 parent f17f776 commit daf8f82
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using Equinor.ProjectExecutionPortal.ClientBackend.Configurations;
using Fusion;
using Microsoft.Extensions.Options;
using Microsoft.Identity.Web;
using Yarp.ReverseProxy.Forwarder;
using Yarp.ReverseProxy.Transforms;

namespace Equinor.ProjectExecutionPortal.ClientBackend.AssetProxy
{
public class FusionAppRequestTransformer : HttpTransformer
{
private readonly ITokenAcquisition _tokenAcquisition;
private readonly FusionProjectPortalApiOptions _options;

public FusionAppRequestTransformer(ITokenAcquisition tokenAcquisition, IOptions<FusionProjectPortalApiOptions> options)
{
_tokenAcquisition = tokenAcquisition;
_options = options.Value;
}

public override async ValueTask TransformRequestAsync(HttpContext httpContext, HttpRequestMessage proxyRequest, string destinationPrefix)
{
var appKey = httpContext.Request.RouteValues["appKey"];

// THIS IS FOR POC ONLY!
// We change the scope to use application permissions
var index = _options.Scope.LastIndexOf("/");
var input = _options.Scope;
if (index >= 0)
{
input = input.Substring(0, index);
}
input = $"{input}/.default";

//var token = await tokenProvider.GetAccessTokenForUserAsync(new[] { options.TokenScope! }, user: httpContext.User);
var token = await _tokenAcquisition.GetAccessTokenForAppAsync(input);

// Copy all request headers
await base.TransformRequestAsync(httpContext, proxyRequest, destinationPrefix);

// Customize the query string:
var queryContext = new QueryTransformContext(httpContext.Request);

// Assign the custom uri. Be careful about extra slashes when concatenating here. RequestUtilities.MakeDestinationAddress is a safe default.
proxyRequest.RequestUri = RequestUtilities.MakeDestinationAddress(_options.BaseAddress!, $"/api/bundles/{appKey}.js", queryContext.QueryString);

proxyRequest.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
proxyRequest.Headers.Add("X-Fusion-App-Bundle-UniqueId", $"{httpContext.User.GetAzureUniqueId()}");

// Suppress the original request header, use the one from the destination Uri.
proxyRequest.Headers.Host = null;
}

public override ValueTask<bool> TransformResponseAsync(HttpContext httpContext, HttpResponseMessage? proxyResponse)
{
// Could remove duplicate headers here
return base.TransformResponseAsync(httpContext, proxyResponse);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ public static IServiceCollection AddFusionPortalAssetProxy(this IServiceCollecti
services.AddScoped<LegacyAppResourcesRequestTransformer>();
services.AddScoped<ProfileImageRequestTransformer>();

services.AddScoped<FusionAppRequestTransformer>();

return services;
}

Expand All @@ -23,6 +25,8 @@ public static IEndpointRouteBuilder MapFusionPortalAssetProxy(this IEndpointRout
endpoints.MapGet("/assets/images/profiles/{uniqueId}", AssetProxyHandler.ProxyRequestAsync<ProfileImageRequestTransformer>);
endpoints.MapGet("/images/profiles/{uniqueId}", AssetProxyHandler.ProxyRequestAsync<ProfileImageRequestTransformer>);

endpoints.MapGet("/bundles/apps/{appKey}", AssetProxyHandler.ProxyRequestAsync<FusionAppRequestTransformer>);

return endpoints;
}
}
Expand Down

0 comments on commit daf8f82

Please sign in to comment.