Browse Source

Introduce ITenantResolveResultAccessor.

pull/926/head
Halil ibrahim Kalkan 7 years ago
parent
commit
25bf043c8e
  1. 4
      framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/CookieTenantResolveContributor.cs
  2. 4
      framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/DomainTenantResolveContributor.cs
  3. 4
      framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/HeaderTenantResolveContributor.cs
  4. 40
      framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/HttpContextTenantResolveResultAccessor.cs
  5. 4
      framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/HttpTenantResolveContributerBase.cs
  6. 9
      framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/ITenantResolveResultAccessor.cs
  7. 35
      framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/MultiTenancyMiddleware.cs
  8. 4
      framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/QueryStringTenantResolveContributor.cs
  9. 4
      framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/RouteTenantResolveContributor.cs
  10. 4
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/en.json
  11. 4
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/tr.json
  12. 8
      framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ActionTenantResolveContributor.cs
  13. 4
      framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/AsyncLocalCurrentTenantAccessor.cs
  14. 8
      framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/CurrentClaimsPrincipalTenantResolveContributor.cs
  15. 16
      framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/CurrentTenant.cs
  16. 12
      framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ICurrentTenantAccessor.cs
  17. 13
      framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ICurrentTenantIdAccessor.cs
  18. 2
      framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ITenantResolveContributor.cs
  19. 4
      framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ITenantResolver.cs
  20. 10
      framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/TenantResolveContributorBase.cs
  21. 16
      framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/TenantResolveResult.cs
  22. 18
      framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/TenantResolver.cs

4
framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/CookieTenantResolveContributor.cs

