Skip to content

Commit

Permalink
feat: namespace cleaned up
Browse files Browse the repository at this point in the history
BREAKING CHANGE: Many namespaces have been updated for consistency. Most code will only need to reference the `Finbuckle.MultiTenant` namespace.
  • Loading branch information
AndrewTriesToCode committed Apr 21, 2024
1 parent f4e20db commit b354838
Show file tree
Hide file tree
Showing 93 changed files with 761 additions and 778 deletions.
5 changes: 3 additions & 2 deletions docs/CoreConcepts.md
Expand Up @@ -15,15 +15,16 @@ type parameter defines the`ITenantInfo` use throughout the library and app.
crazy symbols in a web app where the identifier will be part of the URL). Unlike `Id`, `Identifier` can be changed if
necessary.
* `Name` is a display name for the tenant.
* `ConnectionString` is a connection string that should be used for database operations for this tenant. It might
connect to a shared database or a dedicated database for the single tenant.

`TenantInfo` is a provided basic implementation of `ITenantInfo` with only the required properties.

An app can define a custom `ITenantInfo` and add custom properties as needed. We recommend keeping these
classes lightweight since they are often queried. Keep heavier associated data in an external area that can be pulled in
when needed via the tenant `Id`.

> Previous versions of `ITenantInfo` and `TenantInfo` included a connection string property. If you still need this
> simply add it to your custom `ITenantInfo` implementation.
## `MultiTenantContext<TTenantInfo>`

The `MultiTenantContext<TTenantInfo>` contains information about the current tenant.
Expand Down
@@ -1,10 +1,11 @@
// Copyright Finbuckle LLC, Andrew White, and Contributors.
// Refer to the solution LICENSE file for more information.

using Finbuckle.MultiTenant.AspNetCore;
using Finbuckle.MultiTenant.AspNetCore.Internal;
using Microsoft.AspNetCore.Builder;

// ReSharper disable once CheckNamespace
namespace Microsoft.AspNetCore.Builder;
//ReSharper disable once CheckNamespace
namespace Finbuckle.MultiTenant;

/// <summary>
/// Extension methods for using Finbuckle.MultiTenant.AspNetCore.
Expand Down
Expand Up @@ -3,9 +3,12 @@

using System;
using System.Linq;
using Finbuckle.MultiTenant.Abstractions;
using Finbuckle.MultiTenant.AspNetCore;
using Finbuckle.MultiTenant.AspNetCore.Internal;
using Finbuckle.MultiTenant.AspNetCore.Options;
using Finbuckle.MultiTenant.AspNetCore.Strategies;
using Finbuckle.MultiTenant.Internal;
using Finbuckle.MultiTenant.Strategies;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
Expand All @@ -14,7 +17,8 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace Finbuckle.MultiTenant.AspNetCore.Extensions;
// ReSharper disable once CheckNamespace
namespace Finbuckle.MultiTenant;

/// <summary>
/// Provides builder methods for Finbuckle.MultiTenant services and configuration.
Expand Down
Expand Up @@ -11,14 +11,13 @@
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Options;

// ReSharper disable once CheckNamespace
namespace Finbuckle.MultiTenant.AspNetCore;
namespace Finbuckle.MultiTenant.AspNetCore.Internal;

/// <summary>
/// Implements <see cref="IAuthenticationSchemeProvider"/>.
/// </summary>
// ReSharper disable once ClassWithVirtualMembersNeverInherited.Global
internal class MultiTenantAuthenticationSchemeProvider : IAuthenticationSchemeProvider
public class MultiTenantAuthenticationSchemeProvider : IAuthenticationSchemeProvider
{
private readonly IAuthenticationSchemeProvider _inner;

Expand Down Expand Up @@ -55,7 +54,7 @@ public MultiTenantAuthenticationSchemeProvider(IAuthenticationSchemeProvider inn
// As-is from MS source.
AddScheme(scheme);
}
}
}

