From a4a57f30c2d54d99ed484c20ec5f264e7c3146fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Sun, 26 Jul 2020 16:54:20 +0200 Subject: [PATCH] Add nullable annotations to OpenIddict.EntityFramework --- ...EntityFrameworkApplicationConfiguration.cs | 2 +- ...tityFrameworkAuthorizationConfiguration.cs | 2 +- ...IddictEntityFrameworkScopeConfiguration.cs | 2 +- ...IddictEntityFrameworkTokenConfiguration.cs | 2 +- .../OpenIddict.EntityFramework.csproj | 1 + .../OpenIddictEntityFrameworkBuilder.cs | 11 +- .../OpenIddictEntityFrameworkExtensions.cs | 6 +- .../OpenIddictEntityFrameworkHelpers.cs | 7 +- .../OpenIddictEntityFrameworkOptions.cs | 2 +- ...EntityFrameworkApplicationStoreResolver.cs | 7 +- ...tityFrameworkAuthorizationStoreResolver.cs | 7 +- ...IddictEntityFrameworkScopeStoreResolver.cs | 7 +- ...IddictEntityFrameworkTokenStoreResolver.cs | 7 +- ...enIddictEntityFrameworkApplicationStore.cs | 453 ++++------------ ...IddictEntityFrameworkAuthorizationStore.cs | 403 ++++----------- .../OpenIddictEntityFrameworkScopeStore.cs | 345 +++--------- .../OpenIddictEntityFrameworkTokenStore.cs | 489 ++++-------------- 17 files changed, 395 insertions(+), 1358 deletions(-) diff --git a/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkApplicationConfiguration.cs b/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkApplicationConfiguration.cs index fc8ec31c..e4978601 100644 --- a/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkApplicationConfiguration.cs +++ b/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkApplicationConfiguration.cs @@ -33,7 +33,7 @@ namespace OpenIddict.EntityFramework // Entity Framework would throw an exception due to the TKey generic parameter // being non-nullable when using value types like short, int, long or Guid. - HasKey(application => application.Id); + HasKey(application => application.Id!); Property(application => application.ClientId) .HasMaxLength(100) diff --git a/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkAuthorizationConfiguration.cs b/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkAuthorizationConfiguration.cs index 8108a763..94bcd7c9 100644 --- a/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkAuthorizationConfiguration.cs +++ b/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkAuthorizationConfiguration.cs @@ -31,7 +31,7 @@ namespace OpenIddict.EntityFramework // Entity Framework would throw an exception due to the TKey generic parameter // being non-nullable when using value types like short, int, long or Guid. - HasKey(authorization => authorization.Id); + HasKey(authorization => authorization.Id!); Property(authorization => authorization.ConcurrencyToken) .HasMaxLength(50) diff --git a/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkScopeConfiguration.cs b/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkScopeConfiguration.cs index 625fbb97..eb8a7c4b 100644 --- a/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkScopeConfiguration.cs +++ b/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkScopeConfiguration.cs @@ -29,7 +29,7 @@ namespace OpenIddict.EntityFramework // Entity Framework would throw an exception due to the TKey generic parameter // being non-nullable when using value types like short, int, long or Guid. - HasKey(scope => scope.Id); + HasKey(scope => scope.Id!); Property(scope => scope.ConcurrencyToken) .HasMaxLength(50) diff --git a/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkTokenConfiguration.cs b/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkTokenConfiguration.cs index cf316457..085f8350 100644 --- a/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkTokenConfiguration.cs +++ b/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkTokenConfiguration.cs @@ -33,7 +33,7 @@ namespace OpenIddict.EntityFramework // Entity Framework would throw an exception due to the TKey generic parameter // being non-nullable when using value types like short, int, long or Guid. - HasKey(token => token.Id); + HasKey(token => token.Id!); Property(token => token.ConcurrencyToken) .HasMaxLength(50) diff --git a/src/OpenIddict.EntityFramework/OpenIddict.EntityFramework.csproj b/src/OpenIddict.EntityFramework/OpenIddict.EntityFramework.csproj index ce7d3b6d..aa48ca16 100644 --- a/src/OpenIddict.EntityFramework/OpenIddict.EntityFramework.csproj +++ b/src/OpenIddict.EntityFramework/OpenIddict.EntityFramework.csproj @@ -2,6 +2,7 @@ net461;netstandard2.1 + enable diff --git a/src/OpenIddict.EntityFramework/OpenIddictEntityFrameworkBuilder.cs b/src/OpenIddict.EntityFramework/OpenIddictEntityFrameworkBuilder.cs index 1cb900ac..414cfea7 100644 --- a/src/OpenIddict.EntityFramework/OpenIddictEntityFrameworkBuilder.cs +++ b/src/OpenIddict.EntityFramework/OpenIddictEntityFrameworkBuilder.cs @@ -7,7 +7,6 @@ using System; using System.ComponentModel; using System.Data.Entity; -using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection.Extensions; using OpenIddict.Core; using OpenIddict.EntityFramework; @@ -25,7 +24,7 @@ namespace Microsoft.Extensions.DependencyInjection /// Initializes a new instance of . /// /// The services collection. - public OpenIddictEntityFrameworkBuilder([NotNull] IServiceCollection services) + public OpenIddictEntityFrameworkBuilder(IServiceCollection services) => Services = services ?? throw new ArgumentNullException(nameof(services)); /// @@ -40,7 +39,7 @@ namespace Microsoft.Extensions.DependencyInjection /// The delegate used to configure the OpenIddict options. /// This extension can be safely called multiple times. /// The . - public OpenIddictEntityFrameworkBuilder Configure([NotNull] Action configuration) + public OpenIddictEntityFrameworkBuilder Configure(Action configuration) { if (configuration == null) { @@ -98,7 +97,7 @@ namespace Microsoft.Extensions.DependencyInjection /// /// The type of the used by OpenIddict. /// The . - public OpenIddictEntityFrameworkBuilder UseDbContext([NotNull] Type type) + public OpenIddictEntityFrameworkBuilder UseDbContext(Type type) { if (type == null) { @@ -121,7 +120,7 @@ namespace Microsoft.Extensions.DependencyInjection /// The object to compare with the current object. /// true if the specified object is equal to the current object; otherwise, false. [EditorBrowsable(EditorBrowsableState.Never)] - public override bool Equals([CanBeNull] object obj) => base.Equals(obj); + public override bool Equals(object? obj) => base.Equals(obj); /// /// Serves as the default hash function. @@ -135,6 +134,6 @@ namespace Microsoft.Extensions.DependencyInjection /// /// A string that represents the current object. [EditorBrowsable(EditorBrowsableState.Never)] - public override string ToString() => base.ToString(); + public override string? ToString() => base.ToString(); } } diff --git a/src/OpenIddict.EntityFramework/OpenIddictEntityFrameworkExtensions.cs b/src/OpenIddict.EntityFramework/OpenIddictEntityFrameworkExtensions.cs index 9b4e02a8..a8198172 100644 --- a/src/OpenIddict.EntityFramework/OpenIddictEntityFrameworkExtensions.cs +++ b/src/OpenIddict.EntityFramework/OpenIddictEntityFrameworkExtensions.cs @@ -5,7 +5,6 @@ */ using System; -using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection.Extensions; using OpenIddict.EntityFramework; using OpenIddict.EntityFramework.Models; @@ -24,7 +23,7 @@ namespace Microsoft.Extensions.DependencyInjection /// The services builder used by OpenIddict to register new services. /// This extension can be safely called multiple times. /// The . - public static OpenIddictEntityFrameworkBuilder UseEntityFramework([NotNull] this OpenIddictCoreBuilder builder) + public static OpenIddictEntityFrameworkBuilder UseEntityFramework(this OpenIddictCoreBuilder builder) { if (builder == null) { @@ -68,8 +67,7 @@ namespace Microsoft.Extensions.DependencyInjection /// This extension can be safely called multiple times. /// The . public static OpenIddictCoreBuilder UseEntityFramework( - [NotNull] this OpenIddictCoreBuilder builder, - [NotNull] Action configuration) + this OpenIddictCoreBuilder builder, Action configuration) { if (builder == null) { diff --git a/src/OpenIddict.EntityFramework/OpenIddictEntityFrameworkHelpers.cs b/src/OpenIddict.EntityFramework/OpenIddictEntityFrameworkHelpers.cs index 5f7d7dab..4dac9167 100644 --- a/src/OpenIddict.EntityFramework/OpenIddictEntityFrameworkHelpers.cs +++ b/src/OpenIddict.EntityFramework/OpenIddictEntityFrameworkHelpers.cs @@ -8,7 +8,6 @@ using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Threading; -using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; using OpenIddict.EntityFramework; using OpenIddict.EntityFramework.Models; @@ -26,7 +25,7 @@ namespace System.Data.Entity /// /// The builder used to configure the Entity Framework context. /// The Entity Framework context builder. - public static DbModelBuilder UseOpenIddict([NotNull] this DbModelBuilder builder) + public static DbModelBuilder UseOpenIddict(this DbModelBuilder builder) => builder.UseOpenIddict /// The builder used to configure the Entity Framework context. /// The Entity Framework context builder. - public static DbModelBuilder UseOpenIddict([NotNull] this DbModelBuilder builder) + public static DbModelBuilder UseOpenIddict(this DbModelBuilder builder) where TApplication : OpenIddictEntityFrameworkApplication where TAuthorization : OpenIddictEntityFrameworkAuthorization where TScope : OpenIddictEntityFrameworkScope @@ -70,7 +69,7 @@ namespace System.Data.Entity /// The query source. /// The that can be used to abort the operation. /// The non-streamed async enumeration containing the results. - internal static IAsyncEnumerable AsAsyncEnumerable([NotNull] this IQueryable source, CancellationToken cancellationToken) + internal static IAsyncEnumerable AsAsyncEnumerable(this IQueryable source, CancellationToken cancellationToken) { if (source == null) { diff --git a/src/OpenIddict.EntityFramework/OpenIddictEntityFrameworkOptions.cs b/src/OpenIddict.EntityFramework/OpenIddictEntityFrameworkOptions.cs index 9e563f8f..083795c1 100644 --- a/src/OpenIddict.EntityFramework/OpenIddictEntityFrameworkOptions.cs +++ b/src/OpenIddict.EntityFramework/OpenIddictEntityFrameworkOptions.cs @@ -20,6 +20,6 @@ namespace OpenIddict.EntityFramework /// OpenIddict Entity Framework 6.x stores. If this property is not populated, /// an exception is thrown at runtime when trying to use the stores. /// - public Type DbContextType { get; set; } + public Type? DbContextType { get; set; } } } diff --git a/src/OpenIddict.EntityFramework/Resolvers/OpenIddictEntityFrameworkApplicationStoreResolver.cs b/src/OpenIddict.EntityFramework/Resolvers/OpenIddictEntityFrameworkApplicationStoreResolver.cs index 08aa523d..d8f73aeb 100644 --- a/src/OpenIddict.EntityFramework/Resolvers/OpenIddictEntityFrameworkApplicationStoreResolver.cs +++ b/src/OpenIddict.EntityFramework/Resolvers/OpenIddictEntityFrameworkApplicationStoreResolver.cs @@ -6,7 +6,6 @@ using System; using System.Collections.Concurrent; -using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using OpenIddict.Abstractions; @@ -26,9 +25,9 @@ namespace OpenIddict.EntityFramework private readonly IServiceProvider _provider; public OpenIddictEntityFrameworkApplicationStoreResolver( - [NotNull] TypeResolutionCache cache, - [NotNull] IOptionsMonitor options, - [NotNull] IServiceProvider provider) + TypeResolutionCache cache, + IOptionsMonitor options, + IServiceProvider provider) { _cache = cache; _options = options; diff --git a/src/OpenIddict.EntityFramework/Resolvers/OpenIddictEntityFrameworkAuthorizationStoreResolver.cs b/src/OpenIddict.EntityFramework/Resolvers/OpenIddictEntityFrameworkAuthorizationStoreResolver.cs index 5d6a2f47..993c9e56 100644 --- a/src/OpenIddict.EntityFramework/Resolvers/OpenIddictEntityFrameworkAuthorizationStoreResolver.cs +++ b/src/OpenIddict.EntityFramework/Resolvers/OpenIddictEntityFrameworkAuthorizationStoreResolver.cs @@ -6,7 +6,6 @@ using System; using System.Collections.Concurrent; -using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using OpenIddict.Abstractions; @@ -26,9 +25,9 @@ namespace OpenIddict.EntityFramework private readonly IServiceProvider _provider; public OpenIddictEntityFrameworkAuthorizationStoreResolver( - [NotNull] TypeResolutionCache cache, - [NotNull] IOptionsMonitor options, - [NotNull] IServiceProvider provider) + TypeResolutionCache cache, + IOptionsMonitor options, + IServiceProvider provider) { _cache = cache; _options = options; diff --git a/src/OpenIddict.EntityFramework/Resolvers/OpenIddictEntityFrameworkScopeStoreResolver.cs b/src/OpenIddict.EntityFramework/Resolvers/OpenIddictEntityFrameworkScopeStoreResolver.cs index 8b61e3b0..587e6726 100644 --- a/src/OpenIddict.EntityFramework/Resolvers/OpenIddictEntityFrameworkScopeStoreResolver.cs +++ b/src/OpenIddict.EntityFramework/Resolvers/OpenIddictEntityFrameworkScopeStoreResolver.cs @@ -6,7 +6,6 @@ using System; using System.Collections.Concurrent; -using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using OpenIddict.Abstractions; @@ -26,9 +25,9 @@ namespace OpenIddict.EntityFramework private readonly IServiceProvider _provider; public OpenIddictEntityFrameworkScopeStoreResolver( - [NotNull] TypeResolutionCache cache, - [NotNull] IOptionsMonitor options, - [NotNull] IServiceProvider provider) + TypeResolutionCache cache, + IOptionsMonitor options, + IServiceProvider provider) { _cache = cache; _options = options; diff --git a/src/OpenIddict.EntityFramework/Resolvers/OpenIddictEntityFrameworkTokenStoreResolver.cs b/src/OpenIddict.EntityFramework/Resolvers/OpenIddictEntityFrameworkTokenStoreResolver.cs index 0b1dc141..32e7d507 100644 --- a/src/OpenIddict.EntityFramework/Resolvers/OpenIddictEntityFrameworkTokenStoreResolver.cs +++ b/src/OpenIddict.EntityFramework/Resolvers/OpenIddictEntityFrameworkTokenStoreResolver.cs @@ -6,7 +6,6 @@ using System; using System.Collections.Concurrent; -using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using OpenIddict.Abstractions; @@ -26,9 +25,9 @@ namespace OpenIddict.EntityFramework private readonly IServiceProvider _provider; public OpenIddictEntityFrameworkTokenStoreResolver( - [NotNull] TypeResolutionCache cache, - [NotNull] IOptionsMonitor options, - [NotNull] IServiceProvider provider) + TypeResolutionCache cache, + IOptionsMonitor options, + IServiceProvider provider) { _cache = cache; _options = options; diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkApplicationStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkApplicationStore.cs index 4e78136a..c10d2d3a 100644 --- a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkApplicationStore.cs +++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkApplicationStore.cs @@ -11,6 +11,7 @@ using System.ComponentModel; using System.Data; using System.Data.Entity; using System.Data.Entity.Infrastructure; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Linq; @@ -20,7 +21,6 @@ using System.Text.Encodings.Web; using System.Text.Json; using System.Threading; using System.Threading.Tasks; -using JetBrains.Annotations; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Options; using OpenIddict.Abstractions; @@ -40,9 +40,9 @@ namespace OpenIddict.EntityFramework where TContext : DbContext { public OpenIddictEntityFrameworkApplicationStore( - [NotNull] IMemoryCache cache, - [NotNull] TContext context, - [NotNull] IOptionsMonitor options) + IMemoryCache cache, + TContext context, + IOptionsMonitor options) : base(cache, context, options) { } @@ -64,9 +64,9 @@ namespace OpenIddict.EntityFramework where TKey : IEquatable { public OpenIddictEntityFrameworkApplicationStore( - [NotNull] IMemoryCache cache, - [NotNull] TContext context, - [NotNull] IOptionsMonitor options) + IMemoryCache cache, + TContext context, + IOptionsMonitor options) { Cache = cache; Context = context; @@ -103,28 +103,12 @@ namespace OpenIddict.EntityFramework /// private DbSet Tokens => Context.Set(); - /// - /// Determines the number of applications that exist in the database. - /// - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the number of applications in the database. - /// + /// public virtual async ValueTask CountAsync(CancellationToken cancellationToken) => await Applications.LongCountAsync(cancellationToken); - /// - /// Determines the number of applications that match the specified query. - /// - /// The result type. - /// The query to execute. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the number of applications that match the specified query. - /// - public virtual async ValueTask CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + /// + public virtual async ValueTask CountAsync(Func, IQueryable> query, CancellationToken cancellationToken) { if (query == null) { @@ -134,13 +118,8 @@ namespace OpenIddict.EntityFramework return await query(Applications).LongCountAsync(cancellationToken); } - /// - /// Creates a new application. - /// - /// The application to create. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual async ValueTask CreateAsync([NotNull] TApplication application, CancellationToken cancellationToken) + /// + public virtual async ValueTask CreateAsync(TApplication application, CancellationToken cancellationToken) { if (application == null) { @@ -152,20 +131,15 @@ namespace OpenIddict.EntityFramework await Context.SaveChangesAsync(cancellationToken); } - /// - /// Removes an existing application. - /// - /// The application to delete. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual async ValueTask DeleteAsync([NotNull] TApplication application, CancellationToken cancellationToken) + /// + public virtual async ValueTask DeleteAsync(TApplication application, CancellationToken cancellationToken) { if (application == null) { throw new ArgumentNullException(nameof(application)); } - DbContextTransaction CreateTransaction() + DbContextTransaction? CreateTransaction() { try { @@ -180,13 +154,13 @@ namespace OpenIddict.EntityFramework Task> ListAuthorizationsAsync() => (from authorization in Authorizations.Include(authorization => authorization.Tokens) - where authorization.Application.Id.Equals(application.Id) + where authorization.Application!.Id!.Equals(application.Id) select authorization).ToListAsync(cancellationToken); Task> ListTokensAsync() => (from token in Tokens where token.Authorization == null - where token.Application.Id.Equals(application.Id) + where token.Application!.Id!.Equals(application.Id) select token).ToListAsync(cancellationToken); // To prevent an SQL exception from being thrown if a new associated entity is @@ -241,16 +215,8 @@ namespace OpenIddict.EntityFramework } } - /// - /// Retrieves an application using its unique identifier. - /// - /// The unique identifier associated with the application. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the client application corresponding to the identifier. - /// - public virtual async ValueTask FindByIdAsync([NotNull] string identifier, CancellationToken cancellationToken) + /// + public virtual async ValueTask FindByIdAsync(string identifier, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(identifier)) { @@ -260,20 +226,12 @@ namespace OpenIddict.EntityFramework var key = ConvertIdentifierFromString(identifier); return await (from application in Applications - where application.Id.Equals(key) + where application.Id!.Equals(key) select application).FirstOrDefaultAsync(cancellationToken); } - /// - /// Retrieves an application using its client identifier. - /// - /// The client identifier associated with the application. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the client application corresponding to the identifier. - /// - public virtual async ValueTask FindByClientIdAsync([NotNull] string identifier, CancellationToken cancellationToken) + /// + public virtual async ValueTask FindByClientIdAsync(string identifier, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(identifier)) { @@ -285,14 +243,9 @@ namespace OpenIddict.EntityFramework select application).FirstOrDefaultAsync(cancellationToken); } - /// - /// Retrieves all the applications associated with the specified post_logout_redirect_uri. - /// - /// The post_logout_redirect_uri associated with the applications. - /// The that can be used to abort the operation. - /// The client applications corresponding to the specified post_logout_redirect_uri. + /// public virtual IAsyncEnumerable FindByPostLogoutRedirectUriAsync( - [NotNull] string address, CancellationToken cancellationToken) + string address, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(address)) { @@ -310,7 +263,7 @@ namespace OpenIddict.EntityFramework async IAsyncEnumerable ExecuteAsync([EnumeratorCancellation] CancellationToken cancellationToken) { var applications = (from application in Applications - where application.PostLogoutRedirectUris.Contains(address) + where application.PostLogoutRedirectUris!.Contains(address) select application).AsAsyncEnumerable(cancellationToken); await foreach (var application in applications) @@ -324,14 +277,9 @@ namespace OpenIddict.EntityFramework } } - /// - /// Retrieves all the applications associated with the specified redirect_uri. - /// - /// The redirect_uri associated with the applications. - /// The that can be used to abort the operation. - /// The client applications corresponding to the specified redirect_uri. + /// public virtual IAsyncEnumerable FindByRedirectUriAsync( - [NotNull] string address, CancellationToken cancellationToken) + string address, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(address)) { @@ -349,7 +297,7 @@ namespace OpenIddict.EntityFramework async IAsyncEnumerable ExecuteAsync([EnumeratorCancellation] CancellationToken cancellationToken) { var applications = (from application in Applications - where application.RedirectUris.Contains(address) + where application.RedirectUris!.Contains(address) select application).AsAsyncEnumerable(cancellationToken); await foreach (var application in applications) @@ -363,21 +311,10 @@ namespace OpenIddict.EntityFramework } } - /// - /// Executes the specified query and returns the first element. - /// - /// The state type. - /// The result type. - /// The query to execute. - /// The optional state. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the first element returned when executing the query. - /// + /// public virtual async ValueTask GetAsync( - [NotNull] Func, TState, IQueryable> query, - [CanBeNull] TState state, CancellationToken cancellationToken) + Func, TState, IQueryable> query, + TState state, CancellationToken cancellationToken) { if (query == null) { @@ -387,113 +324,63 @@ namespace OpenIddict.EntityFramework return await query(Applications, state).FirstOrDefaultAsync(cancellationToken); } - /// - /// Retrieves the client identifier associated with an application. - /// - /// The application. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the client identifier associated with the application. - /// - public virtual ValueTask GetClientIdAsync([NotNull] TApplication application, CancellationToken cancellationToken) + /// + public virtual ValueTask GetClientIdAsync(TApplication application, CancellationToken cancellationToken) { if (application == null) { throw new ArgumentNullException(nameof(application)); } - return new ValueTask(application.ClientId); + return new ValueTask(application.ClientId); } - /// - /// Retrieves the client secret associated with an application. - /// Note: depending on the manager used to create the application, - /// the client secret may be hashed for security reasons. - /// - /// The application. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the client secret associated with the application. - /// - public virtual ValueTask GetClientSecretAsync([NotNull] TApplication application, CancellationToken cancellationToken) + /// + public virtual ValueTask GetClientSecretAsync(TApplication application, CancellationToken cancellationToken) { if (application == null) { throw new ArgumentNullException(nameof(application)); } - return new ValueTask(application.ClientSecret); + return new ValueTask(application.ClientSecret); } - /// - /// Retrieves the client type associated with an application. - /// - /// The application. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the client type of the application (by default, "public"). - /// - public virtual ValueTask GetClientTypeAsync([NotNull] TApplication application, CancellationToken cancellationToken) + /// + public virtual ValueTask GetClientTypeAsync(TApplication application, CancellationToken cancellationToken) { if (application == null) { throw new ArgumentNullException(nameof(application)); } - return new ValueTask(application.Type); + return new ValueTask(application.Type); } - /// - /// Retrieves the consent type associated with an application. - /// - /// The application. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the consent type of the application (by default, "explicit"). - /// - public virtual ValueTask GetConsentTypeAsync([NotNull] TApplication application, CancellationToken cancellationToken) + /// + public virtual ValueTask GetConsentTypeAsync(TApplication application, CancellationToken cancellationToken) { if (application == null) { throw new ArgumentNullException(nameof(application)); } - return new ValueTask(application.ConsentType); + return new ValueTask(application.ConsentType); } - /// - /// Retrieves the display name associated with an application. - /// - /// The application. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the display name associated with the application. - /// - public virtual ValueTask GetDisplayNameAsync([NotNull] TApplication application, CancellationToken cancellationToken) + /// + public virtual ValueTask GetDisplayNameAsync(TApplication application, CancellationToken cancellationToken) { if (application == null) { throw new ArgumentNullException(nameof(application)); } - return new ValueTask(application.DisplayName); + return new ValueTask(application.DisplayName); } - /// - /// Retrieves the localized display names associated with an application. - /// - /// The application. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns all the localized display names associated with the application. - /// - public virtual ValueTask> GetDisplayNamesAsync([NotNull] TApplication application, CancellationToken cancellationToken) + /// + public virtual ValueTask> GetDisplayNamesAsync(TApplication application, CancellationToken cancellationToken) { if (application == null) { @@ -520,35 +407,19 @@ namespace OpenIddict.EntityFramework return new ValueTask>(names); } - /// - /// Retrieves the unique identifier associated with an application. - /// - /// The application. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the unique identifier associated with the application. - /// - public virtual ValueTask GetIdAsync([NotNull] TApplication application, CancellationToken cancellationToken) + /// + public virtual ValueTask GetIdAsync(TApplication application, CancellationToken cancellationToken) { if (application == null) { throw new ArgumentNullException(nameof(application)); } - return new ValueTask(ConvertIdentifierToString(application.Id)); + return new ValueTask(ConvertIdentifierToString(application.Id)); } - /// - /// Retrieves the permissions associated with an application. - /// - /// The application. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns all the permissions associated with the application. - /// - public virtual ValueTask> GetPermissionsAsync([NotNull] TApplication application, CancellationToken cancellationToken) + /// + public virtual ValueTask> GetPermissionsAsync(TApplication application, CancellationToken cancellationToken) { if (application == null) { @@ -574,16 +445,8 @@ namespace OpenIddict.EntityFramework return new ValueTask>(permissions); } - /// - /// Retrieves the logout callback addresses associated with an application. - /// - /// The application. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns all the post_logout_redirect_uri associated with the application. - /// - public virtual ValueTask> GetPostLogoutRedirectUrisAsync([NotNull] TApplication application, CancellationToken cancellationToken) + /// + public virtual ValueTask> GetPostLogoutRedirectUrisAsync(TApplication application, CancellationToken cancellationToken) { if (application == null) { @@ -609,16 +472,8 @@ namespace OpenIddict.EntityFramework return new ValueTask>(addresses); } - /// - /// Retrieves the additional properties associated with an application. - /// - /// The application. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns all the additional properties associated with the application. - /// - public virtual ValueTask> GetPropertiesAsync([NotNull] TApplication application, CancellationToken cancellationToken) + /// + public virtual ValueTask> GetPropertiesAsync(TApplication application, CancellationToken cancellationToken) { if (application == null) { @@ -644,16 +499,8 @@ namespace OpenIddict.EntityFramework return new ValueTask>(properties); } - /// - /// Retrieves the callback addresses associated with an application. - /// - /// The application. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns all the redirect_uri associated with the application. - /// - public virtual ValueTask> GetRedirectUrisAsync([NotNull] TApplication application, CancellationToken cancellationToken) + /// + public virtual ValueTask> GetRedirectUrisAsync(TApplication application, CancellationToken cancellationToken) { if (application == null) { @@ -679,16 +526,8 @@ namespace OpenIddict.EntityFramework return new ValueTask>(addresses); } - /// - /// Retrieves the requirements associated with an application. - /// - /// The application. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns all the requirements associated with the application. - /// - public virtual ValueTask> GetRequirementsAsync([NotNull] TApplication application, CancellationToken cancellationToken) + /// + public virtual ValueTask> GetRequirementsAsync(TApplication application, CancellationToken cancellationToken) { if (application == null) { @@ -714,14 +553,7 @@ namespace OpenIddict.EntityFramework return new ValueTask>(requirements); } - /// - /// Instantiates a new application. - /// - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the instantiated application, that can be persisted in the database. - /// + /// public virtual ValueTask InstantiateAsync(CancellationToken cancellationToken) { try @@ -736,17 +568,11 @@ namespace OpenIddict.EntityFramework } } - /// - /// Executes the specified query and returns all the corresponding elements. - /// - /// The number of results to return. - /// The number of results to skip. - /// The that can be used to abort the operation. - /// All the elements returned when executing the specified query. + /// public virtual IAsyncEnumerable ListAsync( - [CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken) + int? count, int? offset, CancellationToken cancellationToken) { - var query = Applications.OrderBy(application => application.Id).AsQueryable(); + var query = Applications.OrderBy(application => application.Id!).AsQueryable(); if (offset.HasValue) { @@ -761,18 +587,10 @@ namespace OpenIddict.EntityFramework return query.AsAsyncEnumerable(cancellationToken); } - /// - /// Executes the specified query and returns all the corresponding elements. - /// - /// The state type. - /// The result type. - /// The query to execute. - /// The optional state. - /// The that can be used to abort the operation. - /// All the elements returned when executing the specified query. + /// public virtual IAsyncEnumerable ListAsync( - [NotNull] Func, TState, IQueryable> query, - [CanBeNull] TState state, CancellationToken cancellationToken) + Func, TState, IQueryable> query, + TState state, CancellationToken cancellationToken) { if (query == null) { @@ -782,15 +600,8 @@ namespace OpenIddict.EntityFramework return query(Applications, state).AsAsyncEnumerable(cancellationToken); } - /// - /// Sets the client identifier associated with an application. - /// - /// The application. - /// The client identifier associated with the application. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual ValueTask SetClientIdAsync([NotNull] TApplication application, - [CanBeNull] string identifier, CancellationToken cancellationToken) + /// + public virtual ValueTask SetClientIdAsync(TApplication application, string? identifier, CancellationToken cancellationToken) { if (application == null) { @@ -802,17 +613,8 @@ namespace OpenIddict.EntityFramework return default; } - /// - /// Sets the client secret associated with an application. - /// Note: depending on the manager used to create the application, - /// the client secret may be hashed for security reasons. - /// - /// The application. - /// The client secret associated with the application. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual ValueTask SetClientSecretAsync([NotNull] TApplication application, - [CanBeNull] string secret, CancellationToken cancellationToken) + /// + public virtual ValueTask SetClientSecretAsync(TApplication application, string? secret, CancellationToken cancellationToken) { if (application == null) { @@ -824,15 +626,8 @@ namespace OpenIddict.EntityFramework return default; } - /// - /// Sets the client type associated with an application. - /// - /// The application. - /// The client type associated with the application. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual ValueTask SetClientTypeAsync([NotNull] TApplication application, - [CanBeNull] string type, CancellationToken cancellationToken) + /// + public virtual ValueTask SetClientTypeAsync(TApplication application, string? type, CancellationToken cancellationToken) { if (application == null) { @@ -844,15 +639,8 @@ namespace OpenIddict.EntityFramework return default; } - /// - /// Sets the consent type associated with an application. - /// - /// The application. - /// The consent type associated with the application. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual ValueTask SetConsentTypeAsync([NotNull] TApplication application, - [CanBeNull] string type, CancellationToken cancellationToken) + /// + public virtual ValueTask SetConsentTypeAsync(TApplication application, string? type, CancellationToken cancellationToken) { if (application == null) { @@ -864,15 +652,8 @@ namespace OpenIddict.EntityFramework return default; } - /// - /// Sets the display name associated with an application. - /// - /// The application. - /// The display name associated with the application. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual ValueTask SetDisplayNameAsync([NotNull] TApplication application, - [CanBeNull] string name, CancellationToken cancellationToken) + /// + public virtual ValueTask SetDisplayNameAsync(TApplication application, string? name, CancellationToken cancellationToken) { if (application == null) { @@ -884,15 +665,9 @@ namespace OpenIddict.EntityFramework return default; } - /// - /// Sets the localized display names associated with an application. - /// - /// The application. - /// The localized display names associated with the application. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual ValueTask SetDisplayNamesAsync([NotNull] TApplication application, - [CanBeNull] ImmutableDictionary names, CancellationToken cancellationToken) + /// + public virtual ValueTask SetDisplayNamesAsync(TApplication application, + ImmutableDictionary names, CancellationToken cancellationToken) { if (application == null) { @@ -929,14 +704,8 @@ namespace OpenIddict.EntityFramework return default; } - /// - /// Sets the permissions associated with an application. - /// - /// The application. - /// The permissions associated with the application - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual ValueTask SetPermissionsAsync([NotNull] TApplication application, ImmutableArray permissions, CancellationToken cancellationToken) + /// + public virtual ValueTask SetPermissionsAsync(TApplication application, ImmutableArray permissions, CancellationToken cancellationToken) { if (application == null) { @@ -959,14 +728,8 @@ namespace OpenIddict.EntityFramework return default; } - /// - /// Sets the logout callback addresses associated with an application. - /// - /// The application. - /// The logout callback addresses associated with the application - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual ValueTask SetPostLogoutRedirectUrisAsync([NotNull] TApplication application, + /// + public virtual ValueTask SetPostLogoutRedirectUrisAsync(TApplication application, ImmutableArray addresses, CancellationToken cancellationToken) { if (application == null) @@ -990,15 +753,9 @@ namespace OpenIddict.EntityFramework return default; } - /// - /// Sets the additional properties associated with an application. - /// - /// The application. - /// The additional properties associated with the application. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual ValueTask SetPropertiesAsync([NotNull] TApplication application, - [CanBeNull] ImmutableDictionary properties, CancellationToken cancellationToken) + /// + public virtual ValueTask SetPropertiesAsync(TApplication application, + ImmutableDictionary properties, CancellationToken cancellationToken) { if (application == null) { @@ -1021,14 +778,8 @@ namespace OpenIddict.EntityFramework return default; } - /// - /// Sets the callback addresses associated with an application. - /// - /// The application. - /// The callback addresses associated with the application - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual ValueTask SetRedirectUrisAsync([NotNull] TApplication application, + /// + public virtual ValueTask SetRedirectUrisAsync(TApplication application, ImmutableArray addresses, CancellationToken cancellationToken) { if (application == null) @@ -1052,14 +803,8 @@ namespace OpenIddict.EntityFramework return default; } - /// - /// Sets the requirements associated with an application. - /// - /// The application. - /// The requirements associated with the application - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual ValueTask SetRequirementsAsync([NotNull] TApplication application, ImmutableArray requirements, CancellationToken cancellationToken) + /// + public virtual ValueTask SetRequirementsAsync(TApplication application, ImmutableArray requirements, CancellationToken cancellationToken) { if (application == null) { @@ -1082,13 +827,8 @@ namespace OpenIddict.EntityFramework return default; } - /// - /// Updates an existing application. - /// - /// The application to update. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual async ValueTask UpdateAsync([NotNull] TApplication application, CancellationToken cancellationToken) + /// + public virtual async ValueTask UpdateAsync(TApplication application, CancellationToken cancellationToken) { if (application == null) { @@ -1122,7 +862,8 @@ namespace OpenIddict.EntityFramework /// /// The identifier to convert. /// An instance of representing the provided identifier. - public virtual TKey ConvertIdentifierFromString([CanBeNull] string identifier) + [return: MaybeNull] + public virtual TKey ConvertIdentifierFromString(string? identifier) { if (string.IsNullOrEmpty(identifier)) { @@ -1137,7 +878,7 @@ namespace OpenIddict.EntityFramework /// /// The identifier to convert. /// A representation of the provided identifier. - public virtual string ConvertIdentifierToString([CanBeNull] TKey identifier) + public virtual string? ConvertIdentifierToString([AllowNull] TKey identifier) { if (Equals(identifier, default(TKey))) { diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkAuthorizationStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkAuthorizationStore.cs index f6413570..051f5d67 100644 --- a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkAuthorizationStore.cs +++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkAuthorizationStore.cs @@ -11,13 +11,13 @@ using System.ComponentModel; using System.Data; using System.Data.Entity; using System.Data.Entity.Infrastructure; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Runtime.CompilerServices; using System.Text.Encodings.Web; using System.Text.Json; using System.Threading; using System.Threading.Tasks; -using JetBrains.Annotations; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Options; using OpenIddict.Abstractions; @@ -37,9 +37,9 @@ namespace OpenIddict.EntityFramework where TContext : DbContext { public OpenIddictEntityFrameworkAuthorizationStore( - [NotNull] IMemoryCache cache, - [NotNull] TContext context, - [NotNull] IOptionsMonitor options) + IMemoryCache cache, + TContext context, + IOptionsMonitor options) : base(cache, context, options) { } @@ -61,9 +61,9 @@ namespace OpenIddict.EntityFramework where TKey : IEquatable { public OpenIddictEntityFrameworkAuthorizationStore( - [NotNull] IMemoryCache cache, - [NotNull] TContext context, - [NotNull] IOptionsMonitor options) + IMemoryCache cache, + TContext context, + IOptionsMonitor options) { Cache = cache; Context = context; @@ -100,28 +100,12 @@ namespace OpenIddict.EntityFramework /// private DbSet Tokens => Context.Set(); - /// - /// Determines the number of authorizations that exist in the database. - /// - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the number of authorizations in the database. - /// + /// public virtual async ValueTask CountAsync(CancellationToken cancellationToken) => await Authorizations.LongCountAsync(cancellationToken); - /// - /// Determines the number of authorizations that match the specified query. - /// - /// The result type. - /// The query to execute. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the number of authorizations that match the specified query. - /// - public virtual async ValueTask CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + /// + public virtual async ValueTask CountAsync(Func, IQueryable> query, CancellationToken cancellationToken) { if (query == null) { @@ -131,13 +115,8 @@ namespace OpenIddict.EntityFramework return await query(Authorizations).LongCountAsync(cancellationToken); } - /// - /// Creates a new authorization. - /// - /// The authorization to create. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual async ValueTask CreateAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken) + /// + public virtual async ValueTask CreateAsync(TAuthorization authorization, CancellationToken cancellationToken) { if (authorization == null) { @@ -149,20 +128,15 @@ namespace OpenIddict.EntityFramework await Context.SaveChangesAsync(cancellationToken); } - /// - /// Removes an existing authorization. - /// - /// The authorization to delete. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual async ValueTask DeleteAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken) + /// + public virtual async ValueTask DeleteAsync(TAuthorization authorization, CancellationToken cancellationToken) { if (authorization == null) { throw new ArgumentNullException(nameof(authorization)); } - DbContextTransaction CreateTransaction() + DbContextTransaction? CreateTransaction() { try { @@ -177,7 +151,7 @@ namespace OpenIddict.EntityFramework Task> ListTokensAsync() => (from token in Tokens - where token.Authorization.Id.Equals(authorization.Id) + where token.Authorization!.Id!.Equals(authorization.Id) select token).ToListAsync(cancellationToken); // To prevent an SQL exception from being thrown if a new associated entity is @@ -214,16 +188,9 @@ namespace OpenIddict.EntityFramework } } - /// - /// Retrieves the authorizations corresponding to the specified - /// subject and associated with the application identifier. - /// - /// The subject associated with the authorization. - /// The client associated with the authorization. - /// The that can be used to abort the operation. - /// The authorizations corresponding to the subject/client. + /// public virtual IAsyncEnumerable FindAsync( - [NotNull] string subject, [NotNull] string client, CancellationToken cancellationToken) + string subject, string client, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(subject)) { @@ -239,22 +206,15 @@ namespace OpenIddict.EntityFramework return (from authorization in Authorizations.Include(authorization => authorization.Application) where authorization.Application != null && - authorization.Application.Id.Equals(key) && + authorization.Application.Id!.Equals(key) && authorization.Subject == subject select authorization).AsAsyncEnumerable(cancellationToken); } - /// - /// Retrieves the authorizations matching the specified parameters. - /// - /// The subject associated with the authorization. - /// The client associated with the authorization. - /// The authorization status. - /// The that can be used to abort the operation. - /// The authorizations corresponding to the criteria. + /// public virtual IAsyncEnumerable FindAsync( - [NotNull] string subject, [NotNull] string client, - [NotNull] string status, CancellationToken cancellationToken) + string subject, string client, + string status, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(subject)) { @@ -275,24 +235,16 @@ namespace OpenIddict.EntityFramework return (from authorization in Authorizations.Include(authorization => authorization.Application) where authorization.Application != null && - authorization.Application.Id.Equals(key) && + authorization.Application.Id!.Equals(key) && authorization.Subject == subject && authorization.Status == status select authorization).AsAsyncEnumerable(cancellationToken); } - /// - /// Retrieves the authorizations matching the specified parameters. - /// - /// The subject associated with the authorization. - /// The client associated with the authorization. - /// The authorization status. - /// The authorization type. - /// The that can be used to abort the operation. - /// The authorizations corresponding to the criteria. + /// public virtual IAsyncEnumerable FindAsync( - [NotNull] string subject, [NotNull] string client, - [NotNull] string status, [NotNull] string type, CancellationToken cancellationToken) + string subject, string client, + string status, string type, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(subject)) { @@ -318,26 +270,17 @@ namespace OpenIddict.EntityFramework return (from authorization in Authorizations.Include(authorization => authorization.Application) where authorization.Application != null && - authorization.Application.Id.Equals(key) && + authorization.Application.Id!.Equals(key) && authorization.Subject == subject && authorization.Status == status && authorization.Type == type select authorization).AsAsyncEnumerable(cancellationToken); } - /// - /// Retrieves the authorizations matching the specified parameters. - /// - /// The subject associated with the authorization. - /// The client associated with the authorization. - /// The authorization status. - /// The authorization type. - /// The minimal scopes associated with the authorization. - /// The that can be used to abort the operation. - /// The authorizations corresponding to the criteria. + /// public virtual IAsyncEnumerable FindAsync( - [NotNull] string subject, [NotNull] string client, - [NotNull] string status, [NotNull] string type, + string subject, string client, + string status, string type, ImmutableArray scopes, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(subject)) @@ -368,7 +311,7 @@ namespace OpenIddict.EntityFramework var authorizations = (from authorization in Authorizations.Include(authorization => authorization.Application) where authorization.Application != null && - authorization.Application.Id.Equals(key) && + authorization.Application.Id!.Equals(key) && authorization.Subject == subject && authorization.Status == status && authorization.Type == type @@ -384,14 +327,9 @@ namespace OpenIddict.EntityFramework } } - /// - /// Retrieves the list of authorizations corresponding to the specified application identifier. - /// - /// The application identifier associated with the authorizations. - /// The that can be used to abort the operation. - /// The authorizations corresponding to the specified application. + /// public virtual IAsyncEnumerable FindByApplicationIdAsync( - [NotNull] string identifier, CancellationToken cancellationToken) + string identifier, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(identifier)) { @@ -401,20 +339,12 @@ namespace OpenIddict.EntityFramework var key = ConvertIdentifierFromString(identifier); return (from authorization in Authorizations.Include(authorization => authorization.Application) - where authorization.Application.Id.Equals(key) + where authorization.Application!.Id!.Equals(key) select authorization).AsAsyncEnumerable(cancellationToken); } - /// - /// Retrieves an authorization using its unique identifier. - /// - /// The unique identifier associated with the authorization. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the authorization corresponding to the identifier. - /// - public virtual async ValueTask FindByIdAsync([NotNull] string identifier, CancellationToken cancellationToken) + /// + public virtual async ValueTask FindByIdAsync(string identifier, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(identifier)) { @@ -424,18 +354,13 @@ namespace OpenIddict.EntityFramework var key = ConvertIdentifierFromString(identifier); return await (from authorization in Authorizations.Include(authorization => authorization.Application) - where authorization.Id.Equals(key) + where authorization.Id!.Equals(key) select authorization).FirstOrDefaultAsync(cancellationToken); } - /// - /// Retrieves all the authorizations corresponding to the specified subject. - /// - /// The subject associated with the authorization. - /// The that can be used to abort the operation. - /// The authorizations corresponding to the specified subject. + /// public virtual IAsyncEnumerable FindBySubjectAsync( - [NotNull] string subject, CancellationToken cancellationToken) + string subject, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(subject)) { @@ -447,16 +372,8 @@ namespace OpenIddict.EntityFramework select authorization).AsAsyncEnumerable(cancellationToken); } - /// - /// Retrieves the optional application identifier associated with an authorization. - /// - /// The authorization. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the application identifier associated with the authorization. - /// - public virtual async ValueTask GetApplicationIdAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken) + /// + public virtual async ValueTask GetApplicationIdAsync(TAuthorization authorization, CancellationToken cancellationToken) { if (authorization == null) { @@ -483,21 +400,10 @@ namespace OpenIddict.EntityFramework return ConvertIdentifierToString(authorization.Application.Id); } - /// - /// Executes the specified query and returns the first element. - /// - /// The state type. - /// The result type. - /// The query to execute. - /// The optional state. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the first element returned when executing the query. - /// + /// public virtual async ValueTask GetAsync( - [NotNull] Func, TState, IQueryable> query, - [CanBeNull] TState state, CancellationToken cancellationToken) + Func, TState, IQueryable> query, + TState state, CancellationToken cancellationToken) { if (query == null) { @@ -508,35 +414,19 @@ namespace OpenIddict.EntityFramework Authorizations.Include(authorization => authorization.Application), state).FirstOrDefaultAsync(cancellationToken); } - /// - /// Retrieves the unique identifier associated with an authorization. - /// - /// The authorization. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the unique identifier associated with the authorization. - /// - public virtual ValueTask GetIdAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken) + /// + public virtual ValueTask GetIdAsync(TAuthorization authorization, CancellationToken cancellationToken) { if (authorization == null) { throw new ArgumentNullException(nameof(authorization)); } - return new ValueTask(ConvertIdentifierToString(authorization.Id)); + return new ValueTask(ConvertIdentifierToString(authorization.Id)); } - /// - /// Retrieves the additional properties associated with an authorization. - /// - /// The authorization. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns all the additional properties associated with the authorization. - /// - public virtual ValueTask> GetPropertiesAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken) + /// + public virtual ValueTask> GetPropertiesAsync(TAuthorization authorization, CancellationToken cancellationToken) { if (authorization == null) { @@ -562,16 +452,8 @@ namespace OpenIddict.EntityFramework return new ValueTask>(properties); } - /// - /// Retrieves the scopes associated with an authorization. - /// - /// The authorization. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the scopes associated with the specified authorization. - /// - public virtual ValueTask> GetScopesAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken) + /// + public virtual ValueTask> GetScopesAsync(TAuthorization authorization, CancellationToken cancellationToken) { if (authorization == null) { @@ -597,71 +479,40 @@ namespace OpenIddict.EntityFramework return new ValueTask>(scopes); } - /// - /// Retrieves the status associated with an authorization. - /// - /// The authorization. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the status associated with the specified authorization. - /// - public virtual ValueTask GetStatusAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken) + /// + public virtual ValueTask GetStatusAsync(TAuthorization authorization, CancellationToken cancellationToken) { if (authorization == null) { throw new ArgumentNullException(nameof(authorization)); } - return new ValueTask(authorization.Status); + return new ValueTask(authorization.Status); } - /// - /// Retrieves the subject associated with an authorization. - /// - /// The authorization. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the subject associated with the specified authorization. - /// - public virtual ValueTask GetSubjectAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken) + /// + public virtual ValueTask GetSubjectAsync(TAuthorization authorization, CancellationToken cancellationToken) { if (authorization == null) { throw new ArgumentNullException(nameof(authorization)); } - return new ValueTask(authorization.Subject); + return new ValueTask(authorization.Subject); } - /// - /// Retrieves the type associated with an authorization. - /// - /// The authorization. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the type associated with the specified authorization. - /// - public virtual ValueTask GetTypeAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken) + /// + public virtual ValueTask GetTypeAsync(TAuthorization authorization, CancellationToken cancellationToken) { if (authorization == null) { throw new ArgumentNullException(nameof(authorization)); } - return new ValueTask(authorization.Type); + return new ValueTask(authorization.Type); } - /// - /// Instantiates a new authorization. - /// - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the instantiated authorization, that can be persisted in the database. - /// + /// public virtual ValueTask InstantiateAsync(CancellationToken cancellationToken) { try @@ -676,18 +527,11 @@ namespace OpenIddict.EntityFramework } } - /// - /// Executes the specified query and returns all the corresponding elements. - /// - /// The number of results to return. - /// The number of results to skip. - /// The that can be used to abort the operation. - /// All the elements returned when executing the specified query. - public virtual IAsyncEnumerable ListAsync( - [CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken) + /// + public virtual IAsyncEnumerable ListAsync(int? count, int? offset, CancellationToken cancellationToken) { var query = Authorizations.Include(authorization => authorization.Application) - .OrderBy(authorization => authorization.Id) + .OrderBy(authorization => authorization.Id!) .AsQueryable(); if (offset.HasValue) @@ -703,18 +547,10 @@ namespace OpenIddict.EntityFramework return query.AsAsyncEnumerable(cancellationToken); } - /// - /// Executes the specified query and returns all the corresponding elements. - /// - /// The state type. - /// The result type. - /// The query to execute. - /// The optional state. - /// The that can be used to abort the operation. - /// All the elements returned when executing the specified query. + /// public virtual IAsyncEnumerable ListAsync( - [NotNull] Func, TState, IQueryable> query, - [CanBeNull] TState state, CancellationToken cancellationToken) + Func, TState, IQueryable> query, + TState state, CancellationToken cancellationToken) { if (query == null) { @@ -724,20 +560,16 @@ namespace OpenIddict.EntityFramework return query(Authorizations.Include(authorization => authorization.Application), state).AsAsyncEnumerable(cancellationToken); } - /// - /// Removes the authorizations that are marked as invalid and the ad-hoc ones that have no valid/nonexpired token attached. - /// - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. + /// public virtual async ValueTask PruneAsync(CancellationToken cancellationToken) { // Note: Entity Framework 6.x doesn't support set-based deletes, which prevents removing // entities in a single command without having to retrieve and materialize them first. // To work around this limitation, entities are manually listed and deleted using a batch logic. - List exceptions = null; + List? exceptions = null; - DbContextTransaction CreateTransaction() + DbContextTransaction? CreateTransaction() { // Note: relational providers like Sqlite are known to lack proper support // for repeatable read transactions. To ensure this method can be safely used @@ -807,17 +639,9 @@ namespace OpenIddict.EntityFramework } } - /// - /// Sets the application identifier associated with an authorization. - /// - /// The authorization. - /// The unique identifier associated with the client application. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation. - /// - public virtual async ValueTask SetApplicationIdAsync([NotNull] TAuthorization authorization, - [CanBeNull] string identifier, CancellationToken cancellationToken) + /// + public virtual async ValueTask SetApplicationIdAsync(TAuthorization authorization, + string? identifier, CancellationToken cancellationToken) { if (authorization == null) { @@ -853,17 +677,9 @@ namespace OpenIddict.EntityFramework } } - /// - /// Sets the additional properties associated with an authorization. - /// - /// The authorization. - /// The additional properties associated with the authorization. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation. - /// - public virtual ValueTask SetPropertiesAsync([NotNull] TAuthorization authorization, - [CanBeNull] ImmutableDictionary properties, CancellationToken cancellationToken) + /// + public virtual ValueTask SetPropertiesAsync(TAuthorization authorization, + ImmutableDictionary properties, CancellationToken cancellationToken) { if (authorization == null) { @@ -886,16 +702,8 @@ namespace OpenIddict.EntityFramework return default; } - /// - /// Sets the scopes associated with an authorization. - /// - /// The authorization. - /// The scopes associated with the authorization. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation. - /// - public virtual ValueTask SetScopesAsync([NotNull] TAuthorization authorization, + /// + public virtual ValueTask SetScopesAsync(TAuthorization authorization, ImmutableArray scopes, CancellationToken cancellationToken) { if (authorization == null) @@ -919,17 +727,8 @@ namespace OpenIddict.EntityFramework return default; } - /// - /// Sets the status associated with an authorization. - /// - /// The authorization. - /// The status associated with the authorization. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation. - /// - public virtual ValueTask SetStatusAsync([NotNull] TAuthorization authorization, - [CanBeNull] string status, CancellationToken cancellationToken) + /// + public virtual ValueTask SetStatusAsync(TAuthorization authorization, string? status, CancellationToken cancellationToken) { if (authorization == null) { @@ -941,17 +740,8 @@ namespace OpenIddict.EntityFramework return default; } - /// - /// Sets the subject associated with an authorization. - /// - /// The authorization. - /// The subject associated with the authorization. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation. - /// - public virtual ValueTask SetSubjectAsync([NotNull] TAuthorization authorization, - [CanBeNull] string subject, CancellationToken cancellationToken) + /// + public virtual ValueTask SetSubjectAsync(TAuthorization authorization, string? subject, CancellationToken cancellationToken) { if (authorization == null) { @@ -963,17 +753,8 @@ namespace OpenIddict.EntityFramework return default; } - /// - /// Sets the type associated with an authorization. - /// - /// The authorization. - /// The type associated with the authorization. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation. - /// - public virtual ValueTask SetTypeAsync([NotNull] TAuthorization authorization, - [CanBeNull] string type, CancellationToken cancellationToken) + /// + public virtual ValueTask SetTypeAsync(TAuthorization authorization, string? type, CancellationToken cancellationToken) { if (authorization == null) { @@ -985,15 +766,8 @@ namespace OpenIddict.EntityFramework return default; } - /// - /// Updates an existing authorization. - /// - /// The authorization to update. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation. - /// - public virtual async ValueTask UpdateAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken) + /// + public virtual async ValueTask UpdateAsync(TAuthorization authorization, CancellationToken cancellationToken) { if (authorization == null) { @@ -1027,7 +801,8 @@ namespace OpenIddict.EntityFramework /// /// The identifier to convert. /// An instance of representing the provided identifier. - public virtual TKey ConvertIdentifierFromString([CanBeNull] string identifier) + [return: MaybeNull] + public virtual TKey ConvertIdentifierFromString(string? identifier) { if (string.IsNullOrEmpty(identifier)) { @@ -1042,7 +817,7 @@ namespace OpenIddict.EntityFramework /// /// The identifier to convert. /// A representation of the provided identifier. - public virtual string ConvertIdentifierToString([CanBeNull] TKey identifier) + public virtual string? ConvertIdentifierToString([AllowNull] TKey identifier) { if (Equals(identifier, default(TKey))) { diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkScopeStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkScopeStore.cs index dc16957b..86f05910 100644 --- a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkScopeStore.cs +++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkScopeStore.cs @@ -10,6 +10,7 @@ using System.Collections.Immutable; using System.ComponentModel; using System.Data.Entity; using System.Data.Entity.Infrastructure; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Linq; @@ -19,7 +20,6 @@ using System.Text.Encodings.Web; using System.Text.Json; using System.Threading; using System.Threading.Tasks; -using JetBrains.Annotations; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Options; using OpenIddict.Abstractions; @@ -37,9 +37,9 @@ namespace OpenIddict.EntityFramework where TContext : DbContext { public OpenIddictEntityFrameworkScopeStore( - [NotNull] IMemoryCache cache, - [NotNull] TContext context, - [NotNull] IOptionsMonitor options) + IMemoryCache cache, + TContext context, + IOptionsMonitor options) : base(cache, context, options) { } @@ -57,9 +57,9 @@ namespace OpenIddict.EntityFramework where TKey : IEquatable { public OpenIddictEntityFrameworkScopeStore( - [NotNull] IMemoryCache cache, - [NotNull] TContext context, - [NotNull] IOptionsMonitor options) + IMemoryCache cache, + TContext context, + IOptionsMonitor options) { Cache = cache; Context = context; @@ -86,28 +86,12 @@ namespace OpenIddict.EntityFramework /// private DbSet Scopes => Context.Set(); - /// - /// Determines the number of scopes that exist in the database. - /// - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the number of scopes in the database. - /// + /// public virtual async ValueTask CountAsync(CancellationToken cancellationToken) => await Scopes.LongCountAsync(cancellationToken); - /// - /// Determines the number of scopes that match the specified query. - /// - /// The result type. - /// The query to execute. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the number of scopes that match the specified query. - /// - public virtual async ValueTask CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + /// + public virtual async ValueTask CountAsync(Func, IQueryable> query, CancellationToken cancellationToken) { if (query == null) { @@ -117,13 +101,8 @@ namespace OpenIddict.EntityFramework return await query(Scopes).LongCountAsync(cancellationToken); } - /// - /// Creates a new scope. - /// - /// The scope to create. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual async ValueTask CreateAsync([NotNull] TScope scope, CancellationToken cancellationToken) + /// + public virtual async ValueTask CreateAsync(TScope scope, CancellationToken cancellationToken) { if (scope == null) { @@ -135,13 +114,8 @@ namespace OpenIddict.EntityFramework await Context.SaveChangesAsync(cancellationToken); } - /// - /// Removes an existing scope. - /// - /// The scope to delete. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual async ValueTask DeleteAsync([NotNull] TScope scope, CancellationToken cancellationToken) + /// + public virtual async ValueTask DeleteAsync(TScope scope, CancellationToken cancellationToken) { if (scope == null) { @@ -164,16 +138,8 @@ namespace OpenIddict.EntityFramework } } - /// - /// Retrieves a scope using its unique identifier. - /// - /// The unique identifier associated with the scope. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the scope corresponding to the identifier. - /// - public virtual async ValueTask FindByIdAsync([NotNull] string identifier, CancellationToken cancellationToken) + /// + public virtual async ValueTask FindByIdAsync(string identifier, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(identifier)) { @@ -183,20 +149,12 @@ namespace OpenIddict.EntityFramework var key = ConvertIdentifierFromString(identifier); return await (from scope in Scopes - where scope.Id.Equals(key) + where scope.Id!.Equals(key) select scope).FirstOrDefaultAsync(cancellationToken); } - /// - /// Retrieves a scope using its name. - /// - /// The name associated with the scope. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the scope corresponding to the specified name. - /// - public virtual async ValueTask FindByNameAsync([NotNull] string name, CancellationToken cancellationToken) + /// + public virtual async ValueTask FindByNameAsync(string name, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(name)) { @@ -208,12 +166,7 @@ namespace OpenIddict.EntityFramework select scope).FirstOrDefaultAsync(cancellationToken); } - /// - /// Retrieves a list of scopes using their name. - /// - /// The names associated with the scopes. - /// The that can be used to abort the operation. - /// The scopes corresponding to the specified names. + /// public virtual IAsyncEnumerable FindByNamesAsync( ImmutableArray names, CancellationToken cancellationToken) { @@ -229,14 +182,9 @@ namespace OpenIddict.EntityFramework select scope).AsAsyncEnumerable(cancellationToken); } - /// - /// Retrieves all the scopes that contain the specified resource. - /// - /// The resource associated with the scopes. - /// The that can be used to abort the operation. - /// The scopes associated with the specified resource. + /// public virtual IAsyncEnumerable FindByResourceAsync( - [NotNull] string resource, CancellationToken cancellationToken) + string resource, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(resource)) { @@ -254,7 +202,7 @@ namespace OpenIddict.EntityFramework async IAsyncEnumerable ExecuteAsync([EnumeratorCancellation] CancellationToken cancellationToken) { var scopes = (from scope in Scopes - where scope.Resources.Contains(resource) + where scope.Resources!.Contains(resource) select scope).AsAsyncEnumerable(cancellationToken); await foreach (var scope in scopes) @@ -268,21 +216,10 @@ namespace OpenIddict.EntityFramework } } - /// - /// Executes the specified query and returns the first element. - /// - /// The state type. - /// The result type. - /// The query to execute. - /// The optional state. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the first element returned when executing the query. - /// + /// public virtual async ValueTask GetAsync( - [NotNull] Func, TState, IQueryable> query, - [CanBeNull] TState state, CancellationToken cancellationToken) + Func, TState, IQueryable> query, + TState state, CancellationToken cancellationToken) { if (query == null) { @@ -292,35 +229,19 @@ namespace OpenIddict.EntityFramework return await query(Scopes, state).FirstOrDefaultAsync(cancellationToken); } - /// - /// Retrieves the description associated with a scope. - /// - /// The scope. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the description associated with the specified scope. - /// - public virtual ValueTask GetDescriptionAsync([NotNull] TScope scope, CancellationToken cancellationToken) + /// + public virtual ValueTask GetDescriptionAsync(TScope scope, CancellationToken cancellationToken) { if (scope == null) { throw new ArgumentNullException(nameof(scope)); } - return new ValueTask(scope.Description); + return new ValueTask(scope.Description); } - /// - /// Retrieves the localized descriptions associated with a scope. - /// - /// The scope. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns all the localized descriptions associated with the specified scope. - /// - public virtual ValueTask> GetDescriptionsAsync([NotNull] TScope scope, CancellationToken cancellationToken) + /// + public virtual ValueTask> GetDescriptionsAsync(TScope scope, CancellationToken cancellationToken) { if (scope == null) { @@ -347,35 +268,19 @@ namespace OpenIddict.EntityFramework return new ValueTask>(descriptions); } - /// - /// Retrieves the display name associated with a scope. - /// - /// The scope. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the display name associated with the scope. - /// - public virtual ValueTask GetDisplayNameAsync([NotNull] TScope scope, CancellationToken cancellationToken) + /// + public virtual ValueTask GetDisplayNameAsync(TScope scope, CancellationToken cancellationToken) { if (scope == null) { throw new ArgumentNullException(nameof(scope)); } - return new ValueTask(scope.DisplayName); + return new ValueTask(scope.DisplayName); } - /// - /// Retrieves the localized display names associated with a scope. - /// - /// The scope. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns all the localized display names associated with the scope. - /// - public virtual ValueTask> GetDisplayNamesAsync([NotNull] TScope scope, CancellationToken cancellationToken) + /// + public virtual ValueTask> GetDisplayNamesAsync(TScope scope, CancellationToken cancellationToken) { if (scope == null) { @@ -402,54 +307,30 @@ namespace OpenIddict.EntityFramework return new ValueTask>(names); } - /// - /// Retrieves the unique identifier associated with a scope. - /// - /// The scope. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the unique identifier associated with the scope. - /// - public virtual ValueTask GetIdAsync([NotNull] TScope scope, CancellationToken cancellationToken) + /// + public virtual ValueTask GetIdAsync(TScope scope, CancellationToken cancellationToken) { if (scope == null) { throw new ArgumentNullException(nameof(scope)); } - return new ValueTask(ConvertIdentifierToString(scope.Id)); + return new ValueTask(ConvertIdentifierToString(scope.Id)); } - /// - /// Retrieves the name associated with a scope. - /// - /// The scope. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the name associated with the specified scope. - /// - public virtual ValueTask GetNameAsync([NotNull] TScope scope, CancellationToken cancellationToken) + /// + public virtual ValueTask GetNameAsync(TScope scope, CancellationToken cancellationToken) { if (scope == null) { throw new ArgumentNullException(nameof(scope)); } - return new ValueTask(scope.Name); + return new ValueTask(scope.Name); } - /// - /// Retrieves the additional properties associated with a scope. - /// - /// The scope. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns all the additional properties associated with the scope. - /// - public virtual ValueTask> GetPropertiesAsync([NotNull] TScope scope, CancellationToken cancellationToken) + /// + public virtual ValueTask> GetPropertiesAsync(TScope scope, CancellationToken cancellationToken) { if (scope == null) { @@ -475,16 +356,8 @@ namespace OpenIddict.EntityFramework return new ValueTask>(properties); } - /// - /// Retrieves the resources associated with a scope. - /// - /// The scope. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns all the resources associated with the scope. - /// - public virtual ValueTask> GetResourcesAsync([NotNull] TScope scope, CancellationToken cancellationToken) + /// + public virtual ValueTask> GetResourcesAsync(TScope scope, CancellationToken cancellationToken) { if (scope == null) { @@ -510,14 +383,7 @@ namespace OpenIddict.EntityFramework return new ValueTask>(resources); } - /// - /// Instantiates a new scope. - /// - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the instantiated scope, that can be persisted in the database. - /// + /// public virtual ValueTask InstantiateAsync(CancellationToken cancellationToken) { try @@ -532,17 +398,10 @@ namespace OpenIddict.EntityFramework } } - /// - /// Executes the specified query and returns all the corresponding elements. - /// - /// The number of results to return. - /// The number of results to skip. - /// The that can be used to abort the operation. - /// All the elements returned when executing the specified query. - public virtual IAsyncEnumerable ListAsync( - [CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken) + /// + public virtual IAsyncEnumerable ListAsync(int? count, int? offset, CancellationToken cancellationToken) { - var query = Scopes.OrderBy(scope => scope.Id).AsQueryable(); + var query = Scopes.OrderBy(scope => scope.Id!).AsQueryable(); if (offset.HasValue) { @@ -557,18 +416,10 @@ namespace OpenIddict.EntityFramework return query.AsAsyncEnumerable(cancellationToken); } - /// - /// Executes the specified query and returns all the corresponding elements. - /// - /// The state type. - /// The result type. - /// The query to execute. - /// The optional state. - /// The that can be used to abort the operation. - /// All the elements returned when executing the specified query. + /// public virtual IAsyncEnumerable ListAsync( - [NotNull] Func, TState, IQueryable> query, - [CanBeNull] TState state, CancellationToken cancellationToken) + Func, TState, IQueryable> query, + TState state, CancellationToken cancellationToken) { if (query == null) { @@ -578,14 +429,8 @@ namespace OpenIddict.EntityFramework return query(Scopes, state).AsAsyncEnumerable(cancellationToken); } - /// - /// Sets the description associated with a scope. - /// - /// The scope. - /// The description associated with the authorization. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual ValueTask SetDescriptionAsync([NotNull] TScope scope, [CanBeNull] string description, CancellationToken cancellationToken) + /// + public virtual ValueTask SetDescriptionAsync(TScope scope, string? description, CancellationToken cancellationToken) { if (scope == null) { @@ -597,15 +442,9 @@ namespace OpenIddict.EntityFramework return default; } - /// - /// Sets the localized descriptions associated with a scope. - /// - /// The scope. - /// The localized descriptions associated with the authorization. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual ValueTask SetDescriptionsAsync([NotNull] TScope scope, - [CanBeNull] ImmutableDictionary descriptions, CancellationToken cancellationToken) + /// + public virtual ValueTask SetDescriptionsAsync(TScope scope, + ImmutableDictionary descriptions, CancellationToken cancellationToken) { if (scope == null) { @@ -642,14 +481,8 @@ namespace OpenIddict.EntityFramework return default; } - /// - /// Sets the display name associated with a scope. - /// - /// The scope. - /// The display name associated with the scope. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual ValueTask SetDisplayNameAsync([NotNull] TScope scope, [CanBeNull] string name, CancellationToken cancellationToken) + /// + public virtual ValueTask SetDisplayNameAsync(TScope scope, string? name, CancellationToken cancellationToken) { if (scope == null) { @@ -661,15 +494,9 @@ namespace OpenIddict.EntityFramework return default; } - /// - /// Sets the localized display names associated with a scope. - /// - /// The scope. - /// The localized display names associated with the scope. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual ValueTask SetDisplayNamesAsync([NotNull] TScope scope, - [CanBeNull] ImmutableDictionary names, CancellationToken cancellationToken) + /// + public virtual ValueTask SetDisplayNamesAsync(TScope scope, + ImmutableDictionary names, CancellationToken cancellationToken) { if (scope == null) { @@ -706,14 +533,8 @@ namespace OpenIddict.EntityFramework return default; } - /// - /// Sets the name associated with a scope. - /// - /// The scope. - /// The name associated with the authorization. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual ValueTask SetNameAsync([NotNull] TScope scope, [CanBeNull] string name, CancellationToken cancellationToken) + /// + public virtual ValueTask SetNameAsync(TScope scope, string? name, CancellationToken cancellationToken) { if (scope == null) { @@ -725,15 +546,9 @@ namespace OpenIddict.EntityFramework return default; } - /// - /// Sets the additional properties associated with a scope. - /// - /// The scope. - /// The additional properties associated with the scope. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual ValueTask SetPropertiesAsync([NotNull] TScope scope, - [CanBeNull] ImmutableDictionary properties, CancellationToken cancellationToken) + /// + public virtual ValueTask SetPropertiesAsync(TScope scope, + ImmutableDictionary properties, CancellationToken cancellationToken) { if (scope == null) { @@ -756,14 +571,8 @@ namespace OpenIddict.EntityFramework return default; } - /// - /// Sets the resources associated with a scope. - /// - /// The scope. - /// The resources associated with the scope. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual ValueTask SetResourcesAsync([NotNull] TScope scope, ImmutableArray resources, CancellationToken cancellationToken) + /// + public virtual ValueTask SetResourcesAsync(TScope scope, ImmutableArray resources, CancellationToken cancellationToken) { if (scope == null) { @@ -786,13 +595,8 @@ namespace OpenIddict.EntityFramework return default; } - /// - /// Updates an existing scope. - /// - /// The scope to update. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual async ValueTask UpdateAsync([NotNull] TScope scope, CancellationToken cancellationToken) + /// + public virtual async ValueTask UpdateAsync(TScope scope, CancellationToken cancellationToken) { if (scope == null) { @@ -826,7 +630,8 @@ namespace OpenIddict.EntityFramework /// /// The identifier to convert. /// An instance of representing the provided identifier. - public virtual TKey ConvertIdentifierFromString([CanBeNull] string identifier) + [return: MaybeNull] + public virtual TKey ConvertIdentifierFromString(string? identifier) { if (string.IsNullOrEmpty(identifier)) { @@ -841,7 +646,7 @@ namespace OpenIddict.EntityFramework /// /// The identifier to convert. /// A representation of the provided identifier. - public virtual string ConvertIdentifierToString([CanBeNull] TKey identifier) + public virtual string? ConvertIdentifierToString([AllowNull] TKey identifier) { if (Equals(identifier, default(TKey))) { diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkTokenStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkTokenStore.cs index 0c3735c1..bdc810ea 100644 --- a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkTokenStore.cs +++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkTokenStore.cs @@ -11,12 +11,12 @@ using System.ComponentModel; using System.Data; using System.Data.Entity; using System.Data.Entity.Infrastructure; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Text.Encodings.Web; using System.Text.Json; using System.Threading; using System.Threading.Tasks; -using JetBrains.Annotations; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Options; using OpenIddict.Abstractions; @@ -36,9 +36,9 @@ namespace OpenIddict.EntityFramework where TContext : DbContext { public OpenIddictEntityFrameworkTokenStore( - [NotNull] IMemoryCache cache, - [NotNull] TContext context, - [NotNull] IOptionsMonitor options) + IMemoryCache cache, + TContext context, + IOptionsMonitor options) : base(cache, context, options) { } @@ -60,9 +60,9 @@ namespace OpenIddict.EntityFramework where TKey : IEquatable { public OpenIddictEntityFrameworkTokenStore( - [NotNull] IMemoryCache cache, - [NotNull] TContext context, - [NotNull] IOptionsMonitor options) + IMemoryCache cache, + TContext context, + IOptionsMonitor options) { Cache = cache; Context = context; @@ -99,28 +99,12 @@ namespace OpenIddict.EntityFramework /// private DbSet Tokens => Context.Set(); - /// - /// Determines the number of tokens that exist in the database. - /// - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the number of applications in the database. - /// + /// public virtual async ValueTask CountAsync(CancellationToken cancellationToken) => await Tokens.LongCountAsync(cancellationToken); - /// - /// Determines the number of tokens that match the specified query. - /// - /// The result type. - /// The query to execute. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the number of tokens that match the specified query. - /// - public virtual async ValueTask CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + /// + public virtual async ValueTask CountAsync(Func, IQueryable> query, CancellationToken cancellationToken) { if (query == null) { @@ -130,13 +114,8 @@ namespace OpenIddict.EntityFramework return await query(Tokens).LongCountAsync(cancellationToken); } - /// - /// Creates a new token. - /// - /// The token to create. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual async ValueTask CreateAsync([NotNull] TToken token, CancellationToken cancellationToken) + /// + public virtual async ValueTask CreateAsync(TToken token, CancellationToken cancellationToken) { if (token == null) { @@ -148,13 +127,8 @@ namespace OpenIddict.EntityFramework await Context.SaveChangesAsync(cancellationToken); } - /// - /// Removes a token. - /// - /// The token to delete. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual async ValueTask DeleteAsync([NotNull] TToken token, CancellationToken cancellationToken) + /// + public virtual async ValueTask DeleteAsync(TToken token, CancellationToken cancellationToken) { if (token == null) { @@ -177,16 +151,9 @@ namespace OpenIddict.EntityFramework } } - /// - /// Retrieves the tokens corresponding to the specified - /// subject and associated with the application identifier. - /// - /// The subject associated with the token. - /// The client associated with the token. - /// The that can be used to abort the operation. - /// The tokens corresponding to the subject/client. - public virtual IAsyncEnumerable FindAsync([NotNull] string subject, - [NotNull] string client, CancellationToken cancellationToken) + /// + public virtual IAsyncEnumerable FindAsync(string subject, + string client, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(subject)) { @@ -202,22 +169,15 @@ namespace OpenIddict.EntityFramework return (from token in Tokens.Include(token => token.Application).Include(token => token.Authorization) where token.Application != null && - token.Application.Id.Equals(key) && + token.Application.Id!.Equals(key) && token.Subject == subject select token).AsAsyncEnumerable(cancellationToken); } - /// - /// Retrieves the tokens matching the specified parameters. - /// - /// The subject associated with the token. - /// The client associated with the token. - /// The token status. - /// The that can be used to abort the operation. - /// The tokens corresponding to the criteria. + /// public virtual IAsyncEnumerable FindAsync( - [NotNull] string subject, [NotNull] string client, - [NotNull] string status, CancellationToken cancellationToken) + string subject, string client, + string status, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(subject)) { @@ -238,24 +198,16 @@ namespace OpenIddict.EntityFramework return (from token in Tokens.Include(token => token.Application).Include(token => token.Authorization) where token.Application != null && - token.Application.Id.Equals(key) && + token.Application.Id!.Equals(key) && token.Subject == subject && token.Status == status select token).AsAsyncEnumerable(cancellationToken); } - /// - /// Retrieves the tokens matching the specified parameters. - /// - /// The subject associated with the token. - /// The client associated with the token. - /// The token status. - /// The token type. - /// The that can be used to abort the operation. - /// The tokens corresponding to the criteria. + /// public virtual IAsyncEnumerable FindAsync( - [NotNull] string subject, [NotNull] string client, - [NotNull] string status, [NotNull] string type, CancellationToken cancellationToken) + string subject, string client, + string status, string type, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(subject)) { @@ -281,20 +233,15 @@ namespace OpenIddict.EntityFramework return (from token in Tokens.Include(token => token.Application).Include(token => token.Authorization) where token.Application != null && - token.Application.Id.Equals(key) && + token.Application.Id!.Equals(key) && token.Subject == subject && token.Status == status && token.Type == type select token).AsAsyncEnumerable(cancellationToken); } - /// - /// Retrieves the list of tokens corresponding to the specified application identifier. - /// - /// The application identifier associated with the tokens. - /// The that can be used to abort the operation. - /// The tokens corresponding to the specified application. - public virtual IAsyncEnumerable FindByApplicationIdAsync([NotNull] string identifier, CancellationToken cancellationToken) + /// + public virtual IAsyncEnumerable FindByApplicationIdAsync(string identifier, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(identifier)) { @@ -305,17 +252,12 @@ namespace OpenIddict.EntityFramework return (from token in Tokens.Include(token => token.Application).Include(token => token.Authorization) where token.Application != null && - token.Application.Id.Equals(key) + token.Application.Id!.Equals(key) select token).AsAsyncEnumerable(cancellationToken); } - /// - /// Retrieves the list of tokens corresponding to the specified authorization identifier. - /// - /// The authorization identifier associated with the tokens. - /// The that can be used to abort the operation. - /// Tokens corresponding to the specified authorization. - public virtual IAsyncEnumerable FindByAuthorizationIdAsync([NotNull] string identifier, CancellationToken cancellationToken) + /// + public virtual IAsyncEnumerable FindByAuthorizationIdAsync(string identifier, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(identifier)) { @@ -326,20 +268,12 @@ namespace OpenIddict.EntityFramework return (from token in Tokens.Include(token => token.Application).Include(token => token.Authorization) where token.Authorization != null && - token.Authorization.Id.Equals(key) + token.Authorization.Id!.Equals(key) select token).AsAsyncEnumerable(cancellationToken); } - /// - /// Retrieves a token using its unique identifier. - /// - /// The unique identifier associated with the token. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the token corresponding to the unique identifier. - /// - public virtual async ValueTask FindByIdAsync([NotNull] string identifier, CancellationToken cancellationToken) + /// + public virtual async ValueTask FindByIdAsync(string identifier, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(identifier)) { @@ -349,21 +283,12 @@ namespace OpenIddict.EntityFramework var key = ConvertIdentifierFromString(identifier); return await (from token in Tokens.Include(token => token.Application).Include(token => token.Authorization) - where token.Id.Equals(key) + where token.Id!.Equals(key) select token).FirstOrDefaultAsync(cancellationToken); } - /// - /// Retrieves the list of tokens corresponding to the specified reference identifier. - /// Note: the reference identifier may be hashed or encrypted for security reasons. - /// - /// The reference identifier associated with the tokens. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the tokens corresponding to the specified reference identifier. - /// - public virtual async ValueTask FindByReferenceIdAsync([NotNull] string identifier, CancellationToken cancellationToken) + /// + public virtual async ValueTask FindByReferenceIdAsync(string identifier, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(identifier)) { @@ -375,13 +300,8 @@ namespace OpenIddict.EntityFramework select token).FirstOrDefaultAsync(cancellationToken); } - /// - /// Retrieves the list of tokens corresponding to the specified subject. - /// - /// The subject associated with the tokens. - /// The that can be used to abort the operation. - /// The tokens corresponding to the specified subject. - public virtual IAsyncEnumerable FindBySubjectAsync([NotNull] string subject, CancellationToken cancellationToken) + /// + public virtual IAsyncEnumerable FindBySubjectAsync(string subject, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(subject)) { @@ -393,16 +313,8 @@ namespace OpenIddict.EntityFramework select token).AsAsyncEnumerable(cancellationToken); } - /// - /// Retrieves the optional application identifier associated with a token. - /// - /// The token. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the application identifier associated with the token. - /// - public virtual async ValueTask GetApplicationIdAsync([NotNull] TToken token, CancellationToken cancellationToken) + /// + public virtual async ValueTask GetApplicationIdAsync(TToken token, CancellationToken cancellationToken) { if (token == null) { @@ -429,21 +341,10 @@ namespace OpenIddict.EntityFramework return ConvertIdentifierToString(token.Application.Id); } - /// - /// Executes the specified query and returns the first element. - /// - /// The state type. - /// The result type. - /// The query to execute. - /// The optional state. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the first element returned when executing the query. - /// + /// public virtual async ValueTask GetAsync( - [NotNull] Func, TState, IQueryable> query, - [CanBeNull] TState state, CancellationToken cancellationToken) + Func, TState, IQueryable> query, + TState state, CancellationToken cancellationToken) { if (query == null) { @@ -455,16 +356,8 @@ namespace OpenIddict.EntityFramework .Include(token => token.Authorization), state).FirstOrDefaultAsync(cancellationToken); } - /// - /// Retrieves the optional authorization identifier associated with a token. - /// - /// The token. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the authorization identifier associated with the token. - /// - public virtual async ValueTask GetAuthorizationIdAsync([NotNull] TToken token, CancellationToken cancellationToken) + /// + public virtual async ValueTask GetAuthorizationIdAsync(TToken token, CancellationToken cancellationToken) { if (token == null) { @@ -491,16 +384,8 @@ namespace OpenIddict.EntityFramework return ConvertIdentifierToString(token.Authorization.Id); } - /// - /// Retrieves the creation date associated with a token. - /// - /// The token. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the creation date associated with the specified token. - /// - public virtual ValueTask GetCreationDateAsync([NotNull] TToken token, CancellationToken cancellationToken) + /// + public virtual ValueTask GetCreationDateAsync(TToken token, CancellationToken cancellationToken) { if (token == null) { @@ -510,16 +395,8 @@ namespace OpenIddict.EntityFramework return new ValueTask(token.CreationDate); } - /// - /// Retrieves the expiration date associated with a token. - /// - /// The token. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the expiration date associated with the specified token. - /// - public virtual ValueTask GetExpirationDateAsync([NotNull] TToken token, CancellationToken cancellationToken) + /// + public virtual ValueTask GetExpirationDateAsync(TToken token, CancellationToken cancellationToken) { if (token == null) { @@ -529,54 +406,30 @@ namespace OpenIddict.EntityFramework return new ValueTask(token.ExpirationDate); } - /// - /// Retrieves the unique identifier associated with a token. - /// - /// The token. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the unique identifier associated with the token. - /// - public virtual ValueTask GetIdAsync([NotNull] TToken token, CancellationToken cancellationToken) + /// + public virtual ValueTask GetIdAsync(TToken token, CancellationToken cancellationToken) { if (token == null) { throw new ArgumentNullException(nameof(token)); } - return new ValueTask(ConvertIdentifierToString(token.Id)); + return new ValueTask(ConvertIdentifierToString(token.Id)); } - /// - /// Retrieves the payload associated with a token. - /// - /// The token. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the payload associated with the specified token. - /// - public virtual ValueTask GetPayloadAsync([NotNull] TToken token, CancellationToken cancellationToken) + /// + public virtual ValueTask GetPayloadAsync(TToken token, CancellationToken cancellationToken) { if (token == null) { throw new ArgumentNullException(nameof(token)); } - return new ValueTask(token.Payload); + return new ValueTask(token.Payload); } - /// - /// Retrieves the additional properties associated with a token. - /// - /// The token. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns all the additional properties associated with the token. - /// - public virtual ValueTask> GetPropertiesAsync([NotNull] TToken token, CancellationToken cancellationToken) + /// + public virtual ValueTask> GetPropertiesAsync(TToken token, CancellationToken cancellationToken) { if (token == null) { @@ -602,92 +455,51 @@ namespace OpenIddict.EntityFramework return new ValueTask>(properties); } - /// - /// Retrieves the reference identifier associated with a token. - /// Note: depending on the manager used to create the token, - /// the reference identifier may be hashed for security reasons. - /// - /// The token. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the reference identifier associated with the specified token. - /// - public virtual ValueTask GetReferenceIdAsync([NotNull] TToken token, CancellationToken cancellationToken) + /// + public virtual ValueTask GetReferenceIdAsync(TToken token, CancellationToken cancellationToken) { if (token == null) { throw new ArgumentNullException(nameof(token)); } - return new ValueTask(token.ReferenceId); + return new ValueTask(token.ReferenceId); } - /// - /// Retrieves the status associated with a token. - /// - /// The token. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the status associated with the specified token. - /// - public virtual ValueTask GetStatusAsync([NotNull] TToken token, CancellationToken cancellationToken) + /// + public virtual ValueTask GetStatusAsync(TToken token, CancellationToken cancellationToken) { if (token == null) { throw new ArgumentNullException(nameof(token)); } - return new ValueTask(token.Status); + return new ValueTask(token.Status); } - /// - /// Retrieves the subject associated with a token. - /// - /// The token. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the subject associated with the specified token. - /// - public virtual ValueTask GetSubjectAsync([NotNull] TToken token, CancellationToken cancellationToken) + /// + public virtual ValueTask GetSubjectAsync(TToken token, CancellationToken cancellationToken) { if (token == null) { throw new ArgumentNullException(nameof(token)); } - return new ValueTask(token.Subject); + return new ValueTask(token.Subject); } - /// - /// Retrieves the token type associated with a token. - /// - /// The token. - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the token type associated with the specified token. - /// - public virtual ValueTask GetTypeAsync([NotNull] TToken token, CancellationToken cancellationToken) + /// + public virtual ValueTask GetTypeAsync(TToken token, CancellationToken cancellationToken) { if (token == null) { throw new ArgumentNullException(nameof(token)); } - return new ValueTask(token.Type); + return new ValueTask(token.Type); } - /// - /// Instantiates a new token. - /// - /// The that can be used to abort the operation. - /// - /// A that can be used to monitor the asynchronous operation, - /// whose result returns the instantiated token, that can be persisted in the database. - /// + /// public virtual ValueTask InstantiateAsync(CancellationToken cancellationToken) { try @@ -702,19 +514,12 @@ namespace OpenIddict.EntityFramework } } - /// - /// Executes the specified query and returns all the corresponding elements. - /// - /// The number of results to return. - /// The number of results to skip. - /// The that can be used to abort the operation. - /// All the elements returned when executing the specified query. - public virtual IAsyncEnumerable ListAsync( - [CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken) + /// + public virtual IAsyncEnumerable ListAsync(int? count, int? offset, CancellationToken cancellationToken) { var query = Tokens.Include(token => token.Application) .Include(token => token.Authorization) - .OrderBy(token => token.Id) + .OrderBy(token => token.Id!) .AsQueryable(); if (offset.HasValue) @@ -730,18 +535,10 @@ namespace OpenIddict.EntityFramework return query.AsAsyncEnumerable(cancellationToken); } - /// - /// Executes the specified query and returns all the corresponding elements. - /// - /// The state type. - /// The result type. - /// The query to execute. - /// The optional state. - /// The that can be used to abort the operation. - /// All the elements returned when executing the specified query. + /// public virtual IAsyncEnumerable ListAsync( - [NotNull] Func, TState, IQueryable> query, - [CanBeNull] TState state, CancellationToken cancellationToken) + Func, TState, IQueryable> query, + TState state, CancellationToken cancellationToken) { if (query == null) { @@ -753,20 +550,16 @@ namespace OpenIddict.EntityFramework .Include(token => token.Authorization), state).AsAsyncEnumerable(cancellationToken); } - /// - /// Removes the tokens that are marked as expired or invalid. - /// - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. + /// public virtual async ValueTask PruneAsync(CancellationToken cancellationToken) { // Note: Entity Framework 6.x doesn't support set-based deletes, which prevents removing // entities in a single command without having to retrieve and materialize them first. // To work around this limitation, entities are manually listed and deleted using a batch logic. - List exceptions = null; + List? exceptions = null; - DbContextTransaction CreateTransaction() + DbContextTransaction? CreateTransaction() { // Note: relational providers like Sqlite are known to lack proper support // for repeatable read transactions. To ensure this method can be safely used @@ -830,15 +623,8 @@ namespace OpenIddict.EntityFramework } } - /// - /// Sets the application identifier associated with a token. - /// - /// The token. - /// The unique identifier associated with the client application. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual async ValueTask SetApplicationIdAsync([NotNull] TToken token, - [CanBeNull] string identifier, CancellationToken cancellationToken) + /// + public virtual async ValueTask SetApplicationIdAsync(TToken token, string? identifier, CancellationToken cancellationToken) { if (token == null) { @@ -874,15 +660,8 @@ namespace OpenIddict.EntityFramework } } - /// - /// Sets the authorization identifier associated with a token. - /// - /// The token. - /// The unique identifier associated with the authorization. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual async ValueTask SetAuthorizationIdAsync([NotNull] TToken token, - [CanBeNull] string identifier, CancellationToken cancellationToken) + /// + public virtual async ValueTask SetAuthorizationIdAsync(TToken token, string? identifier, CancellationToken cancellationToken) { if (token == null) { @@ -918,15 +697,8 @@ namespace OpenIddict.EntityFramework } } - /// - /// Sets the creation date associated with a token. - /// - /// The token. - /// The creation date. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual ValueTask SetCreationDateAsync([NotNull] TToken token, - [CanBeNull] DateTimeOffset? date, CancellationToken cancellationToken) + /// + public virtual ValueTask SetCreationDateAsync(TToken token, DateTimeOffset? date, CancellationToken cancellationToken) { if (token == null) { @@ -938,15 +710,8 @@ namespace OpenIddict.EntityFramework return default; } - /// - /// Sets the expiration date associated with a token. - /// - /// The token. - /// The expiration date. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual ValueTask SetExpirationDateAsync([NotNull] TToken token, - [CanBeNull] DateTimeOffset? date, CancellationToken cancellationToken) + /// + public virtual ValueTask SetExpirationDateAsync(TToken token, DateTimeOffset? date, CancellationToken cancellationToken) { if (token == null) { @@ -958,14 +723,8 @@ namespace OpenIddict.EntityFramework return default; } - /// - /// Sets the payload associated with a token. - /// - /// The token. - /// The payload associated with the token. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual ValueTask SetPayloadAsync([NotNull] TToken token, [CanBeNull] string payload, CancellationToken cancellationToken) + /// + public virtual ValueTask SetPayloadAsync(TToken token, string? payload, CancellationToken cancellationToken) { if (token == null) { @@ -977,15 +736,9 @@ namespace OpenIddict.EntityFramework return default; } - /// - /// Sets the additional properties associated with a token. - /// - /// The token. - /// The additional properties associated with the token. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual ValueTask SetPropertiesAsync([NotNull] TToken token, - [CanBeNull] ImmutableDictionary properties, CancellationToken cancellationToken) + /// + public virtual ValueTask SetPropertiesAsync(TToken token, + ImmutableDictionary properties, CancellationToken cancellationToken) { if (token == null) { @@ -1008,16 +761,8 @@ namespace OpenIddict.EntityFramework return default; } - /// - /// Sets the reference identifier associated with a token. - /// Note: depending on the manager used to create the token, - /// the reference identifier may be hashed for security reasons. - /// - /// The token. - /// The reference identifier associated with the token. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual ValueTask SetReferenceIdAsync([NotNull] TToken token, [CanBeNull] string identifier, CancellationToken cancellationToken) + /// + public virtual ValueTask SetReferenceIdAsync(TToken token, string? identifier, CancellationToken cancellationToken) { if (token == null) { @@ -1029,14 +774,8 @@ namespace OpenIddict.EntityFramework return default; } - /// - /// Sets the status associated with a token. - /// - /// The token. - /// The status associated with the authorization. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual ValueTask SetStatusAsync([NotNull] TToken token, [CanBeNull] string status, CancellationToken cancellationToken) + /// + public virtual ValueTask SetStatusAsync(TToken token, string? status, CancellationToken cancellationToken) { if (token == null) { @@ -1048,14 +787,8 @@ namespace OpenIddict.EntityFramework return default; } - /// - /// Sets the subject associated with a token. - /// - /// The token. - /// The subject associated with the token. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual ValueTask SetSubjectAsync([NotNull] TToken token, [CanBeNull] string subject, CancellationToken cancellationToken) + /// + public virtual ValueTask SetSubjectAsync(TToken token, string? subject, CancellationToken cancellationToken) { if (token == null) { @@ -1067,14 +800,8 @@ namespace OpenIddict.EntityFramework return default; } - /// - /// Sets the token type associated with a token. - /// - /// The token. - /// The token type associated with the token. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual ValueTask SetTypeAsync([NotNull] TToken token, [CanBeNull] string type, CancellationToken cancellationToken) + /// + public virtual ValueTask SetTypeAsync(TToken token, string? type, CancellationToken cancellationToken) { if (token == null) { @@ -1086,13 +813,8 @@ namespace OpenIddict.EntityFramework return default; } - /// - /// Updates an existing token. - /// - /// The token to update. - /// The that can be used to abort the operation. - /// A that can be used to monitor the asynchronous operation. - public virtual async ValueTask UpdateAsync([NotNull] TToken token, CancellationToken cancellationToken) + /// + public virtual async ValueTask UpdateAsync(TToken token, CancellationToken cancellationToken) { if (token == null) { @@ -1126,7 +848,8 @@ namespace OpenIddict.EntityFramework /// /// The identifier to convert. /// An instance of representing the provided identifier. - public virtual TKey ConvertIdentifierFromString([CanBeNull] string identifier) + [return: MaybeNull] + public virtual TKey ConvertIdentifierFromString(string? identifier) { if (string.IsNullOrEmpty(identifier)) { @@ -1141,7 +864,7 @@ namespace OpenIddict.EntityFramework /// /// The identifier to convert. /// A representation of the provided identifier. - public virtual string ConvertIdentifierToString([CanBeNull] TKey identifier) + public virtual string? ConvertIdentifierToString([AllowNull] TKey identifier) { if (Equals(identifier, default(TKey))) {