@ -5,6 +5,10 @@ namespace Volo.Abp.AspNetCore.MultiTenancy
{
public class CookieTenantResolveContributor : HttpTenantResolveContributorBase
{
public const string ContributorName = "Cookie";
public override string Name => ContributorName;
protected override string GetTenantIdOrNameFromHttpContextOrNull(ITenantResolveContext context, HttpContext httpContext)
{
return httpContext.Request?.Cookies[context.GetAspNetCoreMultiTenancyOptions().TenantKey];

4
framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/DomainTenantResolveContributor.cs

@ -9,6 +9,10 @@ namespace Volo.Abp.AspNetCore.MultiTenancy
public class DomainTenantResolveContributor : HttpTenantResolveContributorBase
{
public const string ContributorName = "Domain";
public override string Name => ContributorName;
private static readonly string[] ProtocolPrefixes = { "http://", "https://" };
private readonly string _domainFormat;

4
framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/HeaderTenantResolveContributor.cs

@ -9,6 +9,10 @@ namespace Volo.Abp.AspNetCore.MultiTenancy
{
public class HeaderTenantResolveContributor : HttpTenantResolveContributorBase
{
public const string ContributorName = "Header";
public override string Name => ContributorName;
protected override string GetTenantIdOrNameFromHttpContextOrNull(ITenantResolveContext context, HttpContext httpContext)
{
if (httpContext.Request == null || httpContext.Request.Headers.IsNullOrEmpty())

40
framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/HttpContextTenantResolveResultAccessor.cs

@ -0,0 +1,40 @@
using JetBrains.Annotations;
using Microsoft.AspNetCore.Http;
using Volo.Abp.DependencyInjection;
using Volo.Abp.MultiTenancy;
namespace Volo.Abp.AspNetCore.MultiTenancy
{
public class HttpContextTenantResolveResultAccessor : ITenantResolveResultAccessor, ITransientDependency
{
[CanBeNull]
public TenantResolveResult Result
{
get
{
if (_httpContextAccessor.HttpContext == null)
{
return null;
}
return _httpContextAccessor.HttpContext.Items[""] as TenantResolveResult;
}
set
{
if (_httpContextAccessor.HttpContext == null)
{
return;
}
_httpContextAccessor.HttpContext.Items[""] = value;
}
}
private readonly IHttpContextAccessor _httpContextAccessor;
public HttpContextTenantResolveResultAccessor(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
}
}

4
framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/HttpTenantResolveContributerBase.cs

@ -7,9 +7,9 @@ using Volo.Abp.MultiTenancy;
namespace Volo.Abp.AspNetCore.MultiTenancy
{
public abstract class HttpTenantResolveContributorBase : ITenantResolveContributor
public abstract class HttpTenantResolveContributorBase : TenantResolveContributorBase
{
public virtual void Resolve(ITenantResolveContext context)
public override void Resolve(ITenantResolveContext context)
{
var httpContext = context.GetHttpContext();
if (httpContext == null)

9
framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/ITenantResolveResultAccessor.cs

@ -0,0 +1,9 @@
using Volo.Abp.MultiTenancy;
namespace Volo.Abp.AspNetCore.MultiTenancy
{
public interface ITenantResolveResultAccessor
{
TenantResolveResult Result { get; set; }
}
}

35
framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/MultiTenancyMiddleware.cs

@ -12,43 +12,44 @@ namespace Volo.Abp.AspNetCore.MultiTenancy
private readonly ITenantResolver _tenantResolver;
private readonly ITenantStore _tenantStore;
private readonly ICurrentTenant _currentTenant;
private readonly ITenantResolveResultAccessor _tenantResolveResultAccessor;
public MultiTenancyMiddleware(
RequestDelegate next,
ITenantResolver tenantResolver,
ITenantStore tenantStore,
ICurrentTenant currentTenant)
ICurrentTenant currentTenant,
ITenantResolveResultAccessor tenantResolveResultAccessor)
{
_next = next;
_tenantResolver = tenantResolver;
_tenantStore = tenantStore;
_currentTenant = currentTenant;
_tenantResolveResultAccessor = tenantResolveResultAccessor;
}
public async Task Invoke(HttpContext httpContext)
{
var tenant = await ResolveCurrentTenantAsync();
using (_currentTenant.Change(tenant?.Id, tenant?.Name))
{
await _next(httpContext);
}
}
var resolveResult = _tenantResolver.ResolveTenantIdOrName();
_tenantResolveResultAccessor.Result = resolveResult;
private async Task<TenantConfiguration> ResolveCurrentTenantAsync()
{
var tenantIdOrName = _tenantResolver.ResolveTenantIdOrName();
if (tenantIdOrName == null)
TenantConfiguration tenant = null;
if (resolveResult.TenantIdOrName != null)
{
return null;
tenant = await FindTenantAsync(resolveResult.TenantIdOrName);
if (tenant == null)
{
//TODO: A better exception?
throw new AbpException(
"There is no tenant with given tenant id or name: " + resolveResult.TenantIdOrName
);
}
}
var tenant = await FindTenantAsync(tenantIdOrName);
if (tenant == null)
using (_currentTenant.Change(tenant?.Id, tenant?.Name))
{
throw new AbpException("There is no tenant with given tenant id or name: " + tenantIdOrName);
await _next(httpContext);
}
return tenant;
}
private async Task<TenantConfiguration> FindTenantAsync(string tenantIdOrName)

4
framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/QueryStringTenantResolveContributor.cs

@ -5,6 +5,10 @@ namespace Volo.Abp.AspNetCore.MultiTenancy
{
public class QueryStringTenantResolveContributor : HttpTenantResolveContributorBase
{
public const string ContributorName = "QueryString";
public override string Name => ContributorName;
protected override string GetTenantIdOrNameFromHttpContextOrNull(ITenantResolveContext context, HttpContext httpContext)
{
if (httpContext.Request == null || !httpContext.Request.QueryString.HasValue)

4
framework/src/Volo.Abp.AspNetCore.MultiTenancy/Volo/Abp/AspNetCore/MultiTenancy/RouteTenantResolveContributor.cs

@ -7,6 +7,10 @@ namespace Volo.Abp.AspNetCore.MultiTenancy
{
public class RouteTenantResolveContributor : HttpTenantResolveContributorBase
{
public const string ContributorName = "Route";
public override string Name => ContributorName;
protected override string GetTenantIdOrNameFromHttpContextOrNull(ITenantResolveContext context, HttpContext httpContext)
{
var tenantId = httpContext.GetRouteValue(context.GetAspNetCoreMultiTenancyOptions().TenantKey);

4
framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/en.json

@ -3,9 +3,9 @@
"texts": {
"GivenTenantIsNotAvailable": "Given tenant is not available: {0}",
"Tenant": "Tenant",
"Switch": "Switch",
"Switch": "switch",
"Name": "Name",
"SwitchTenantHint": "Leave the name field blank to switch to the host side.",
"NotSelected": "Seçili değil"
"NotSelected": "Not selected"
}
}

4
framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/tr.json

@ -3,9 +3,9 @@
"texts": {
"GivenTenantIsNotAvailable": "İstenilen müşteri bulunamadı: {0}",
"Tenant": "Müşteri",
"Switch": "Değiştir",
"Switch": "değiştir",
"Name": "İsim",
"SwitchTenantHint": "Host tarafına geçmek için isim alanını boş bırakın.",
"NotSelected": "Not selected"
"NotSelected": "Seçili değil"
}
}

8
framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ActionTenantResolveContributor.cs

@ -3,8 +3,12 @@ using JetBrains.Annotations;
namespace Volo.Abp.MultiTenancy
{
public class ActionTenantResolveContributor : ITenantResolveContributor
public class ActionTenantResolveContributor : TenantResolveContributorBase
{
public const string ContributorName = "Action";
public override string Name => ContributorName;
private readonly Action<ITenantResolveContext> _resolveAction;
public ActionTenantResolveContributor([NotNull] Action<ITenantResolveContext> resolveAction)
@ -14,7 +18,7 @@ namespace Volo.Abp.MultiTenancy
_resolveAction = resolveAction;
}
public void Resolve(ITenantResolveContext context)
public override void Resolve(ITenantResolveContext context)
{
_resolveAction(context);
}

4
framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/AsyncLocalCurrentTenantIdAccessor.cs → framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/AsyncLocalCurrentTenantAccessor.cs

@ -3,7 +3,7 @@ using Volo.Abp.DependencyInjection;
namespace Volo.Abp.MultiTenancy
{
public class AsyncLocalCurrentTenantIdAccessor : ICurrentTenantIdAccessor, ISingletonDependency
public class AsyncLocalCurrentTenantAccessor : ICurrentTenantAccessor, ISingletonDependency
{
public BasicTenantInfo Current
{
@ -13,7 +13,7 @@ namespace Volo.Abp.MultiTenancy
private readonly AsyncLocal<BasicTenantInfo> _currentScope;
public AsyncLocalCurrentTenantIdAccessor()
public AsyncLocalCurrentTenantAccessor()
{
_currentScope = new AsyncLocal<BasicTenantInfo>();
}

8
framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/CurrentClaimsPrincipalTenantResolveContributor.cs

@ -4,9 +4,13 @@ using Volo.Abp.Security.Claims;
namespace Volo.Abp.MultiTenancy
{
public class CurrentClaimsPrincipalTenantResolveContributor : ITenantResolveContributor
public class CurrentClaimsPrincipalTenantResolveContributor : TenantResolveContributorBase
{
public void Resolve(ITenantResolveContext context)
public const string ContributorName = "CurrentClaims";
public override string Name => ContributorName;
public override void Resolve(ITenantResolveContext context)
{
var principal = context.ServiceProvider.GetRequiredService<ICurrentPrincipalAccessor>().Principal;
if (principal?.Identity?.IsAuthenticated != true)

16
framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/CurrentTenant.cs

@ -7,15 +7,15 @@ namespace Volo.Abp.MultiTenancy
{
public virtual bool IsAvailable => Id.HasValue;
public virtual Guid? Id => _currentTenantIdAccessor.Current?.TenantId;
public virtual Guid? Id => _currentTenantAccessor.Current?.TenantId;
public string Name => _currentTenantIdAccessor.Current?.Name;
public string Name => _currentTenantAccessor.Current?.Name;
private readonly ICurrentTenantIdAccessor _currentTenantIdAccessor;
private readonly ICurrentTenantAccessor _currentTenantAccessor;
public CurrentTenant(ICurrentTenantIdAccessor currentTenantIdAccessor)
public CurrentTenant(ICurrentTenantAccessor currentTenantAccessor)
{
_currentTenantIdAccessor = currentTenantIdAccessor;
_currentTenantAccessor = currentTenantAccessor;
}
public IDisposable Change(Guid? id, string name = null)
@ -25,11 +25,11 @@ namespace Volo.Abp.MultiTenancy
private IDisposable SetCurrent(Guid? tenantId, string name = null)
{
var parentScope = _currentTenantIdAccessor.Current;
_currentTenantIdAccessor.Current = new BasicTenantInfo(tenantId, name);
var parentScope = _currentTenantAccessor.Current;
_currentTenantAccessor.Current = new BasicTenantInfo(tenantId, name);
return new DisposeAction(() =>
{
_currentTenantIdAccessor.Current = parentScope;
_currentTenantAccessor.Current = parentScope;
});
}
}

12
framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ICurrentTenantAccessor.cs

@ -0,0 +1,12 @@
namespace Volo.Abp.MultiTenancy
{
/* A null Current indicates that we haven't set it explicitly.
* A null Current.TenantId indicates that we have set null tenant id value explicitly.
* A non-null Current.TenantId indicates that we have set a tenant id value explicitly.
*/
public interface ICurrentTenantAccessor
{
BasicTenantInfo Current { get; set; }
}
}

13
framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ICurrentTenantIdAccessor.cs

@ -1,13 +0,0 @@
namespace Volo.Abp.MultiTenancy
{
/* Uses TenantScopeTenantInfoWrapper instead of TenantInfo because being null of Current is different that being null of Current.Tenant.
* A null Current indicates that we haven't set it explicitly.
* A null Current.Tenant indicates that we have set null tenant value explicitly.
* A non-null Current.Tenant indicates that we have set a tenant value explicitly.
*/
public interface ICurrentTenantIdAccessor
{
BasicTenantInfo Current { get; set; }
}
}

2
framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ITenantResolveContributor.cs

@ -2,6 +2,8 @@ namespace Volo.Abp.MultiTenancy
{
public interface ITenantResolveContributor
{
string Name { get; }
void Resolve(ITenantResolveContext context);
}
}

4
framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ITenantResolver.cs

@ -10,7 +10,7 @@ namespace Volo.Abp.MultiTenancy
/// <returns>
/// Tenant id, unique name or null (if could not resolve).
/// </returns>
[CanBeNull]
string ResolveTenantIdOrName();
[NotNull]
TenantResolveResult ResolveTenantIdOrName();
}
}

10
framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/TenantResolveContributorBase.cs

@ -0,0 +1,10 @@
namespace Volo.Abp.MultiTenancy
{
public abstract class TenantResolveContributorBase : ITenantResolveContributor
{
public abstract string Name { get; }
//TODO: We can make this async
public abstract void Resolve(ITenantResolveContext context);
}
}

16
framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/TenantResolveResult.cs

@ -0,0 +1,16 @@
using System.Collections.Generic;
namespace Volo.Abp.MultiTenancy
{
public class TenantResolveResult
{
public string TenantIdOrName { get; set; }
public List<string> AppliedResolvers { get; }
public TenantResolveResult()
{
AppliedResolvers = new List<string>();
}
}
}

18
framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/TenantResolver.cs

@ -1,5 +1,6 @@
using System;
using System.Linq;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
@ -17,12 +18,9 @@ namespace Volo.Abp.MultiTenancy
_options = options.Value;
}
public string ResolveTenantIdOrName()
public TenantResolveResult ResolveTenantIdOrName()
{
if (!_options.TenantResolvers.Any())
{
return null;
}
var result = new TenantResolveResult();
using (var serviceScope = _serviceProvider.CreateScope())
{
@ -32,15 +30,17 @@ namespace Volo.Abp.MultiTenancy
{
tenantResolver.Resolve(context);
result.AppliedResolvers.Add(tenantResolver.Name);
if (context.HasResolvedTenantOrHost())
{
return context.TenantIdOrName;
result.TenantIdOrName = context.TenantIdOrName;
break;
}
}
//Could not find a tenant
return null;
}
return result;
}
}
}
Loading…
Cancel
Save