private readonly IOptions<AuthenticationOptions> _optionsProvider;
private readonly object _lock = new object();
Expand Down Expand Up @@ -130,21 +129,21 @@ public MultiTenantAuthenticationSchemeProvider(IAuthenticationSchemeProvider inn
/// <returns>The scheme or null if not found.</returns>
public virtual async Task<AuthenticationScheme?> GetSchemeAsync(string name)
{
AuthenticationScheme? scheme = null;

if (_inner != null)
{
scheme = await _inner.GetSchemeAsync(name);
}
AuthenticationScheme? scheme = null;

if (scheme == null)
{
scheme = _schemes.ContainsKey(name) ? _schemes[name] : null;
}
if (_inner != null)
{
scheme = await _inner.GetSchemeAsync(name);
}

return scheme;
if (scheme == null)
{
scheme = _schemes.ContainsKey(name) ? _schemes[name] : null;
}

return scheme;
}

/// <summary>
/// Returns the scheme for this tenants in priority order for request handling.
/// </summary>
Expand All @@ -160,44 +159,44 @@ public virtual Task<IEnumerable<AuthenticationScheme>> GetRequestHandlerSchemesA
/// <param name="scheme">The scheme.</param>
public virtual void AddScheme(AuthenticationScheme scheme)
{
if (_schemes.ContainsKey(scheme.Name))
{
throw new InvalidOperationException("Scheme already exists: " + scheme.Name);
}
lock (_lock)
{
if (_schemes.ContainsKey(scheme.Name))
{
throw new InvalidOperationException("Scheme already exists: " + scheme.Name);
}
lock (_lock)
if (typeof(IAuthenticationRequestHandler).IsAssignableFrom(scheme.HandlerType))
{
if (_schemes.ContainsKey(scheme.Name))
{
throw new InvalidOperationException("Scheme already exists: " + scheme.Name);
}
if (typeof(IAuthenticationRequestHandler).IsAssignableFrom(scheme.HandlerType))
{
_requestHandlers.Add(scheme);
}
_schemes[scheme.Name] = scheme;
_requestHandlers.Add(scheme);
}
_schemes[scheme.Name] = scheme;
}
}

/// <summary>
/// Removes a scheme, preventing it from being used by <see cref="IAuthenticationService"/>.
/// </summary>
/// <param name="name">The name of the authenticationScheme being removed.</param>
public virtual void RemoveScheme(string name)
{
if (!_schemes.ContainsKey(name))
{
return;
}
lock (_lock)
if (!_schemes.ContainsKey(name))
{
return;
}
lock (_lock)
{
if (_schemes.ContainsKey(name))
{
if (_schemes.ContainsKey(name))
{
var scheme = _schemes[name];
_requestHandlers.Remove(scheme);
_schemes.Remove(name);
}
var scheme = _schemes[name];
_requestHandlers.Remove(scheme);
_schemes.Remove(name);
}
}
}

public virtual Task<IEnumerable<AuthenticationScheme>> GetAllSchemesAsync()
=> Task.FromResult<IEnumerable<AuthenticationScheme>>(_schemes.Values);
Expand Down
@@ -1,16 +1,18 @@
// Copyright Finbuckle LLC, Andrew White, and Contributors.
// Refer to the solution LICENSE file for more information.

using System.Diagnostics.CodeAnalysis;
using System.Security.Claims;
using System.Threading.Tasks;
using Finbuckle.MultiTenant.Abstractions;
using Finbuckle.MultiTenant.Internal;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Options;

// ReSharper disable once CheckNamespace
namespace Finbuckle.MultiTenant.AspNetCore;
namespace Finbuckle.MultiTenant.AspNetCore.Internal;

[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")]
internal class MultiTenantAuthenticationService<TTenantInfo> : IAuthenticationService
where TTenantInfo : class, ITenantInfo, new()
{
Expand All @@ -33,38 +35,38 @@ private static void AddTenantIdentifierToProperties(HttpContext context, ref Aut
if(!properties.Items.Keys.Contains(Constants.TenantToken))
properties.Items.Add(Constants.TenantToken, multiTenantContext.TenantInfo.Identifier);
}
}
}

public Task<AuthenticateResult> AuthenticateAsync(HttpContext context, string? scheme)
=> _inner.AuthenticateAsync(context, scheme);

public async Task ChallengeAsync(HttpContext context, string? scheme, AuthenticationProperties? properties)
{
if (_multiTenantAuthenticationOptions.CurrentValue.SkipChallengeIfTenantNotResolved)
{
if (context.GetMultiTenantContext<TTenantInfo>()?.TenantInfo == null)
return;
}

AddTenantIdentifierToProperties(context, ref properties);
await _inner.ChallengeAsync(context, scheme, properties);
if (_multiTenantAuthenticationOptions.CurrentValue.SkipChallengeIfTenantNotResolved)
{
if (context.GetMultiTenantContext<TTenantInfo>()?.TenantInfo == null)
return;
}

AddTenantIdentifierToProperties(context, ref properties);
await _inner.ChallengeAsync(context, scheme, properties);
}

public async Task ForbidAsync(HttpContext context, string? scheme, AuthenticationProperties? properties)
{
AddTenantIdentifierToProperties(context, ref properties);
await _inner.ForbidAsync(context, scheme, properties);
}
AddTenantIdentifierToProperties(context, ref properties);
await _inner.ForbidAsync(context, scheme, properties);
}

