diff --git a/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreApplicationConfiguration.cs b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreApplicationConfiguration.cs index 84292082..6c7c6c60 100644 --- a/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreApplicationConfiguration.cs +++ b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreApplicationConfiguration.cs @@ -6,7 +6,6 @@ using System; using System.ComponentModel; -using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using OpenIddict.EntityFrameworkCore.Models; @@ -27,7 +26,7 @@ namespace OpenIddict.EntityFrameworkCore where TToken : OpenIddictEntityFrameworkCoreToken where TKey : IEquatable { - public void Configure([NotNull] EntityTypeBuilder builder) + public void Configure(EntityTypeBuilder builder) { if (builder == null) { @@ -47,28 +46,26 @@ namespace OpenIddict.EntityFrameworkCore .IsUnique(); builder.Property(application => application.ClientId) - .HasMaxLength(100) - .IsRequired(); + .HasMaxLength(100); builder.Property(application => application.ConcurrencyToken) .HasMaxLength(50) .IsConcurrencyToken(); - builder.Property(application => application.Id) + builder.Property(application => application.Id!) .ValueGeneratedOnAdd(); builder.Property(application => application.Type) - .HasMaxLength(25) - .IsRequired(); + .HasMaxLength(25); builder.HasMany(application => application.Authorizations) - .WithOne(authorization => authorization.Application) + .WithOne(authorization => authorization.Application!) .HasForeignKey(nameof(OpenIddictEntityFrameworkCoreAuthorization.Application) + nameof(OpenIddictEntityFrameworkCoreApplication.Id)) .IsRequired(required: false); builder.HasMany(application => application.Tokens) - .WithOne(token => token.Application) + .WithOne(token => token.Application!) .HasForeignKey(nameof(OpenIddictEntityFrameworkCoreToken.Application) + nameof(OpenIddictEntityFrameworkCoreApplication.Id)) .IsRequired(required: false); diff --git a/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreAuthorizationConfiguration.cs b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreAuthorizationConfiguration.cs index 7d221db7..627e97e0 100644 --- a/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreAuthorizationConfiguration.cs +++ b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreAuthorizationConfiguration.cs @@ -6,7 +6,6 @@ using System; using System.ComponentModel; -using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using OpenIddict.EntityFrameworkCore.Models; @@ -27,7 +26,7 @@ namespace OpenIddict.EntityFrameworkCore where TToken : OpenIddictEntityFrameworkCoreToken where TKey : IEquatable { - public void Configure([NotNull] EntityTypeBuilder builder) + public void Configure(EntityTypeBuilder builder) { if (builder == null) { @@ -50,22 +49,20 @@ namespace OpenIddict.EntityFrameworkCore .HasMaxLength(50) .IsConcurrencyToken(); - builder.Property(authorization => authorization.Id) + builder.Property(authorization => authorization.Id!) .ValueGeneratedOnAdd(); builder.Property(authorization => authorization.Status) - .HasMaxLength(25) - .IsRequired(); + .HasMaxLength(25); builder.Property(authorization => authorization.Subject) .HasMaxLength(450); builder.Property(authorization => authorization.Type) - .HasMaxLength(25) - .IsRequired(); + .HasMaxLength(25); builder.HasMany(authorization => authorization.Tokens) - .WithOne(token => token.Authorization) + .WithOne(token => token.Authorization!) .HasForeignKey(nameof(OpenIddictEntityFrameworkCoreToken.Authorization) + nameof(OpenIddictEntityFrameworkCoreAuthorization.Id)) .IsRequired(required: false); diff --git a/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreScopeConfiguration.cs b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreScopeConfiguration.cs index f44bdaa0..5d77bbd6 100644 --- a/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreScopeConfiguration.cs +++ b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreScopeConfiguration.cs @@ -6,7 +6,6 @@ using System; using System.ComponentModel; -using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using OpenIddict.EntityFrameworkCore.Models; @@ -23,7 +22,7 @@ namespace OpenIddict.EntityFrameworkCore where TScope : OpenIddictEntityFrameworkCoreScope where TKey : IEquatable { - public void Configure([NotNull] EntityTypeBuilder builder) + public void Configure(EntityTypeBuilder builder) { if (builder == null) { @@ -46,12 +45,11 @@ namespace OpenIddict.EntityFrameworkCore .HasMaxLength(50) .IsConcurrencyToken(); - builder.Property(scope => scope.Id) + builder.Property(scope => scope.Id!) .ValueGeneratedOnAdd(); builder.Property(scope => scope.Name) - .HasMaxLength(200) - .IsRequired(); + .HasMaxLength(200); builder.ToTable("OpenIddictScopes"); } diff --git a/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreTokenConfiguration.cs b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreTokenConfiguration.cs index 891d648a..9cfbe99b 100644 --- a/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreTokenConfiguration.cs +++ b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreTokenConfiguration.cs @@ -6,7 +6,6 @@ using System; using System.ComponentModel; -using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using OpenIddict.EntityFrameworkCore.Models; @@ -27,7 +26,7 @@ namespace OpenIddict.EntityFrameworkCore where TAuthorization : OpenIddictEntityFrameworkCoreAuthorization where TKey : IEquatable { - public void Configure([NotNull] EntityTypeBuilder builder) + public void Configure(EntityTypeBuilder builder) { if (builder == null) { @@ -56,22 +55,20 @@ namespace OpenIddict.EntityFrameworkCore .HasMaxLength(50) .IsConcurrencyToken(); - builder.Property(token => token.Id) + builder.Property(token => token.Id!) .ValueGeneratedOnAdd(); builder.Property(token => token.ReferenceId) .HasMaxLength(100); builder.Property(token => token.Status) - .HasMaxLength(25) - .IsRequired(); + .HasMaxLength(25); builder.Property(token => token.Subject) .HasMaxLength(450); builder.Property(token => token.Type) - .HasMaxLength(25) - .IsRequired(); + .HasMaxLength(25); builder.ToTable("OpenIddictTokens"); } diff --git a/src/OpenIddict.EntityFrameworkCore/OpenIddict.EntityFrameworkCore.csproj b/src/OpenIddict.EntityFrameworkCore/OpenIddict.EntityFrameworkCore.csproj index 64c8840d..f02bc56b 100644 --- a/src/OpenIddict.EntityFrameworkCore/OpenIddict.EntityFrameworkCore.csproj +++ b/src/OpenIddict.EntityFrameworkCore/OpenIddict.EntityFrameworkCore.csproj @@ -2,6 +2,7 @@ net461;netcoreapp2.1;netcoreapp3.1;netstandard2.0;netstandard2.1 + enable diff --git a/src/OpenIddict.EntityFrameworkCore/OpenIddictEntityFrameworkCoreBuilder.cs b/src/OpenIddict.EntityFrameworkCore/OpenIddictEntityFrameworkCoreBuilder.cs index a9c144f8..d78ff90f 100644 --- a/src/OpenIddict.EntityFrameworkCore/OpenIddictEntityFrameworkCoreBuilder.cs +++ b/src/OpenIddict.EntityFrameworkCore/OpenIddictEntityFrameworkCoreBuilder.cs @@ -6,7 +6,6 @@ using System; using System.ComponentModel; -using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; using OpenIddict.Core; using OpenIddict.EntityFrameworkCore; @@ -24,7 +23,7 @@ namespace Microsoft.Extensions.DependencyInjection /// Initializes a new instance of . /// /// The services collection. - public OpenIddictEntityFrameworkCoreBuilder([NotNull] IServiceCollection services) + public OpenIddictEntityFrameworkCoreBuilder(IServiceCollection services) => Services = services ?? throw new ArgumentNullException(nameof(services)); /// @@ -39,7 +38,7 @@ namespace Microsoft.Extensions.DependencyInjection /// The delegate used to configure the OpenIddict options. /// This extension can be safely called multiple times. /// The . - public OpenIddictEntityFrameworkCoreBuilder Configure([NotNull] Action configuration) + public OpenIddictEntityFrameworkCoreBuilder Configure(Action configuration) { if (configuration == null) { @@ -100,7 +99,7 @@ namespace Microsoft.Extensions.DependencyInjection /// /// The type of the used by OpenIddict. /// The . - public OpenIddictEntityFrameworkCoreBuilder UseDbContext([NotNull] Type type) + public OpenIddictEntityFrameworkCoreBuilder 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.EntityFrameworkCore/OpenIddictEntityFrameworkCoreCustomizer.cs b/src/OpenIddict.EntityFrameworkCore/OpenIddictEntityFrameworkCoreCustomizer.cs index e0bacd2f..02ae4a24 100644 --- a/src/OpenIddict.EntityFrameworkCore/OpenIddictEntityFrameworkCoreCustomizer.cs +++ b/src/OpenIddict.EntityFrameworkCore/OpenIddictEntityFrameworkCoreCustomizer.cs @@ -5,7 +5,6 @@ */ using System; -using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using OpenIddict.EntityFrameworkCore.Models; @@ -23,12 +22,12 @@ namespace OpenIddict.EntityFrameworkCore where TToken : OpenIddictEntityFrameworkCoreToken where TKey : IEquatable { - public OpenIddictEntityFrameworkCoreCustomizer([NotNull] ModelCustomizerDependencies dependencies) + public OpenIddictEntityFrameworkCoreCustomizer(ModelCustomizerDependencies dependencies) : base(dependencies) { } - public override void Customize([NotNull] ModelBuilder modelBuilder, [NotNull] DbContext context) + public override void Customize(ModelBuilder modelBuilder, DbContext context) { if (modelBuilder == null) { diff --git a/src/OpenIddict.EntityFrameworkCore/OpenIddictEntityFrameworkCoreExtensions.cs b/src/OpenIddict.EntityFrameworkCore/OpenIddictEntityFrameworkCoreExtensions.cs index 7c9a64b2..dd6d50e0 100644 --- a/src/OpenIddict.EntityFrameworkCore/OpenIddictEntityFrameworkCoreExtensions.cs +++ b/src/OpenIddict.EntityFrameworkCore/OpenIddictEntityFrameworkCoreExtensions.cs @@ -5,7 +5,6 @@ */ using System; -using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection.Extensions; using OpenIddict.EntityFrameworkCore; using OpenIddict.EntityFrameworkCore.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 OpenIddictEntityFrameworkCoreBuilder UseEntityFrameworkCore([NotNull] this OpenIddictCoreBuilder builder) + public static OpenIddictEntityFrameworkCoreBuilder UseEntityFrameworkCore(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 UseEntityFrameworkCore( - [NotNull] this OpenIddictCoreBuilder builder, - [NotNull] Action configuration) + this OpenIddictCoreBuilder builder, Action configuration) { if (builder == null) { diff --git a/src/OpenIddict.EntityFrameworkCore/OpenIddictEntityFrameworkCoreHelpers.cs b/src/OpenIddict.EntityFrameworkCore/OpenIddictEntityFrameworkCoreHelpers.cs index b8675ee5..aeffafde 100644 --- a/src/OpenIddict.EntityFrameworkCore/OpenIddictEntityFrameworkCoreHelpers.cs +++ b/src/OpenIddict.EntityFrameworkCore/OpenIddictEntityFrameworkCoreHelpers.cs @@ -9,7 +9,6 @@ using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Threading; -using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.Extensions.DependencyInjection; using OpenIddict.EntityFrameworkCore; @@ -28,7 +27,7 @@ namespace Microsoft.EntityFrameworkCore /// /// The builder used to configure the Entity Framework context. /// The Entity Framework context builder. - public static DbContextOptionsBuilder UseOpenIddict([NotNull] this DbContextOptionsBuilder builder) + public static DbContextOptionsBuilder UseOpenIddict(this DbContextOptionsBuilder builder) => builder.UseOpenIddict /// The builder used to configure the Entity Framework context. /// The Entity Framework context builder. - public static DbContextOptionsBuilder UseOpenIddict([NotNull] this DbContextOptionsBuilder builder) + public static DbContextOptionsBuilder UseOpenIddict(this DbContextOptionsBuilder builder) where TKey : IEquatable => builder.UseOpenIddict, OpenIddictEntityFrameworkCoreAuthorization, @@ -62,7 +61,7 @@ namespace Microsoft.EntityFrameworkCore /// The builder used to configure the Entity Framework context. /// The Entity Framework context builder. public static DbContextOptionsBuilder UseOpenIddict( - [NotNull] this DbContextOptionsBuilder builder) + this DbContextOptionsBuilder builder) where TApplication : OpenIddictEntityFrameworkCoreApplication where TAuthorization : OpenIddictEntityFrameworkCoreAuthorization where TScope : OpenIddictEntityFrameworkCoreScope @@ -84,7 +83,7 @@ namespace Microsoft.EntityFrameworkCore /// /// The builder used to configure the Entity Framework context. /// The Entity Framework context builder. - public static ModelBuilder UseOpenIddict([NotNull] this ModelBuilder builder) + public static ModelBuilder UseOpenIddict(this ModelBuilder builder) => builder.UseOpenIddict /// The builder used to configure the Entity Framework context. /// The Entity Framework context builder. - public static ModelBuilder UseOpenIddict([NotNull] this ModelBuilder builder) where TKey : IEquatable + public static ModelBuilder UseOpenIddict(this ModelBuilder builder) where TKey : IEquatable => builder.UseOpenIddict, OpenIddictEntityFrameworkCoreAuthorization, OpenIddictEntityFrameworkCoreScope, @@ -116,7 +115,7 @@ namespace Microsoft.EntityFrameworkCore /// /// The builder used to configure the Entity Framework context. /// The Entity Framework context builder. - public static ModelBuilder UseOpenIddict([NotNull] this ModelBuilder builder) + public static ModelBuilder UseOpenIddict(this ModelBuilder builder) where TApplication : OpenIddictEntityFrameworkCoreApplication where TAuthorization : OpenIddictEntityFrameworkCoreAuthorization where TScope : OpenIddictEntityFrameworkCoreScope @@ -144,7 +143,7 @@ namespace Microsoft.EntityFrameworkCore /// 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 = default) + this IQueryable source, CancellationToken cancellationToken = default) { if (source == null) { diff --git a/src/OpenIddict.EntityFrameworkCore/OpenIddictEntityFrameworkCoreOptions.cs b/src/OpenIddict.EntityFrameworkCore/OpenIddictEntityFrameworkCoreOptions.cs index 47a9efc0..c786dc3e 100644 --- a/src/OpenIddict.EntityFrameworkCore/OpenIddictEntityFrameworkCoreOptions.cs +++ b/src/OpenIddict.EntityFrameworkCore/OpenIddictEntityFrameworkCoreOptions.cs @@ -20,6 +20,6 @@ namespace OpenIddict.EntityFrameworkCore /// OpenIddict Entity Framework Core 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.EntityFrameworkCore/Resolvers/OpenIddictEntityFrameworkCoreApplicationStoreResolver.cs b/src/OpenIddict.EntityFrameworkCore/Resolvers/OpenIddictEntityFrameworkCoreApplicationStoreResolver.cs index 2ca4df92..e27e221e 100644 --- a/src/OpenIddict.EntityFrameworkCore/Resolvers/OpenIddictEntityFrameworkCoreApplicationStoreResolver.cs +++ b/src/OpenIddict.EntityFrameworkCore/Resolvers/OpenIddictEntityFrameworkCoreApplicationStoreResolver.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.EntityFrameworkCore private readonly IServiceProvider _provider; public OpenIddictEntityFrameworkCoreApplicationStoreResolver( - [NotNull] TypeResolutionCache cache, - [NotNull] IOptionsMonitor options, - [NotNull] IServiceProvider provider) + TypeResolutionCache cache, + IOptionsMonitor options, + IServiceProvider provider) { _cache = cache; _options = options; diff --git a/src/OpenIddict.EntityFrameworkCore/Resolvers/OpenIddictEntityFrameworkCoreAuthorizationStoreResolver.cs b/src/OpenIddict.EntityFrameworkCore/Resolvers/OpenIddictEntityFrameworkCoreAuthorizationStoreResolver.cs index 5cf008ce..4cf4c005 100644 --- a/src/OpenIddict.EntityFrameworkCore/Resolvers/OpenIddictEntityFrameworkCoreAuthorizationStoreResolver.cs +++ b/src/OpenIddict.EntityFrameworkCore/Resolvers/OpenIddictEntityFrameworkCoreAuthorizationStoreResolver.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.EntityFrameworkCore private readonly IServiceProvider _provider; public OpenIddictEntityFrameworkCoreAuthorizationStoreResolver( - [NotNull] TypeResolutionCache cache, - [NotNull] IOptionsMonitor options, - [NotNull] IServiceProvider provider) + TypeResolutionCache cache, + IOptionsMonitor options, + IServiceProvider provider) { _cache = cache; _options = options; diff --git a/src/OpenIddict.EntityFrameworkCore/Resolvers/OpenIddictEntityFrameworkCoreScopeStoreResolver.cs b/src/OpenIddict.EntityFrameworkCore/Resolvers/OpenIddictEntityFrameworkCoreScopeStoreResolver.cs index 1aa0f63b..cad7250e 100644 --- a/src/OpenIddict.EntityFrameworkCore/Resolvers/OpenIddictEntityFrameworkCoreScopeStoreResolver.cs +++ b/src/OpenIddict.EntityFrameworkCore/Resolvers/OpenIddictEntityFrameworkCoreScopeStoreResolver.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.EntityFrameworkCore private readonly IServiceProvider _provider; public OpenIddictEntityFrameworkCoreScopeStoreResolver( - [NotNull] TypeResolutionCache cache, - [NotNull] IOptionsMonitor options, - [NotNull] IServiceProvider provider) + TypeResolutionCache cache, + IOptionsMonitor options, + IServiceProvider provider) { _cache = cache; _options = options; diff --git a/src/OpenIddict.EntityFrameworkCore/Resolvers/OpenIddictEntityFrameworkCoreTokenStoreResolver.cs b/src/OpenIddict.EntityFrameworkCore/Resolvers/OpenIddictEntityFrameworkCoreTokenStoreResolver.cs index c33552f0..1941b2fa 100644 --- a/src/OpenIddict.EntityFrameworkCore/Resolvers/OpenIddictEntityFrameworkCoreTokenStoreResolver.cs +++ b/src/OpenIddict.EntityFrameworkCore/Resolvers/OpenIddictEntityFrameworkCoreTokenStoreResolver.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.EntityFrameworkCore private readonly IServiceProvider _provider; public OpenIddictEntityFrameworkCoreTokenStoreResolver( - [NotNull] TypeResolutionCache cache, - [NotNull] IOptionsMonitor options, - [NotNull] IServiceProvider provider) + TypeResolutionCache cache, + IOptionsMonitor options, + IServiceProvider provider) { _cache = cache; _options = options; diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreApplicationStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreApplicationStore.cs index 7a0baa84..2526d983 100644 --- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreApplicationStore.cs +++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreApplicationStore.cs @@ -9,6 +9,7 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.ComponentModel; using System.Data; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Linq; @@ -18,7 +19,6 @@ using System.Text.Encodings.Web; using System.Text.Json; using System.Threading; using System.Threading.Tasks; -using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage; @@ -41,9 +41,9 @@ namespace OpenIddict.EntityFrameworkCore where TContext : DbContext { public OpenIddictEntityFrameworkCoreApplicationStore( - [NotNull] IMemoryCache cache, - [NotNull] TContext context, - [NotNull] IOptionsMonitor options) + IMemoryCache cache, + TContext context, + IOptionsMonitor options) : base(cache, context, options) { } @@ -62,9 +62,9 @@ namespace OpenIddict.EntityFrameworkCore where TKey : IEquatable { public OpenIddictEntityFrameworkCoreApplicationStore( - [NotNull] IMemoryCache cache, - [NotNull] TContext context, - [NotNull] IOptionsMonitor options) + IMemoryCache cache, + TContext context, + IOptionsMonitor options) : base(cache, context, options) { } @@ -86,9 +86,9 @@ namespace OpenIddict.EntityFrameworkCore where TKey : IEquatable { public OpenIddictEntityFrameworkCoreApplicationStore( - [NotNull] IMemoryCache cache, - [NotNull] TContext context, - [NotNull] IOptionsMonitor options) + IMemoryCache cache, + TContext context, + IOptionsMonitor options) { Cache = cache; Context = context; @@ -136,17 +136,8 @@ namespace OpenIddict.EntityFrameworkCore public virtual async ValueTask CountAsync(CancellationToken cancellationToken) => await Applications.AsQueryable().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) { @@ -156,13 +147,8 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -174,20 +160,15 @@ namespace OpenIddict.EntityFrameworkCore 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)); } - async ValueTask CreateTransactionAsync() + async ValueTask CreateTransactionAsync() { // Note: transactions that specify an explicit isolation level are only supported by // relational providers and trying to use them with a different provider results in @@ -217,8 +198,8 @@ namespace OpenIddict.EntityFrameworkCore Task> ListAuthorizationsAsync() => (from authorization in Authorizations.Include(authorization => authorization.Tokens).AsTracking() - join element in Applications.AsTracking() on authorization.Application.Id equals element.Id - where element.Id.Equals(application.Id) + join element in Applications.AsTracking() on authorization.Application!.Id equals element.Id + where element.Id!.Equals(application.Id) select authorization).ToListAsync(cancellationToken); // Note: due to a bug in Entity Framework Core's query visitor, the tokens can't be @@ -229,8 +210,8 @@ namespace OpenIddict.EntityFrameworkCore Task> ListTokensAsync() => (from token in Tokens.AsTracking() where token.Authorization == null - join element in Applications.AsTracking() on token.Application.Id equals element.Id - where element.Id.Equals(application.Id) + join element in Applications.AsTracking() on token.Application!.Id equals element.Id + where element.Id!.Equals(application.Id) select token).ToListAsync(cancellationToken); // To prevent an SQL exception from being thrown if a new associated entity is @@ -285,16 +266,8 @@ namespace OpenIddict.EntityFrameworkCore } } - /// - /// 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)) { @@ -306,16 +279,8 @@ namespace OpenIddict.EntityFrameworkCore select application).FirstOrDefaultAsync(cancellationToken); } - /// - /// 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)) { @@ -325,18 +290,13 @@ namespace OpenIddict.EntityFrameworkCore var key = ConvertIdentifierFromString(identifier); return await (from application in Applications.AsTracking() - where application.Id.Equals(key) + where application.Id!.Equals(key) 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)) { @@ -354,7 +314,7 @@ namespace OpenIddict.EntityFrameworkCore async IAsyncEnumerable ExecuteAsync([EnumeratorCancellation] CancellationToken cancellationToken) { var applications = (from application in Applications.AsTracking() - where application.PostLogoutRedirectUris.Contains(address) + where application.PostLogoutRedirectUris!.Contains(address) select application).AsAsyncEnumerable(); await foreach (var application in applications) @@ -368,14 +328,9 @@ namespace OpenIddict.EntityFrameworkCore } } - /// - /// 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)) { @@ -393,7 +348,7 @@ namespace OpenIddict.EntityFrameworkCore async IAsyncEnumerable ExecuteAsync([EnumeratorCancellation] CancellationToken cancellationToken) { var applications = (from application in Applications.AsTracking() - where application.RedirectUris.Contains(address) + where application.RedirectUris!.Contains(address) select application).AsAsyncEnumerable(); await foreach (var application in applications) @@ -407,21 +362,10 @@ namespace OpenIddict.EntityFrameworkCore } } - /// - /// 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) { @@ -431,113 +375,63 @@ namespace OpenIddict.EntityFrameworkCore return await query(Applications.AsTracking(), 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) { @@ -564,35 +458,19 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -618,16 +496,8 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -653,16 +523,8 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -688,16 +550,8 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -723,16 +577,8 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -758,14 +604,7 @@ namespace OpenIddict.EntityFrameworkCore 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 @@ -780,17 +619,10 @@ namespace OpenIddict.EntityFrameworkCore } } - /// - /// 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 = Applications.AsQueryable().OrderBy(application => application.Id).AsTracking(); + var query = Applications.AsQueryable().OrderBy(application => application.Id!).AsTracking(); if (offset.HasValue) { @@ -805,18 +637,10 @@ namespace OpenIddict.EntityFrameworkCore return query.AsAsyncEnumerable(); } - /// - /// 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) { @@ -826,15 +650,8 @@ namespace OpenIddict.EntityFrameworkCore return query(Applications.AsTracking(), state).AsAsyncEnumerable(); } - /// - /// 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) { @@ -846,17 +663,8 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -868,15 +676,8 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -888,15 +689,8 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -908,15 +702,8 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -928,15 +715,9 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -958,7 +739,7 @@ namespace OpenIddict.EntityFrameworkCore }); writer.WriteStartObject(); - + foreach (var pair in names) { writer.WritePropertyName(pair.Key.Name); @@ -973,14 +754,8 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -1003,14 +778,8 @@ namespace OpenIddict.EntityFrameworkCore 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) @@ -1034,15 +803,9 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -1065,14 +828,8 @@ namespace OpenIddict.EntityFrameworkCore 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) @@ -1096,14 +853,8 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -1126,13 +877,8 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -1166,7 +912,8 @@ namespace OpenIddict.EntityFrameworkCore /// /// 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)) { @@ -1181,7 +928,7 @@ namespace OpenIddict.EntityFrameworkCore /// /// 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.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreAuthorizationStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreAuthorizationStore.cs index c4c6a012..3b936cfc 100644 --- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreAuthorizationStore.cs +++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreAuthorizationStore.cs @@ -9,13 +9,13 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.ComponentModel; using System.Data; +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.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage; @@ -38,9 +38,9 @@ namespace OpenIddict.EntityFrameworkCore where TContext : DbContext { public OpenIddictEntityFrameworkCoreAuthorizationStore( - [NotNull] IMemoryCache cache, - [NotNull] TContext context, - [NotNull] IOptionsMonitor options) + IMemoryCache cache, + TContext context, + IOptionsMonitor options) : base(cache, context, options) { } @@ -59,9 +59,9 @@ namespace OpenIddict.EntityFrameworkCore where TKey : IEquatable { public OpenIddictEntityFrameworkCoreAuthorizationStore( - [NotNull] IMemoryCache cache, - [NotNull] TContext context, - [NotNull] IOptionsMonitor options) + IMemoryCache cache, + TContext context, + IOptionsMonitor options) : base(cache, context, options) { } @@ -83,9 +83,9 @@ namespace OpenIddict.EntityFrameworkCore where TKey : IEquatable { public OpenIddictEntityFrameworkCoreAuthorizationStore( - [NotNull] IMemoryCache cache, - [NotNull] TContext context, - [NotNull] IOptionsMonitor options) + IMemoryCache cache, + TContext context, + IOptionsMonitor options) { Cache = cache; Context = context; @@ -122,28 +122,12 @@ namespace OpenIddict.EntityFrameworkCore /// 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.AsQueryable().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) { @@ -153,13 +137,8 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -171,20 +150,15 @@ namespace OpenIddict.EntityFrameworkCore 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)); } - async ValueTask CreateTransactionAsync() + async ValueTask CreateTransactionAsync() { // Note: transactions that specify an explicit isolation level are only supported by // relational providers and trying to use them with a different provider results in @@ -214,8 +188,8 @@ namespace OpenIddict.EntityFrameworkCore Task> ListTokensAsync() => (from token in Tokens.AsTracking() - join element in Authorizations.AsTracking() on token.Authorization.Id equals element.Id - where element.Id.Equals(authorization.Id) + join element in Authorizations.AsTracking() on token.Authorization!.Id equals element.Id + where element.Id!.Equals(authorization.Id) select token).ToListAsync(cancellationToken); // To prevent an SQL exception from being thrown if a new associated entity is @@ -252,16 +226,9 @@ namespace OpenIddict.EntityFrameworkCore } } - /// - /// 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)) { @@ -282,22 +249,15 @@ namespace OpenIddict.EntityFrameworkCore return (from authorization in Authorizations.Include(authorization => authorization.Application).AsTracking() where authorization.Subject == subject - join application in Applications.AsTracking() on authorization.Application.Id equals application.Id - where application.Id.Equals(key) + join application in Applications.AsTracking() on authorization.Application!.Id equals application.Id + where application.Id!.Equals(key) select authorization).AsAsyncEnumerable(); } - /// - /// 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)) { @@ -323,23 +283,15 @@ namespace OpenIddict.EntityFrameworkCore return (from authorization in Authorizations.Include(authorization => authorization.Application).AsTracking() where authorization.Subject == subject && authorization.Status == status - join application in Applications.AsTracking() on authorization.Application.Id equals application.Id - where application.Id.Equals(key) + join application in Applications.AsTracking() on authorization.Application!.Id equals application.Id + where application.Id!.Equals(key) select authorization).AsAsyncEnumerable(); } - /// - /// 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)) { @@ -372,24 +324,15 @@ namespace OpenIddict.EntityFrameworkCore where authorization.Subject == subject && authorization.Status == status && authorization.Type == type - join application in Applications.AsTracking() on authorization.Application.Id equals application.Id - where application.Id.Equals(key) + join application in Applications.AsTracking() on authorization.Application!.Id equals application.Id + where application.Id!.Equals(key) select authorization).AsAsyncEnumerable(); } - /// - /// 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)) @@ -427,8 +370,8 @@ namespace OpenIddict.EntityFrameworkCore where authorization.Subject == subject && authorization.Status == status && authorization.Type == type - join application in Applications.AsTracking() on authorization.Application.Id equals application.Id - where application.Id.Equals(key) + join application in Applications.AsTracking() on authorization.Application!.Id equals application.Id + where application.Id!.Equals(key) select authorization).AsAsyncEnumerable(); await foreach (var authorization in authorizations) @@ -441,14 +384,9 @@ namespace OpenIddict.EntityFrameworkCore } } - /// - /// 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)) { @@ -463,18 +401,13 @@ namespace OpenIddict.EntityFrameworkCore var key = ConvertIdentifierFromString(identifier); return (from authorization in Authorizations.Include(authorization => authorization.Application).AsTracking() - join application in Applications.AsTracking() on authorization.Application.Id equals application.Id - where application.Id.Equals(identifier) + join application in Applications.AsTracking() on authorization.Application!.Id equals application.Id + where application.Id!.Equals(identifier) select authorization).AsAsyncEnumerable(); } - /// - /// Retrieves an authorization using its unique identifier. - /// - /// The unique identifier associated with the authorization. - /// The that can be used to abort the operation. - /// 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)) { @@ -484,18 +417,13 @@ namespace OpenIddict.EntityFrameworkCore var key = ConvertIdentifierFromString(identifier); return await (from authorization in Authorizations.Include(authorization => authorization.Application).AsTracking() - where authorization.Id.Equals(key) + where authorization.Id!.Equals(key) select authorization).FirstOrDefaultAsync(cancellationToken); } - /// - /// Retrieves the subject associated with an authorization. - /// - /// 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)) { @@ -507,16 +435,8 @@ namespace OpenIddict.EntityFrameworkCore select authorization).AsAsyncEnumerable(); } - /// - /// 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) { @@ -543,21 +463,10 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -569,35 +478,19 @@ namespace OpenIddict.EntityFrameworkCore .AsTracking(), 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) { @@ -623,16 +516,8 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -658,71 +543,40 @@ namespace OpenIddict.EntityFrameworkCore 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 @@ -737,18 +591,11 @@ namespace OpenIddict.EntityFrameworkCore } } - /// - /// 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!) .AsTracking(); if (offset.HasValue) @@ -764,18 +611,10 @@ namespace OpenIddict.EntityFrameworkCore return query.AsAsyncEnumerable(); } - /// - /// 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) { @@ -787,20 +626,16 @@ namespace OpenIddict.EntityFrameworkCore .AsTracking(), state).AsAsyncEnumerable(); } - /// - /// 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 Core 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; - async ValueTask CreateTransactionAsync() + async ValueTask CreateTransactionAsync() { // Note: transactions that specify an explicit isolation level are only supported by // relational providers and trying to use them with a different provider results in @@ -880,15 +715,9 @@ namespace OpenIddict.EntityFrameworkCore } } - /// - /// 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) { @@ -902,7 +731,7 @@ namespace OpenIddict.EntityFrameworkCore // Warning: FindAsync() is deliberately not used to work around a breaking change introduced // in Entity Framework Core 3.x (where a ValueTask instead of a Task is now returned). var application = await Applications.AsQueryable() - .FirstOrDefaultAsync(application => application.Id.Equals(key), cancellationToken); + .FirstOrDefaultAsync(application => application.Id!.Equals(key), cancellationToken); if (application == null) { @@ -930,15 +759,9 @@ namespace OpenIddict.EntityFrameworkCore } } - /// - /// 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) { @@ -961,14 +784,8 @@ namespace OpenIddict.EntityFrameworkCore 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) @@ -992,15 +809,9 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -1012,15 +823,9 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -1032,15 +837,9 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -1052,13 +851,8 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -1092,7 +886,8 @@ namespace OpenIddict.EntityFrameworkCore /// /// 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)) { @@ -1107,7 +902,7 @@ namespace OpenIddict.EntityFrameworkCore /// /// 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.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreScopeStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreScopeStore.cs index 6c174dde..8079129b 100644 --- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreScopeStore.cs +++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreScopeStore.cs @@ -8,6 +8,7 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Linq; @@ -17,7 +18,6 @@ using System.Text.Encodings.Web; using System.Text.Json; using System.Threading; using System.Threading.Tasks; -using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Options; @@ -35,9 +35,9 @@ namespace OpenIddict.EntityFrameworkCore where TContext : DbContext { public OpenIddictEntityFrameworkCoreScopeStore( - [NotNull] IMemoryCache cache, - [NotNull] TContext context, - [NotNull] IOptionsMonitor options) + IMemoryCache cache, + TContext context, + IOptionsMonitor options) : base(cache, context, options) { } @@ -53,9 +53,9 @@ namespace OpenIddict.EntityFrameworkCore where TKey : IEquatable { public OpenIddictEntityFrameworkCoreScopeStore( - [NotNull] IMemoryCache cache, - [NotNull] TContext context, - [NotNull] IOptionsMonitor options) + IMemoryCache cache, + TContext context, + IOptionsMonitor options) : base(cache, context, options) { } @@ -73,9 +73,9 @@ namespace OpenIddict.EntityFrameworkCore where TKey : IEquatable { public OpenIddictEntityFrameworkCoreScopeStore( - [NotNull] IMemoryCache cache, - [NotNull] TContext context, - [NotNull] IOptionsMonitor options) + IMemoryCache cache, + TContext context, + IOptionsMonitor options) { Cache = cache; Context = context; @@ -102,28 +102,12 @@ namespace OpenIddict.EntityFrameworkCore /// 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.AsQueryable().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) { @@ -133,13 +117,8 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -151,13 +130,8 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -180,16 +154,8 @@ namespace OpenIddict.EntityFrameworkCore } } - /// - /// 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)) { @@ -199,20 +165,12 @@ namespace OpenIddict.EntityFrameworkCore var key = ConvertIdentifierFromString(identifier); return await (from scope in Scopes.AsTracking() - 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)) { @@ -224,12 +182,7 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -245,14 +198,9 @@ namespace OpenIddict.EntityFrameworkCore select scope).AsAsyncEnumerable(); } - /// - /// 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)) { @@ -270,7 +218,7 @@ namespace OpenIddict.EntityFrameworkCore async IAsyncEnumerable ExecuteAsync([EnumeratorCancellation] CancellationToken cancellationToken) { var scopes = (from scope in Scopes.AsTracking() - where scope.Resources.Contains(resource) + where scope.Resources!.Contains(resource) select scope).AsAsyncEnumerable(); await foreach (var scope in scopes) @@ -284,21 +232,10 @@ namespace OpenIddict.EntityFrameworkCore } } - /// - /// 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) { @@ -308,35 +245,19 @@ namespace OpenIddict.EntityFrameworkCore return await query(Scopes.AsTracking(), 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) { @@ -363,35 +284,19 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -418,54 +323,30 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -491,16 +372,8 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -526,14 +399,7 @@ namespace OpenIddict.EntityFrameworkCore 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 @@ -548,17 +414,10 @@ namespace OpenIddict.EntityFrameworkCore } } - /// - /// 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.AsQueryable().OrderBy(scope => scope.Id).AsTracking(); + var query = Scopes.AsQueryable().OrderBy(scope => scope.Id!).AsTracking(); if (offset.HasValue) { @@ -573,18 +432,10 @@ namespace OpenIddict.EntityFrameworkCore return query.AsAsyncEnumerable(); } - /// - /// 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) { @@ -594,14 +445,8 @@ namespace OpenIddict.EntityFrameworkCore return query(Scopes.AsTracking(), state).AsAsyncEnumerable(); } - /// - /// 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) { @@ -613,15 +458,9 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -658,14 +497,8 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -677,15 +510,9 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -722,14 +549,8 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -741,15 +562,9 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -772,14 +587,8 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -802,13 +611,8 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -842,7 +646,8 @@ namespace OpenIddict.EntityFrameworkCore /// /// 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)) { @@ -857,7 +662,7 @@ namespace OpenIddict.EntityFrameworkCore /// /// 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.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreTokenStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreTokenStore.cs index 8613dc27..ab0e7fbe 100644 --- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreTokenStore.cs +++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreTokenStore.cs @@ -9,12 +9,12 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.ComponentModel; using System.Data; +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.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage; @@ -37,9 +37,9 @@ namespace OpenIddict.EntityFrameworkCore where TContext : DbContext { public OpenIddictEntityFrameworkCoreTokenStore( - [NotNull] IMemoryCache cache, - [NotNull] TContext context, - [NotNull] IOptionsMonitor options) + IMemoryCache cache, + TContext context, + IOptionsMonitor options) : base(cache, context, options) { } @@ -58,9 +58,9 @@ namespace OpenIddict.EntityFrameworkCore where TKey : IEquatable { public OpenIddictEntityFrameworkCoreTokenStore( - [NotNull] IMemoryCache cache, - [NotNull] TContext context, - [NotNull] IOptionsMonitor options) + IMemoryCache cache, + TContext context, + IOptionsMonitor options) : base(cache, context, options) { } @@ -82,9 +82,9 @@ namespace OpenIddict.EntityFrameworkCore where TKey : IEquatable { public OpenIddictEntityFrameworkCoreTokenStore( - [NotNull] IMemoryCache cache, - [NotNull] TContext context, - [NotNull] IOptionsMonitor options) + IMemoryCache cache, + TContext context, + IOptionsMonitor options) { Cache = cache; Context = context; @@ -121,28 +121,12 @@ namespace OpenIddict.EntityFrameworkCore /// 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.AsQueryable().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) { @@ -152,13 +136,8 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -170,13 +149,8 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -199,16 +173,8 @@ namespace OpenIddict.EntityFrameworkCore } } - /// - /// 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)) { @@ -229,22 +195,15 @@ namespace OpenIddict.EntityFrameworkCore return (from token in Tokens.Include(token => token.Application).Include(token => token.Authorization).AsTracking() where token.Subject == subject - join application in Applications.AsTracking() on token.Application.Id equals application.Id - where application.Id.Equals(key) + join application in Applications.AsTracking() on token.Application!.Id equals application.Id + where application.Id!.Equals(key) select token).AsAsyncEnumerable(); } - /// - /// 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)) { @@ -271,23 +230,15 @@ namespace OpenIddict.EntityFrameworkCore return (from token in Tokens.Include(token => token.Application).Include(token => token.Authorization).AsTracking() where token.Subject == subject && token.Status == status - join application in Applications.AsTracking() on token.Application.Id equals application.Id - where application.Id.Equals(key) + join application in Applications.AsTracking() on token.Application!.Id equals application.Id + where application.Id!.Equals(key) select token).AsAsyncEnumerable(); } - /// - /// 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)) { @@ -320,18 +271,13 @@ namespace OpenIddict.EntityFrameworkCore where token.Subject == subject && token.Status == status && token.Type == type - join application in Applications.AsTracking() on token.Application.Id equals application.Id - where application.Id.Equals(key) + join application in Applications.AsTracking() on token.Application!.Id equals application.Id + where application.Id!.Equals(key) select token).AsAsyncEnumerable(); } - /// - /// 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)) { @@ -346,18 +292,13 @@ namespace OpenIddict.EntityFrameworkCore var key = ConvertIdentifierFromString(identifier); return (from token in Tokens.Include(token => token.Application).Include(token => token.Authorization).AsTracking() - join application in Applications.AsTracking() on token.Application.Id equals application.Id - where application.Id.Equals(key) + join application in Applications.AsTracking() on token.Application!.Id equals application.Id + where application.Id!.Equals(key) select token).AsAsyncEnumerable(); } - /// - /// 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. - /// The 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)) { @@ -372,21 +313,13 @@ namespace OpenIddict.EntityFrameworkCore var key = ConvertIdentifierFromString(identifier); return (from token in Tokens.Include(token => token.Application).Include(token => token.Authorization).AsTracking() - join authorization in Authorizations.AsTracking() on token.Authorization.Id equals authorization.Id - where authorization.Id.Equals(key) + join authorization in Authorizations.AsTracking() on token.Authorization!.Id equals authorization.Id + where authorization.Id!.Equals(key) select token).AsAsyncEnumerable(); } - /// - /// 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)) { @@ -396,21 +329,12 @@ namespace OpenIddict.EntityFrameworkCore var key = ConvertIdentifierFromString(identifier); return await (from token in Tokens.Include(token => token.Application).Include(token => token.Authorization).AsTracking() - 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)) { @@ -422,13 +346,8 @@ namespace OpenIddict.EntityFrameworkCore 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)) { @@ -440,16 +359,8 @@ namespace OpenIddict.EntityFrameworkCore select token).AsAsyncEnumerable(); } - /// - /// 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) { @@ -476,21 +387,10 @@ namespace OpenIddict.EntityFrameworkCore 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 ValueTask GetAsync( - [NotNull] Func, TState, IQueryable> query, - [CanBeNull] TState state, CancellationToken cancellationToken) + Func, TState, IQueryable> query, + TState state, CancellationToken cancellationToken) { if (query == null) { @@ -503,16 +403,8 @@ namespace OpenIddict.EntityFrameworkCore .AsTracking(), 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) { @@ -539,16 +431,8 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -558,16 +442,8 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -577,54 +453,30 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -650,92 +502,51 @@ namespace OpenIddict.EntityFrameworkCore 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 @@ -750,19 +561,12 @@ namespace OpenIddict.EntityFrameworkCore } } - /// - /// 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!) .AsTracking(); if (offset.HasValue) @@ -778,18 +582,10 @@ namespace OpenIddict.EntityFrameworkCore return query.AsAsyncEnumerable(); } - /// - /// 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) { @@ -802,20 +598,16 @@ namespace OpenIddict.EntityFrameworkCore .AsTracking(), state).AsAsyncEnumerable(); } - /// - /// 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 Core 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; - async ValueTask CreateTransactionAsync() + async ValueTask CreateTransactionAsync() { // Note: transactions that specify an explicit isolation level are only supported by // relational providers and trying to use them with a different provider results in @@ -889,17 +681,8 @@ namespace OpenIddict.EntityFrameworkCore } } - /// - /// 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) { @@ -913,7 +696,7 @@ namespace OpenIddict.EntityFrameworkCore // Warning: FindAsync() is deliberately not used to work around a breaking change introduced // in Entity Framework Core 3.x (where a ValueTask instead of a Task is now returned). var application = await Applications.AsQueryable() - .FirstOrDefaultAsync(application => application.Id.Equals(key), cancellationToken); + .FirstOrDefaultAsync(application => application.Id!.Equals(key), cancellationToken); if (application == null) { @@ -941,17 +724,8 @@ namespace OpenIddict.EntityFrameworkCore } } - /// - /// 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) { @@ -965,7 +739,7 @@ namespace OpenIddict.EntityFrameworkCore // Warning: FindAsync() is deliberately not used to work around a breaking change introduced // in Entity Framework Core 3.x (where a ValueTask instead of a Task is now returned). var authorization = await Authorizations.AsQueryable() - .FirstOrDefaultAsync(authorization => authorization.Id.Equals(key), cancellationToken); + .FirstOrDefaultAsync(authorization => authorization.Id!.Equals(key), cancellationToken); if (authorization == null) { @@ -993,17 +767,8 @@ namespace OpenIddict.EntityFrameworkCore } } - /// - /// 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) { @@ -1015,17 +780,8 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -1037,16 +793,8 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -1058,17 +806,9 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -1091,18 +831,8 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -1114,16 +844,8 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -1135,16 +857,8 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -1156,16 +870,8 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -1177,15 +883,8 @@ namespace OpenIddict.EntityFrameworkCore 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) { @@ -1219,7 +918,8 @@ namespace OpenIddict.EntityFrameworkCore /// /// 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)) { @@ -1234,7 +934,7 @@ namespace OpenIddict.EntityFrameworkCore /// /// 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))) {