Skip to content

Commit

Permalink
Merge pull request #6395 from elsa-workflows/improvement/configurable…
Browse files Browse the repository at this point in the history
…-tenant-http-header

Add customizable tenant header support for HTTP routing
  • Loading branch information
sfmskywalker authored Feb 10, 2025
2 parents 484a126 + 689fd6f commit 9a2483b
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 5 deletions.
3 changes: 1 addition & 2 deletions Elsa.sln
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docker", "docker", "{986E54
ProjectSection(SolutionItems) = preProject
docker\.dockerignore = docker\.dockerignore
docker\docker-compose-datadog.yml = docker\docker-compose-datadog.yml
docker\docker-compose-kafka.yml = docker\docker-compose-kafka.yml
docker\docker-compose.yml = docker\docker-compose.yml
docker\ElsaServer-Datadog.Dockerfile = docker\ElsaServer-Datadog.Dockerfile
docker\ElsaServer.Dockerfile = docker\ElsaServer.Dockerfile
docker\ElsaServerAndStudio.Dockerfile = docker\ElsaServerAndStudio.Dockerfile
docker\ElsaStudio.Dockerfile = docker\ElsaStudio.Dockerfile
docker\otel-collector-config.yaml = docker\otel-collector-config.yaml
docker\docker-compose-kafka.yml = docker\docker-compose-kafka.yml
docker\init-db-postgres.sh = docker\init-db-postgres.sh
EndProjectSection
EndProject
Expand Down Expand Up @@ -399,6 +397,7 @@ EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Sql.Sqlite", "src\modules\Elsa.Sql.Sqlite\Elsa.Sql.Sqlite.csproj", "{FA5E857F-B173-4B5D-8049-B817A210DEF5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Sql.SqlServer", "src\modules\Elsa.Sql.SqlServer\Elsa.Sql.SqlServer.csproj", "{A51F9683-DA9F-45E7-82DE-1E261ACD6D68}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "oracle-setup", "oracle-setup", "{66E2E2CF-967F-4564-89E8-F46FA973C99B}"
ProjectSection(SolutionItems) = preProject
docker\oracle-setup\setup.sql = docker\oracle-setup\setup.sql
Expand Down
6 changes: 5 additions & 1 deletion src/apps/Elsa.Server.Web/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,11 @@
}
});

elsa.UseTenantHttpRouting();
elsa.UseTenantHttpRouting(tenantHttpRouting =>
{
// Override the tenant header name with a custom one.
tenantHttpRouting.WithTenantHeader("X-Company-Id");
});
}

elsa.InstallDropIns(options => options.DropInRootDirectory = Path.Combine(Directory.GetCurrentDirectory(), "App_Data", "DropIns"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Elsa.Features.Attributes;
using Elsa.Features.Services;
using Elsa.Http.Features;
using Elsa.Tenants.AspNetCore.Options;
using Elsa.Tenants.AspNetCore.Services;
using Elsa.Tenants.Features;
using Microsoft.Extensions.DependencyInjection;
Expand All @@ -13,6 +14,26 @@ namespace Elsa.Tenants.AspNetCore.Features;
[DependencyOf(typeof(TenantsFeature))]
public class MultitenantHttpRoutingFeature(IModule module) : FeatureBase(module)
{
private Action<MultitenancyHttpOptions> _configureMultitenancyHttpOptions = _ => { };

/// <summary>
/// Configures the MultitenantHttpRoutingFeature to use a specific tenant header name.
/// </summary>
/// <param name="headerName">The name of the HTTP header used to identify the tenant.</param>
/// <returns>The current instance of <see cref="MultitenantHttpRoutingFeature"/> for fluent configuration.</returns>
public MultitenantHttpRoutingFeature WithTenantHeader(string headerName) => WithMultitenancyHttpOptions(options => options.TenantHeaderName = headerName);

/// <summary>
/// Configures the MultitenantHttpRoutingFeature with custom multitenancy HTTP options.
/// </summary>
/// <param name="configure">The action to configure <see cref="MultitenancyHttpOptions"/>.</param>
/// <returns>The current instance of <see cref="MultitenantHttpRoutingFeature"/> for fluent configuration.</returns>
public MultitenantHttpRoutingFeature WithMultitenancyHttpOptions(Action<MultitenancyHttpOptions> configure)
{
_configureMultitenancyHttpOptions = configure;
return this;
}

public override void Configure()
{
Module.Configure<HttpFeature>(feature =>
Expand All @@ -24,6 +45,9 @@ public override void Configure()

public override void Apply()
{
// Multitenancy HTTP options.
Services.Configure(_configureMultitenancyHttpOptions);

// Tenant resolvers.
Services
.AddScoped<ITenantResolver, RoutePrefixTenantResolver>()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Elsa.Tenants.AspNetCore.Options;

public class MultitenancyHttpOptions
{
public string TenantHeaderName { get; set; } = "X-Tenant-Id";
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
using Elsa.Common.Multitenancy;
using Elsa.Tenants.AspNetCore.Options;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Options;

namespace Elsa.Tenants.AspNetCore;

/// <summary>
/// Resolves the tenant based on the header in the request.
/// </summary>
public class HeaderTenantResolver(IHttpContextAccessor httpContextAccessor) : TenantResolverBase
public class HeaderTenantResolver(IHttpContextAccessor httpContextAccessor, IOptions<MultitenancyHttpOptions> options) : TenantResolverBase
{
protected override TenantResolverResult Resolve(TenantResolverContext context)
{
Expand All @@ -15,7 +17,8 @@ protected override TenantResolverResult Resolve(TenantResolverContext context)
if (httpContext == null)
return Unresolved();

var tenantId = httpContext.Request.Headers["X-Tenant-Id"].FirstOrDefault();
var headerName = options.Value.TenantHeaderName;
var tenantId = httpContext.Request.Headers[headerName].FirstOrDefault();

return AutoResolve(tenantId);
}
Expand Down

0 comments on commit 9a2483b

Please sign in to comment.