diff --git a/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs b/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs index 7994f4c3..8c17deea 100644 --- a/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs +++ b/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs @@ -671,38 +671,48 @@ namespace OpenIddict.Core /// public virtual async Task PruneInvalidAsync(CancellationToken cancellationToken = default) { - ImmutableArray authorizations; + IList exceptions = null; + var authorizations = new List(); - do + // First, start retrieving the invalid authorizations from the database. + for (var offset = 0; offset < 10_000; offset = offset + 100) { - // Note: don't use an offset here, as the elements returned by this method - // are progressively removed from the database immediately after calling it. - authorizations = await ListInvalidAsync(100, 0, cancellationToken); + cancellationToken.ThrowIfCancellationRequested(); - foreach (var authorization in authorizations) + var results = await ListAsync(100, offset, cancellationToken); + if (results.IsEmpty) { - cancellationToken.ThrowIfCancellationRequested(); + break; + } - try - { - await DeleteAsync(authorization, cancellationToken); + authorizations.AddRange(results); + } - Logger.LogDebug("The authorization {AuthorizationId} was successfully removed from the database.", - await GetIdAsync(authorization, cancellationToken)); - } + // Then, remove the invalid authorizations one by one. + foreach (var authorization in authorizations) + { + cancellationToken.ThrowIfCancellationRequested(); - catch (Exception exception) + try + { + await DeleteAsync(authorization, cancellationToken); + } + + catch (Exception exception) + { + if (exceptions == null) { - Logger.LogDebug(exception, - "An error occurred while removing the authorization {AuthorizationId} from the database.", - await GetIdAsync(authorization, cancellationToken)); + exceptions = new List(capacity: 1); } - } - cancellationToken.ThrowIfCancellationRequested(); + exceptions.Add(exception); + } } - while (!authorizations.IsDefaultOrEmpty); + if (exceptions != null) + { + throw new AggregateException("An error occurred while pruning authorizations.", exceptions); + } } /// diff --git a/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs b/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs index 96094279..f06c48d6 100644 --- a/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs +++ b/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs @@ -5,6 +5,7 @@ */ using System; +using System.Collections.Generic; using System.Collections.Immutable; using System.ComponentModel.DataAnnotations; using System.Linq; @@ -638,38 +639,48 @@ namespace OpenIddict.Core /// public virtual async Task PruneInvalidAsync(CancellationToken cancellationToken = default) { - ImmutableArray tokens; + IList exceptions = null; + var tokens = new List(); - do + // First, start retrieving the invalid tokens from the database. + for (var offset = 0; offset < 10_000; offset = offset + 100) { - // Note: don't use an offset here, as the elements returned by this method - // are progressively removed from the database immediately after calling it. - tokens = await ListInvalidAsync(100, 0, cancellationToken); + cancellationToken.ThrowIfCancellationRequested(); - foreach (var token in tokens) + var results = await ListInvalidAsync(100, offset, cancellationToken); + if (results.IsEmpty) { - cancellationToken.ThrowIfCancellationRequested(); + break; + } - try - { - await DeleteAsync(token, cancellationToken); + tokens.AddRange(results); + } - Logger.LogDebug("The token {TokenId} was successfully removed from the database.", - await GetIdAsync(token, cancellationToken)); - } + // Then, remove the invalid tokens one by one. + foreach (var token in tokens) + { + cancellationToken.ThrowIfCancellationRequested(); + + try + { + await DeleteAsync(token, cancellationToken); + } - catch (Exception exception) + catch (Exception exception) + { + if (exceptions == null) { - Logger.LogDebug(exception, - "An error occurred while removing the token {TokenId} from the database.", - await GetIdAsync(token, cancellationToken)); + exceptions = new List(capacity: 1); } - } - cancellationToken.ThrowIfCancellationRequested(); + exceptions.Add(exception); + } } - while (!tokens.IsDefaultOrEmpty); + if (exceptions != null) + { + throw new AggregateException("An error occurred while pruning tokens.", exceptions); + } } /// diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs index 3430195a..df50b5c5 100644 --- a/src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs +++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs @@ -163,7 +163,7 @@ namespace OpenIddict.EntityFramework Task> ListTokensAsync() => (from token in Tokens - where token.Application.Id.Equals(authorization.Id) + where token.Authorization.Id.Equals(authorization.Id) select token).ToListAsync(cancellationToken); // Remove all the tokens associated with the application. diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs index 1abf8662..519314b4 100644 --- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs +++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs @@ -163,7 +163,7 @@ namespace OpenIddict.EntityFrameworkCore Task> ListTokensAsync() => (from token in Tokens - where token.Application.Id.Equals(authorization.Id) + where token.Authorization.Id.Equals(authorization.Id) select token).ToListAsync(cancellationToken); // Remove all the tokens associated with the application.