You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
126 lines
4.6 KiB
126 lines
4.6 KiB
/*
|
|
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
|
|
* See https://github.com/openiddict/openiddict-core for more information concerning
|
|
* the license and the contributors participating to this project.
|
|
*/
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
using Microsoft.Extensions.Options;
|
|
|
|
namespace OpenIddict.Client;
|
|
|
|
public class OpenIddictClientDispatcher : IOpenIddictClientDispatcher
|
|
{
|
|
private readonly ILogger<OpenIddictClientDispatcher> _logger;
|
|
private readonly IOptionsMonitor<OpenIddictClientOptions> _options;
|
|
private readonly IServiceProvider _provider;
|
|
|
|
/// <summary>
|
|
/// Creates a new instance of the <see cref="OpenIddictClientDispatcher"/> class.
|
|
/// </summary>
|
|
public OpenIddictClientDispatcher(
|
|
ILogger<OpenIddictClientDispatcher> logger!!,
|
|
IOptionsMonitor<OpenIddictClientOptions> options!!,
|
|
IServiceProvider provider!!)
|
|
{
|
|
_logger = logger;
|
|
_options = options;
|
|
_provider = provider;
|
|
}
|
|
|
|
public async ValueTask DispatchAsync<TContext>(TContext context!!) where TContext : BaseContext
|
|
{
|
|
await foreach (var handler in GetHandlersAsync())
|
|
{
|
|
try
|
|
{
|
|
await handler.HandleAsync(context);
|
|
}
|
|
|
|
catch (Exception exception) when (_logger.IsEnabled(LogLevel.Debug))
|
|
{
|
|
_logger.LogDebug(exception, SR.GetResourceString(SR.ID6132), handler.GetType().FullName, typeof(TContext).FullName);
|
|
|
|
throw;
|
|
}
|
|
|
|
if (_logger.IsEnabled(LogLevel.Debug))
|
|
{
|
|
_logger.LogDebug(SR.GetResourceString(SR.ID6133), typeof(TContext).FullName, handler.GetType().FullName);
|
|
}
|
|
|
|
switch (context)
|
|
{
|
|
case BaseRequestContext { IsRequestHandled: true }:
|
|
if (_logger.IsEnabled(LogLevel.Debug))
|
|
{
|
|
_logger.LogDebug(SR.GetResourceString(SR.ID6134), typeof(TContext).FullName, handler.GetType().FullName);
|
|
}
|
|
return;
|
|
|
|
case BaseRequestContext { IsRequestSkipped: true }:
|
|
if (_logger.IsEnabled(LogLevel.Debug))
|
|
{
|
|
_logger.LogDebug(SR.GetResourceString(SR.ID6135), typeof(TContext).FullName, handler.GetType().FullName);
|
|
}
|
|
return;
|
|
|
|
case BaseValidatingContext { IsRejected: true }:
|
|
if (_logger.IsEnabled(LogLevel.Debug))
|
|
{
|
|
_logger.LogDebug(SR.GetResourceString(SR.ID6136), typeof(TContext).FullName, handler.GetType().FullName);
|
|
}
|
|
return;
|
|
|
|
default: continue;
|
|
}
|
|
}
|
|
|
|
async IAsyncEnumerable<IOpenIddictClientHandler<TContext>> GetHandlersAsync()
|
|
{
|
|
// Note: the descriptors collection is sorted during options initialization for performance reasons.
|
|
var descriptors = _options.CurrentValue.Handlers;
|
|
if (descriptors.Count == 0)
|
|
{
|
|
yield break;
|
|
}
|
|
|
|
for (var index = 0; index < descriptors.Count; index++)
|
|
{
|
|
var descriptor = descriptors[index];
|
|
if (descriptor.ContextType != typeof(TContext) || !await IsActiveAsync(descriptor))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
yield return descriptor.ServiceDescriptor switch
|
|
{
|
|
{ ImplementationInstance: IOpenIddictClientHandler<TContext> handler } => handler,
|
|
|
|
_ when _provider.GetService(descriptor.ServiceDescriptor.ServiceType)
|
|
is IOpenIddictClientHandler<TContext> handler => handler,
|
|
|
|
_ => throw new InvalidOperationException(SR.FormatID0312(descriptor.ServiceDescriptor.ServiceType))
|
|
};
|
|
}
|
|
}
|
|
|
|
async ValueTask<bool> IsActiveAsync(OpenIddictClientHandlerDescriptor descriptor)
|
|
{
|
|
for (var index = 0; index < descriptor.FilterTypes.Length; index++)
|
|
{
|
|
if (!(_provider.GetService(descriptor.FilterTypes[index]) is IOpenIddictClientHandlerFilter<TContext> filter))
|
|
{
|
|
throw new InvalidOperationException(SR.FormatID0099(descriptor.FilterTypes[index]));
|
|
}
|
|
|
|
if (!await filter.IsActiveAsync(context))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|