public async Task SignInAsync(HttpContext context, string? scheme, ClaimsPrincipal principal, AuthenticationProperties? properties)
{
AddTenantIdentifierToProperties(context, ref properties);
await _inner.SignInAsync(context, scheme, principal, properties);
}
AddTenantIdentifierToProperties(context, ref properties);
await _inner.SignInAsync(context, scheme, principal, properties);
}

public async Task SignOutAsync(HttpContext context, string? scheme, AuthenticationProperties? properties)
{
AddTenantIdentifierToProperties(context, ref properties);
await _inner.SignOutAsync(context, scheme, properties);
}
AddTenantIdentifierToProperties(context, ref properties);
await _inner.SignOutAsync(context, scheme, properties);
}
}
Expand Up @@ -6,12 +6,12 @@
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;

namespace Finbuckle.MultiTenant.AspNetCore;
namespace Finbuckle.MultiTenant.AspNetCore.Internal;

/// <summary>
/// Middleware for resolving the MultiTenantContext and storing it in HttpContext.
/// </summary>
internal class MultiTenantMiddleware
public class MultiTenantMiddleware
{
private readonly RequestDelegate next;

Expand All @@ -22,7 +22,7 @@ public MultiTenantMiddleware(RequestDelegate next)

public async Task Invoke(HttpContext context)
{
var mtcAccessor = context.RequestServices.GetRequiredService<IMultiTenantContextAccessor>();
context.RequestServices.GetRequiredService<IMultiTenantContextAccessor>();
var mtcSetter = context.RequestServices.GetRequiredService<IMultiTenantContextSetter>();

var resolver = context.RequestServices.GetRequiredService<ITenantResolver>();
Expand Down

This file was deleted.

Expand Up @@ -6,5 +6,5 @@ namespace Finbuckle.MultiTenant.AspNetCore.Options;
public class BasePathStrategyOptions
{
// TODO make this default to true in next major release
public bool RebaseAspNetCorePathBase { get; set; } = false;
public bool RebaseAspNetCorePathBase { get; set; }
}
Expand Up @@ -3,9 +3,10 @@

using System;
using System.Threading.Tasks;
using Finbuckle.MultiTenant.Abstractions;
using Microsoft.AspNetCore.Http;

namespace Finbuckle.MultiTenant.Strategies;
namespace Finbuckle.MultiTenant.AspNetCore.Strategies;

public class BasePathStrategy : IMultiTenantStrategy
{
Expand Down
Expand Up @@ -4,13 +4,13 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Finbuckle.MultiTenant.Abstractions;
using Finbuckle.MultiTenant.Internal;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;

// ReSharper disable once CheckNamespace
namespace Finbuckle.MultiTenant.Strategies;
namespace Finbuckle.MultiTenant.AspNetCore.Strategies;

// ReSharper disable once ClassNeverInstantiated.Global
public class ClaimStrategy : IMultiTenantStrategy
Expand Down
Expand Up @@ -2,12 +2,15 @@
// Refer to the solution LICENSE file for more information.

using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;
using Finbuckle.MultiTenant.Abstractions;
using Microsoft.AspNetCore.Http;

namespace Finbuckle.MultiTenant.Strategies;
namespace Finbuckle.MultiTenant.AspNetCore.Strategies;

[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")]
public class HeaderStrategy : IMultiTenantStrategy
{
private readonly string _headerKey;
Expand Down

0 comments on commit b354838

Please sign in to comment.