Merge pull request #2371 from DuendeSoftware/dh/coop-cancellation

Add CancellationToken parameter to interfaces and flow CT throughout
This commit is contained in:
Damian Hickey 2026-02-26 14:27:49 +01:00 committed by GitHub
commit e556d5b314
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
598 changed files with 3852 additions and 3840 deletions

View file

@ -70,7 +70,7 @@ internal class DPoPProofValidator : IDPoPProofValidator
/// <summary>
/// Validates the DPoP proof.
/// </summary>
public async Task<DPoPProofValidationResult> Validate(DPoPProofValidationContext context, CT ct = default)
public async Task<DPoPProofValidationResult> Validate(DPoPProofValidationContext context, Ct ct = default)
{
using var activity = Tracing.ActivitySource.StartActivity("DPoPProofValidator.Validate");
@ -368,7 +368,7 @@ internal class DPoPProofValidator : IDPoPProofValidator
internal async Task ValidateReplay(
DPoPProofValidationContext context,
DPoPProofValidationResult result,
CT ct = default)
Ct ct = default)
{
var dPoPOptions = OptionsMonitor.Get(context.Scheme);

View file

@ -11,5 +11,5 @@ public interface IDPoPProofValidator
/// <summary>
/// Validates the DPoP proof.
/// </summary>
Task<DPoPProofValidationResult> Validate(DPoPProofValidationContext context, CT ct = default);
Task<DPoPProofValidationResult> Validate(DPoPProofValidationContext context, Ct ct = default);
}

View file

@ -11,11 +11,11 @@ public interface IReplayCache
/// <summary>
/// Adds a hashed jti to the cache.
/// </summary>
Task Add(string jtiHash, TimeSpan expiration, CT ct = default);
Task Add(string jtiHash, TimeSpan expiration, Ct ct = default);
/// <summary>
/// Checks if a cached jti hash exists in the hash.
/// </summary>
Task<bool> Exists(string jtiHash, CT ct = default);
Task<bool> Exists(string jtiHash, Ct ct = default);
}

View file

@ -24,7 +24,7 @@ internal class ReplayCache(DPoPHybridCacheProvider cacheProvider) : IReplayCache
}
}
public async Task Add(string handle, TimeSpan expiration, CT ct)
public async Task Add(string handle, TimeSpan expiration, Ct ct)
{
using var activity = Tracing.ActivitySource.StartActivity("ReplayCache.Add");
@ -43,14 +43,14 @@ internal class ReplayCache(DPoPHybridCacheProvider cacheProvider) : IReplayCache
| HybridCacheEntryFlags.DisableUnderlyingData
};
public async Task<bool> Exists(string handle, CT ct)
public async Task<bool> Exists(string handle, Ct ct)
{
using var activity = Tracing.ActivitySource.StartActivity("ReplayCache.Exists");
// The factory will never be invoked because the ReadOnlyEntryOptions set the DisableUnderlyingData flag
return await Cache.GetOrCreateAsync<bool>(
Prefix + handle,
// The factory will never be invoked because the ReadOnlyEntryOptions set the DisableUnderlyingData flag
cancel => throw new InvalidOperationException("Can't Happen"),
_ => throw new InvalidOperationException("Can't Happen"),
ReadOnlyEntryOptions,
cancellationToken: ct);
}

View file

@ -15,7 +15,7 @@ public class TestBrowserClient : HttpClient
public HttpResponseMessage LastResponse { get; private set; } = default!;
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CT ct)
Ct ct)
{
CurrentUri = request.RequestUri!;
var cookieHeader = CookieContainer.GetCookieHeader(request.RequestUri!);

View file

@ -11,8 +11,8 @@ internal class TestHybridCache : HybridCache
private readonly List<(string key, object value, HybridCacheEntryOptions? options)> _setAsyncCalls = new();
private readonly List<(string key, HybridCacheEntryOptions? options)> _getOrCreateAsyncCalls = new();
public override async ValueTask<T> GetOrCreateAsync<TState, T>(string key, TState state, Func<TState, CT, ValueTask<T>> factory, HybridCacheEntryOptions? options = null,
IEnumerable<string>? tags = null, CT ct = new())
public override async ValueTask<T> GetOrCreateAsync<TState, T>(string key, TState state, Func<TState, Ct, ValueTask<T>> factory, HybridCacheEntryOptions? options = null,
IEnumerable<string>? tags = null, Ct ct = new())
{
_getOrCreateAsyncCalls.Add((key, options));
@ -25,16 +25,16 @@ internal class TestHybridCache : HybridCache
}
public override ValueTask SetAsync<T>(string key, T value, HybridCacheEntryOptions? options = null, IEnumerable<string>? tags = null,
CT ct = new())
Ct ct = new())
{
_setAsyncCalls.Add((key, value!, options));
_cache[key] = value!;
return ValueTask.CompletedTask;
}
public override ValueTask RemoveAsync(string key, CT ct = new()) => throw new NotImplementedException();
public override ValueTask RemoveAsync(string key, Ct ct = new()) => throw new NotImplementedException();
public override ValueTask RemoveByTagAsync(string tag, CT ct = new()) => throw new NotImplementedException();
public override ValueTask RemoveByTagAsync(string tag, Ct ct = new()) => throw new NotImplementedException();
public IReadOnlyList<(string key, object value, HybridCacheEntryOptions? options)> SetAsyncCalls => _setAsyncCalls;
public IReadOnlyList<(string key, HybridCacheEntryOptions? options)> GetOrCreateAsyncCalls => _getOrCreateAsyncCalls;

View file

@ -14,14 +14,14 @@ public class TestReplayCache : IReplayCache
// Configuration for test behavior
public Func<string, bool>? ExistsFunc { get; set; }
public Task Add(string jtiHash, TimeSpan expiration, CT ct = default)
public Task Add(string jtiHash, TimeSpan expiration, Ct ct = default)
{
_addCalls.Add((jtiHash, expiration));
_cache[jtiHash] = (expiration, DateTime.UtcNow);
return Task.CompletedTask;
}
public Task<bool> Exists(string jtiHash, CT ct = default)
public Task<bool> Exists(string jtiHash, Ct ct = default)
{
_existsCalls.Add(jtiHash);

View file

@ -9,7 +9,7 @@ namespace Bff;
public class ImpersonationAccessTokenRetriever(IAccessTokenRetriever inner) : IAccessTokenRetriever
{
public async Task<AccessTokenResult> GetAccessTokenAsync(AccessTokenRetrievalContext context, CT ct = default)
public async Task<AccessTokenResult> GetAccessTokenAsync(AccessTokenRetrievalContext context, Ct ct = default)
{
var result = await inner.GetAccessTokenAsync(context, ct);

View file

@ -9,7 +9,7 @@ namespace Bff;
public class ImpersonationAccessTokenRetriever(IAccessTokenRetriever inner) : IAccessTokenRetriever
{
public async Task<AccessTokenResult> GetAccessTokenAsync(AccessTokenRetrievalContext context, CT ct = default)
public async Task<AccessTokenResult> GetAccessTokenAsync(AccessTokenRetrievalContext context, Ct ct = default)
{
var result = await inner.GetAccessTokenAsync(context, ct);

View file

@ -166,7 +166,7 @@ app.MapGet("/local/self-contained", (CurrentFrontendAccessor currentFrontendAcce
return data;
});
app.MapGet("/local/invokes-external-api", async (CurrentFrontendAccessor currentFrontendAccessor, IHttpClientFactory httpClientFactory, HttpContext c, CT ct) =>
app.MapGet("/local/invokes-external-api", async (CurrentFrontendAccessor currentFrontendAccessor, IHttpClientFactory httpClientFactory, HttpContext c, Ct ct) =>
{
var httpClient = httpClientFactory.CreateClient("api");
var apiResult = await httpClient.GetAsync("/user-token");
@ -235,7 +235,7 @@ RouteConfig[] BuildYarpRoutes()
public class FrontendAwareIndexHtmlTransformer : IIndexHtmlTransformer
{
public Task<string?> Transform(string indexHtml, BffFrontend frontend, CT ct = default)
public Task<string?> Transform(string indexHtml, BffFrontend frontend, Ct ct = default)
{
indexHtml = indexHtml.Replace("[FrontendName]", frontend.Name);
indexHtml = indexHtml.Replace("[Path]", frontend.MatchingCriteria.MatchingPath + "/"); // Note, the path must end with a slash

View file

@ -9,7 +9,7 @@ public class ApiHostedService(IOptions<ApiSettings> apiSettings) : BackgroundSer
{
public ApiSettings Settings { get; } = apiSettings.Value;
protected override Task ExecuteAsync(CT stoppingToken)
protected override Task ExecuteAsync(Ct stoppingToken)
{
var builder = WebApplication.CreateBuilder();
builder.AddServiceDefaults();

View file

@ -15,7 +15,7 @@ public abstract class BffService(string[] urlConfigKeys, IConfiguration config,
public IConfiguration Config { get; } = config;
public BffSettings Settings { get; } = bffSettings.Value;
protected override async Task ExecuteAsync(CT stoppingToken)
protected override async Task ExecuteAsync(Ct stoppingToken)
{
var urls = urlConfigKeys
.Select(x => Config[x])

View file

@ -17,7 +17,7 @@ public class IdentityServerService(IOptions<IdentityServerSettings> settings, IC
{
public IdentityServerSettings Settings { get; } = settings.Value;
protected override Task ExecuteAsync(CT stoppingToken)
protected override Task ExecuteAsync(Ct stoppingToken)
{
var builder = WebApplication.CreateBuilder();
builder.AddServiceDefaults();

View file

@ -9,7 +9,7 @@ namespace Bff.Benchmarks.Hosts;
internal class CookieHandler(HttpMessageHandler innerHandler, CookieContainer cookieContainer)
: DelegatingHandler(innerHandler)
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CT ct)
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, Ct ct)
{
var requestUri = request.RequestUri;
var header = cookieContainer.GetCookieHeader(requestUri!);

View file

@ -12,7 +12,7 @@ internal class RedirectHandler() : DelegatingHandler
public bool AutoFollowRedirects { get; set; } = true;
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CT ct)
Ct ct)
{
var originalUri = request.RequestUri;

View file

@ -27,7 +27,7 @@ internal class RoutingMessageHandler : HttpMessageHandler
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CT ct)
Ct ct)
{
var host = $"{request.RequestUri?.Host}:{request.RequestUri?.Port}";
@ -46,7 +46,7 @@ internal class RoutingMessageHandler : HttpMessageHandler
{
internal Task<HttpResponseMessage> SuppressedSend(
HttpRequestMessage request,
CT ct)
Ct ct)
{
Task<HttpResponseMessage> t;
if (ExecutionContext.IsFlowSuppressed())

View file

@ -64,7 +64,7 @@ internal class SimulatedInternet : DelegatingHandler
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CT ct)
Ct ct)
{
var httpResponseMessage = await base.SendAsync(request, ct);
return httpResponseMessage;

View file

@ -8,7 +8,7 @@ namespace Bff.Performance.TestInfra;
public class AutoFollowRedirectHandler(Action<string> writeOutput) : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CT ct)
Ct ct)
{
var previousUri = request.RequestUri;
for (var i = 0; i < 20; i++)

View file

@ -9,7 +9,7 @@ public class CloningHttpMessageHandler(HttpClient innerHttpClient) : HttpMessage
innerHttpClient ?? throw new ArgumentNullException(nameof(innerHttpClient));
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CT ct)
Ct ct)
{
// Clone the incoming request
var clonedRequest = await CloneHttpRequestMessageAsync(request);

View file

@ -12,7 +12,7 @@ public class RequestLoggingHandler(
: DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CT ct)
Ct ct)
{
if (!shouldLog(request))
{

View file

@ -6,7 +6,7 @@ namespace Duende.Bff.Blazor.Client.Internals;
internal class AntiForgeryHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CT ct)
Ct ct)
{
request.Headers.Add("X-CSRF", "1");
return base.SendAsync(request, ct);

View file

@ -126,7 +126,7 @@ internal sealed class BffServerAuthenticationStateProvider : RevalidatingServerA
/// <param name="authenticationState">The current authentication state.</param>
/// <param name="ct">A token that can be used to request cancellation of the asynchronous operation.</param>
/// <returns>A boolean indicating whether the authentication state is valid.</returns>
protected override async Task<bool> ValidateAuthenticationStateAsync(AuthenticationState authenticationState, CT ct)
protected override async Task<bool> ValidateAuthenticationStateAsync(AuthenticationState authenticationState, Ct ct)
{
using var scope = _serviceScopeFactory.CreateScope();
var sessionStore = scope.ServiceProvider.GetRequiredService<IUserSessionStore>();

View file

@ -32,7 +32,7 @@ internal class ServerSideTokenStore(
?? throw new ArgumentException("AuthenticationStateProvider must implement IHostEnvironmentAuthenticationStateProvider");
public async Task<TokenResult<TokenForParameters>> GetTokenAsync(ClaimsPrincipal user, UserTokenRequestParameters? parameters = null,
CT ct = default)
Ct ct = default)
{
logger.RetrievingTokenForUser(LogLevel.Debug, user.Identity?.Name);
var session = await GetSession(user);
@ -83,7 +83,7 @@ internal class ServerSideTokenStore(
}
public async Task StoreTokenAsync(ClaimsPrincipal user, UserToken token,
UserTokenRequestParameters? parameters = null, CT ct = default)
UserTokenRequestParameters? parameters = null, Ct ct = default)
{
logger.StoringTokenForUser(LogLevel.Debug, user.Identity?.Name);
await UpdateTicket(user,
@ -91,7 +91,7 @@ internal class ServerSideTokenStore(
}
public async Task ClearTokenAsync(ClaimsPrincipal user, UserTokenRequestParameters? parameters = null, CT ct = default)
public async Task ClearTokenAsync(ClaimsPrincipal user, UserTokenRequestParameters? parameters = null, Ct ct = default)
{
logger.RemovingTokenForUser(LogLevel.Debug, user.Identity?.Name);
await UpdateTicket(user, ticket =>

View file

@ -23,5 +23,5 @@ public interface ISessionDbContext
/// Saves the changes.
/// </summary>
/// <returns></returns>
Task<int> SaveChangesAsync(CT ct = default);
Task<int> SaveChangesAsync(Ct ct = default);
}

View file

@ -18,7 +18,7 @@ internal sealed class UserSessionStore(
: IUserSessionStore, IUserSessionStoreCleanup
{
/// <inheritdoc/>
public async Task CreateUserSessionAsync(UserSession session, CT ct)
public async Task CreateUserSessionAsync(UserSession session, Ct ct)
{
if (!session.PartitionKey.HasValue)
{
@ -67,7 +67,7 @@ internal sealed class UserSessionStore(
}
/// <inheritdoc/>
public async Task DeleteUserSessionAsync(UserSessionKey key, CT ct)
public async Task DeleteUserSessionAsync(UserSessionKey key, Ct ct)
{
var userKey = key.UserKey;
var partitionKey = key.PartitionKey;
@ -104,7 +104,7 @@ internal sealed class UserSessionStore(
}
/// <inheritdoc/>
public async Task DeleteUserSessionsAsync(PartitionKey partitionKey, UserSessionsFilter filter, CT ct)
public async Task DeleteUserSessionsAsync(PartitionKey partitionKey, UserSessionsFilter filter, Ct ct)
{
filter.Validate();
var query = sessionDbContext.UserSessions.Where(x => x.PartitionKey == partitionKey).AsQueryable();
@ -152,7 +152,7 @@ internal sealed class UserSessionStore(
}
/// <inheritdoc/>
public async Task<UserSession?> GetUserSessionAsync(UserSessionKey key, CT ct)
public async Task<UserSession?> GetUserSessionAsync(UserSessionKey key, Ct ct)
{
var userKey = key.UserKey;
var partitionKey = key.PartitionKey;
@ -175,7 +175,7 @@ internal sealed class UserSessionStore(
}
/// <inheritdoc/>
public async Task<IReadOnlyCollection<UserSession>> GetUserSessionsAsync(PartitionKey partitionKey, UserSessionsFilter filter, CT ct)
public async Task<IReadOnlyCollection<UserSession>> GetUserSessionsAsync(PartitionKey partitionKey, UserSessionsFilter filter, Ct ct)
{
filter.Validate();
var query = sessionDbContext.UserSessions.Where(x => x.PartitionKey == partitionKey).AsQueryable();
@ -213,7 +213,7 @@ internal sealed class UserSessionStore(
}
/// <inheritdoc/>
public async Task UpdateUserSessionAsync(UserSessionKey key, UserSessionUpdate session, CT ct)
public async Task UpdateUserSessionAsync(UserSessionKey key, UserSessionUpdate session, Ct ct)
{
var userKey = key.UserKey;
var partitionKey = key.PartitionKey;
@ -235,7 +235,7 @@ internal sealed class UserSessionStore(
}
/// <inheritdoc/>
public async Task<int> DeleteExpiredSessionsAsync(CT ct = default)
public async Task<int> DeleteExpiredSessionsAsync(Ct ct = default)
{
var removed = 0;

View file

@ -68,7 +68,7 @@ internal class RemoteRouteHandler : IDisposable
public void ClearTransformerCacheFor(BffFrontend frontend) => _cache.TryRemove(frontend.Name, out _);
public async Task<bool> HandleAsync(HttpContext context, CT ct)
public async Task<bool> HandleAsync(HttpContext context, Ct ct)
{
if (!_currentFrontendAccessor.TryGet(out var frontend))
{

View file

@ -15,5 +15,5 @@ public interface IAccessTokenRetriever
/// <returns>A task that contains the access token result, which is an
/// object model that can represent various types of tokens (bearer, dpop),
/// the absence of an optional token, or an error. </returns>
public Task<AccessTokenResult> GetAccessTokenAsync(AccessTokenRetrievalContext context, CT ct = default);
public Task<AccessTokenResult> GetAccessTokenAsync(AccessTokenRetrievalContext context, Ct ct = default);
}

View file

@ -8,7 +8,7 @@ namespace Duende.Bff.Diagnostics;
internal class DiagnosticDataService(DateTime serverStartTime, IEnumerable<IDiagnosticEntry> entries)
{
public async Task<ReadOnlyMemory<byte>> GetJsonBytesAsync(CT ct = default)
public async Task<ReadOnlyMemory<byte>> GetJsonBytesAsync(Ct ct = default)
{
var bufferWriter = new ArrayBufferWriter<byte>();
await using var writer = new Utf8JsonWriter(bufferWriter, new JsonWriterOptions { Indented = false });

View file

@ -14,7 +14,7 @@ internal class DiagnosticHostedService(
ILogger<DiagnosticHostedService> logger,
TimeProvider timeProvider) : BackgroundService
{
protected override async Task ExecuteAsync(CT stoppingToken)
protected override async Task ExecuteAsync(Ct stoppingToken)
{
using var timer = new PeriodicTimer(options.Value.Diagnostics.LogFrequency, timeProvider);
try
@ -40,7 +40,7 @@ internal class DiagnosticHostedService(
}
}
public override async Task StopAsync(CT ct)
public override async Task StopAsync(Ct ct)
{
await diagnosticsSummary.PrintSummaryAsync(ct);

View file

@ -15,7 +15,7 @@ internal class DiagnosticSummary(
{
private readonly ILogger _logger = loggerFactory.CreateLogger("Duende.BFF.Diagnostics.Summary");
public async Task PrintSummaryAsync(CT ct = default)
public async Task PrintSummaryAsync(Ct ct = default)
{
var bffOptions = options.Value;
var jsonMemory = await diagnosticDataService.GetJsonBytesAsync(ct);

View file

@ -10,5 +10,5 @@ namespace Duende.Bff.DynamicFrontends;
/// </summary>
public interface IIndexHtmlTransformer
{
Task<string?> Transform(string indexHtml, BffFrontend frontend, CT ct = default);
Task<string?> Transform(string indexHtml, BffFrontend frontend, Ct ct = default);
}

View file

@ -20,7 +20,7 @@ public interface IStaticFilesClient
/// </summary>
/// <param name="ct">CancellationToken</param>
/// <returns>Index HTML</returns>
Task<string?> GetIndexHtmlAsync(CT ct = default);
Task<string?> GetIndexHtmlAsync(Ct ct = default);
/// <summary>
/// This method proxies all static asset requests to the configured CDN URL for the current frontend.
@ -34,5 +34,5 @@ public interface IStaticFilesClient
/// <param name="context">HttpContext</param>
/// <param name="ct">CancellationToken</param>
/// <returns></returns>
Task ProxyStaticAssetsAsync(HttpContext context, CT ct = default);
Task ProxyStaticAssetsAsync(HttpContext context, Ct ct = default);
}

View file

@ -30,7 +30,7 @@ internal class BffCacheClearingHostedService(
private ChannelWriter<BffFrontend> Writer => _channel.Writer;
private ChannelReader<BffFrontend> Reader => _channel.Reader;
protected override async Task ExecuteAsync(CT ct)
protected override async Task ExecuteAsync(Ct ct)
{
// Subscribe to frontend changes and publish messages to the channel
frontendCollection.OnFrontendChanged += changedFrontend =>
@ -55,7 +55,7 @@ internal class BffCacheClearingHostedService(
await ProcessFrontendChangesAsync(ct);
}
private async Task ProcessFrontendChangesAsync(CT ct)
private async Task ProcessFrontendChangesAsync(Ct ct)
{
try
{
@ -77,7 +77,7 @@ internal class BffCacheClearingHostedService(
}
}
private async Task ProcessFrontendChangeAsync(BffFrontend changedFrontend, CT ct)
private async Task ProcessFrontendChangeAsync(BffFrontend changedFrontend, Ct ct)
{
try
{

View file

@ -23,7 +23,7 @@ internal class StaticFilesHttpClient(
{
private readonly CancellationTokenSource _stopping = new();
public async Task<string?> GetIndexHtmlAsync(CT ct = default)
public async Task<string?> GetIndexHtmlAsync(Ct ct = default)
{
var frontend = currentFrontendAccessor.Get();
@ -67,7 +67,7 @@ internal class StaticFilesHttpClient(
}
}
public async Task ProxyStaticAssetsAsync(HttpContext context, CT ct = default)
public async Task ProxyStaticAssetsAsync(HttpContext context, Ct ct = default)
{
var frontend = currentFrontendAccessor.Get();

View file

@ -14,5 +14,5 @@ public interface IBffEndpoint
/// Process a request
/// </summary>
/// <returns></returns>
Task ProcessRequestAsync(HttpContext context, CT ct = default);
Task ProcessRequestAsync(HttpContext context, Ct ct = default);
}

View file

@ -26,5 +26,5 @@ public interface IUserEndpointClaimsEnricher
/// <param name="claims">The current set of claims to be returned. </param>
/// <param name="ct">Cancellation token</param>
/// <returns>The updated list of claims.</returns>
Task<IReadOnlyList<ClaimRecord>> EnrichClaimsAsync(AuthenticateResult authenticateResult, IReadOnlyList<ClaimRecord> claims, CT ct = default);
Task<IReadOnlyList<ClaimRecord>> EnrichClaimsAsync(AuthenticateResult authenticateResult, IReadOnlyList<ClaimRecord> claims, Ct ct = default);
}

View file

@ -27,7 +27,7 @@ internal class DefaultBackchannelLogoutEndpoint(
ILogger<DefaultBackchannelLogoutEndpoint> logger) : IBackchannelLogoutEndpoint
{
/// <inheritdoc />
public async Task ProcessRequestAsync(HttpContext context, CT ct = default)
public async Task ProcessRequestAsync(HttpContext context, Ct ct = default)
{
logger.ProcessingBackChannelLogoutRequest(LogLevel.Debug);
@ -167,7 +167,7 @@ internal class DefaultBackchannelLogoutEndpoint(
var config = options.Configuration;
if (config == null)
{
config = await options.ConfigurationManager?.GetConfigurationAsync(CT.None)!;
config = await options.ConfigurationManager?.GetConfigurationAsync(Ct.None)!;
}
if (config == null)

View file

@ -24,7 +24,7 @@ internal class DefaultDiagnosticsEndpoint(IWebHostEnvironment environment, IOpti
};
/// <inheritdoc />
public async Task ProcessRequestAsync(HttpContext context, CT ct = default)
public async Task ProcessRequestAsync(HttpContext context, Ct ct = default)
{
if (options.Value.DiagnosticsEnvironments?.Contains(environment.EnvironmentName) is null or false)
{

View file

@ -27,7 +27,7 @@ internal class DefaultLoginEndpoint(
: ILoginEndpoint
{
/// <inheritdoc />
public async Task ProcessRequestAsync(HttpContext context, CT ct = default)
public async Task ProcessRequestAsync(HttpContext context, Ct ct = default)
{
logger.ProcessingLoginRequest(LogLevel.Debug);
@ -85,7 +85,7 @@ internal class DefaultLoginEndpoint(
await context.ChallengeAsync(props);
}
private async Task<ICollection<string>?> GetPromptValuesAsync(CT ct = default)
private async Task<ICollection<string>?> GetPromptValuesAsync(Ct ct = default)
{
Scheme scheme;

View file

@ -22,7 +22,7 @@ internal class DefaultLogoutEndpoint(IOptions<BffOptions> options,
: ILogoutEndpoint
{
/// <inheritdoc />
public async Task ProcessRequestAsync(HttpContext context, CT ct = default)
public async Task ProcessRequestAsync(HttpContext context, Ct ct = default)
{
logger.ProcessingLogoutRequest(LogLevel.Debug);

View file

@ -21,7 +21,7 @@ internal class DefaultSilentLoginCallbackEndpoint(
{
/// <inheritdoc />
public async Task ProcessRequestAsync(HttpContext context, CT ct = default)
public async Task ProcessRequestAsync(HttpContext context, Ct ct = default)
{
logger.ProcessingSilentLoginCallbackRequest(LogLevel.Debug);

View file

@ -23,7 +23,7 @@ internal class DefaultSilentLoginEndpoint(IOptions<BffOptions> options, ILogger<
private readonly BffOptions _options = options.Value;
/// <inheritdoc />
public async Task ProcessRequestAsync(HttpContext context, CT ct = default)
public async Task ProcessRequestAsync(HttpContext context, Ct ct = default)
{
logger.ProcessingSilentLoginRequest(LogLevel.Debug);

View file

@ -26,7 +26,7 @@ internal class DefaultUserEndpoint(IOptions<BffOptions> options, ILogger<Default
private readonly BffOptions _options = options.Value;
/// <inheritdoc />
public async Task ProcessRequestAsync(HttpContext context, CT ct = default)
public async Task ProcessRequestAsync(HttpContext context, Ct ct = default)
{
logger.ProcessingUserRequest(LogLevel.Debug);
@ -76,7 +76,7 @@ internal class DefaultUserEndpoint(IOptions<BffOptions> options, ILogger<Default
/// Collect user-centric claims
/// </summary>
/// <returns></returns>
private static Task<IEnumerable<ClaimRecord>> GetUserClaimsAsync(AuthenticateResult authenticateResult, CT ct = default) =>
private static Task<IEnumerable<ClaimRecord>> GetUserClaimsAsync(AuthenticateResult authenticateResult, Ct ct = default) =>
Task.FromResult(authenticateResult.Principal?.Claims.Select(x => new ClaimRecord(x.Type, x.Value)) ?? Enumerable.Empty<ClaimRecord>());
/// <summary>
@ -86,7 +86,7 @@ internal class DefaultUserEndpoint(IOptions<BffOptions> options, ILogger<Default
private Task<IEnumerable<ClaimRecord>> GetManagementClaimsAsync(
HttpContext context,
AuthenticateResult authenticateResult,
CT ct = default)
Ct ct = default)
{
var claims = new List<ClaimRecord>();

View file

@ -51,7 +51,7 @@ internal static class HttpContextExtensions
this HttpContext context,
RequiredTokenType requiredTokenType,
BffUserAccessTokenParameters? userAccessTokenParameters = null,
CT ct = default)
Ct ct = default)
{
if (requiredTokenType == RequiredTokenType.None)
{

View file

@ -12,7 +12,7 @@ namespace Duende.Bff.Internal;
internal class DefaultAccessTokenRetriever() : IAccessTokenRetriever
{
/// <inheritdoc />
public async Task<AccessTokenResult> GetAccessTokenAsync(AccessTokenRetrievalContext context, CT ct = default)
public async Task<AccessTokenResult> GetAccessTokenAsync(AccessTokenRetrievalContext context, Ct ct = default)
{
if (context.Metadata.TokenType.HasValue)
{

View file

@ -17,5 +17,5 @@ public interface ISessionRevocationService
/// <param name="filter"></param>
/// <param name="ct">A token that can be used to request cancellation of the asynchronous operation.</param>
/// <returns></returns>
Task RevokeSessionsAsync(UserSessionsFilter filter, CT ct = default);
Task RevokeSessionsAsync(UserSessionsFilter filter, Ct ct = default);
}

View file

@ -13,7 +13,7 @@ namespace Duende.Bff.SessionManagement.Revocation;
internal class NopSessionRevocationService(ILogger<NopSessionRevocationService> logger) : ISessionRevocationService
{
/// <inheritdoc />
public Task RevokeSessionsAsync(UserSessionsFilter filter, CT ct = default)
public Task RevokeSessionsAsync(UserSessionsFilter filter, Ct ct = default)
{
logger.NopSessionRevocation(LogLevel.Debug, filter.SubjectId, filter.SessionId);
return Task.CompletedTask;

View file

@ -27,7 +27,7 @@ internal class SessionRevocationService(
private readonly BffOptions _options = options.Value;
/// <inheritdoc/>
public async Task RevokeSessionsAsync(UserSessionsFilter filter, CT ct = default)
public async Task RevokeSessionsAsync(UserSessionsFilter filter, Ct ct = default)
{
if (_options.BackchannelLogoutAllUserSessions)
{

View file

@ -15,7 +15,7 @@ public interface IUserSessionStore
/// <param name="key"></param>
/// <param name="ct">A token that can be used to request cancellation of the asynchronous operation.</param>
/// <returns></returns>
Task<UserSession?> GetUserSessionAsync(UserSessionKey key, CT ct = default);
Task<UserSession?> GetUserSessionAsync(UserSessionKey key, Ct ct = default);
/// <summary>
/// Creates a user session
@ -23,7 +23,7 @@ public interface IUserSessionStore
/// <param name="session"></param>
/// <param name="ct">A token that can be used to request cancellation of the asynchronous operation.</param>
/// <returns></returns>
Task CreateUserSessionAsync(UserSession session, CT ct = default);
Task CreateUserSessionAsync(UserSession session, Ct ct = default);
/// <summary>
/// Updates a user session
@ -32,7 +32,7 @@ public interface IUserSessionStore
/// <param name="session"></param>
/// <param name="ct">A token that can be used to request cancellation of the asynchronous operation.</param>
/// <returns></returns>
Task UpdateUserSessionAsync(UserSessionKey key, UserSessionUpdate session, CT ct = default);
Task UpdateUserSessionAsync(UserSessionKey key, UserSessionUpdate session, Ct ct = default);
/// <summary>
/// Deletes a user session
@ -40,7 +40,7 @@ public interface IUserSessionStore
/// <param name="key"></param>
/// <param name="ct">A token that can be used to request cancellation of the asynchronous operation.</param>
/// <returns></returns>
Task DeleteUserSessionAsync(UserSessionKey key, CT ct = default);
Task DeleteUserSessionAsync(UserSessionKey key, Ct ct = default);
/// <summary>
/// Queries user sessions based on the filter.
@ -49,7 +49,7 @@ public interface IUserSessionStore
/// <param name="filter"></param>
/// <param name="ct">A token that can be used to request cancellation of the asynchronous operation.</param>
/// <returns></returns>
Task<IReadOnlyCollection<UserSession>> GetUserSessionsAsync(PartitionKey partitionKey, UserSessionsFilter filter, CT ct = default);
Task<IReadOnlyCollection<UserSession>> GetUserSessionsAsync(PartitionKey partitionKey, UserSessionsFilter filter, Ct ct = default);
/// <summary>
/// Deletes user sessions based on the filter.
@ -58,5 +58,5 @@ public interface IUserSessionStore
/// <param name="filter"></param>
/// <param name="ct">A token that can be used to request cancellation of the asynchronous operation.</param>
/// <returns></returns>
Task DeleteUserSessionsAsync(PartitionKey partitionKey, UserSessionsFilter filter, CT ct = default);
Task DeleteUserSessionsAsync(PartitionKey partitionKey, UserSessionsFilter filter, Ct ct = default);
}

View file

@ -12,5 +12,5 @@ public interface IUserSessionStoreCleanup
/// <summary>
/// Deletes expired sessions
/// </summary>
Task<int> DeleteExpiredSessionsAsync(CT ct = default);
Task<int> DeleteExpiredSessionsAsync(Ct ct = default);
}

View file

@ -19,7 +19,7 @@ internal class InMemoryUserSessionStore(
// A dictionary of dictionaries, where the outer dictionary is keyed by partition key
private readonly ConcurrentDictionary<PartitionKey, UserSessionDictionary> _store = new();
public Task CreateUserSessionAsync(UserSession session, CT ct = default)
public Task CreateUserSessionAsync(UserSession session, Ct ct = default)
{
if (!session.PartitionKey.HasValue)
{
@ -47,7 +47,7 @@ internal class InMemoryUserSessionStore(
return partition;
}
public Task<UserSession?> GetUserSessionAsync(UserSessionKey key, CT ct = default)
public Task<UserSession?> GetUserSessionAsync(UserSessionKey key, Ct ct = default)
{
var partition = GetPartition(key.PartitionKey);
partition.TryGetValue(key.UserKey, out var item);
@ -55,7 +55,7 @@ internal class InMemoryUserSessionStore(
return Task.FromResult(item?.Clone());
}
public Task UpdateUserSessionAsync(UserSessionKey key, UserSessionUpdate session, CT ct = default)
public Task UpdateUserSessionAsync(UserSessionKey key, UserSessionUpdate session, Ct ct = default)
{
var partition = GetPartition(key.PartitionKey);
if (!partition.TryGetValue(key.UserKey, out var existing))
@ -70,14 +70,14 @@ internal class InMemoryUserSessionStore(
return Task.CompletedTask;
}
public Task DeleteUserSessionAsync(UserSessionKey key, CT ct = default)
public Task DeleteUserSessionAsync(UserSessionKey key, Ct ct = default)
{
var partition = GetPartition(key.PartitionKey);
partition.TryRemove(key.UserKey, out _);
return Task.CompletedTask;
}
public Task<IReadOnlyCollection<UserSession>> GetUserSessionsAsync(PartitionKey partitionKey, UserSessionsFilter filter, CT ct = default)
public Task<IReadOnlyCollection<UserSession>> GetUserSessionsAsync(PartitionKey partitionKey, UserSessionsFilter filter, Ct ct = default)
{
filter.Validate();
var partition = GetPartition(partitionKey);
@ -97,7 +97,7 @@ internal class InMemoryUserSessionStore(
return Task.FromResult((IReadOnlyCollection<UserSession>)results);
}
public Task DeleteUserSessionsAsync(PartitionKey partitionKey, UserSessionsFilter filter, CT ct = default)
public Task DeleteUserSessionsAsync(PartitionKey partitionKey, UserSessionsFilter filter, Ct ct = default)
{
filter.Validate();
var partition = GetPartition(partitionKey);

View file

@ -23,7 +23,7 @@ internal class SessionCleanupHost(
private TimeSpan CleanupInterval => _options.SessionCleanupInterval;
public override Task StartAsync(CT ct)
public override Task StartAsync(Ct ct)
{
if (!IsIUserSessionStoreCleanupRegistered())
{
@ -34,7 +34,7 @@ internal class SessionCleanupHost(
return base.StartAsync(ct);
}
protected override async Task ExecuteAsync(CT ct)
protected override async Task ExecuteAsync(Ct ct)
{
while (true)
{
@ -70,7 +70,7 @@ internal class SessionCleanupHost(
}
}
internal async Task RunAsync(CT ct = default)
internal async Task RunAsync(Ct ct = default)
{
try
{

View file

@ -18,5 +18,5 @@ public interface IServerTicketStore : ITicketStore
/// <param name="filter"></param>
/// <param name="ct">A token that can be used to request cancellation of the asynchronous operation.</param>
/// <returns></returns>
Task<IReadOnlyCollection<AuthenticationTicket>> GetUserTicketsAsync(UserSessionsFilter filter, CT ct = default);
Task<IReadOnlyCollection<AuthenticationTicket>> GetUserTicketsAsync(UserSessionsFilter filter, Ct ct = default);
}

View file

@ -31,7 +31,7 @@ internal class ServerSideTicketStore(
private readonly IDataProtector _protector = dataProtectionProvider.CreateProtector(DataProtectorPurpose);
private CT ct => accessor.HttpContext?.RequestAborted ?? CT.None;
private Ct _ct => accessor.HttpContext?.RequestAborted ?? Ct.None;
/// <inheritdoc />
public async Task<string> StoreAsync(AuthenticationTicket ticket)
@ -43,7 +43,7 @@ internal class ServerSideTicketStore(
{
SubjectId = ticket.GetSubjectId(),
SessionId = ticket.GetSessionId()
}, ct);
}, _ct);
var key = CryptoRandom.CreateUniqueId(format: CryptoRandom.OutputFormat.Hex);
@ -68,7 +68,7 @@ internal class ServerSideTicketStore(
Ticket = ticket.Serialize(_protector)
};
await store.CreateUserSessionAsync(session, ct);
await store.CreateUserSessionAsync(session, _ct);
metrics.SessionStarted();
}
@ -78,7 +78,7 @@ internal class ServerSideTicketStore(
logger.RetrieveAuthenticationTicket(LogLevel.Debug, key);
var userSessionKey = BuildUserSessionKey(key);
var session = await store.GetUserSessionAsync(userSessionKey, ct);
var session = await store.GetUserSessionAsync(userSessionKey, _ct);
if (session == null)
{
logger.NoAuthenticationTicketFoundForKey(LogLevel.Debug, key);
@ -111,7 +111,7 @@ internal class ServerSideTicketStore(
public async Task RenewAsync(string key, AuthenticationTicket ticket)
{
var userSessionKey = BuildUserSessionKey(key);
var session = await store.GetUserSessionAsync(userSessionKey, ct);
var session = await store.GetUserSessionAsync(userSessionKey, _ct);
if (session == null)
{
// https://github.com/dotnet/aspnetcore/issues/41516#issuecomment-1178076544
@ -134,7 +134,7 @@ internal class ServerSideTicketStore(
Renewed = ticket.GetIssued(timeProvider.GetUtcNow()),
Expires = ticket.GetExpiration(),
Ticket = ticket.Serialize(_protector)
}, ct);
}, _ct);
}
/// <inheritdoc />
@ -150,11 +150,11 @@ internal class ServerSideTicketStore(
logger.RemovingAuthenticationTicket(LogLevel.Debug, userSessionKey.ToString());
metrics.SessionEnded();
return store.DeleteUserSessionAsync(userSessionKey, ct);
return store.DeleteUserSessionAsync(userSessionKey, _ct);
}
/// <inheritdoc />
public async Task<IReadOnlyCollection<AuthenticationTicket>> GetUserTicketsAsync(UserSessionsFilter filter, CT ct)
public async Task<IReadOnlyCollection<AuthenticationTicket>> GetUserTicketsAsync(UserSessionsFilter filter, Ct ct)
{
logger.GettingAuthenticationTickets(LogLevel.Debug, filter.SubjectId, filter.SessionId);

View file

@ -171,7 +171,7 @@ public class BffFrontendIndexTests : BffTestBase
{
private int count = 1;
public Task<string?> Transform(string html, BffFrontend frontend, CT ct = default) => Task.FromResult<string?>($"{html} - transformed {count++}");
public Task<string?> Transform(string html, BffFrontend frontend, Ct ct = default) => Task.FromResult<string?>($"{html} - transformed {count++}");
}
[Fact]

View file

@ -60,7 +60,7 @@ public class BffFrontendSigninTests : BffTestBase
Bff.OnConfigureApp += app =>
{
app.MapGet(pathString, (HttpContext c, CT ct) => "ok");
app.MapGet(pathString, (HttpContext c, Ct ct) => "ok");
};
await InitializeAsync();

View file

@ -143,7 +143,7 @@ public class BffRemoteApiTests : BffTestBase
public bool WasCalled = false;
public Task<TokenResult<UserToken>> GetAccessTokenAsync(ClaimsPrincipal user, UserTokenRequestParameters? parameters = null,
CT ct = new CT())
Ct ct = new Ct())
{
WasCalled = true;
// We don't care actually about the result token. Just if it was called or not.
@ -151,7 +151,7 @@ public class BffRemoteApiTests : BffTestBase
}
public Task RevokeRefreshTokenAsync(ClaimsPrincipal user, UserTokenRequestParameters? parameters = null,
CT ct = new CT()) => throw new NotImplementedException();
Ct ct = new Ct()) => throw new NotImplementedException();
}
[Fact]

View file

@ -47,7 +47,7 @@ public class BffScenarioTests : BffTestBase
TaskCompletionSource<string> contentReceived,
TaskCompletionSource workerIsAllowedToStart) : BackgroundService
{
protected override async Task ExecuteAsync(CT stoppingToken)
protected override async Task ExecuteAsync(Ct stoppingToken)
{
await workerIsAllowedToStart.Task;

View file

@ -11,7 +11,7 @@ public class BffWithoutExplicitFrontendTests : BffTestBase
{
Bff.OnConfigureApp += app =>
{
app.MapGet("/secret", (HttpContext c, CT ct) =>
app.MapGet("/secret", (HttpContext c, Ct ct) =>
{
if (!c.User.IsAuthenticated())
{

View file

@ -23,7 +23,7 @@ public class AntiForgeryHandlerTests
var client = new HttpClient(sut);
await client.SendAsync(request, CT.None);
await client.SendAsync(request, Ct.None);
request.Headers.ShouldContain(h => h.Key == "X-CSRF" && h.Value.Contains("1"));
}
@ -31,5 +31,5 @@ public class AntiForgeryHandlerTests
public class NoOpHttpMessageHandler : HttpMessageHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CT ct) => Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK));
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, Ct ct) => Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK));
}

View file

@ -60,7 +60,7 @@ public class MockHttpMessageHandler : HttpMessageHandler
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CT ct)
Ct ct)
{
if (request.Content != null) // Could be a GET-request without a body
{

View file

@ -211,12 +211,12 @@ public class ConventionTests
failures.Add($"{type.FullName}.{method.Name}: Async method should be suffixed with 'Async'.");
}
// 2. Last parameter should be a CT (if there are any parameters)
// 2. Last parameter should be a Ct (if there are any parameters)
var parameters = method.GetParameters();
if (parameters.Length == 0 || parameters.Last().ParameterType != typeof(CT))
if (parameters.Length == 0 || parameters.Last().ParameterType != typeof(Ct))
{
failures.Add(
$"{type.FullName}.{method.Name}: Async method should have a CT as the last parameter.");
$"{type.FullName}.{method.Name}: Async method should have a Ct as the last parameter.");
}
}
}
@ -273,7 +273,7 @@ public class ConventionTests
}
var ctParam = parameters.Last();
if (ctParam.ParameterType != typeof(CT))
if (ctParam.ParameterType != typeof(Ct))
{
failures.Add($"{type.FullName}.{method.Name}: Last parameter should be CancellationToken.");
continue;

View file

@ -33,7 +33,7 @@ public class UserEndpointTests : BffTestBase
private class TestClaimsEnricher(IHttpClientFactory factory) : IUserEndpointClaimsEnricher
{
public async Task<IReadOnlyList<ClaimRecord>> EnrichClaimsAsync(AuthenticateResult authenticateResult, IReadOnlyList<ClaimRecord> claims, CT ct = default)
public async Task<IReadOnlyList<ClaimRecord>> EnrichClaimsAsync(AuthenticateResult authenticateResult, IReadOnlyList<ClaimRecord> claims, Ct ct = default)
{
var client = factory.CreateClient("c1");

View file

@ -92,7 +92,7 @@ public class IAccessTokenRetriever_Extensibility_tests : BffTestBase
{
}
public async Task<AccessTokenResult> GetAccessTokenAsync(AccessTokenRetrievalContext context, CT ct = default)
public async Task<AccessTokenResult> GetAccessTokenAsync(AccessTokenRetrievalContext context, Ct ct = default)
{
UsedContext = context;
if (context.Metadata.TokenType.HasValue)

View file

@ -117,7 +117,7 @@ public class ServerSideTokenStoreTests
public Task SetUserTokenAsync(UserToken token, AuthenticationProperties authenticationProperties,
UserTokenRequestParameters? parameters = null, CT ct = new CT())
UserTokenRequestParameters? parameters = null, Ct ct = new Ct())
{
Stored = token;
return Task.CompletedTask;
@ -127,7 +127,7 @@ public class ServerSideTokenStoreTests
UserTokenRequestParameters? parameters = null) => Stored = null;
public Task<Scheme> GetSchemeAsync(UserTokenRequestParameters? parameters = null,
CT ct = new CT()) =>
Ct ct = new Ct()) =>
Task.FromResult(Scheme.Bearer);
}

View file

@ -7,7 +7,7 @@ namespace Duende.Bff.Tests.TestFramework;
public class FailureAccessTokenRetriever : IAccessTokenRetriever
{
public Task<AccessTokenResult> GetAccessTokenAsync(AccessTokenRetrievalContext context, CT ct = default) =>
public Task<AccessTokenResult> GetAccessTokenAsync(AccessTokenRetrievalContext context, Ct ct = default) =>
Task.FromResult<AccessTokenResult>(new AccessTokenRetrievalError
{
Error = "no access token"

View file

@ -10,7 +10,7 @@ public class MockSessionRevocationService : ISessionRevocationService
{
public bool DeleteUserSessionsWasCalled { get; set; }
public UserSessionsFilter? DeleteUserSessionsFilter { get; set; }
public Task RevokeSessionsAsync(UserSessionsFilter filter, CT ct)
public Task RevokeSessionsAsync(UserSessionsFilter filter, Ct ct)
{
DeleteUserSessionsWasCalled = true;
DeleteUserSessionsFilter = filter;

View file

@ -7,5 +7,5 @@ namespace Duende.Bff.Tests.TestFramework;
public class TestAccessTokenRetriever(Func<Task<AccessTokenResult>> accessTokenGetter) : IAccessTokenRetriever
{
public async Task<AccessTokenResult> GetAccessTokenAsync(AccessTokenRetrievalContext context, CT ct = default) => await accessTokenGetter();
public async Task<AccessTokenResult> GetAccessTokenAsync(AccessTokenRetrievalContext context, Ct ct = default) => await accessTokenGetter();
}

View file

@ -15,7 +15,7 @@ public class TestBrowserClient : HttpClient
public HttpResponseMessage? LastResponse { get; private set; }
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CT ct)
Ct ct)
{
CurrentUri = request.RequestUri ?? throw new NullReferenceException("RequestUri is not set");
var cookieHeader = CookieContainer.GetCookieHeader(request.RequestUri);
@ -83,7 +83,7 @@ public class TestBrowserClient : HttpClient
internal async Task<BffHostResponse> CallBffHostApi(
string url,
HttpStatusCode? expectedStatusCode = null,
CT ct = default)
Ct ct = default)
{
var req = new HttpRequestMessage(HttpMethod.Get, url);
req.Headers.Add("x-csrf", "1");
@ -112,7 +112,7 @@ public class TestBrowserClient : HttpClient
HttpMethod method,
HttpContent? content = null,
HttpStatusCode? expectedStatusCode = null,
CT ct = default)
Ct ct = default)
{
var req = new HttpRequestMessage(method, url);
if (req.Content == null)

View file

@ -51,7 +51,7 @@ public class BffHttpClient(RedirectHandler handler, CookieContainer cookies, Ide
HttpContent? content = null,
HttpStatusCode? expectedStatusCode = null,
Dictionary<string, string>? headers = null,
CT ct = default) => CallBffHostApi(
Ct ct = default) => CallBffHostApi(
url: new Uri(path, UriKind.Relative),
method: method,
content: content,
@ -65,7 +65,7 @@ public class BffHttpClient(RedirectHandler handler, CookieContainer cookies, Ide
HttpContent? content = null,
HttpStatusCode? expectedStatusCode = null,
Dictionary<string, string>? headers = null,
CT ct = default)
Ct ct = default)
{
method ??= HttpMethod.Get;
var req = new HttpRequestMessage(method, url);

View file

@ -9,7 +9,7 @@ namespace Duende.Bff.Tests.TestInfra;
public class CookieHandler(HttpMessageHandler innerHandler, CookieContainer cookieContainer)
: DelegatingHandler(innerHandler)
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CT ct)
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, Ct ct)
{
var requestUri = request.RequestUri;
var header = cookieContainer.GetCookieHeader(requestUri!);

View file

@ -12,7 +12,7 @@ public class RedirectHandler(WriteTestOutput output) : DelegatingHandler
public bool AutoFollowRedirects { get; set; } = true;
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CT ct)
Ct ct)
{
var originalUri = request.RequestUri;

View file

@ -27,7 +27,7 @@ public class RoutingMessageHandler : HttpMessageHandler
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CT ct)
Ct ct)
{
var host = $"{request.RequestUri?.Host}:{request.RequestUri?.Port}";
@ -46,7 +46,7 @@ public class RoutingMessageHandler : HttpMessageHandler
{
internal Task<HttpResponseMessage> SuppressedSend(
HttpRequestMessage request,
CT ct)
Ct ct)
{
Task<HttpResponseMessage> t;
if (ExecutionContext.IsFlowSuppressed())

View file

@ -59,7 +59,7 @@ public class SimulatedInternet : DelegatingHandler
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CT ct)
Ct ct)
{
var requestId = Interlocked.Increment(ref _requestIdSeed);

View file

@ -10,19 +10,19 @@ internal class TestHybridCache : HybridCache
{
private ConcurrentDictionary<string, ValueTask<object>> _cache = new();
public override async ValueTask<T> GetOrCreateAsync<TState, T>(string key, TState state,
Func<TState, CT, ValueTask<T>> factory, HybridCacheEntryOptions? options = null,
IEnumerable<string>? tags = null, CT ct = new CT()) => (T)await _cache.GetOrAdd(key, async _ => (await factory(state, ct))!);
Func<TState, Ct, ValueTask<T>> factory, HybridCacheEntryOptions? options = null,
IEnumerable<string>? tags = null, Ct ct = new Ct()) => (T)await _cache.GetOrAdd(key, async _ => (await factory(state, ct))!);
public override ValueTask SetAsync<T>(string key, T value, HybridCacheEntryOptions? options = null,
IEnumerable<string>? tags = null,
CT ct = new CT())
Ct ct = new Ct())
{
_cache[key] = new ValueTask<object>(value!);
return ValueTask.CompletedTask;
}
public override ValueTask
RemoveAsync(string key, CT ct = new CT())
RemoveAsync(string key, Ct ct = new Ct())
{
_waitUntilRemoveAsyncCalled.Set();
_cache.TryRemove(key, out _);
@ -33,7 +33,7 @@ internal class TestHybridCache : HybridCache
ManualResetEventSlim _waitUntilRemoveAsyncCalled = new ManualResetEventSlim();
public override ValueTask RemoveByTagAsync(string tag,
CT ct = new CT())
Ct ct = new Ct())
{
_waitUntilRemoveByTagAsyncCalled.Set();
_cache.Clear();

View file

@ -11,7 +11,7 @@ public class TestTokenRetriever : IAccessTokenRetriever
public AccessTokenRetrievalContext? UsedContext { get; set; }
public Task<AccessTokenResult> GetAccessTokenAsync(AccessTokenRetrievalContext context,
CT ct = default)
Ct ct = default)
{
UsedContext = context;
return Task.FromResult<AccessTokenResult>(new NoAccessTokenResult());

View file

@ -41,7 +41,7 @@ internal sealed partial class ConformanceReportEndpoint
/// <summary>
/// Processes requests for the HTML conformance report.
/// </summary>
public async Task<IResult> GetHtmlReportAsync(HttpContext context, CT ct = default)
public async Task<IResult> GetHtmlReportAsync(HttpContext context, Ct ct)
{
LogProcessingRequest();
@ -53,7 +53,7 @@ internal sealed partial class ConformanceReportEndpoint
try
{
var report = await _assessmentService.GenerateReportAsync(ct: ct);
var report = await _assessmentService.GenerateReportAsync(ct);
using var slice = Duende.ConformanceReport.Slices.ConformanceReport.Create(report);
var sb = new StringBuilder();

View file

@ -25,7 +25,7 @@ public static class ConformanceReportEndpointExtensions
var group = endpoints.MapGroup(basePath);
// HTML endpoint - requires custom authorization policy
_ = group.MapGet("", async (ConformanceReportEndpoint endpoint, HttpContext context, CT ct) =>
_ = group.MapGet("", async (ConformanceReportEndpoint endpoint, HttpContext context, Ct ct) =>
await endpoint.GetHtmlReportAsync(context, ct))
.RequireAuthorization(options.AuthorizationPolicyName)
.WithName("GetConformanceHtmlReport")

View file

@ -5,5 +5,5 @@ namespace Duende.ConformanceReport;
internal interface IConformanceReportClientStore
{
Task<IEnumerable<ConformanceReportClient>> GetAllClientsAsync(CT ct = default);
Task<IEnumerable<ConformanceReportClient>> GetAllClientsAsync(Ct ct);
}

View file

@ -44,7 +44,7 @@ internal class ConformanceReportAssessmentService
/// </summary>
/// <param name="ct">The cancellation token.</param>
/// <returns>A conformance report containing the assessment results.</returns>
public async Task<ConformanceReportResult> GenerateReportAsync(CT ct = default)
public async Task<ConformanceReportResult> GenerateReportAsync(Ct ct)
{
var clients = await _clientStore.GetAllClientsAsync(ct);
var clientList = clients.ToList();
@ -91,7 +91,7 @@ internal class ConformanceReportAssessmentService
/// <returns>A profile result containing the assessment findings.</returns>
public async Task<ProfileResult> AssessProfileAsync(
ConformanceReportProfile profile,
CT ct = default)
Ct ct)
{
var clients = await _clientStore.GetAllClientsAsync(ct);
var clientList = clients.ToList();

View file

@ -99,7 +99,7 @@ public class ConformanceReportEndpointTests
private sealed class InMemoryClientStore(IEnumerable<ConformanceReportClient> clients) : IConformanceReportClientStore
{
public Task<IEnumerable<ConformanceReportClient>> GetAllClientsAsync(CancellationToken ct = default)
public Task<IEnumerable<ConformanceReportClient>> GetAllClientsAsync(CancellationToken ct)
=> Task.FromResult(clients);
}
@ -124,13 +124,14 @@ public class ConformanceReportEndpointTests
public class HtmlEndpointTests
{
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
[Fact]
public async Task GetHtmlReportWhenEnabledReturnsHtmlContent()
{
var endpoint = CreateEndpoint();
var context = CreateHttpContext();
var result = await endpoint.GetHtmlReportAsync(context);
var result = await endpoint.GetHtmlReportAsync(context, _ct);
_ = result.ShouldNotBeNull();
_ = result.ShouldBeOfType<Microsoft.AspNetCore.Http.HttpResults.ContentHttpResult>();
@ -145,7 +146,7 @@ public class ConformanceReportEndpointTests
var endpoint = CreateEndpoint(options: options);
var context = CreateHttpContext();
var result = await endpoint.GetHtmlReportAsync(context);
var result = await endpoint.GetHtmlReportAsync(context, _ct);
_ = result.ShouldBeOfType<Microsoft.AspNetCore.Http.HttpResults.NotFound>();
}
@ -163,7 +164,7 @@ public class ConformanceReportEndpointTests
var endpoint = CreateEndpoint(licenseInfo: licenseInfo);
var context = CreateHttpContext();
var result = await endpoint.GetHtmlReportAsync(context);
var result = await endpoint.GetHtmlReportAsync(context, _ct);
var contentResult = (Microsoft.AspNetCore.Http.HttpResults.ContentHttpResult)result;
var html = contentResult.ResponseContent!;

View file

@ -104,7 +104,7 @@ public class ConformanceAssessmentServiceTests
private sealed class InMemoryClientStore(IEnumerable<ConformanceReportClient> clients) : IConformanceReportClientStore
{
public Task<IEnumerable<ConformanceReportClient>> GetAllClientsAsync(CancellationToken ct = default) => Task.FromResult(clients);
public Task<IEnumerable<ConformanceReportClient>> GetAllClientsAsync(CancellationToken ct) => Task.FromResult(clients);
}
private sealed class TestHttpContextAccessor : IHttpContextAccessor
@ -123,12 +123,13 @@ public class ConformanceAssessmentServiceTests
public class ReportGenerationTests
{
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
[Fact]
public async Task GenerateReportWithBothProfilesEnabledReturnsCompleteReport()
{
var service = CreateService();
var report = await service.GenerateReportAsync();
var report = await service.GenerateReportAsync(_ct);
_ = report.ShouldNotBeNull();
_ = report.Profiles.ShouldNotBeNull();
@ -142,7 +143,7 @@ public class ConformanceAssessmentServiceTests
var options = CreateDefaultOptions(enableOAuth21: true, enableFapi2: false);
var service = CreateService(options: options);
var report = await service.GenerateReportAsync();
var report = await service.GenerateReportAsync(_ct);
_ = report.Profiles.OAuth21.ShouldNotBeNull();
report.Profiles.Fapi2Security.ShouldBeNull();
@ -154,7 +155,7 @@ public class ConformanceAssessmentServiceTests
var options = CreateDefaultOptions(enableOAuth21: false, enableFapi2: true);
var service = CreateService(options: options);
var report = await service.GenerateReportAsync();
var report = await service.GenerateReportAsync(_ct);
report.Profiles.OAuth21.ShouldBeNull();
_ = report.Profiles.Fapi2Security.ShouldNotBeNull();
@ -166,7 +167,7 @@ public class ConformanceAssessmentServiceTests
var service = CreateService();
var beforeTime = DateTimeOffset.UtcNow;
var report = await service.GenerateReportAsync();
var report = await service.GenerateReportAsync(_ct);
var afterTime = DateTimeOffset.UtcNow;
report.AssessedAt.ShouldBeGreaterThanOrEqualTo(beforeTime);
@ -184,7 +185,7 @@ public class ConformanceAssessmentServiceTests
};
var service = CreateService(clients: clients);
var report = await service.GenerateReportAsync();
var report = await service.GenerateReportAsync(_ct);
// Overall summary
report.OverallSummary.TotalClients.ShouldBe(3);

View file

@ -21,7 +21,7 @@
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)shared/GlobalAliasses.cs" Link="GlobalAliasses.cs" />
<Compile Include="$(MSBuildThisFileDirectory)shared/Global.cs" Link="Global.cs" />
</ItemGroup>
</Project>

View file

@ -45,7 +45,7 @@ public class SystemBrowser : IBrowser
return port;
}
public async Task<BrowserResult> InvokeAsync(BrowserOptions options, CT ct = default)
public async Task<BrowserResult> InvokeAsync(BrowserOptions options, Ct ct = default)
{
using (var listener = new LoopbackHttpListener(Port, _path))
{

View file

@ -37,7 +37,7 @@ public class SystemBrowser : IBrowser
return port;
}
public async Task<BrowserResult> InvokeAsync(BrowserOptions options, CT ct = default)
public async Task<BrowserResult> InvokeAsync(BrowserOptions options, Ct ct = default)
{
using (var listener = new LoopbackHttpListener(Port, _path))
{

View file

@ -8,7 +8,7 @@ public class TestHandler : DelegatingHandler
private readonly ILogger<TestHandler> _logger;
public TestHandler(ILogger<TestHandler> logger) => _logger = logger;
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CT ct)
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, Ct ct)
{
var response = await base.SendAsync(request, ct);
if (response.Headers.Contains("WWW-Authenticate"))

View file

@ -10,7 +10,7 @@ namespace MvcJarJwt;
public class ClientAssertionService(AssertionService assertionService) : IClientAssertionService
{
public Task<ClientAssertion> GetClientAssertionAsync(ClientCredentialsClientName? clientName = null, TokenRequestParameters parameters = null,
CT ct = new())
Ct ct = new())
{
var assertion = new ClientAssertion
{

View file

@ -11,7 +11,7 @@ public class ClientAssertionService(AssertionService assertionService) : IClient
{
public Task<ClientAssertion> GetClientAssertionAsync(ClientCredentialsClientName? clientName = null,
TokenRequestParameters parameters = null,
CT ct = new())
Ct ct = new())
{
var assertion = new ClientAssertion
{

View file

@ -10,7 +10,7 @@ namespace Web;
public class ClientAssertionService(AssertionService assertionService) : IClientAssertionService
{
public Task<ClientAssertion?> GetClientAssertionAsync(ClientCredentialsClientName? clientName = null, TokenRequestParameters? parameters = null,
CT ct = new CT())
Ct ct = new Ct())
{
var assertion = new ClientAssertion
{

View file

@ -26,9 +26,9 @@ internal class CallbackManager
}
}
public async Task<string> RunServer(CT? token = null)
public async Task<string> RunServer(Ct? token = null)
{
token = CT.None;
token = Ct.None;
await using var server = new NamedPipeServerStream(_name, PipeDirection.In);
await server.WaitForConnectionAsync(token.Value);

View file

@ -12,7 +12,7 @@ public class TestOperationalStoreNotification : IOperationalStoreNotification
{
public TestOperationalStoreNotification() => Console.WriteLine("ctor");
public Task PersistedGrantsRemovedAsync(IEnumerable<PersistedGrant> persistedGrants, CT ct = default)
public Task PersistedGrantsRemovedAsync(IEnumerable<PersistedGrant> persistedGrants, Ct ct)
{
ArgumentNullException.ThrowIfNull(persistedGrants);
foreach (var grant in persistedGrants)
@ -22,7 +22,7 @@ public class TestOperationalStoreNotification : IOperationalStoreNotification
return Task.CompletedTask;
}
public Task DeviceCodesRemovedAsync(IEnumerable<DeviceFlowCodes> deviceCodes, CT ct = default)
public Task DeviceCodesRemovedAsync(IEnumerable<DeviceFlowCodes> deviceCodes, Ct ct)
{
ArgumentNullException.ThrowIfNull(deviceCodes);
foreach (var deviceCode in deviceCodes)
@ -32,7 +32,7 @@ public class TestOperationalStoreNotification : IOperationalStoreNotification
return Task.CompletedTask;
}
public Task ServerSideSessionsRemovedAsync(IEnumerable<ServerSideSession> userSessions, CT ct = default)
public Task ServerSideSessionsRemovedAsync(IEnumerable<ServerSideSession> userSessions, Ct ct)
{
ArgumentNullException.ThrowIfNull(userSessions);
foreach (var session in userSessions)

View file

@ -18,14 +18,14 @@ public sealed class CustomClientRegistrationProcessor(
IClientStore clientStore) : DynamicClientRegistrationRequestProcessor(options, dcrStore)
{
protected override async Task<IStepResult> AddClientId(DynamicClientRegistrationContext context)
protected override async Task<IStepResult> AddClientId(DynamicClientRegistrationContext context, Ct ct)
{
if (context.Request.Extensions.TryGetValue("client_id", out var clientIdParameter))
{
var clientId = clientIdParameter.ToString();
if (clientId != null)
{
var existingClient = await clientStore.FindClientByIdAsync(clientId);
var existingClient = await clientStore.FindClientByIdAsync(clientId, ct);
if (existingClient is not null)
{
return new DynamicClientRegistrationError(
@ -40,7 +40,7 @@ public sealed class CustomClientRegistrationProcessor(
}
}
}
return await base.AddClientId(context);
return await base.AddClientId(context, ct);
}
protected override async Task<(Secret, string)> GenerateSecret(DynamicClientRegistrationContext context)

View file

@ -18,7 +18,7 @@ public class DiscoveryHealthCheck : IHealthCheck
_httpContextAccessor = httpContextAccessor;
}
public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CT ct = default)
public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, Ct ct = default)
{
ArgumentNullException.ThrowIfNull(context);
try
@ -55,7 +55,7 @@ public class DiscoveryKeysHealthCheck : IHealthCheck
_httpContextAccessor = httpContextAccessor;
}
public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CT ct = default)
public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, Ct ct = default)
{
ArgumentNullException.ThrowIfNull(context);
try

View file

@ -8,7 +8,7 @@ namespace Duende.IdentityServer.Hosts.Shared.Customization;
public class ExtensionGrantValidator : IExtensionGrantValidator
{
public Task ValidateAsync(ExtensionGrantValidationContext context)
public Task ValidateAsync(ExtensionGrantValidationContext context, Ct ct)
{
ArgumentNullException.ThrowIfNull(context);
var credential = context.Request.Raw.Get("custom_credential");

View file

@ -9,10 +9,10 @@ namespace Duende.IdentityServer.Hosts.Shared.Customization;
public class HostProfileService(TestUserStore users, ILogger<TestUserProfileService> logger) : TestUserProfileService(users, logger)
{
public override async Task GetProfileDataAsync(ProfileDataRequestContext context)
public override async Task GetProfileDataAsync(ProfileDataRequestContext context, Ct ct)
{
ArgumentNullException.ThrowIfNull(context);
await base.GetProfileDataAsync(context);
await base.GetProfileDataAsync(context, ct);
var transaction = context.RequestedResources.ParsedScopes.FirstOrDefault(x => x.ParsedName == "transaction");
if (transaction?.ParsedParameter != null)

View file

@ -8,7 +8,7 @@ namespace Duende.IdentityServer.Hosts.Shared.Customization;
public class NoSubjectExtensionGrantValidator : IExtensionGrantValidator
{
public Task ValidateAsync(ExtensionGrantValidationContext context)
public Task ValidateAsync(ExtensionGrantValidationContext context, Ct ct)
{
ArgumentNullException.ThrowIfNull(context);
var credential = context.Request.Raw.Get("custom_credential");

View file

@ -8,7 +8,7 @@ namespace Duende.IdentityServer.Hosts.Shared.Customization;
public class ParameterizedScopeTokenRequestValidator : ICustomTokenRequestValidator
{
public Task ValidateAsync(CustomTokenRequestValidationContext context)
public Task ValidateAsync(CustomTokenRequestValidationContext context, Ct ct)
{
ArgumentNullException.ThrowIfNull(context);
var transaction = context.Result?.ValidatedRequest.ValidatedResources.ParsedScopes.FirstOrDefault(x => x.ParsedName == "transaction");

View file

@ -50,7 +50,7 @@ public class Index : PageModel
public async Task<IActionResult> OnGet(string? returnUrl)
{
await BuildModelAsync(returnUrl);
await BuildModelAsync(returnUrl, HttpContext.RequestAborted);
if (View.IsExternalLoginOnly)
{
@ -64,7 +64,7 @@ public class Index : PageModel
public async Task<IActionResult> OnPost()
{
// check if we are in the context of an authorization request
var context = await _interaction.GetAuthorizationContextAsync(Input.ReturnUrl);
var context = await _interaction.GetAuthorizationContextAsync(Input.ReturnUrl, HttpContext.RequestAborted);
// the user clicked the "cancel" button
if (Input.Button != "login")
@ -77,7 +77,7 @@ public class Index : PageModel
// if the user cancels, send a result back into IdentityServer as if they
// denied the consent (even if this client does not require consent).
// this will send back an access denied OIDC error response to the client.
await _interaction.DenyAuthorizationAsync(context, AuthorizationError.AccessDenied);
await _interaction.DenyAuthorizationAsync(context, AuthorizationError.AccessDenied, HttpContext.RequestAborted);
// we can trust model.ReturnUrl since GetAuthorizationContextAsync returned non-null
if (context.IsNativeClient())
@ -105,7 +105,7 @@ public class Index : PageModel
if (result.Succeeded)
{
var user = await _userManager.FindByNameAsync(Input.Username!);
await _events.RaiseAsync(new UserLoginSuccessEvent(user!.UserName, user.Id, user.UserName, clientId: context?.Client.ClientId));
await _events.RaiseAsync(new UserLoginSuccessEvent(user!.UserName, user.Id, user.UserName, clientId: context?.Client.ClientId), HttpContext.RequestAborted);
Duende.IdentityServer.UI.Pages.Telemetry.Metrics.UserLogin(context?.Client.ClientId, IdentityServerConstants.LocalIdentityProvider);
if (context != null)
@ -141,24 +141,24 @@ public class Index : PageModel
}
const string error = "invalid credentials";
await _events.RaiseAsync(new UserLoginFailureEvent(Input.Username, error, clientId: context?.Client.ClientId));
await _events.RaiseAsync(new UserLoginFailureEvent(Input.Username, error, clientId: context?.Client.ClientId), HttpContext.RequestAborted);
Duende.IdentityServer.UI.Pages.Telemetry.Metrics.UserLoginFailure(context?.Client.ClientId, IdentityServerConstants.LocalIdentityProvider, error);
ModelState.AddModelError(string.Empty, LoginOptions.InvalidCredentialsErrorMessage);
}
// something went wrong, show form with error
await BuildModelAsync(Input.ReturnUrl);
await BuildModelAsync(Input.ReturnUrl, HttpContext.RequestAborted);
return Page();
}
private async Task BuildModelAsync(string? returnUrl)
private async Task BuildModelAsync(string? returnUrl, Ct ct)
{
Input = new InputModel
{
ReturnUrl = returnUrl
};
var context = await _interaction.GetAuthorizationContextAsync(returnUrl);
var context = await _interaction.GetAuthorizationContextAsync(returnUrl, HttpContext.RequestAborted);
if (context?.IdP != null)
{
var scheme = await _schemeProvider.GetSchemeAsync(context.IdP);
@ -193,7 +193,7 @@ public class Index : PageModel
displayName: x.DisplayName ?? x.Name
)).ToList();
var dynamicSchemes = (await _identityProviderStore.GetAllSchemeNamesAsync())
var dynamicSchemes = (await _identityProviderStore.GetAllSchemeNamesAsync(ct))
.Where(x => x.Enabled)
.Select(x => new ViewModel.ExternalProvider
(

View file

@ -47,7 +47,7 @@ public class Index : PageModel
}
else
{
var context = await _interaction.GetLogoutContextAsync(LogoutId);
var context = await _interaction.GetLogoutContextAsync(LogoutId, HttpContext.RequestAborted);
if (context?.ShowSignoutPrompt == false)
{
// it's safe to automatically sign-out
@ -72,7 +72,7 @@ public class Index : PageModel
// if there's no current logout context, we need to create one
// this captures necessary info from the current logged in user
// this can still return null if there is no context needed
LogoutId ??= await _interaction.CreateLogoutContextAsync();
LogoutId ??= await _interaction.CreateLogoutContextAsync(HttpContext.RequestAborted);
// delete local authentication cookie
await _signInManager.SignOutAsync();
@ -81,7 +81,7 @@ public class Index : PageModel
var idp = User.FindFirst(JwtClaimTypes.IdentityProvider)?.Value;
// raise the logout event
await _events.RaiseAsync(new UserLogoutSuccessEvent(User.GetSubjectId(), User.GetDisplayName()));
await _events.RaiseAsync(new UserLogoutSuccessEvent(User.GetSubjectId(), User.GetDisplayName()), HttpContext.RequestAborted);
Duende.IdentityServer.UI.Pages.Telemetry.Metrics.UserLogout(idp);
// if it's a local login we can ignore this workflow

Some files were not shown because too many files have changed in this diff Show more