diff --git a/Directory.Packages.props b/Directory.Packages.props
index ea3acabe..581c71af 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -145,6 +145,7 @@
+
diff --git a/sandbox/OpenIddict.Sandbox.AspNetCore.Client/OpenIddict.Sandbox.AspNetCore.Client.csproj b/sandbox/OpenIddict.Sandbox.AspNetCore.Client/OpenIddict.Sandbox.AspNetCore.Client.csproj
index 04c251da..27545421 100644
--- a/sandbox/OpenIddict.Sandbox.AspNetCore.Client/OpenIddict.Sandbox.AspNetCore.Client.csproj
+++ b/sandbox/OpenIddict.Sandbox.AspNetCore.Client/OpenIddict.Sandbox.AspNetCore.Client.csproj
@@ -12,6 +12,7 @@
+
diff --git a/sandbox/OpenIddict.Sandbox.AspNetCore.Client/Program.cs b/sandbox/OpenIddict.Sandbox.AspNetCore.Client/Program.cs
index 1891abf6..0620da17 100644
--- a/sandbox/OpenIddict.Sandbox.AspNetCore.Client/Program.cs
+++ b/sandbox/OpenIddict.Sandbox.AspNetCore.Client/Program.cs
@@ -14,6 +14,12 @@ var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDbContext(options =>
{
options.UseSqlite($"Filename={Path.Combine(Path.GetTempPath(), "openiddict-sandbox-aspnetcore-client.sqlite3")}");
+
+ // Developers who prefer using Microsoft SQL Server instead of SQLite can remove
+ // the previous line and configure OpenIddict to use the specified database:
+ //
+ // options.UseSqlServer($"Server=(localdb)\\MSSQLLocalDB;Database=openiddict-sandbox-aspnetcore-client;Trusted_Connection=True");
+
options.UseOpenIddict();
});
diff --git a/sandbox/OpenIddict.Sandbox.AspNetCore.Server/OpenIddict.Sandbox.AspNetCore.Server.csproj b/sandbox/OpenIddict.Sandbox.AspNetCore.Server/OpenIddict.Sandbox.AspNetCore.Server.csproj
index 0fa209a0..5ca4a091 100644
--- a/sandbox/OpenIddict.Sandbox.AspNetCore.Server/OpenIddict.Sandbox.AspNetCore.Server.csproj
+++ b/sandbox/OpenIddict.Sandbox.AspNetCore.Server/OpenIddict.Sandbox.AspNetCore.Server.csproj
@@ -15,6 +15,7 @@
+
diff --git a/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Program.cs b/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Program.cs
index 856a71f1..113beae2 100644
--- a/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Program.cs
+++ b/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Program.cs
@@ -20,6 +20,12 @@ builder.Services.AddMvc();
builder.Services.AddDbContext(options =>
{
options.UseSqlite($"Filename={Path.Combine(Path.GetTempPath(), "openiddict-sandbox-aspnetcore-server.sqlite3")}");
+
+ // Developers who prefer using Microsoft SQL Server instead of SQLite can remove
+ // the previous line and configure OpenIddict to use the specified database:
+ //
+ // options.UseSqlServer($"Server=(localdb)\\MSSQLLocalDB;Database=openiddict-sandbox-aspnetcore-server;Trusted_Connection=True");
+
options.UseOpenIddict();
});
diff --git a/src/OpenIddict.Abstractions/Primitives/OpenIddictSerializer.cs b/src/OpenIddict.Abstractions/Primitives/OpenIddictSerializer.cs
index ca7e8302..f5b7ab1b 100644
--- a/src/OpenIddict.Abstractions/Primitives/OpenIddictSerializer.cs
+++ b/src/OpenIddict.Abstractions/Primitives/OpenIddictSerializer.cs
@@ -13,6 +13,8 @@ namespace OpenIddict.Abstractions;
///
[EditorBrowsable(EditorBrowsableState.Never)]
[JsonSerializable(typeof(bool))]
+[JsonSerializable(typeof(IDictionary))]
+[JsonSerializable(typeof(IDictionary))]
[JsonSerializable(typeof(JsonArray))]
[JsonSerializable(typeof(JsonElement))]
[JsonSerializable(typeof(JsonNode))]
diff --git a/src/OpenIddict.EntityFramework.Models/OpenIddictEntityFrameworkApplication.cs b/src/OpenIddict.EntityFramework.Models/OpenIddictEntityFrameworkApplication.cs
index 1b104811..cfa52908 100644
--- a/src/OpenIddict.EntityFramework.Models/OpenIddictEntityFrameworkApplication.cs
+++ b/src/OpenIddict.EntityFramework.Models/OpenIddictEntityFrameworkApplication.cs
@@ -27,116 +27,112 @@ public class OpenIddictEntityFrameworkApplication
where TToken : class
{
///
- /// Gets or sets the application type associated with the current application.
+ /// Gets or sets the application type of the application.
///
public virtual string? ApplicationType { get; set; }
///
- /// Gets the list of the authorizations associated with this application.
+ /// Gets the list of the authorizations associated with the application.
///
public virtual ICollection Authorizations { get; } = new HashSet();
///
- /// Gets or sets the client identifier associated with the current application.
+ /// Gets or sets the client identifier of the application.
///
public virtual string? ClientId { get; set; }
///
- /// Gets or sets the client secret associated with the current application.
- /// Note: depending on the application manager used to create this instance,
- /// this property may be hashed or encrypted for security reasons.
+ /// Gets or sets the client secret of the application.
///
///
+ ///
+ /// Note: depending on the application manager used to create this instance,
+ /// this property may be hashed or encrypted for security reasons.
+ ///
+ ///
/// Note: client authentication based on shared secrets is not recommended and should
/// only be used for backward compatibility with legacy applications that only support
/// client secrets. When possible, consider using public/private key pairs or TLS client
/// certificates instead, as these client authentication methods are significantly safer.
+ ///
///
public virtual string? ClientSecret { get; set; }
///
- /// Gets or sets the client type associated with the current application.
+ /// Gets or sets the client type of the application.
///
public virtual string? ClientType { get; set; }
///
- /// Gets or sets the concurrency token.
+ /// Gets or sets the concurrency token of the application.
///
public virtual string? ConcurrencyToken { get; set; } = Guid.NewGuid().ToString();
///
- /// Gets or sets the consent type associated with the current application.
+ /// Gets or sets the consent type of the application.
///
public virtual string? ConsentType { get; set; }
///
- /// Gets or sets the display name associated with the current application.
+ /// Gets or sets the display name of the application.
///
public virtual string? DisplayName { get; set; }
///
- /// Gets or sets the localized display names
- /// associated with the current application,
- /// serialized as a JSON object.
+ /// Gets or sets the localized display names of the application, serialized as a JSON object.
///
[StringSyntax(StringSyntaxAttribute.Json)]
public virtual string? DisplayNames { get; set; }
///
- /// Gets or sets the unique identifier associated with the current application.
+ /// Gets or sets the unique identifier of the application.
///
public virtual TKey? Id { get; set; }
///
- /// Gets or sets the JSON Web Key Set associated with
- /// the application, serialized as a JSON object.
+ /// Gets or sets the JSON Web Key Set of the application, serialized as a JSON object.
///
[StringSyntax(StringSyntaxAttribute.Json)]
public virtual string? JsonWebKeySet { get; set; }
///
- /// Gets or sets the permissions associated with the
- /// current application, serialized as a JSON array.
+ /// Gets or sets the permissions of the application, serialized as a JSON array.
///
[StringSyntax(StringSyntaxAttribute.Json)]
public virtual string? Permissions { get; set; }
///
- /// Gets or sets the post-logout redirect URIs associated with
- /// the current application, serialized as a JSON array.
+ /// Gets or sets the post-logout redirect URIs of the application, serialized as a JSON array.
///
[StringSyntax(StringSyntaxAttribute.Json)]
public virtual string? PostLogoutRedirectUris { get; set; }
///
- /// Gets or sets the additional properties serialized as a JSON object,
- /// or if no bag was associated with the current application.
+ /// Gets or sets the additional properties of the application, serialized as a JSON object.
///
[StringSyntax(StringSyntaxAttribute.Json)]
public virtual string? Properties { get; set; }
///
- /// Gets or sets the redirect URIs associated with the
- /// current application, serialized as a JSON array.
+ /// Gets or sets the redirect URIs of the application, serialized as a JSON array.
///
[StringSyntax(StringSyntaxAttribute.Json)]
public virtual string? RedirectUris { get; set; }
///
- /// Gets or sets the requirements associated with the
- /// current application, serialized as a JSON array.
+ /// Gets or sets the requirements of the application, serialized as a JSON array.
///
[StringSyntax(StringSyntaxAttribute.Json)]
public virtual string? Requirements { get; set; }
///
- /// Gets or sets the settings serialized as a JSON object.
+ /// Gets or sets the settings of the application, serialized as a JSON object.
///
[StringSyntax(StringSyntaxAttribute.Json)]
public virtual string? Settings { get; set; }
///
- /// Gets the list of the tokens associated with this application.
+ /// Gets the list of the tokens associated with the application.
///
public virtual ICollection Tokens { get; } = new HashSet();
}
diff --git a/src/OpenIddict.EntityFramework.Models/OpenIddictEntityFrameworkAuthorization.cs b/src/OpenIddict.EntityFramework.Models/OpenIddictEntityFrameworkAuthorization.cs
index b6b74bcd..382248ae 100644
--- a/src/OpenIddict.EntityFramework.Models/OpenIddictEntityFrameworkAuthorization.cs
+++ b/src/OpenIddict.EntityFramework.Models/OpenIddictEntityFrameworkAuthorization.cs
@@ -27,56 +27,54 @@ public class OpenIddictEntityFrameworkAuthorization
where TToken : class
{
///
- /// Gets or sets the application associated with the current authorization.
+ /// Gets or sets the application associated with the authorization.
///
public virtual TApplication? Application { get; set; }
///
- /// Gets or sets the concurrency token.
+ /// Gets or sets the concurrency token of the authorization.
///
public virtual string? ConcurrencyToken { get; set; } = Guid.NewGuid().ToString();
///
- /// Gets or sets the UTC creation date of the current authorization.
+ /// Gets or sets the UTC creation date of the authorization.
///
public virtual DateTime? CreationDate { get; set; }
///
- /// Gets or sets the unique identifier associated with the current authorization.
+ /// Gets or sets the unique identifier of the authorization.
///
public virtual TKey? Id { get; set; }
///
- /// Gets or sets the additional properties serialized as a JSON object,
- /// or if no bag was associated with the current authorization.
+ /// Gets or sets the additional properties of the authorization, serialized as a JSON object.
///
[StringSyntax(StringSyntaxAttribute.Json)]
public virtual string? Properties { get; set; }
///
- /// Gets or sets the scopes associated with the current
- /// authorization, serialized as a JSON array.
+ /// Gets or sets the scopes of the authorization, serialized as a JSON array.
///
[StringSyntax(StringSyntaxAttribute.Json)]
public virtual string? Scopes { get; set; }
///
- /// Gets or sets the status of the current authorization.
+ /// Gets or sets the status of the authorization.
///
public virtual string? Status { get; set; }
///
- /// Gets or sets the subject associated with the current authorization.
+ /// Gets or sets the subject of the authorization.
///
public virtual string? Subject { get; set; }
///
- /// Gets the list of tokens associated with the current authorization.
+ /// Gets the list of tokens associated with the authorization.
///
public virtual ICollection Tokens { get; } = new HashSet();
///
- /// Gets or sets the type of the current authorization.
+ /// Gets or sets the type of the authorization.
///
public virtual string? Type { get; set; }
}
diff --git a/src/OpenIddict.EntityFramework.Models/OpenIddictEntityFrameworkResource.cs b/src/OpenIddict.EntityFramework.Models/OpenIddictEntityFrameworkResource.cs
index d0989df0..c67e750c 100644
--- a/src/OpenIddict.EntityFramework.Models/OpenIddictEntityFrameworkResource.cs
+++ b/src/OpenIddict.EntityFramework.Models/OpenIddictEntityFrameworkResource.cs
@@ -24,48 +24,44 @@ public class OpenIddictEntityFrameworkResource : OpenIddictEntityFrameworkResour
public class OpenIddictEntityFrameworkResource where TKey : notnull, IEquatable
{
///
- /// Gets or sets the concurrency token.
+ /// Gets or sets the concurrency token of the resource.
///
public virtual string? ConcurrencyToken { get; set; } = Guid.NewGuid().ToString();
///
- /// Gets or sets the public description associated with the current resource.
+ /// Gets or sets the public description of the resource.
///
public virtual string? Description { get; set; }
///
- /// Gets or sets the localized public descriptions associated
- /// with the current resource, serialized as a JSON object.
+ /// Gets or sets the localized public descriptions of the resource, serialized as a JSON object.
///
[StringSyntax(StringSyntaxAttribute.Json)]
public virtual string? Descriptions { get; set; }
///
- /// Gets or sets the display name associated with the current resource.
+ /// Gets or sets the display name of the resource.
///
public virtual string? DisplayName { get; set; }
///
- /// Gets or sets the localized display names
- /// associated with the current application,
- /// serialized as a JSON object.
+ /// Gets or sets the localized display names of the resource, serialized as a JSON object.
///
[StringSyntax(StringSyntaxAttribute.Json)]
public virtual string? DisplayNames { get; set; }
///
- /// Gets or sets the unique identifier associated with the current resource.
+ /// Gets or sets the unique identifier of the resource.
///
public virtual TKey? Id { get; set; }
///
- /// Gets or sets the unique name associated with the current resource.
+ /// Gets or sets the unique name of the resource.
///
public virtual string? Name { get; set; }
///
- /// Gets or sets the additional properties serialized as a JSON object,
- /// or if no bag was associated with the current resource.
+ /// Gets or sets the additional properties of the resource, serialized as a JSON object.
///
[StringSyntax(StringSyntaxAttribute.Json)]
public virtual string? Properties { get; set; }
diff --git a/src/OpenIddict.EntityFramework.Models/OpenIddictEntityFrameworkScope.cs b/src/OpenIddict.EntityFramework.Models/OpenIddictEntityFrameworkScope.cs
index 14b09fff..183304b6 100644
--- a/src/OpenIddict.EntityFramework.Models/OpenIddictEntityFrameworkScope.cs
+++ b/src/OpenIddict.EntityFramework.Models/OpenIddictEntityFrameworkScope.cs
@@ -24,55 +24,50 @@ public class OpenIddictEntityFrameworkScope : OpenIddictEntityFrameworkScope where TKey : notnull, IEquatable
{
///
- /// Gets or sets the concurrency token.
+ /// Gets or sets the concurrency token of the scope.
///
public virtual string? ConcurrencyToken { get; set; } = Guid.NewGuid().ToString();
///
- /// Gets or sets the public description associated with the current scope.
+ /// Gets or sets the public description of the scope.
///
public virtual string? Description { get; set; }
///
- /// Gets or sets the localized public descriptions associated
- /// with the current scope, serialized as a JSON object.
+ /// Gets or sets the localized public descriptions of the scope, serialized as a JSON object.
///
[StringSyntax(StringSyntaxAttribute.Json)]
public virtual string? Descriptions { get; set; }
///
- /// Gets or sets the display name associated with the current scope.
+ /// Gets or sets the display name of the scope.
///
public virtual string? DisplayName { get; set; }
///
- /// Gets or sets the localized display names
- /// associated with the current application,
- /// serialized as a JSON object.
+ /// Gets or sets the localized display names of the scope, serialized as a JSON object.
///
[StringSyntax(StringSyntaxAttribute.Json)]
public virtual string? DisplayNames { get; set; }
///
- /// Gets or sets the unique identifier associated with the current scope.
+ /// Gets or sets the unique identifier of the scope.
///
public virtual TKey? Id { get; set; }
///
- /// Gets or sets the unique name associated with the current scope.
+ /// Gets or sets the unique name of the scope.
///
public virtual string? Name { get; set; }
///
- /// Gets or sets the additional properties serialized as a JSON object,
- /// or if no bag was associated with the current scope.
+ /// Gets or sets the additional properties of the scope, serialized as a JSON object.
///
[StringSyntax(StringSyntaxAttribute.Json)]
public virtual string? Properties { get; set; }
///
- /// Gets or sets the resources associated with the
- /// current scope, serialized as a JSON array.
+ /// Gets or sets the resources of the scope, serialized as a JSON array.
///
[StringSyntax(StringSyntaxAttribute.Json)]
public virtual string? Resources { get; set; }
diff --git a/src/OpenIddict.EntityFramework.Models/OpenIddictEntityFrameworkToken.cs b/src/OpenIddict.EntityFramework.Models/OpenIddictEntityFrameworkToken.cs
index 087a454d..9aa210ca 100644
--- a/src/OpenIddict.EntityFramework.Models/OpenIddictEntityFrameworkToken.cs
+++ b/src/OpenIddict.EntityFramework.Models/OpenIddictEntityFrameworkToken.cs
@@ -27,74 +27,76 @@ public class OpenIddictEntityFrameworkToken
where TAuthorization : class
{
///
- /// Gets or sets the application associated with the current token.
+ /// Gets or sets the application associated with the token.
///
public virtual TApplication? Application { get; set; }
///
- /// Gets or sets the authorization associated with the current token.
+ /// Gets or sets the authorization associated with the token.
///
public virtual TAuthorization? Authorization { get; set; }
///
- /// Gets or sets the concurrency token.
+ /// Gets or sets the concurrency token of the token.
///
public virtual string? ConcurrencyToken { get; set; } = Guid.NewGuid().ToString();
///
- /// Gets or sets the UTC creation date of the current token.
+ /// Gets or sets the UTC creation date of the token.
///
public virtual DateTime? CreationDate { get; set; }
///
- /// Gets or sets the UTC expiration date of the current token.
+ /// Gets or sets the UTC expiration date of the token.
///
public virtual DateTime? ExpirationDate { get; set; }
///
- /// Gets or sets the unique identifier associated with the current token.
+ /// Gets or sets the unique identifier of the token.
///
public virtual TKey? Id { get; set; }
///
- /// Gets or sets the payload of the current token, if applicable.
- /// Note: this property is only used for reference tokens
- /// and may be encrypted for security reasons.
+ /// Gets or sets the payload of the token.
///
+ ///
+ /// Note: this property is only used for reference tokens
+ /// and may be hashed or encrypted for security reasons.
+ ///
public virtual string? Payload { get; set; }
///
- /// Gets or sets the additional properties serialized as a JSON object,
- /// or if no bag was associated with the current token.
+ /// Gets or sets the additional properties of the token, serialized as a JSON object.
///
[StringSyntax(StringSyntaxAttribute.Json)]
public virtual string? Properties { get; set; }
///
- /// Gets or sets the UTC redemption date of the current token.
+ /// Gets or sets the UTC redemption date of the token.
///
public virtual DateTime? RedemptionDate { get; set; }
///
- /// Gets or sets the reference identifier associated
- /// with the current token, if applicable.
+ /// Gets or sets the reference identifier associated with the token.
+ ///
+ ///
/// Note: this property is only used for reference tokens
/// and may be hashed or encrypted for security reasons.
- ///
+ ///
public virtual string? ReferenceId { get; set; }
///
- /// Gets or sets the status of the current token.
+ /// Gets or sets the status of the token.
///
public virtual string? Status { get; set; }
///
- /// Gets or sets the subject associated with the current token.
+ /// Gets or sets the subject associated with the token.
///
public virtual string? Subject { get; set; }
///
- /// Gets or sets the type of the current token.
+ /// Gets or sets the type of the token.
///
public virtual string? Type { get; set; }
}
diff --git a/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkApplicationConfiguration.cs b/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkApplicationConfiguration.cs
index 0edc45c6..8f8acd63 100644
--- a/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkApplicationConfiguration.cs
+++ b/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkApplicationConfiguration.cs
@@ -5,8 +5,6 @@
*/
using System.ComponentModel;
-using System.ComponentModel.DataAnnotations.Schema;
-using System.Data.Entity.Infrastructure.Annotations;
using System.Data.Entity.ModelConfiguration;
using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
@@ -38,17 +36,22 @@ public sealed class OpenIddictEntityFrameworkApplicationConfiguration<
// Entity Framework would throw an exception due to the TKey generic parameter
// being non-nullable when using value types like short, int, long or Guid.
- HasKey(static application => application.Id);
+ HasMany(static application => application.Authorizations)
+ .WithOptional(static authorization => authorization.Application!)
+ .Map(static association =>
+ {
+ association.MapKey(nameof(OpenIddictEntityFrameworkAuthorization.Application) +
+ nameof(OpenIddictEntityFrameworkApplication.Id));
+ });
Property(static application => application.ApplicationType)
.HasMaxLength(50);
Property(static application => application.ClientId)
- .HasMaxLength(100)
- .HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute
- {
- IsUnique = true
- }));
+ .HasMaxLength(100);
+
+ HasIndex(static application => application.ClientId)
+ .IsUnique();
Property(static application => application.ClientType)
.HasMaxLength(50);
@@ -60,6 +63,8 @@ public sealed class OpenIddictEntityFrameworkApplicationConfiguration<
Property(static application => application.ConsentType)
.HasMaxLength(50);
+ HasKey(static application => application.Id);
+
if (typeof(TKey) == typeof(string))
{
var parameter = Expression.Parameter(typeof(TApplication), "application");
@@ -70,14 +75,6 @@ public sealed class OpenIddictEntityFrameworkApplicationConfiguration<
Property(lambda).HasMaxLength(100);
}
- HasMany(static application => application.Authorizations)
- .WithOptional(static authorization => authorization.Application!)
- .Map(static association =>
- {
- association.MapKey(nameof(OpenIddictEntityFrameworkAuthorization.Application) +
- nameof(OpenIddictEntityFrameworkApplication.Id));
- });
-
HasMany(static application => application.Tokens)
.WithOptional(static token => token.Application!)
.Map(static association =>
diff --git a/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkAuthorizationConfiguration.cs b/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkAuthorizationConfiguration.cs
index 2daf0bae..fcdb5cb9 100644
--- a/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkAuthorizationConfiguration.cs
+++ b/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkAuthorizationConfiguration.cs
@@ -36,12 +36,12 @@ public sealed class OpenIddictEntityFrameworkAuthorizationConfiguration<
// Entity Framework would throw an exception due to the TKey generic parameter
// being non-nullable when using value types like short, int, long or Guid.
- HasKey(static authorization => authorization.Id);
-
Property(static authorization => authorization.ConcurrencyToken)
.HasMaxLength(50)
.IsConcurrencyToken();
+ HasKey(static authorization => authorization.Id);
+
if (typeof(TKey) == typeof(string))
{
var parameter = Expression.Parameter(typeof(TAuthorization), "authorization");
@@ -58,15 +58,15 @@ public sealed class OpenIddictEntityFrameworkAuthorizationConfiguration<
Property(static authorization => authorization.Subject)
.HasMaxLength(400);
- Property(static authorization => authorization.Type)
- .HasMaxLength(50);
-
HasMany(static authorization => authorization.Tokens)
.WithOptional(static token => token.Authorization!)
.Map(static association => association.MapKey(nameof(OpenIddictEntityFrameworkToken.Authorization) +
nameof(OpenIddictEntityFrameworkAuthorization.Id)))
.WillCascadeOnDelete();
+ Property(static authorization => authorization.Type)
+ .HasMaxLength(50);
+
ToTable("OpenIddictAuthorizations");
}
}
diff --git a/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkResourceConfiguration.cs b/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkResourceConfiguration.cs
index 52c92596..14c7c5fc 100644
--- a/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkResourceConfiguration.cs
+++ b/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkResourceConfiguration.cs
@@ -5,8 +5,6 @@
*/
using System.ComponentModel;
-using System.ComponentModel.DataAnnotations.Schema;
-using System.Data.Entity.Infrastructure.Annotations;
using System.Data.Entity.ModelConfiguration;
using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
@@ -32,12 +30,12 @@ public sealed class OpenIddictEntityFrameworkResourceConfiguration<
// Entity Framework would throw an exception due to the TKey generic parameter
// being non-nullable when using value types like short, int, long or Guid.
- HasKey(static resource => resource.Id);
-
Property(static resource => resource.ConcurrencyToken)
.HasMaxLength(50)
.IsConcurrencyToken();
+ HasKey(static resource => resource.Id);
+
if (typeof(TKey) == typeof(string))
{
var parameter = Expression.Parameter(typeof(TResource), "resource");
@@ -49,11 +47,10 @@ public sealed class OpenIddictEntityFrameworkResourceConfiguration<
}
Property(static resource => resource.Name)
- .HasMaxLength(200)
- .HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute
- {
- IsUnique = true
- }));
+ .HasMaxLength(200);
+
+ HasIndex(static resource => resource.Name)
+ .IsUnique();
ToTable("OpenIddictResources");
}
diff --git a/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkScopeConfiguration.cs b/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkScopeConfiguration.cs
index 36093621..67a47459 100644
--- a/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkScopeConfiguration.cs
+++ b/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkScopeConfiguration.cs
@@ -5,8 +5,6 @@
*/
using System.ComponentModel;
-using System.ComponentModel.DataAnnotations.Schema;
-using System.Data.Entity.Infrastructure.Annotations;
using System.Data.Entity.ModelConfiguration;
using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
@@ -32,12 +30,12 @@ public sealed class OpenIddictEntityFrameworkScopeConfiguration<
// Entity Framework would throw an exception due to the TKey generic parameter
// being non-nullable when using value types like short, int, long or Guid.
- HasKey(static scope => scope.Id);
-
Property(static scope => scope.ConcurrencyToken)
.HasMaxLength(50)
.IsConcurrencyToken();
+ HasKey(static scope => scope.Id);
+
if (typeof(TKey) == typeof(string))
{
var parameter = Expression.Parameter(typeof(TScope), "scope");
@@ -49,11 +47,10 @@ public sealed class OpenIddictEntityFrameworkScopeConfiguration<
}
Property(static scope => scope.Name)
- .HasMaxLength(200)
- .HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute
- {
- IsUnique = true
- }));
+ .HasMaxLength(200);
+
+ HasIndex(static scope => scope.Name)
+ .IsUnique();
ToTable("OpenIddictScopes");
}
diff --git a/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkTokenConfiguration.cs b/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkTokenConfiguration.cs
index 93ec7b0c..d2b0d735 100644
--- a/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkTokenConfiguration.cs
+++ b/src/OpenIddict.EntityFramework/Configurations/OpenIddictEntityFrameworkTokenConfiguration.cs
@@ -5,8 +5,6 @@
*/
using System.ComponentModel;
-using System.ComponentModel.DataAnnotations.Schema;
-using System.Data.Entity.Infrastructure.Annotations;
using System.Data.Entity.ModelConfiguration;
using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
@@ -38,12 +36,12 @@ public sealed class OpenIddictEntityFrameworkTokenConfiguration<
// Entity Framework would throw an exception due to the TKey generic parameter
// being non-nullable when using value types like short, int, long or Guid.
- HasKey(static token => token.Id);
-
Property(static token => token.ConcurrencyToken)
.HasMaxLength(50)
.IsConcurrencyToken();
+ HasKey(static token => token.Id);
+
if (typeof(TKey) == typeof(string))
{
var parameter = Expression.Parameter(typeof(TToken), "token");
@@ -54,12 +52,13 @@ public sealed class OpenIddictEntityFrameworkTokenConfiguration<
Property(lambda).HasMaxLength(100);
}
+ Property(static token => token.ReferenceId)
+ .HasMaxLength(100);
+
// Warning: the index on the ReferenceId property MUST NOT be declared as
// a unique index, as Entity Framework 6.x doesn't support creating indexes
// with null-friendly WHERE conditions, unlike Entity Framework Core.
- Property(static token => token.ReferenceId)
- .HasMaxLength(100)
- .HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute()));
+ HasIndex(static token => token.ReferenceId);
Property(static token => token.Status)
.HasMaxLength(50);
diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkAuthorizationStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkAuthorizationStore.cs
index 3ae99726..87716235 100644
--- a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkAuthorizationStore.cs
+++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkAuthorizationStore.cs
@@ -309,12 +309,7 @@ public class OpenIddictEntityFrameworkAuthorizationStore<
{
ArgumentNullException.ThrowIfNull(authorization);
- if (authorization.CreationDate is null)
- {
- return new(result: null);
- }
-
- return new(DateTime.SpecifyKind(authorization.CreationDate.Value, DateTimeKind.Utc));
+ return new(authorization.CreationDate is DateTime date ? DateTime.SpecifyKind(date, DateTimeKind.Utc) : null);
}
///
diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkTokenStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkTokenStore.cs
index 40136706..b8c83f39 100644
--- a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkTokenStore.cs
+++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkTokenStore.cs
@@ -353,12 +353,7 @@ public class OpenIddictEntityFrameworkTokenStore<
{
ArgumentNullException.ThrowIfNull(token);
- if (token.CreationDate is null)
- {
- return new(result: null);
- }
-
- return new(DateTime.SpecifyKind(token.CreationDate.Value, DateTimeKind.Utc));
+ return new(token.CreationDate is DateTime date ? DateTime.SpecifyKind(date, DateTimeKind.Utc) : null);
}
///
@@ -366,12 +361,7 @@ public class OpenIddictEntityFrameworkTokenStore<
{
ArgumentNullException.ThrowIfNull(token);
- if (token.ExpirationDate is null)
- {
- return new(result: null);
- }
-
- return new(DateTime.SpecifyKind(token.ExpirationDate.Value, DateTimeKind.Utc));
+ return new(token.ExpirationDate is DateTime date ? DateTime.SpecifyKind(date, DateTimeKind.Utc) : null);
}
///
@@ -427,12 +417,7 @@ public class OpenIddictEntityFrameworkTokenStore<
{
ArgumentNullException.ThrowIfNull(token);
- if (token.RedemptionDate is null)
- {
- return new(result: null);
- }
-
- return new(DateTime.SpecifyKind(token.RedemptionDate.Value, DateTimeKind.Utc));
+ return new(token.RedemptionDate is DateTime date ? DateTime.SpecifyKind(date, DateTimeKind.Utc) : null);
}
///
diff --git a/src/OpenIddict.EntityFrameworkCore.Models/OpenIddict.EntityFrameworkCore.Models.csproj b/src/OpenIddict.EntityFrameworkCore.Models/OpenIddict.EntityFrameworkCore.Models.csproj
index 24bc9f22..1400a04d 100644
--- a/src/OpenIddict.EntityFrameworkCore.Models/OpenIddict.EntityFrameworkCore.Models.csproj
+++ b/src/OpenIddict.EntityFrameworkCore.Models/OpenIddict.EntityFrameworkCore.Models.csproj
@@ -10,4 +10,8 @@
$(PackageTags);entityframeworkcore;models
+
+
+
+
diff --git a/src/OpenIddict.EntityFrameworkCore.Models/OpenIddictEntityFrameworkCoreApplication.cs b/src/OpenIddict.EntityFrameworkCore.Models/OpenIddictEntityFrameworkCoreApplication.cs
index eb7968b6..5c436636 100644
--- a/src/OpenIddict.EntityFrameworkCore.Models/OpenIddictEntityFrameworkCoreApplication.cs
+++ b/src/OpenIddict.EntityFrameworkCore.Models/OpenIddictEntityFrameworkCoreApplication.cs
@@ -5,7 +5,8 @@
*/
using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
+using System.Text.Json;
+using Microsoft.IdentityModel.Tokens;
namespace OpenIddict.EntityFrameworkCore.Models;
@@ -21,9 +22,7 @@ public class OpenIddictEntityFrameworkCoreApplication : OpenIddictEntityFramewor
/// Represents an OpenIddict application.
///
public class OpenIddictEntityFrameworkCoreApplication : OpenIddictEntityFrameworkCoreApplication, OpenIddictEntityFrameworkCoreToken>
- where TKey : notnull, IEquatable
-{
-}
+ where TKey : notnull, IEquatable;
///
/// Represents an OpenIddict application.
@@ -35,116 +34,104 @@ public class OpenIddictEntityFrameworkCoreApplication
- /// Gets or sets the application type associated with the current application.
+ /// Gets or sets the application type of the application.
///
public virtual string? ApplicationType { get; set; }
///
- /// Gets the list of the authorizations associated with this application.
+ /// Gets the list of the authorizations associated with the application.
///
public virtual ICollection Authorizations { get; } = new HashSet();
///
- /// Gets or sets the client identifier associated with the current application.
+ /// Gets or sets the client identifier of the application.
///
public virtual string? ClientId { get; set; }
///
- /// Gets or sets the client secret associated with the current application.
- /// Note: depending on the application manager used to create this instance,
- /// this property may be hashed or encrypted for security reasons.
+ /// Gets or sets the client secret of the application.
///
///
+ ///
+ /// Note: depending on the application manager used to create this instance,
+ /// this property may be hashed or encrypted for security reasons.
+ ///
+ ///
/// Note: client authentication based on shared secrets is not recommended and should
/// only be used for backward compatibility with legacy applications that only support
/// client secrets. When possible, consider using public/private key pairs or TLS client
/// certificates instead, as these client authentication methods are significantly safer.
+ ///
///
public virtual string? ClientSecret { get; set; }
///
- /// Gets or sets the client type associated with the current application.
+ /// Gets or sets the client type of the application.
///
public virtual string? ClientType { get; set; }
///
- /// Gets or sets the concurrency token.
+ /// Gets or sets the concurrency token of the application.
///
public virtual string? ConcurrencyToken { get; set; } = Guid.NewGuid().ToString();
///
- /// Gets or sets the consent type associated with the current application.
+ /// Gets or sets the consent type of the application.
///
public virtual string? ConsentType { get; set; }
///
- /// Gets or sets the display name associated with the current application.
+ /// Gets or sets the display name of the application.
///
public virtual string? DisplayName { get; set; }
///
- /// Gets or sets the localized display names
- /// associated with the current application,
- /// serialized as a JSON object.
+ /// Gets or sets the localized display names of the application.
///
- [StringSyntax(StringSyntaxAttribute.Json)]
- public virtual string? DisplayNames { get; set; }
+ public virtual IDictionary? DisplayNames { get; set; }
///
- /// Gets or sets the unique identifier associated with the current application.
+ /// Gets or sets the unique identifier of the application.
///
public virtual TKey? Id { get; set; }
///
- /// Gets or sets the JSON Web Key Set associated with
- /// the application, serialized as a JSON object.
+ /// Gets or sets the JSON Web Key Set of the application.
///
- [StringSyntax(StringSyntaxAttribute.Json)]
- public virtual string? JsonWebKeySet { get; set; }
+ public virtual JsonWebKeySet? JsonWebKeySet { get; set; }
///
- /// Gets or sets the permissions associated with the
- /// current application, serialized as a JSON array.
+ /// Gets or sets the permissions of the application.
///
- [StringSyntax(StringSyntaxAttribute.Json)]
- public virtual string? Permissions { get; set; }
+ public virtual string[]? Permissions { get; set; }
///
- /// Gets or sets the post-logout redirect URIs associated with
- /// the current application, serialized as a JSON array.
+ /// Gets or sets the post-logout redirect URIs of the application.
///
- [StringSyntax(StringSyntaxAttribute.Json)]
- public virtual string? PostLogoutRedirectUris { get; set; }
+ public virtual string[]? PostLogoutRedirectUris { get; set; }
///
- /// Gets or sets the additional properties serialized as a JSON object,
- /// or if no bag was associated with the current application.
+ /// Gets or sets the additional properties of the application.
///
- [StringSyntax(StringSyntaxAttribute.Json)]
- public virtual string? Properties { get; set; }
+ public virtual IDictionary? Properties { get; set; }
///
- /// Gets or sets the redirect URIs associated with the
- /// current application, serialized as a JSON array.
+ /// Gets or sets the redirect URIs of the application.
///
- [StringSyntax(StringSyntaxAttribute.Json)]
- public virtual string? RedirectUris { get; set; }
+ public virtual string[]? RedirectUris { get; set; }
///
- /// Gets or sets the requirements associated with the
- /// current application, serialized as a JSON array.
+ /// Gets or sets the requirements of the application.
///
- [StringSyntax(StringSyntaxAttribute.Json)]
- public virtual string? Requirements { get; set; }
+ public virtual string[]? Requirements { get; set; }
///
- /// Gets or sets the settings serialized as a JSON object.
+ /// Gets or sets the settings of the application.
///
- [StringSyntax(StringSyntaxAttribute.Json)]
- public virtual string? Settings { get; set; }
+ public virtual IDictionary? Settings { get; set; }
///
- /// Gets the list of the tokens associated with this application.
+ /// Gets the list of the tokens associated with the application.
///
public virtual ICollection Tokens { get; } = new HashSet();
}
diff --git a/src/OpenIddict.EntityFrameworkCore.Models/OpenIddictEntityFrameworkCoreAuthorization.cs b/src/OpenIddict.EntityFrameworkCore.Models/OpenIddictEntityFrameworkCoreAuthorization.cs
index ee5477a8..f6d883b9 100644
--- a/src/OpenIddict.EntityFrameworkCore.Models/OpenIddictEntityFrameworkCoreAuthorization.cs
+++ b/src/OpenIddict.EntityFrameworkCore.Models/OpenIddictEntityFrameworkCoreAuthorization.cs
@@ -5,7 +5,7 @@
*/
using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
+using System.Text.Json;
namespace OpenIddict.EntityFrameworkCore.Models;
@@ -21,9 +21,7 @@ public class OpenIddictEntityFrameworkCoreAuthorization : OpenIddictEntityFramew
/// Represents an OpenIddict authorization.
///
public class OpenIddictEntityFrameworkCoreAuthorization : OpenIddictEntityFrameworkCoreAuthorization, OpenIddictEntityFrameworkCoreToken>
- where TKey : notnull, IEquatable
-{
-}
+ where TKey : notnull, IEquatable;
///
/// Represents an OpenIddict authorization.
@@ -35,55 +33,52 @@ public class OpenIddictEntityFrameworkCoreAuthorization
- /// Gets or sets the application associated with the current authorization.
+ /// Gets or sets the application of the authorization.
///
public virtual TApplication? Application { get; set; }
///
- /// Gets or sets the concurrency token.
+ /// Gets or sets the concurrency token of the authorization.
///
public virtual string? ConcurrencyToken { get; set; } = Guid.NewGuid().ToString();
///
- /// Gets or sets the UTC creation date of the current authorization.
+ /// Gets or sets the UTC creation date of the authorization.
///
public virtual DateTime? CreationDate { get; set; }
///
- /// Gets or sets the unique identifier associated with the current authorization.
+ /// Gets or sets the unique identifier of the authorization.
///
public virtual TKey? Id { get; set; }
///
- /// Gets or sets the additional properties serialized as a JSON object,
- /// or if no bag was associated with the current authorization.
+ /// Gets or sets the additional properties of the authorization.
///
- [StringSyntax(StringSyntaxAttribute.Json)]
- public virtual string? Properties { get; set; }
+ public virtual IDictionary? Properties { get; set; }
///
- /// Gets or sets the scopes associated with the current
- /// authorization, serialized as a JSON array.
+ /// Gets or sets the scopes of the authorization.
///
- public virtual string? Scopes { get; set; }
+ public virtual string[]? Scopes { get; set; }
///
- /// Gets or sets the status of the current authorization.
+ /// Gets or sets the status of the authorization.
///
public virtual string? Status { get; set; }
///
- /// Gets or sets the subject associated with the current authorization.
+ /// Gets or sets the subject of the authorization.
///
public virtual string? Subject { get; set; }
///
- /// Gets the list of tokens associated with the current authorization.
+ /// Gets the list of tokens associated with the authorization.
///
public virtual ICollection Tokens { get; } = new HashSet();
///
- /// Gets or sets the type of the current authorization.
+ /// Gets or sets the type of the authorization.
///
public virtual string? Type { get; set; }
}
diff --git a/src/OpenIddict.EntityFrameworkCore.Models/OpenIddictEntityFrameworkCoreResource.cs b/src/OpenIddict.EntityFrameworkCore.Models/OpenIddictEntityFrameworkCoreResource.cs
index 2b7603a4..9a0b4acb 100644
--- a/src/OpenIddict.EntityFrameworkCore.Models/OpenIddictEntityFrameworkCoreResource.cs
+++ b/src/OpenIddict.EntityFrameworkCore.Models/OpenIddictEntityFrameworkCoreResource.cs
@@ -5,7 +5,7 @@
*/
using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
+using System.Text.Json;
namespace OpenIddict.EntityFrameworkCore.Models;
@@ -24,49 +24,42 @@ public class OpenIddictEntityFrameworkCoreResource : OpenIddictEntityFrameworkCo
public class OpenIddictEntityFrameworkCoreResource where TKey : notnull, IEquatable
{
///
- /// Gets or sets the concurrency token.
+ /// Gets or sets the concurrency token of the resource.
///
public virtual string? ConcurrencyToken { get; set; } = Guid.NewGuid().ToString();
///
- /// Gets or sets the public description associated with the current resource.
+ /// Gets or sets the public description of the resource.
///
public virtual string? Description { get; set; }
///
- /// Gets or sets the localized public descriptions associated
- /// with the current resource, serialized as a JSON object.
+ /// Gets or sets the localized public descriptions of the resource.
///
- [StringSyntax(StringSyntaxAttribute.Json)]
- public virtual string? Descriptions { get; set; }
+ public virtual IDictionary? Descriptions { get; set; }
///
- /// Gets or sets the display name associated with the current resource.
+ /// Gets or sets the display name of the resource.
///
public virtual string? DisplayName { get; set; }
///
- /// Gets or sets the localized display names
- /// associated with the current application,
- /// serialized as a JSON object.
+ /// Gets or sets the localized display names of the resource.
///
- [StringSyntax(StringSyntaxAttribute.Json)]
- public virtual string? DisplayNames { get; set; }
+ public virtual IDictionary? DisplayNames { get; set; }
///
- /// Gets or sets the unique identifier associated with the current resource.
+ /// Gets or sets the unique identifier of the resource.
///
public virtual TKey? Id { get; set; }
///
- /// Gets or sets the unique name associated with the current resource.
+ /// Gets or sets the unique name of the resource.
///
public virtual string? Name { get; set; }
///
- /// Gets or sets the additional properties serialized as a JSON object,
- /// or if no bag was associated with the current resource.
+ /// Gets or sets the additional properties of the resource.
///
- [StringSyntax(StringSyntaxAttribute.Json)]
- public virtual string? Properties { get; set; }
+ public virtual IDictionary? Properties { get; set; }
}
diff --git a/src/OpenIddict.EntityFrameworkCore.Models/OpenIddictEntityFrameworkCoreScope.cs b/src/OpenIddict.EntityFrameworkCore.Models/OpenIddictEntityFrameworkCoreScope.cs
index cbb035c3..1e1a3073 100644
--- a/src/OpenIddict.EntityFrameworkCore.Models/OpenIddictEntityFrameworkCoreScope.cs
+++ b/src/OpenIddict.EntityFrameworkCore.Models/OpenIddictEntityFrameworkCoreScope.cs
@@ -5,7 +5,7 @@
*/
using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
+using System.Text.Json;
namespace OpenIddict.EntityFrameworkCore.Models;
@@ -24,56 +24,47 @@ public class OpenIddictEntityFrameworkCoreScope : OpenIddictEntityFrameworkCoreS
public class OpenIddictEntityFrameworkCoreScope where TKey : notnull, IEquatable
{
///
- /// Gets or sets the concurrency token.
+ /// Gets or sets the concurrency token of the scope.
///
public virtual string? ConcurrencyToken { get; set; } = Guid.NewGuid().ToString();
///
- /// Gets or sets the public description associated with the current scope.
+ /// Gets or sets the public description of the scope.
///
public virtual string? Description { get; set; }
///
- /// Gets or sets the localized public descriptions associated
- /// with the current scope, serialized as a JSON object.
+ /// Gets or sets the localized public descriptions of the scope.
///
- [StringSyntax(StringSyntaxAttribute.Json)]
- public virtual string? Descriptions { get; set; }
+ public virtual IDictionary? Descriptions { get; set; }
///
- /// Gets or sets the display name associated with the current scope.
+ /// Gets or sets the display name of the scope.
///
public virtual string? DisplayName { get; set; }
///
- /// Gets or sets the localized display names
- /// associated with the current application,
- /// serialized as a JSON object.
+ /// Gets or sets the localized display names of the scope.
///
- [StringSyntax(StringSyntaxAttribute.Json)]
- public virtual string? DisplayNames { get; set; }
+ public virtual IDictionary? DisplayNames { get; set; }
///
- /// Gets or sets the unique identifier associated with the current scope.
+ /// Gets or sets the unique identifier of the scope.
///
public virtual TKey? Id { get; set; }
///
- /// Gets or sets the unique name associated with the current scope.
+ /// Gets or sets the unique name of the scope.
///
public virtual string? Name { get; set; }
///
- /// Gets or sets the additional properties serialized as a JSON object,
- /// or if no bag was associated with the current scope.
+ /// Gets or sets the additional properties of the scope.
///
- [StringSyntax(StringSyntaxAttribute.Json)]
- public virtual string? Properties { get; set; }
+ public virtual IDictionary? Properties { get; set; }
///
- /// Gets or sets the resources associated with the
- /// current scope, serialized as a JSON array.
+ /// Gets or sets the resources of the scope.
///
- [StringSyntax(StringSyntaxAttribute.Json)]
- public virtual string? Resources { get; set; }
+ public virtual string[]? Resources { get; set; }
}
diff --git a/src/OpenIddict.EntityFrameworkCore.Models/OpenIddictEntityFrameworkCoreToken.cs b/src/OpenIddict.EntityFrameworkCore.Models/OpenIddictEntityFrameworkCoreToken.cs
index 1650359c..56b52235 100644
--- a/src/OpenIddict.EntityFrameworkCore.Models/OpenIddictEntityFrameworkCoreToken.cs
+++ b/src/OpenIddict.EntityFrameworkCore.Models/OpenIddictEntityFrameworkCoreToken.cs
@@ -5,7 +5,7 @@
*/
using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
+using System.Text.Json;
namespace OpenIddict.EntityFrameworkCore.Models;
@@ -21,9 +21,7 @@ public class OpenIddictEntityFrameworkCoreToken : OpenIddictEntityFrameworkCoreT
/// Represents an OpenIddict token.
///
public class OpenIddictEntityFrameworkCoreToken : OpenIddictEntityFrameworkCoreToken, OpenIddictEntityFrameworkCoreAuthorization>
- where TKey : notnull, IEquatable
-{
-}
+ where TKey : notnull, IEquatable;
///
/// Represents an OpenIddict token.
@@ -45,64 +43,65 @@ public class OpenIddictEntityFrameworkCoreToken
- /// Gets or sets the concurrency token.
+ /// Gets or sets the concurrency token of the token.
///
public virtual string? ConcurrencyToken { get; set; } = Guid.NewGuid().ToString();
///
- /// Gets or sets the UTC creation date of the current token.
+ /// Gets or sets the UTC creation date of the token.
///
public virtual DateTime? CreationDate { get; set; }
///
- /// Gets or sets the UTC expiration date of the current token.
+ /// Gets or sets the UTC expiration date of the token.
///
public virtual DateTime? ExpirationDate { get; set; }
///
- /// Gets or sets the unique identifier associated with the current token.
+ /// Gets or sets the unique identifier of the token.
///
public virtual TKey? Id { get; set; }
///
- /// Gets or sets the payload of the current token, if applicable.
- /// Note: this property is only used for reference tokens
- /// and may be encrypted for security reasons.
+ /// Gets or sets the payload of the token.
///
+ ///
+ /// Note: this property is only used for reference tokens
+ /// and may be hashed or encrypted for security reasons.
+ ///
public virtual string? Payload { get; set; }
///
- /// Gets or sets the additional properties serialized as a JSON object,
- /// or if no bag was associated with the current token.
+ /// Gets or sets the additional properties of the token.
///
- [StringSyntax(StringSyntaxAttribute.Json)]
- public virtual string? Properties { get; set; }
+ public virtual IDictionary? Properties { get; set; }
///
- /// Gets or sets the UTC redemption date of the current token.
+ /// Gets or sets the UTC redemption date of the token.
///
public virtual DateTime? RedemptionDate { get; set; }
///
- /// Gets or sets the reference identifier associated
- /// with the current token, if applicable.
+ /// Gets or sets the reference identifier of the token.
+ ///
+ ///
/// Note: this property is only used for reference tokens
/// and may be hashed or encrypted for security reasons.
- ///
+ ///
public virtual string? ReferenceId { get; set; }
///
- /// Gets or sets the status of the current token.
+ /// Gets or sets the status of the token.
///
public virtual string? Status { get; set; }
///
- /// Gets or sets the subject associated with the current token.
+ /// Gets or sets the subject of the token.
///
public virtual string? Subject { get; set; }
///
- /// Gets or sets the type of the current token.
+ /// Gets or sets the type of the token.
///
public virtual string? Type { get; set; }
}
diff --git a/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreApplicationConfiguration.cs b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreApplicationConfiguration.cs
index 399ea5f8..805eb02a 100644
--- a/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreApplicationConfiguration.cs
+++ b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreApplicationConfiguration.cs
@@ -6,7 +6,9 @@
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
+using System.Text.Json;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
+using Microsoft.IdentityModel.Tokens;
using OpenIddict.EntityFrameworkCore.Models;
namespace OpenIddict.EntityFrameworkCore;
@@ -37,11 +39,15 @@ public sealed class OpenIddictEntityFrameworkCoreApplicationConfiguration<
// Entity Framework would throw an exception due to the TKey generic parameter
// being non-nullable when using value types like short, int, long or Guid.
- builder.HasKey(static application => application.Id);
-
builder.Property(static application => application.ApplicationType)
.HasMaxLength(50);
+ builder.HasMany(static application => application.Authorizations)
+ .WithOne(static authorization => authorization.Application!)
+ .HasForeignKey(nameof(OpenIddictEntityFrameworkCoreAuthorization.Application) +
+ nameof(OpenIddictEntityFrameworkCoreApplication.Id))
+ .IsRequired(required: false);
+
builder.HasIndex(static application => application.ClientId)
.IsUnique();
@@ -58,6 +64,13 @@ public sealed class OpenIddictEntityFrameworkCoreApplicationConfiguration<
builder.Property(static application => application.ConsentType)
.HasMaxLength(50);
+ builder.Property(static application => application.DisplayNames)
+ .HasConversion(
+ static value => JsonSerializer.Serialize(value, OpenIddictSerializer.Default.IDictionaryStringString),
+ static value => JsonSerializer.Deserialize(value, OpenIddictSerializer.Default.IDictionaryStringString));
+
+ builder.HasKey(static application => application.Id);
+
builder.Property(static application => application.Id)
.ValueGeneratedOnAdd();
@@ -67,11 +80,20 @@ public sealed class OpenIddictEntityFrameworkCoreApplicationConfiguration<
.HasMaxLength(100);
}
- builder.HasMany(static application => application.Authorizations)
- .WithOne(static authorization => authorization.Application!)
- .HasForeignKey(nameof(OpenIddictEntityFrameworkCoreAuthorization.Application) +
- nameof(OpenIddictEntityFrameworkCoreApplication.Id))
- .IsRequired(required: false);
+ builder.Property(static application => application.JsonWebKeySet)
+ .HasConversion(
+ static value => JsonSerializer.Serialize(value, OpenIddictSerializer.Default.JsonWebKeySet),
+ static value => JsonWebKeySet.Create(value));
+
+ builder.Property(static application => application.Properties)
+ .HasConversion(
+ static value => JsonSerializer.Serialize(value, OpenIddictSerializer.Default.IDictionaryStringJsonElement),
+ static value => JsonSerializer.Deserialize(value, OpenIddictSerializer.Default.IDictionaryStringJsonElement));
+
+ builder.Property(static application => application.Settings)
+ .HasConversion(
+ static value => JsonSerializer.Serialize(value, OpenIddictSerializer.Default.IDictionaryStringString),
+ static value => JsonSerializer.Deserialize(value, OpenIddictSerializer.Default.IDictionaryStringString));
builder.HasMany(static application => application.Tokens)
.WithOne(static token => token.Application!)
diff --git a/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreAuthorizationConfiguration.cs b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreAuthorizationConfiguration.cs
index 61146224..bcf93313 100644
--- a/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreAuthorizationConfiguration.cs
+++ b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreAuthorizationConfiguration.cs
@@ -6,6 +6,7 @@
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
+using System.Text.Json;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using OpenIddict.EntityFrameworkCore.Models;
@@ -37,8 +38,6 @@ public sealed class OpenIddictEntityFrameworkCoreAuthorizationConfiguration<
// Entity Framework would throw an exception due to the TKey generic parameter
// being non-nullable when using value types like short, int, long or Guid.
- builder.HasKey(static authorization => authorization.Id);
-
builder.HasIndex(
nameof(OpenIddictEntityFrameworkCoreAuthorization.Application) + nameof(OpenIddictEntityFrameworkCoreApplication.Id),
nameof(OpenIddictEntityFrameworkCoreAuthorization.Status),
@@ -49,6 +48,8 @@ public sealed class OpenIddictEntityFrameworkCoreAuthorizationConfiguration<
.HasMaxLength(50)
.IsConcurrencyToken();
+ builder.HasKey(static authorization => authorization.Id);
+
builder.Property(static authorization => authorization.Id)
.ValueGeneratedOnAdd();
@@ -58,21 +59,26 @@ public sealed class OpenIddictEntityFrameworkCoreAuthorizationConfiguration<
.HasMaxLength(100);
}
+ builder.Property(static authorization => authorization.Properties)
+ .HasConversion(
+ static value => JsonSerializer.Serialize(value, OpenIddictSerializer.Default.IDictionaryStringJsonElement),
+ static value => JsonSerializer.Deserialize(value, OpenIddictSerializer.Default.IDictionaryStringJsonElement));
+
builder.Property(static authorization => authorization.Status)
.HasMaxLength(50);
builder.Property(static authorization => authorization.Subject)
.HasMaxLength(400);
- builder.Property(static authorization => authorization.Type)
- .HasMaxLength(50);
-
builder.HasMany(static authorization => authorization.Tokens)
.WithOne(static token => token.Authorization!)
.HasForeignKey(nameof(OpenIddictEntityFrameworkCoreToken.Authorization) +
nameof(OpenIddictEntityFrameworkCoreAuthorization.Id))
.IsRequired(required: false);
+ builder.Property(static authorization => authorization.Type)
+ .HasMaxLength(50);
+
builder.ToTable("OpenIddictAuthorizations");
}
}
diff --git a/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreResourceConfiguration.cs b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreResourceConfiguration.cs
index 70636ec1..1b762a77 100644
--- a/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreResourceConfiguration.cs
+++ b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreResourceConfiguration.cs
@@ -6,6 +6,7 @@
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
+using System.Text.Json;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using OpenIddict.EntityFrameworkCore.Models;
@@ -31,15 +32,22 @@ public sealed class OpenIddictEntityFrameworkCoreResourceConfiguration<
// Entity Framework would throw an exception due to the TKey generic parameter
// being non-nullable when using value types like short, int, long or Guid.
- builder.HasKey(static resource => resource.Id);
-
- builder.HasIndex(static resource => resource.Name)
- .IsUnique();
-
builder.Property(static resource => resource.ConcurrencyToken)
.HasMaxLength(50)
.IsConcurrencyToken();
+ builder.Property(static resource => resource.Descriptions)
+ .HasConversion(
+ static value => JsonSerializer.Serialize(value, OpenIddictSerializer.Default.IDictionaryStringString),
+ static value => JsonSerializer.Deserialize(value, OpenIddictSerializer.Default.IDictionaryStringString));
+
+ builder.Property(static resource => resource.DisplayNames)
+ .HasConversion(
+ static value => JsonSerializer.Serialize(value, OpenIddictSerializer.Default.IDictionaryStringString),
+ static value => JsonSerializer.Deserialize(value, OpenIddictSerializer.Default.IDictionaryStringString));
+
+ builder.HasKey(static resource => resource.Id);
+
builder.Property(static resource => resource.Id)
.ValueGeneratedOnAdd();
@@ -52,6 +60,14 @@ public sealed class OpenIddictEntityFrameworkCoreResourceConfiguration<
builder.Property(static resource => resource.Name)
.HasMaxLength(200);
+ builder.HasIndex(static resource => resource.Name)
+ .IsUnique();
+
+ builder.Property(static resource => resource.Properties)
+ .HasConversion(
+ static value => JsonSerializer.Serialize(value, OpenIddictSerializer.Default.IDictionaryStringJsonElement),
+ static value => JsonSerializer.Deserialize(value, OpenIddictSerializer.Default.IDictionaryStringJsonElement));
+
builder.ToTable("OpenIddictResources");
}
}
diff --git a/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreScopeConfiguration.cs b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreScopeConfiguration.cs
index 98ed324f..6ce2b52d 100644
--- a/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreScopeConfiguration.cs
+++ b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreScopeConfiguration.cs
@@ -6,6 +6,7 @@
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
+using System.Text.Json;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using OpenIddict.EntityFrameworkCore.Models;
@@ -31,15 +32,22 @@ public sealed class OpenIddictEntityFrameworkCoreScopeConfiguration<
// Entity Framework would throw an exception due to the TKey generic parameter
// being non-nullable when using value types like short, int, long or Guid.
- builder.HasKey(static scope => scope.Id);
-
- builder.HasIndex(static scope => scope.Name)
- .IsUnique();
-
builder.Property(static scope => scope.ConcurrencyToken)
.HasMaxLength(50)
.IsConcurrencyToken();
+ builder.Property(static scope => scope.Descriptions)
+ .HasConversion(
+ static value => JsonSerializer.Serialize(value, OpenIddictSerializer.Default.IDictionaryStringString),
+ static value => JsonSerializer.Deserialize(value, OpenIddictSerializer.Default.IDictionaryStringString));
+
+ builder.Property(static scope => scope.DisplayNames)
+ .HasConversion(
+ static value => JsonSerializer.Serialize(value, OpenIddictSerializer.Default.IDictionaryStringString),
+ static value => JsonSerializer.Deserialize(value, OpenIddictSerializer.Default.IDictionaryStringString));
+
+ builder.HasKey(static scope => scope.Id);
+
builder.Property(static scope => scope.Id)
.ValueGeneratedOnAdd();
@@ -52,6 +60,14 @@ public sealed class OpenIddictEntityFrameworkCoreScopeConfiguration<
builder.Property(static scope => scope.Name)
.HasMaxLength(200);
+ builder.HasIndex(static scope => scope.Name)
+ .IsUnique();
+
+ builder.Property(static scope => scope.Properties)
+ .HasConversion(
+ static value => JsonSerializer.Serialize(value, OpenIddictSerializer.Default.IDictionaryStringJsonElement),
+ static value => JsonSerializer.Deserialize(value, OpenIddictSerializer.Default.IDictionaryStringJsonElement));
+
builder.ToTable("OpenIddictScopes");
}
}
diff --git a/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreTokenConfiguration.cs b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreTokenConfiguration.cs
index 775c1fab..dc1b39aa 100644
--- a/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreTokenConfiguration.cs
+++ b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreTokenConfiguration.cs
@@ -6,6 +6,7 @@
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
+using System.Text.Json;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using OpenIddict.EntityFrameworkCore.Models;
@@ -37,11 +38,6 @@ public sealed class OpenIddictEntityFrameworkCoreTokenConfiguration<
// Entity Framework would throw an exception due to the TKey generic parameter
// being non-nullable when using value types like short, int, long or Guid.
- builder.HasKey(static token => token.Id);
-
- builder.HasIndex(static token => token.ReferenceId)
- .IsUnique();
-
builder.HasIndex(
nameof(OpenIddictEntityFrameworkCoreToken.Application) + nameof(OpenIddictEntityFrameworkCoreApplication.Id),
nameof(OpenIddictEntityFrameworkCoreToken.Status),
@@ -52,6 +48,8 @@ public sealed class OpenIddictEntityFrameworkCoreTokenConfiguration<
.HasMaxLength(50)
.IsConcurrencyToken();
+ builder.HasKey(static token => token.Id);
+
builder.Property(static token => token.Id)
.ValueGeneratedOnAdd();
@@ -64,12 +62,20 @@ public sealed class OpenIddictEntityFrameworkCoreTokenConfiguration<
builder.Property(static token => token.ReferenceId)
.HasMaxLength(100);
+ builder.HasIndex(static token => token.ReferenceId)
+ .IsUnique();
+
builder.Property(static token => token.Status)
.HasMaxLength(50);
builder.Property(static token => token.Subject)
.HasMaxLength(400);
+ builder.Property(static token => token.Properties)
+ .HasConversion(
+ static value => JsonSerializer.Serialize(value, OpenIddictSerializer.Default.IDictionaryStringJsonElement),
+ static value => JsonSerializer.Deserialize(value, OpenIddictSerializer.Default.IDictionaryStringJsonElement));
+
builder.Property(static token => token.Type)
.HasMaxLength(150);
diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreApplicationStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreApplicationStore.cs
index 49de4576..e7deebe5 100644
--- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreApplicationStore.cs
+++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreApplicationStore.cs
@@ -10,10 +10,7 @@ using System.Data;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Runtime.CompilerServices;
-using System.Text;
-using System.Text.Encodings.Web;
using System.Text.Json;
-using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using OpenIddict.EntityFrameworkCore.Models;
@@ -30,10 +27,9 @@ public class OpenIddictEntityFrameworkCoreApplicationStore :
OpenIddictEntityFrameworkCoreToken, string>
{
public OpenIddictEntityFrameworkCoreApplicationStore(
- IMemoryCache cache,
IOpenIddictEntityFrameworkCoreContext context,
IOptionsMonitor options)
- : base(cache, context, options)
+ : base(context, options)
{
}
}
@@ -50,10 +46,9 @@ public class OpenIddictEntityFrameworkCoreApplicationStore<
where TKey : notnull, IEquatable
{
public OpenIddictEntityFrameworkCoreApplicationStore(
- IMemoryCache cache,
IOpenIddictEntityFrameworkCoreContext context,
IOptionsMonitor options)
- : base(cache, context, options)
+ : base(context, options)
{
}
}
@@ -76,20 +71,13 @@ public class OpenIddictEntityFrameworkCoreApplicationStore<
where TKey : notnull, IEquatable
{
public OpenIddictEntityFrameworkCoreApplicationStore(
- IMemoryCache cache,
IOpenIddictEntityFrameworkCoreContext context,
IOptionsMonitor options)
{
- Cache = cache ?? throw new ArgumentNullException(nameof(cache));
Context = context ?? throw new ArgumentNullException(nameof(context));
Options = options ?? throw new ArgumentNullException(nameof(options));
}
- ///
- /// Gets the memory cache associated with the current store.
- ///
- protected IMemoryCache Cache { get; }
-
///
/// Gets the database context associated with the current store.
///
@@ -314,29 +302,18 @@ public class OpenIddictEntityFrameworkCoreApplicationStore<
{
ArgumentException.ThrowIfNullOrEmpty(uri);
- // To optimize the efficiency of the query a bit, only applications whose stringified
- // PostLogoutRedirectUris contains the specified URI are returned. Once the applications
- // are retrieved, a second pass is made to ensure only valid elements are returned.
- // Implementers that use this method in a hot path may want to override this method
- // to use SQL Server 2016 functions like JSON_VALUE to make the query more efficient.
-
return ExecuteAsync(cancellationToken);
async IAsyncEnumerable ExecuteAsync([EnumeratorCancellation] CancellationToken cancellationToken)
{
var context = await Context.GetDbContextAsync(cancellationToken);
- var applications = (from application in context.Set().AsTracking()
- where application.PostLogoutRedirectUris!.Contains(uri)
- select application).AsAsyncEnumerable().WithCancellation(cancellationToken);
-
- await foreach (var application in applications)
+ await foreach (var application in
+ (from application in context.Set().AsTracking()
+ where application.PostLogoutRedirectUris!.Contains(uri)
+ select application).AsAsyncEnumerable().WithCancellation(cancellationToken))
{
- var uris = await GetPostLogoutRedirectUrisAsync(application, cancellationToken);
- if (uris.Contains(uri, StringComparer.Ordinal))
- {
- yield return application;
- }
+ yield return application;
}
}
}
@@ -347,29 +324,18 @@ public class OpenIddictEntityFrameworkCoreApplicationStore<
{
ArgumentException.ThrowIfNullOrEmpty(uri);
- // To optimize the efficiency of the query a bit, only applications whose stringified
- // RedirectUris property contains the specified URI are returned. Once the applications
- // are retrieved, a second pass is made to ensure only valid elements are returned.
- // Implementers that use this method in a hot path may want to override this method
- // to use SQL Server 2016 functions like JSON_VALUE to make the query more efficient.
-
return ExecuteAsync(cancellationToken);
async IAsyncEnumerable ExecuteAsync([EnumeratorCancellation] CancellationToken cancellationToken)
{
var context = await Context.GetDbContextAsync(cancellationToken);
- var applications = (from application in context.Set().AsTracking()
- where application.RedirectUris!.Contains(uri)
- select application).AsAsyncEnumerable().WithCancellation(cancellationToken);
-
- await foreach (var application in applications)
+ await foreach (var application in
+ (from application in context.Set().AsTracking()
+ where application.RedirectUris!.Contains(uri)
+ select application).AsAsyncEnumerable().WithCancellation(cancellationToken))
{
- var uris = await GetRedirectUrisAsync(application, cancellationToken);
- if (uris.Contains(uri, StringComparer.Ordinal))
- {
- yield return application;
- }
+ yield return application;
}
}
}
@@ -439,37 +405,9 @@ public class OpenIddictEntityFrameworkCoreApplicationStore<
{
ArgumentNullException.ThrowIfNull(application);
- if (string.IsNullOrEmpty(application.DisplayNames))
- {
- return new(ImmutableDictionary.Create());
- }
-
- // Note: parsing the stringified display names is an expensive operation.
- // To mitigate that, the resulting object is stored in the memory cache.
- var key = string.Concat("7762c378-c113-4564-b14b-1402b3949aaa", "\x1e", application.DisplayNames);
- var names = Cache.GetOrCreate(key, entry =>
- {
- entry.SetPriority(CacheItemPriority.High)
- .SetSlidingExpiration(TimeSpan.FromMinutes(1));
-
- using var document = JsonDocument.Parse(application.DisplayNames);
- var builder = ImmutableDictionary.CreateBuilder();
-
- foreach (var property in document.RootElement.EnumerateObject())
- {
- var value = property.Value.GetString();
- if (string.IsNullOrEmpty(value))
- {
- continue;
- }
-
- builder[CultureInfo.GetCultureInfo(property.Name)] = value;
- }
-
- return builder.ToImmutable();
- })!;
-
- return new(names);
+ return new(application.DisplayNames is { Count: > 0 } names
+ ? names.ToImmutableDictionary(static pair => CultureInfo.GetCultureInfo(pair.Key), static pair => pair.Value)
+ : []);
}
///
@@ -485,23 +423,7 @@ public class OpenIddictEntityFrameworkCoreApplicationStore<
{
ArgumentNullException.ThrowIfNull(application);
- if (string.IsNullOrEmpty(application.JsonWebKeySet))
- {
- return new(result: null);
- }
-
- // Note: parsing the stringified JSON Web Key Set is an expensive operation.
- // To mitigate that, the resulting object is stored in the memory cache.
- var key = string.Concat("1e0a697d-0623-481a-927a-5e6c31458782", "\x1e", application.JsonWebKeySet);
- var set = Cache.GetOrCreate(key, entry =>
- {
- entry.SetPriority(CacheItemPriority.High)
- .SetSlidingExpiration(TimeSpan.FromMinutes(1));
-
- return JsonWebKeySet.Create(application.JsonWebKeySet);
- })!;
-
- return new(set);
+ return new(application.JsonWebKeySet);
}
///
@@ -509,37 +431,7 @@ public class OpenIddictEntityFrameworkCoreApplicationStore<
{
ArgumentNullException.ThrowIfNull(application);
- if (string.IsNullOrEmpty(application.Permissions))
- {
- return new([]);
- }
-
- // Note: parsing the stringified permissions is an expensive operation.
- // To mitigate that, the resulting array is stored in the memory cache.
- var key = string.Concat("0347e0aa-3a26-410a-97e8-a83bdeb21a1f", "\x1e", application.Permissions);
- var permissions = Cache.GetOrCreate(key, entry =>
- {
- entry.SetPriority(CacheItemPriority.High)
- .SetSlidingExpiration(TimeSpan.FromMinutes(1));
-
- using var document = JsonDocument.Parse(application.Permissions);
- var builder = ImmutableArray.CreateBuilder(document.RootElement.GetArrayLength());
-
- foreach (var element in document.RootElement.EnumerateArray())
- {
- var value = element.GetString();
- if (string.IsNullOrEmpty(value))
- {
- continue;
- }
-
- builder.Add(value);
- }
-
- return builder.ToImmutable();
- });
-
- return new(permissions);
+ return new(application.Permissions is { Length: > 0 } permissions ? [.. permissions] : []);
}
///
@@ -547,37 +439,7 @@ public class OpenIddictEntityFrameworkCoreApplicationStore<
{
ArgumentNullException.ThrowIfNull(application);
- if (string.IsNullOrEmpty(application.PostLogoutRedirectUris))
- {
- return new([]);
- }
-
- // Note: parsing the stringified URIs is an expensive operation.
- // To mitigate that, the resulting array is stored in the memory cache.
- var key = string.Concat("fb14dfb9-9216-4b77-bfa9-7e85f8201ff4", "\x1e", application.PostLogoutRedirectUris);
- var uris = Cache.GetOrCreate(key, entry =>
- {
- entry.SetPriority(CacheItemPriority.High)
- .SetSlidingExpiration(TimeSpan.FromMinutes(1));
-
- using var document = JsonDocument.Parse(application.PostLogoutRedirectUris);
- var builder = ImmutableArray.CreateBuilder(document.RootElement.GetArrayLength());
-
- foreach (var element in document.RootElement.EnumerateArray())
- {
- var value = element.GetString();
- if (string.IsNullOrEmpty(value))
- {
- continue;
- }
-
- builder.Add(value);
- }
-
- return builder.ToImmutable();
- });
-
- return new(uris);
+ return new(application.PostLogoutRedirectUris is { Length: > 0 } uris ? [.. uris] : []);
}
///
@@ -585,31 +447,7 @@ public class OpenIddictEntityFrameworkCoreApplicationStore<
{
ArgumentNullException.ThrowIfNull(application);
- if (string.IsNullOrEmpty(application.Properties))
- {
- return new(ImmutableDictionary.Create());
- }
-
- // Note: parsing the stringified properties is an expensive operation.
- // To mitigate that, the resulting object is stored in the memory cache.
- var key = string.Concat("2e3e9680-5654-48d8-a27d-b8bb4f0f1d50", "\x1e", application.Properties);
- var properties = Cache.GetOrCreate(key, entry =>
- {
- entry.SetPriority(CacheItemPriority.High)
- .SetSlidingExpiration(TimeSpan.FromMinutes(1));
-
- using var document = JsonDocument.Parse(application.Properties);
- var builder = ImmutableDictionary.CreateBuilder();
-
- foreach (var property in document.RootElement.EnumerateObject())
- {
- builder[property.Name] = property.Value.Clone();
- }
-
- return builder.ToImmutable();
- })!;
-
- return new(properties);
+ return new(application.Properties is { Count: > 0 } properties ? [.. properties] : []);
}
///
@@ -617,37 +455,7 @@ public class OpenIddictEntityFrameworkCoreApplicationStore<
{
ArgumentNullException.ThrowIfNull(application);
- if (string.IsNullOrEmpty(application.RedirectUris))
- {
- return new([]);
- }
-
- // Note: parsing the stringified URIs is an expensive operation.
- // To mitigate that, the resulting array is stored in the memory cache.
- var key = string.Concat("851d6f08-2ee0-4452-bbe5-ab864611ecaa", "\x1e", application.RedirectUris);
- var uris = Cache.GetOrCreate(key, entry =>
- {
- entry.SetPriority(CacheItemPriority.High)
- .SetSlidingExpiration(TimeSpan.FromMinutes(1));
-
- using var document = JsonDocument.Parse(application.RedirectUris);
- var builder = ImmutableArray.CreateBuilder(document.RootElement.GetArrayLength());
-
- foreach (var element in document.RootElement.EnumerateArray())
- {
- var value = element.GetString();
- if (string.IsNullOrEmpty(value))
- {
- continue;
- }
-
- builder.Add(value);
- }
-
- return builder.ToImmutable();
- });
-
- return new(uris);
+ return new(application.RedirectUris is { Length: > 0 } uris ? [.. uris] : []);
}
///
@@ -655,37 +463,7 @@ public class OpenIddictEntityFrameworkCoreApplicationStore<
{
ArgumentNullException.ThrowIfNull(application);
- if (string.IsNullOrEmpty(application.Requirements))
- {
- return new([]);
- }
-
- // Note: parsing the stringified requirements is an expensive operation.
- // To mitigate that, the resulting array is stored in the memory cache.
- var key = string.Concat("b4808a89-8969-4512-895f-a909c62a8995", "\x1e", application.Requirements);
- var requirements = Cache.GetOrCreate(key, entry =>
- {
- entry.SetPriority(CacheItemPriority.High)
- .SetSlidingExpiration(TimeSpan.FromMinutes(1));
-
- using var document = JsonDocument.Parse(application.Requirements);
- var builder = ImmutableArray.CreateBuilder(document.RootElement.GetArrayLength());
-
- foreach (var element in document.RootElement.EnumerateArray())
- {
- var value = element.GetString();
- if (string.IsNullOrEmpty(value))
- {
- continue;
- }
-
- builder.Add(value);
- }
-
- return builder.ToImmutable();
- });
-
- return new(requirements);
+ return new(application.Requirements is { Length: > 0 } requirements ? [.. requirements] : []);
}
///
@@ -693,37 +471,7 @@ public class OpenIddictEntityFrameworkCoreApplicationStore<
{
ArgumentNullException.ThrowIfNull(application);
- if (string.IsNullOrEmpty(application.Settings))
- {
- return new(ImmutableDictionary.Create());
- }
-
- // Note: parsing the stringified settings is an expensive operation.
- // To mitigate that, the resulting object is stored in the memory cache.
- var key = string.Concat("492ea63f-c26f-47ea-bf9b-b0a0c3d02656", "\x1e", application.Settings);
- var settings = Cache.GetOrCreate(key, entry =>
- {
- entry.SetPriority(CacheItemPriority.High)
- .SetSlidingExpiration(TimeSpan.FromMinutes(1));
-
- using var document = JsonDocument.Parse(application.Settings);
- var builder = ImmutableDictionary.CreateBuilder();
-
- foreach (var property in document.RootElement.EnumerateObject())
- {
- var value = property.Value.GetString();
- if (string.IsNullOrEmpty(value))
- {
- continue;
- }
-
- builder[property.Name] = value;
- }
-
- return builder.ToImmutable();
- })!;
-
- return new(settings);
+ return new(application.Settings is { Count: > 0 } settings ? [.. settings] : []);
}
///
@@ -852,32 +600,9 @@ public class OpenIddictEntityFrameworkCoreApplicationStore<
{
ArgumentNullException.ThrowIfNull(application);
- if (names is not { Count: > 0 })
- {
- application.DisplayNames = null;
-
- return ValueTask.CompletedTask;
- }
-
- using var stream = new MemoryStream();
- using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
- {
- Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
- Indented = false
- });
-
- writer.WriteStartObject();
-
- foreach (var pair in names)
- {
- writer.WritePropertyName(pair.Key.Name);
- writer.WriteStringValue(pair.Value);
- }
-
- writer.WriteEndObject();
- writer.Flush();
-
- application.DisplayNames = Encoding.UTF8.GetString(stream.ToArray());
+ application.DisplayNames = names is { Count: > 0 }
+ ? names.ToImmutableDictionary(static pair => pair.Key.Name, static pair => pair.Value)
+ : null;
return ValueTask.CompletedTask;
}
@@ -887,7 +612,7 @@ public class OpenIddictEntityFrameworkCoreApplicationStore<
{
ArgumentNullException.ThrowIfNull(application);
- application.JsonWebKeySet = set is not null ? JsonSerializer.Serialize(set, OpenIddictSerializer.Default.JsonWebKeySet) : null;
+ application.JsonWebKeySet = set;
return ValueTask.CompletedTask;
}
@@ -904,24 +629,7 @@ public class OpenIddictEntityFrameworkCoreApplicationStore<
return ValueTask.CompletedTask;
}
- using var stream = new MemoryStream();
- using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
- {
- Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
- Indented = false
- });
-
- writer.WriteStartArray();
-
- foreach (var permission in permissions)
- {
- writer.WriteStringValue(permission);
- }
-
- writer.WriteEndArray();
- writer.Flush();
-
- application.Permissions = Encoding.UTF8.GetString(stream.ToArray());
+ application.Permissions = permissions.ToArray();
return ValueTask.CompletedTask;
}
@@ -939,24 +647,7 @@ public class OpenIddictEntityFrameworkCoreApplicationStore<
return ValueTask.CompletedTask;
}
- using var stream = new MemoryStream();
- using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
- {
- Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
- Indented = false
- });
-
- writer.WriteStartArray();
-
- foreach (var uri in uris)
- {
- writer.WriteStringValue(uri);
- }
-
- writer.WriteEndArray();
- writer.Flush();
-
- application.PostLogoutRedirectUris = Encoding.UTF8.GetString(stream.ToArray());
+ application.PostLogoutRedirectUris = uris.ToArray();
return ValueTask.CompletedTask;
}
@@ -967,32 +658,7 @@ public class OpenIddictEntityFrameworkCoreApplicationStore<
{
ArgumentNullException.ThrowIfNull(application);
- if (properties is not { Count: > 0 })
- {
- application.Properties = null;
-
- return ValueTask.CompletedTask;
- }
-
- using var stream = new MemoryStream();
- using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
- {
- Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
- Indented = false
- });
-
- writer.WriteStartObject();
-
- foreach (var property in properties)
- {
- writer.WritePropertyName(property.Key);
- property.Value.WriteTo(writer);
- }
-
- writer.WriteEndObject();
- writer.Flush();
-
- application.Properties = Encoding.UTF8.GetString(stream.ToArray());
+ application.Properties = properties;
return ValueTask.CompletedTask;
}
@@ -1010,24 +676,7 @@ public class OpenIddictEntityFrameworkCoreApplicationStore<
return ValueTask.CompletedTask;
}
- using var stream = new MemoryStream();
- using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
- {
- Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
- Indented = false
- });
-
- writer.WriteStartArray();
-
- foreach (var uri in uris)
- {
- writer.WriteStringValue(uri);
- }
-
- writer.WriteEndArray();
- writer.Flush();
-
- application.RedirectUris = Encoding.UTF8.GetString(stream.ToArray());
+ application.RedirectUris = uris.ToArray();
return ValueTask.CompletedTask;
}
@@ -1044,24 +693,7 @@ public class OpenIddictEntityFrameworkCoreApplicationStore<
return ValueTask.CompletedTask;
}
- using var stream = new MemoryStream();
- using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
- {
- Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
- Indented = false
- });
-
- writer.WriteStartArray();
-
- foreach (var requirement in requirements)
- {
- writer.WriteStringValue(requirement);
- }
-
- writer.WriteEndArray();
- writer.Flush();
-
- application.Requirements = Encoding.UTF8.GetString(stream.ToArray());
+ application.Requirements = requirements.ToArray();
return ValueTask.CompletedTask;
}
@@ -1072,32 +704,7 @@ public class OpenIddictEntityFrameworkCoreApplicationStore<
{
ArgumentNullException.ThrowIfNull(application);
- if (settings is not { Count: > 0 })
- {
- application.Settings = null;
-
- return ValueTask.CompletedTask;
- }
-
- using var stream = new MemoryStream();
- using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
- {
- Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
- Indented = false
- });
-
- writer.WriteStartObject();
-
- foreach (var setting in settings)
- {
- writer.WritePropertyName(setting.Key);
- writer.WriteStringValue(setting.Value);
- }
-
- writer.WriteEndObject();
- writer.Flush();
-
- application.Settings = Encoding.UTF8.GetString(stream.ToArray());
+ application.Settings = settings;
return ValueTask.CompletedTask;
}
diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreAuthorizationStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreAuthorizationStore.cs
index 22ea424d..be9ce639 100644
--- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreAuthorizationStore.cs
+++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreAuthorizationStore.cs
@@ -9,10 +9,7 @@ using System.ComponentModel;
using System.Data;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
-using System.Text;
-using System.Text.Encodings.Web;
using System.Text.Json;
-using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Options;
using OpenIddict.EntityFrameworkCore.Models;
using static OpenIddict.Abstractions.OpenIddictExceptions;
@@ -28,10 +25,9 @@ public class OpenIddictEntityFrameworkCoreAuthorizationStore :
OpenIddictEntityFrameworkCoreToken, string>
{
public OpenIddictEntityFrameworkCoreAuthorizationStore(
- IMemoryCache cache,
IOpenIddictEntityFrameworkCoreContext context,
IOptionsMonitor options)
- : base(cache, context, options)
+ : base(context, options)
{
}
}
@@ -48,10 +44,9 @@ public class OpenIddictEntityFrameworkCoreAuthorizationStore<
where TKey : notnull, IEquatable
{
public OpenIddictEntityFrameworkCoreAuthorizationStore(
- IMemoryCache cache,
IOpenIddictEntityFrameworkCoreContext context,
IOptionsMonitor options)
- : base(cache, context, options)
+ : base(context, options)
{
}
}
@@ -74,20 +69,13 @@ public class OpenIddictEntityFrameworkCoreAuthorizationStore<
where TKey : notnull, IEquatable
{
public OpenIddictEntityFrameworkCoreAuthorizationStore(
- IMemoryCache cache,
IOpenIddictEntityFrameworkCoreContext context,
IOptionsMonitor options)
{
- Cache = cache ?? throw new ArgumentNullException(nameof(cache));
Context = context ?? throw new ArgumentNullException(nameof(context));
Options = options ?? throw new ArgumentNullException(nameof(options));
}
- ///
- /// Gets the memory cache associated with the current store.
- ///
- protected IMemoryCache Cache { get; }
-
///
/// Gets the database context associated with the current store.
///
@@ -393,12 +381,7 @@ public class OpenIddictEntityFrameworkCoreAuthorizationStore<
{
ArgumentNullException.ThrowIfNull(authorization);
- if (authorization.CreationDate is null)
- {
- return new(result: null);
- }
-
- return new(DateTime.SpecifyKind(authorization.CreationDate.Value, DateTimeKind.Utc));
+ return new(authorization.CreationDate is DateTime date ? DateTime.SpecifyKind(date, DateTimeKind.Utc) : null);
}
///
@@ -414,31 +397,7 @@ public class OpenIddictEntityFrameworkCoreAuthorizationStore<
{
ArgumentNullException.ThrowIfNull(authorization);
- if (string.IsNullOrEmpty(authorization.Properties))
- {
- return new(ImmutableDictionary.Create());
- }
-
- // Note: parsing the stringified properties is an expensive operation.
- // To mitigate that, the resulting object is stored in the memory cache.
- var key = string.Concat("68056e1a-dbcf-412b-9a6a-d791c7dbe726", "\x1e", authorization.Properties);
- var properties = Cache.GetOrCreate(key, entry =>
- {
- entry.SetPriority(CacheItemPriority.High)
- .SetSlidingExpiration(TimeSpan.FromMinutes(1));
-
- using var document = JsonDocument.Parse(authorization.Properties);
- var builder = ImmutableDictionary.CreateBuilder();
-
- foreach (var property in document.RootElement.EnumerateObject())
- {
- builder[property.Name] = property.Value.Clone();
- }
-
- return builder.ToImmutable();
- })!;
-
- return new(properties);
+ return new(authorization.Properties is { Count: > 0 } properties ? [.. properties] : []);
}
///
@@ -446,37 +405,7 @@ public class OpenIddictEntityFrameworkCoreAuthorizationStore<
{
ArgumentNullException.ThrowIfNull(authorization);
- if (string.IsNullOrEmpty(authorization.Scopes))
- {
- return new([]);
- }
-
- // Note: parsing the stringified scopes is an expensive operation.
- // To mitigate that, the resulting array is stored in the memory cache.
- var key = string.Concat("2ba4ab0f-e2ec-4d48-b3bd-28e2bb660c75", "\x1e", authorization.Scopes);
- var scopes = Cache.GetOrCreate(key, entry =>
- {
- entry.SetPriority(CacheItemPriority.High)
- .SetSlidingExpiration(TimeSpan.FromMinutes(1));
-
- using var document = JsonDocument.Parse(authorization.Scopes);
- var builder = ImmutableArray.CreateBuilder(document.RootElement.GetArrayLength());
-
- foreach (var element in document.RootElement.EnumerateArray())
- {
- var value = element.GetString();
- if (string.IsNullOrEmpty(value))
- {
- continue;
- }
-
- builder.Add(value);
- }
-
- return builder.ToImmutable();
- });
-
- return new(scopes);
+ return new(authorization.Scopes is { Length: > 0 } scopes ? [.. scopes] : []);
}
///
@@ -939,32 +868,7 @@ public class OpenIddictEntityFrameworkCoreAuthorizationStore<
{
ArgumentNullException.ThrowIfNull(authorization);
- if (properties is not { Count: > 0 })
- {
- authorization.Properties = null;
-
- return ValueTask.CompletedTask;
- }
-
- using var stream = new MemoryStream();
- using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
- {
- Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
- Indented = false
- });
-
- writer.WriteStartObject();
-
- foreach (var property in properties)
- {
- writer.WritePropertyName(property.Key);
- property.Value.WriteTo(writer);
- }
-
- writer.WriteEndObject();
- writer.Flush();
-
- authorization.Properties = Encoding.UTF8.GetString(stream.ToArray());
+ authorization.Properties = properties;
return ValueTask.CompletedTask;
}
@@ -982,24 +886,7 @@ public class OpenIddictEntityFrameworkCoreAuthorizationStore<
return ValueTask.CompletedTask;
}
- using var stream = new MemoryStream();
- using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
- {
- Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
- Indented = false
- });
-
- writer.WriteStartArray();
-
- foreach (var scope in scopes)
- {
- writer.WriteStringValue(scope);
- }
-
- writer.WriteEndArray();
- writer.Flush();
-
- authorization.Scopes = Encoding.UTF8.GetString(stream.ToArray());
+ authorization.Scopes = scopes.ToArray();
return ValueTask.CompletedTask;
}
diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreResourceStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreResourceStore.cs
index 3294f0f2..ad668fb5 100644
--- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreResourceStore.cs
+++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreResourceStore.cs
@@ -9,10 +9,7 @@ using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Runtime.CompilerServices;
-using System.Text;
-using System.Text.Encodings.Web;
using System.Text.Json;
-using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Options;
using OpenIddict.EntityFrameworkCore.Models;
using static OpenIddict.Abstractions.OpenIddictExceptions;
@@ -25,10 +22,9 @@ namespace OpenIddict.EntityFrameworkCore;
public class OpenIddictEntityFrameworkCoreResourceStore : OpenIddictEntityFrameworkCoreResourceStore
{
public OpenIddictEntityFrameworkCoreResourceStore(
- IMemoryCache cache,
IOpenIddictEntityFrameworkCoreContext context,
IOptionsMonitor options)
- : base(cache, context, options)
+ : base(context, options)
{
}
}
@@ -42,10 +38,9 @@ public class OpenIddictEntityFrameworkCoreResourceStore<
where TKey : notnull, IEquatable
{
public OpenIddictEntityFrameworkCoreResourceStore(
- IMemoryCache cache,
IOpenIddictEntityFrameworkCoreContext context,
IOptionsMonitor options)
- : base(cache, context, options)
+ : base(context, options)
{
}
}
@@ -62,20 +57,13 @@ public class OpenIddictEntityFrameworkCoreResourceStore<
where TKey : notnull, IEquatable
{
public OpenIddictEntityFrameworkCoreResourceStore(
- IMemoryCache cache,
IOpenIddictEntityFrameworkCoreContext context,
IOptionsMonitor options)
{
- Cache = cache ?? throw new ArgumentNullException(nameof(cache));
Context = context ?? throw new ArgumentNullException(nameof(context));
Options = options ?? throw new ArgumentNullException(nameof(options));
}
- ///
- /// Gets the memory cache associated with the current store.
- ///
- protected IMemoryCache Cache { get; }
-
///
/// Gets the database context associated with the current store.
///
@@ -232,37 +220,9 @@ public class OpenIddictEntityFrameworkCoreResourceStore<
{
ArgumentNullException.ThrowIfNull(resource);
- if (string.IsNullOrEmpty(resource.Descriptions))
- {
- return new(ImmutableDictionary.Create());
- }
-
- // Note: parsing the stringified descriptions is an expensive operation.
- // To mitigate that, the resulting object is stored in the memory cache.
- var key = string.Concat("20e1ab51-b505-40b0-9a10-d0596b9f2143", "\x1e", resource.Descriptions);
- var descriptions = Cache.GetOrCreate(key, entry =>
- {
- entry.SetPriority(CacheItemPriority.High)
- .SetSlidingExpiration(TimeSpan.FromMinutes(1));
-
- using var document = JsonDocument.Parse(resource.Descriptions);
- var builder = ImmutableDictionary.CreateBuilder();
-
- foreach (var property in document.RootElement.EnumerateObject())
- {
- var value = property.Value.GetString();
- if (string.IsNullOrEmpty(value))
- {
- continue;
- }
-
- builder[CultureInfo.GetCultureInfo(property.Name)] = value;
- }
-
- return builder.ToImmutable();
- })!;
-
- return new(descriptions);
+ return new(resource.Descriptions is { Count: > 0 } descriptions
+ ? descriptions.ToImmutableDictionary(static pair => CultureInfo.GetCultureInfo(pair.Key), static pair => pair.Value)
+ : []);
}
///
@@ -278,37 +238,9 @@ public class OpenIddictEntityFrameworkCoreResourceStore<
{
ArgumentNullException.ThrowIfNull(resource);
- if (string.IsNullOrEmpty(resource.DisplayNames))
- {
- return new(ImmutableDictionary.Create());
- }
-
- // Note: parsing the stringified display names is an expensive operation.
- // To mitigate that, the resulting object is stored in the memory cache.
- var key = string.Concat("65c3ea08-ded7-488f-b001-5098de04172b", "\x1e", resource.DisplayNames);
- var names = Cache.GetOrCreate(key, entry =>
- {
- entry.SetPriority(CacheItemPriority.High)
- .SetSlidingExpiration(TimeSpan.FromMinutes(1));
-
- using var document = JsonDocument.Parse(resource.DisplayNames);
- var builder = ImmutableDictionary.CreateBuilder();
-
- foreach (var property in document.RootElement.EnumerateObject())
- {
- var value = property.Value.GetString();
- if (string.IsNullOrEmpty(value))
- {
- continue;
- }
-
- builder[CultureInfo.GetCultureInfo(property.Name)] = value;
- }
-
- return builder.ToImmutable();
- })!;
-
- return new(names);
+ return new(resource.DisplayNames is { Count: > 0 } names
+ ? names.ToImmutableDictionary(static pair => CultureInfo.GetCultureInfo(pair.Key), static pair => pair.Value)
+ : []);
}
///
@@ -332,31 +264,7 @@ public class OpenIddictEntityFrameworkCoreResourceStore<
{
ArgumentNullException.ThrowIfNull(resource);
- if (string.IsNullOrEmpty(resource.Properties))
- {
- return new(ImmutableDictionary.Create());
- }
-
- // Note: parsing the stringified properties is an expensive operation.
- // To mitigate that, the resulting object is stored in the memory cache.
- var key = string.Concat("1f414494-e5aa-4cad-9c5f-4f98688e3623", "\x1e", resource.Properties);
- var properties = Cache.GetOrCreate(key, entry =>
- {
- entry.SetPriority(CacheItemPriority.High)
- .SetSlidingExpiration(TimeSpan.FromMinutes(1));
-
- using var document = JsonDocument.Parse(resource.Properties);
- var builder = ImmutableDictionary.CreateBuilder();
-
- foreach (var property in document.RootElement.EnumerateObject())
- {
- builder[property.Name] = property.Value.Clone();
- }
-
- return builder.ToImmutable();
- })!;
-
- return new(properties);
+ return new(resource.Properties is { Count: > 0 } properties ? [.. properties] : []);
}
///
@@ -434,32 +342,9 @@ public class OpenIddictEntityFrameworkCoreResourceStore<
{
ArgumentNullException.ThrowIfNull(resource);
- if (descriptions is not { Count: > 0 })
- {
- resource.Descriptions = null;
-
- return ValueTask.CompletedTask;
- }
-
- using var stream = new MemoryStream();
- using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
- {
- Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
- Indented = false
- });
-
- writer.WriteStartObject();
-
- foreach (var description in descriptions)
- {
- writer.WritePropertyName(description.Key.Name);
- writer.WriteStringValue(description.Value);
- }
-
- writer.WriteEndObject();
- writer.Flush();
-
- resource.Descriptions = Encoding.UTF8.GetString(stream.ToArray());
+ resource.Descriptions = descriptions is { Count: > 0 }
+ ? descriptions.ToImmutableDictionary(static pair => pair.Key.Name, static pair => pair.Value)
+ : null;
return ValueTask.CompletedTask;
}
@@ -480,32 +365,9 @@ public class OpenIddictEntityFrameworkCoreResourceStore<
{
ArgumentNullException.ThrowIfNull(resource);
- if (names is not { Count: > 0 })
- {
- resource.DisplayNames = null;
-
- return ValueTask.CompletedTask;
- }
-
- using var stream = new MemoryStream();
- using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
- {
- Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
- Indented = false
- });
-
- writer.WriteStartObject();
-
- foreach (var name in names)
- {
- writer.WritePropertyName(name.Key.Name);
- writer.WriteStringValue(name.Value);
- }
-
- writer.WriteEndObject();
- writer.Flush();
-
- resource.DisplayNames = Encoding.UTF8.GetString(stream.ToArray());
+ resource.DisplayNames = names is { Count: > 0 }
+ ? names.ToImmutableDictionary(static pair => pair.Key.Name, static pair => pair.Value)
+ : null;
return ValueTask.CompletedTask;
}
@@ -526,32 +388,7 @@ public class OpenIddictEntityFrameworkCoreResourceStore<
{
ArgumentNullException.ThrowIfNull(resource);
- if (properties is not { Count: > 0 })
- {
- resource.Properties = null;
-
- return ValueTask.CompletedTask;
- }
-
- using var stream = new MemoryStream();
- using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
- {
- Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
- Indented = false
- });
-
- writer.WriteStartObject();
-
- foreach (var property in properties)
- {
- writer.WritePropertyName(property.Key);
- property.Value.WriteTo(writer);
- }
-
- writer.WriteEndObject();
- writer.Flush();
-
- resource.Properties = Encoding.UTF8.GetString(stream.ToArray());
+ resource.Properties = properties;
return ValueTask.CompletedTask;
}
diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreScopeStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreScopeStore.cs
index 80593c3e..cda95a0e 100644
--- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreScopeStore.cs
+++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreScopeStore.cs
@@ -9,10 +9,7 @@ using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Runtime.CompilerServices;
-using System.Text;
-using System.Text.Encodings.Web;
using System.Text.Json;
-using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Options;
using OpenIddict.EntityFrameworkCore.Models;
using static OpenIddict.Abstractions.OpenIddictExceptions;
@@ -25,10 +22,9 @@ namespace OpenIddict.EntityFrameworkCore;
public class OpenIddictEntityFrameworkCoreScopeStore : OpenIddictEntityFrameworkCoreScopeStore
{
public OpenIddictEntityFrameworkCoreScopeStore(
- IMemoryCache cache,
IOpenIddictEntityFrameworkCoreContext context,
IOptionsMonitor options)
- : base(cache, context, options)
+ : base(context, options)
{
}
}
@@ -42,10 +38,9 @@ public class OpenIddictEntityFrameworkCoreScopeStore<
where TKey : notnull, IEquatable
{
public OpenIddictEntityFrameworkCoreScopeStore(
- IMemoryCache cache,
IOpenIddictEntityFrameworkCoreContext context,
IOptionsMonitor options)
- : base(cache, context, options)
+ : base(context, options)
{
}
}
@@ -62,20 +57,13 @@ public class OpenIddictEntityFrameworkCoreScopeStore<
where TKey : notnull, IEquatable
{
public OpenIddictEntityFrameworkCoreScopeStore(
- IMemoryCache cache,
IOpenIddictEntityFrameworkCoreContext context,
IOptionsMonitor options)
{
- Cache = cache ?? throw new ArgumentNullException(nameof(cache));
Context = context ?? throw new ArgumentNullException(nameof(context));
Options = options ?? throw new ArgumentNullException(nameof(options));
}
- ///
- /// Gets the memory cache associated with the current store.
- ///
- protected IMemoryCache Cache { get; }
-
///
/// Gets the database context associated with the current store.
///
@@ -212,29 +200,17 @@ public class OpenIddictEntityFrameworkCoreScopeStore<
{
ArgumentException.ThrowIfNullOrEmpty(resource);
- // To optimize the efficiency of the query a bit, only scopes whose stringified
- // Resources column contains the specified resource are returned. Once the scopes
- // are retrieved, a second pass is made to ensure only valid elements are returned.
- // Implementers that use this method in a hot path may want to override this method
- // to use SQL Server 2016 functions like JSON_VALUE to make the query more efficient.
-
return ExecuteAsync(cancellationToken);
async IAsyncEnumerable ExecuteAsync([EnumeratorCancellation] CancellationToken cancellationToken)
{
var context = await Context.GetDbContextAsync(cancellationToken);
- var scopes = (from scope in context.Set().AsTracking()
- where scope.Resources!.Contains(resource)
- select scope).AsAsyncEnumerable().WithCancellation(cancellationToken);
-
- await foreach (var scope in scopes)
+ await foreach (var scope in (from scope in context.Set().AsTracking()
+ where scope.Resources!.Contains(resource)
+ select scope).AsAsyncEnumerable().WithCancellation(cancellationToken))
{
- var resources = await GetResourcesAsync(scope, cancellationToken);
- if (resources.Contains(resource, StringComparer.Ordinal))
- {
- yield return scope;
- }
+ yield return scope;
}
}
}
@@ -264,37 +240,9 @@ public class OpenIddictEntityFrameworkCoreScopeStore<
{
ArgumentNullException.ThrowIfNull(scope);
- if (string.IsNullOrEmpty(scope.Descriptions))
- {
- return new(ImmutableDictionary.Create());
- }
-
- // Note: parsing the stringified descriptions is an expensive operation.
- // To mitigate that, the resulting object is stored in the memory cache.
- var key = string.Concat("42891062-8f69-43ba-9111-db7e8ded2553", "\x1e", scope.Descriptions);
- var descriptions = Cache.GetOrCreate(key, entry =>
- {
- entry.SetPriority(CacheItemPriority.High)
- .SetSlidingExpiration(TimeSpan.FromMinutes(1));
-
- using var document = JsonDocument.Parse(scope.Descriptions);
- var builder = ImmutableDictionary.CreateBuilder();
-
- foreach (var property in document.RootElement.EnumerateObject())
- {
- var value = property.Value.GetString();
- if (string.IsNullOrEmpty(value))
- {
- continue;
- }
-
- builder[CultureInfo.GetCultureInfo(property.Name)] = value;
- }
-
- return builder.ToImmutable();
- })!;
-
- return new(descriptions);
+ return new(scope.Descriptions is { Count: > 0 } descriptions
+ ? descriptions.ToImmutableDictionary(static pair => CultureInfo.GetCultureInfo(pair.Key), static pair => pair.Value)
+ : ImmutableDictionary.Create());
}
///
@@ -310,37 +258,9 @@ public class OpenIddictEntityFrameworkCoreScopeStore<
{
ArgumentNullException.ThrowIfNull(scope);
- if (string.IsNullOrEmpty(scope.DisplayNames))
- {
- return new(ImmutableDictionary.Create());
- }
-
- // Note: parsing the stringified display names is an expensive operation.
- // To mitigate that, the resulting object is stored in the memory cache.
- var key = string.Concat("e17d437b-bdd2-43f3-974e-46d524f4bae1", "\x1e", scope.DisplayNames);
- var names = Cache.GetOrCreate(key, entry =>
- {
- entry.SetPriority(CacheItemPriority.High)
- .SetSlidingExpiration(TimeSpan.FromMinutes(1));
-
- using var document = JsonDocument.Parse(scope.DisplayNames);
- var builder = ImmutableDictionary.CreateBuilder();
-
- foreach (var property in document.RootElement.EnumerateObject())
- {
- var value = property.Value.GetString();
- if (string.IsNullOrEmpty(value))
- {
- continue;
- }
-
- builder[CultureInfo.GetCultureInfo(property.Name)] = value;
- }
-
- return builder.ToImmutable();
- })!;
-
- return new(names);
+ return new(scope.DisplayNames is { Count: > 0 } names
+ ? names.ToImmutableDictionary(static pair => CultureInfo.GetCultureInfo(pair.Key), static pair => pair.Value)
+ : []);
}
///
@@ -364,31 +284,7 @@ public class OpenIddictEntityFrameworkCoreScopeStore<
{
ArgumentNullException.ThrowIfNull(scope);
- if (string.IsNullOrEmpty(scope.Properties))
- {
- return new(ImmutableDictionary.Create());
- }
-
- // Note: parsing the stringified properties is an expensive operation.
- // To mitigate that, the resulting object is stored in the memory cache.
- var key = string.Concat("78d8dfdd-3870-442e-b62e-dc9bf6eaeff7", "\x1e", scope.Properties);
- var properties = Cache.GetOrCreate(key, entry =>
- {
- entry.SetPriority(CacheItemPriority.High)
- .SetSlidingExpiration(TimeSpan.FromMinutes(1));
-
- using var document = JsonDocument.Parse(scope.Properties);
- var builder = ImmutableDictionary.CreateBuilder();
-
- foreach (var property in document.RootElement.EnumerateObject())
- {
- builder[property.Name] = property.Value.Clone();
- }
-
- return builder.ToImmutable();
- })!;
-
- return new(properties);
+ return new(scope.Properties is { Count: > 0 } properties ? [.. properties] : []);
}
///
@@ -396,37 +292,7 @@ public class OpenIddictEntityFrameworkCoreScopeStore<
{
ArgumentNullException.ThrowIfNull(scope);
- if (string.IsNullOrEmpty(scope.Resources))
- {
- return new([]);
- }
-
- // Note: parsing the stringified resources is an expensive operation.
- // To mitigate that, the resulting array is stored in the memory cache.
- var key = string.Concat("b6148250-aede-4fb9-a621-07c9bcf238c3", "\x1e", scope.Resources);
- var resources = Cache.GetOrCreate(key, entry =>
- {
- entry.SetPriority(CacheItemPriority.High)
- .SetSlidingExpiration(TimeSpan.FromMinutes(1));
-
- using var document = JsonDocument.Parse(scope.Resources);
- var builder = ImmutableArray.CreateBuilder(document.RootElement.GetArrayLength());
-
- foreach (var element in document.RootElement.EnumerateArray())
- {
- var value = element.GetString();
- if (string.IsNullOrEmpty(value))
- {
- continue;
- }
-
- builder.Add(value);
- }
-
- return builder.ToImmutable();
- });
-
- return new(resources);
+ return new(scope.Resources is { Length: > 0 } resources ? [.. resources] : []);
}
///
@@ -504,32 +370,9 @@ public class OpenIddictEntityFrameworkCoreScopeStore<
{
ArgumentNullException.ThrowIfNull(scope);
- if (descriptions is not { Count: > 0 })
- {
- scope.Descriptions = null;
-
- return ValueTask.CompletedTask;
- }
-
- using var stream = new MemoryStream();
- using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
- {
- Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
- Indented = false
- });
-
- writer.WriteStartObject();
-
- foreach (var description in descriptions)
- {
- writer.WritePropertyName(description.Key.Name);
- writer.WriteStringValue(description.Value);
- }
-
- writer.WriteEndObject();
- writer.Flush();
-
- scope.Descriptions = Encoding.UTF8.GetString(stream.ToArray());
+ scope.Descriptions = descriptions is { Count: > 0 }
+ ? descriptions.ToImmutableDictionary(static pair => pair.Key.Name, static pair => pair.Value)
+ : null;
return ValueTask.CompletedTask;
}
@@ -550,32 +393,9 @@ public class OpenIddictEntityFrameworkCoreScopeStore<
{
ArgumentNullException.ThrowIfNull(scope);
- if (names is not { Count: > 0 })
- {
- scope.DisplayNames = null;
-
- return ValueTask.CompletedTask;
- }
-
- using var stream = new MemoryStream();
- using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
- {
- Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
- Indented = false
- });
-
- writer.WriteStartObject();
-
- foreach (var name in names)
- {
- writer.WritePropertyName(name.Key.Name);
- writer.WriteStringValue(name.Value);
- }
-
- writer.WriteEndObject();
- writer.Flush();
-
- scope.DisplayNames = Encoding.UTF8.GetString(stream.ToArray());
+ scope.DisplayNames = names is { Count: > 0 }
+ ? names.ToImmutableDictionary(static pair => pair.Key.Name, static pair => pair.Value)
+ : null;
return ValueTask.CompletedTask;
}
@@ -596,32 +416,7 @@ public class OpenIddictEntityFrameworkCoreScopeStore<
{
ArgumentNullException.ThrowIfNull(scope);
- if (properties is not { Count: > 0 })
- {
- scope.Properties = null;
-
- return ValueTask.CompletedTask;
- }
-
- using var stream = new MemoryStream();
- using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
- {
- Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
- Indented = false
- });
-
- writer.WriteStartObject();
-
- foreach (var property in properties)
- {
- writer.WritePropertyName(property.Key);
- property.Value.WriteTo(writer);
- }
-
- writer.WriteEndObject();
- writer.Flush();
-
- scope.Properties = Encoding.UTF8.GetString(stream.ToArray());
+ scope.Properties = properties;
return ValueTask.CompletedTask;
}
@@ -638,24 +433,7 @@ public class OpenIddictEntityFrameworkCoreScopeStore<
return ValueTask.CompletedTask;
}
- using var stream = new MemoryStream();
- using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
- {
- Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
- Indented = false
- });
-
- writer.WriteStartArray();
-
- foreach (var resource in resources)
- {
- writer.WriteStringValue(resource);
- }
-
- writer.WriteEndArray();
- writer.Flush();
-
- scope.Resources = Encoding.UTF8.GetString(stream.ToArray());
+ scope.Resources = resources.ToArray();
return ValueTask.CompletedTask;
}
diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreTokenStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreTokenStore.cs
index d21d45df..e67eb4db 100644
--- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreTokenStore.cs
+++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreTokenStore.cs
@@ -9,10 +9,7 @@ using System.ComponentModel;
using System.Data;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
-using System.Text;
-using System.Text.Encodings.Web;
using System.Text.Json;
-using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Options;
using OpenIddict.EntityFrameworkCore.Models;
using static OpenIddict.Abstractions.OpenIddictExceptions;
@@ -28,10 +25,9 @@ public class OpenIddictEntityFrameworkCoreTokenStore :
OpenIddictEntityFrameworkCoreAuthorization, string>
{
public OpenIddictEntityFrameworkCoreTokenStore(
- IMemoryCache cache,
IOpenIddictEntityFrameworkCoreContext context,
IOptionsMonitor options)
- : base(cache, context, options)
+ : base(context, options)
{
}
}
@@ -48,10 +44,9 @@ public class OpenIddictEntityFrameworkCoreTokenStore<
where TKey : notnull, IEquatable
{
public OpenIddictEntityFrameworkCoreTokenStore(
- IMemoryCache cache,
IOpenIddictEntityFrameworkCoreContext context,
IOptionsMonitor options)
- : base(cache, context, options)
+ : base(context, options)
{
}
}
@@ -74,20 +69,13 @@ public class OpenIddictEntityFrameworkCoreTokenStore<
where TKey : notnull, IEquatable
{
public OpenIddictEntityFrameworkCoreTokenStore(
- IMemoryCache cache,
IOpenIddictEntityFrameworkCoreContext context,
IOptionsMonitor options)
{
- Cache = cache ?? throw new ArgumentNullException(nameof(cache));
Context = context ?? throw new ArgumentNullException(nameof(context));
Options = options ?? throw new ArgumentNullException(nameof(options));
}
- ///
- /// Gets the memory cache associated with the current store.
- ///
- protected IMemoryCache Cache { get; }
-
///
/// Gets the database context associated with the current store.
///
@@ -400,12 +388,7 @@ public class OpenIddictEntityFrameworkCoreTokenStore<
{
ArgumentNullException.ThrowIfNull(token);
- if (token.CreationDate is null)
- {
- return new(result: null);
- }
-
- return new(DateTime.SpecifyKind(token.CreationDate.Value, DateTimeKind.Utc));
+ return new(token.CreationDate is DateTime date ? DateTime.SpecifyKind(date, DateTimeKind.Utc) : null);
}
///
@@ -413,12 +396,7 @@ public class OpenIddictEntityFrameworkCoreTokenStore<
{
ArgumentNullException.ThrowIfNull(token);
- if (token.ExpirationDate is null)
- {
- return new(result: null);
- }
-
- return new(DateTime.SpecifyKind(token.ExpirationDate.Value, DateTimeKind.Utc));
+ return new(token.ExpirationDate is DateTime date ? DateTime.SpecifyKind(date, DateTimeKind.Utc) : null);
}
///
@@ -442,31 +420,7 @@ public class OpenIddictEntityFrameworkCoreTokenStore<
{
ArgumentNullException.ThrowIfNull(token);
- if (string.IsNullOrEmpty(token.Properties))
- {
- return new(ImmutableDictionary.Create());
- }
-
- // Note: parsing the stringified properties is an expensive operation.
- // To mitigate that, the resulting object is stored in the memory cache.
- var key = string.Concat("d0509397-1bbf-40e7-97e1-5e6d7bc2536c", "\x1e", token.Properties);
- var properties = Cache.GetOrCreate(key, entry =>
- {
- entry.SetPriority(CacheItemPriority.High)
- .SetSlidingExpiration(TimeSpan.FromMinutes(1));
-
- using var document = JsonDocument.Parse(token.Properties);
- var builder = ImmutableDictionary.CreateBuilder();
-
- foreach (var property in document.RootElement.EnumerateObject())
- {
- builder[property.Name] = property.Value.Clone();
- }
-
- return builder.ToImmutable();
- })!;
-
- return new(properties);
+ return new(token.Properties is { Count: > 0 } properties ? [.. properties] : []);
}
///
@@ -474,12 +428,7 @@ public class OpenIddictEntityFrameworkCoreTokenStore<
{
ArgumentNullException.ThrowIfNull(token);
- if (token.RedemptionDate is null)
- {
- return new(result: null);
- }
-
- return new(DateTime.SpecifyKind(token.RedemptionDate.Value, DateTimeKind.Utc));
+ return new(token.RedemptionDate is DateTime date ? DateTime.SpecifyKind(date, DateTimeKind.Utc) : null);
}
///
@@ -1070,32 +1019,7 @@ public class OpenIddictEntityFrameworkCoreTokenStore<
{
ArgumentNullException.ThrowIfNull(token);
- if (properties is not { Count: > 0 })
- {
- token.Properties = null;
-
- return ValueTask.CompletedTask;
- }
-
- using var stream = new MemoryStream();
- using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions
- {
- Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
- Indented = false
- });
-
- writer.WriteStartObject();
-
- foreach (var property in properties)
- {
- writer.WritePropertyName(property.Key);
- property.Value.WriteTo(writer);
- }
-
- writer.WriteEndObject();
- writer.Flush();
-
- token.Properties = Encoding.UTF8.GetString(stream.ToArray());
+ token.Properties = properties;
return ValueTask.CompletedTask;
}
diff --git a/src/OpenIddict.MongoDb.Models/OpenIddictMongoDbApplication.cs b/src/OpenIddict.MongoDb.Models/OpenIddictMongoDbApplication.cs
index 87f09f94..ab7a6c87 100644
--- a/src/OpenIddict.MongoDb.Models/OpenIddictMongoDbApplication.cs
+++ b/src/OpenIddict.MongoDb.Models/OpenIddictMongoDbApplication.cs
@@ -16,105 +16,109 @@ namespace OpenIddict.MongoDb.Models;
public class OpenIddictMongoDbApplication
{
///
- /// Gets or sets the application type associated with the current application.
+ /// Gets or sets the application type of the application.
///
[BsonElement("application_type"), BsonIgnoreIfNull]
public virtual string? ApplicationType { get; set; }
///
- /// Gets or sets the client identifier associated with the current application.
+ /// Gets or sets the client identifier of the application.
///
[BsonElement("client_id"), BsonIgnoreIfNull]
public virtual string? ClientId { get; set; }
///
- /// Gets or sets the client secret associated with the current application.
- /// Note: depending on the application manager used to create this instance,
- /// this property may be hashed or encrypted for security reasons.
+ /// Gets or sets the client secret of the application.
///
///
+ ///
+ /// Note: depending on the application manager used to create this instance,
+ /// this property may be hashed or encrypted for security reasons.
+ ///
+ ///
/// Note: client authentication based on shared secrets is not recommended and should
/// only be used for backward compatibility with legacy applications that only support
/// client secrets. When possible, consider using public/private key pairs or TLS client
/// certificates instead, as these client authentication methods are significantly safer.
+ ///
///
[BsonElement("client_secret"), BsonIgnoreIfNull]
public virtual string? ClientSecret { get; set; }
///
- /// Gets or sets the client type associated with the current application.
+ /// Gets or sets the client type of the application.
///
[BsonElement("client_type"), BsonIgnoreIfNull]
public virtual string? ClientType { get; set; }
///
- /// Gets or sets the concurrency token.
+ /// Gets or sets the concurrency token of the application.
///
[BsonElement("concurrency_token"), BsonIgnoreIfNull]
public virtual string? ConcurrencyToken { get; set; } = Guid.NewGuid().ToString();
///
- /// Gets or sets the consent type associated with the current application.
+ /// Gets or sets the consent type of the application.
///
[BsonElement("consent_type"), BsonIgnoreIfNull]
public virtual string? ConsentType { get; set; }
///
- /// Gets or sets the display name associated with the current application.
+ /// Gets or sets the display name of the application.
///
[BsonElement("display_name"), BsonIgnoreIfNull]
public virtual string? DisplayName { get; set; }
///
- /// Gets or sets the localized display names associated with the current application.
+ /// Gets or sets the localized display names of the application.
///
[BsonElement("display_names"), BsonIgnoreIfNull]
public virtual ImmutableDictionary? DisplayNames { get; set; }
///
- /// Gets or sets the unique identifier associated with the current application.
+ /// Gets or sets the unique identifier of the application.
///
[BsonId, BsonRequired]
public virtual ObjectId Id { get; set; }
///
- /// Gets or sets the JSON Web Key Set associated with the application.
+ /// Gets or sets the JSON Web Key Set of the application.
///
[BsonElement("json_web_key_set"), BsonIgnoreIfNull]
public virtual BsonDocument? JsonWebKeySet { get; set; }
///
- /// Gets or sets the permissions associated with the current application.
+ /// Gets or sets the permissions of the application.
///
[BsonElement("permissions"), BsonIgnoreIfNull]
public virtual ImmutableArray? Permissions { get; set; }
///
- /// Gets or sets the post-logout redirect URIs associated with the current application.
+ /// Gets or sets the post-logout redirect URIs of the application.
///
[BsonElement("post_logout_redirect_uris"), BsonIgnoreIfNull]
public virtual ImmutableArray? PostLogoutRedirectUris { get; set; }
///
- /// Gets or sets the additional properties associated with the current application.
+ /// Gets or sets the additional properties of the application.
///
[BsonElement("properties"), BsonIgnoreIfNull]
public virtual BsonDocument? Properties { get; set; }
///
- /// Gets or sets the redirect URIs associated with the current application.
+ /// Gets or sets the redirect URIs of the application.
///
[BsonElement("redirect_uris"), BsonIgnoreIfNull]
public virtual ImmutableArray? RedirectUris { get; set; }
///
- /// Gets or sets the requirements associated with the current application.
+ /// Gets or sets the requirements of the application.
///
[BsonElement("requirements"), BsonIgnoreIfNull]
public virtual ImmutableArray? Requirements { get; set; }
///
- /// Gets or sets the settings associated with the current application.
+ /// Gets or sets the settings of the application.
///
[BsonElement("settings"), BsonIgnoreIfNull]
public virtual ImmutableDictionary? Settings { get; set; }
diff --git a/src/OpenIddict.MongoDb.Models/OpenIddictMongoDbAuthorization.cs b/src/OpenIddict.MongoDb.Models/OpenIddictMongoDbAuthorization.cs
index df91d6df..cd71d00f 100644
--- a/src/OpenIddict.MongoDb.Models/OpenIddictMongoDbAuthorization.cs
+++ b/src/OpenIddict.MongoDb.Models/OpenIddictMongoDbAuthorization.cs
@@ -16,55 +16,55 @@ namespace OpenIddict.MongoDb.Models;
public class OpenIddictMongoDbAuthorization
{
///
- /// Gets or sets the identifier of the application associated with the current authorization.
+ /// Gets or sets the identifier of the application associated with the authorization.
///
[BsonElement("application_id"), BsonIgnoreIfDefault]
public virtual ObjectId ApplicationId { get; set; }
///
- /// Gets or sets the concurrency token.
+ /// Gets or sets the concurrency token of the authorization.
///
[BsonElement("concurrency_token"), BsonIgnoreIfNull]
public virtual string? ConcurrencyToken { get; set; } = Guid.NewGuid().ToString();
///
- /// Gets or sets the UTC creation date of the current authorization.
+ /// Gets or sets the UTC creation date of the authorization.
///
[BsonElement("creation_date"), BsonIgnoreIfNull]
public virtual DateTime? CreationDate { get; set; }
///
- /// Gets or sets the unique identifier associated with the current authorization.
+ /// Gets or sets the unique identifier of the authorization.
///
[BsonId, BsonRequired]
public virtual ObjectId Id { get; set; }
///
- /// Gets or sets the additional properties associated with the current authorization.
+ /// Gets or sets the additional properties of the authorization.
///
[BsonElement("properties"), BsonIgnoreIfNull]
public virtual BsonDocument? Properties { get; set; }
///
- /// Gets or sets the scopes associated with the current authorization.
+ /// Gets or sets the scopes of the authorization.
///
[BsonElement("scopes"), BsonIgnoreIfNull]
public virtual ImmutableArray? Scopes { get; set; }
///
- /// Gets or sets the status of the current authorization.
+ /// Gets or sets the status of the authorization.
///
[BsonElement("status"), BsonIgnoreIfNull]
public virtual string? Status { get; set; }
///
- /// Gets or sets the subject associated with the current authorization.
+ /// Gets or sets the subject associated with the authorization.
///
[BsonElement("subject"), BsonIgnoreIfNull]
public virtual string? Subject { get; set; }
///
- /// Gets or sets the type of the current authorization.
+ /// Gets or sets the type of the authorization.
///
[BsonElement("type"), BsonIgnoreIfNull]
public virtual string? Type { get; set; }
diff --git a/src/OpenIddict.MongoDb.Models/OpenIddictMongoDbResource.cs b/src/OpenIddict.MongoDb.Models/OpenIddictMongoDbResource.cs
index 76109501..b22bc969 100644
--- a/src/OpenIddict.MongoDb.Models/OpenIddictMongoDbResource.cs
+++ b/src/OpenIddict.MongoDb.Models/OpenIddictMongoDbResource.cs
@@ -16,49 +16,49 @@ namespace OpenIddict.MongoDb.Models;
public class OpenIddictMongoDbResource
{
///
- /// Gets or sets the concurrency token.
+ /// Gets or sets the concurrency token of the resource.
///
[BsonElement("concurrency_token"), BsonIgnoreIfNull]
public virtual string? ConcurrencyToken { get; set; } = Guid.NewGuid().ToString();
///
- /// Gets or sets the public description associated with the current resource.
+ /// Gets or sets the public description of the resource.
///
[BsonElement("description"), BsonIgnoreIfNull]
public virtual string? Description { get; set; }
///
- /// Gets or sets the localized public descriptions associated with the current resource.
+ /// Gets or sets the localized public descriptions of the resource.
///
[BsonElement("descriptions"), BsonIgnoreIfNull]
public virtual ImmutableDictionary? Descriptions { get; set; }
///
- /// Gets or sets the display name associated with the current resource.
+ /// Gets or sets the display name of the resource.
///
[BsonElement("display_name"), BsonIgnoreIfNull]
public virtual string? DisplayName { get; set; }
///
- /// Gets or sets the localized display names associated with the current resource.
+ /// Gets or sets the localized display names of the resource.
///
[BsonElement("display_names"), BsonIgnoreIfNull]
public virtual ImmutableDictionary? DisplayNames { get; set; }
///
- /// Gets or sets the unique identifier associated with the current resource.
+ /// Gets or sets the unique identifier of the resource.
///
[BsonId, BsonRequired]
public virtual ObjectId Id { get; set; }
///
- /// Gets or sets the unique name associated with the current resource.
+ /// Gets or sets the unique name of the resource.
///
[BsonElement("name"), BsonIgnoreIfNull]
public virtual string? Name { get; set; }
///
- /// Gets or sets the additional properties associated with the current resource.
+ /// Gets or sets the additional properties of the resource.
///
[BsonElement("properties"), BsonIgnoreIfNull]
public virtual BsonDocument? Properties { get; set; }
diff --git a/src/OpenIddict.MongoDb.Models/OpenIddictMongoDbScope.cs b/src/OpenIddict.MongoDb.Models/OpenIddictMongoDbScope.cs
index 227c9866..9bec260f 100644
--- a/src/OpenIddict.MongoDb.Models/OpenIddictMongoDbScope.cs
+++ b/src/OpenIddict.MongoDb.Models/OpenIddictMongoDbScope.cs
@@ -16,55 +16,55 @@ namespace OpenIddict.MongoDb.Models;
public class OpenIddictMongoDbScope
{
///
- /// Gets or sets the concurrency token.
+ /// Gets or sets the concurrency token of the scope.
///
[BsonElement("concurrency_token"), BsonIgnoreIfNull]
public virtual string? ConcurrencyToken { get; set; } = Guid.NewGuid().ToString();
///
- /// Gets or sets the public description associated with the current scope.
+ /// Gets or sets the public description of the scope.
///
[BsonElement("description"), BsonIgnoreIfNull]
public virtual string? Description { get; set; }
///
- /// Gets or sets the localized public descriptions associated with the current scope.
+ /// Gets or sets the localized public descriptions of the scope.
///
[BsonElement("descriptions"), BsonIgnoreIfNull]
public virtual ImmutableDictionary? Descriptions { get; set; }
///
- /// Gets or sets the display name associated with the current scope.
+ /// Gets or sets the display name of the scope.
///
[BsonElement("display_name"), BsonIgnoreIfNull]
public virtual string? DisplayName { get; set; }
///
- /// Gets or sets the localized display names associated with the current scope.
+ /// Gets or sets the localized display names of the scope.
///
[BsonElement("display_names"), BsonIgnoreIfNull]
public virtual ImmutableDictionary? DisplayNames { get; set; }
///
- /// Gets or sets the unique identifier associated with the current scope.
+ /// Gets or sets the unique identifier of the scope.
///
[BsonId, BsonRequired]
public virtual ObjectId Id { get; set; }
///
- /// Gets or sets the unique name associated with the current scope.
+ /// Gets or sets the unique name of the scope.
///
[BsonElement("name"), BsonIgnoreIfNull]
public virtual string? Name { get; set; }
///
- /// Gets or sets the additional properties associated with the current scope.
+ /// Gets or sets the additional properties of the scope.
///
[BsonElement("properties"), BsonIgnoreIfNull]
public virtual BsonDocument? Properties { get; set; }
///
- /// Gets or sets the resources associated with the current scope.
+ /// Gets or sets the resources associated with the scope.
///
[BsonElement("resources"), BsonIgnoreIfNull]
public virtual ImmutableArray? Resources { get; set; }
diff --git a/src/OpenIddict.MongoDb.Models/OpenIddictMongoDbToken.cs b/src/OpenIddict.MongoDb.Models/OpenIddictMongoDbToken.cs
index f566ef68..063759a6 100644
--- a/src/OpenIddict.MongoDb.Models/OpenIddictMongoDbToken.cs
+++ b/src/OpenIddict.MongoDb.Models/OpenIddictMongoDbToken.cs
@@ -15,84 +15,87 @@ namespace OpenIddict.MongoDb.Models;
public class OpenIddictMongoDbToken
{
///
- /// Gets or sets the identifier of the application associated with the current token.
+ /// Gets or sets the identifier of the application associated with the token.
///
[BsonElement("application_id"), BsonIgnoreIfDefault]
public virtual ObjectId ApplicationId { get; set; }
///
- /// Gets or sets the identifier of the authorization associated with the current token.
+ /// Gets or sets the identifier of the authorization associated with the token.
///
[BsonElement("authorization_id"), BsonIgnoreIfDefault]
public virtual ObjectId AuthorizationId { get; set; }
///
- /// Gets or sets the concurrency token.
+ /// Gets or sets the concurrency token of the token.
///
[BsonElement("concurrency_token"), BsonIgnoreIfNull]
public virtual string? ConcurrencyToken { get; set; } = Guid.NewGuid().ToString();
///
- /// Gets or sets the UTC creation date of the current token.
+ /// Gets or sets the UTC creation date of the token.
///
[BsonElement("creation_date"), BsonIgnoreIfNull]
public virtual DateTime? CreationDate { get; set; }
///
- /// Gets or sets the UTC expiration date of the current token.
+ /// Gets or sets the UTC expiration date of the token.
///
[BsonElement("expiration_date"), BsonIgnoreIfNull]
public virtual DateTime? ExpirationDate { get; set; }
///
- /// Gets or sets the unique identifier associated with the current token.
+ /// Gets or sets the unique identifier of the token.
///
[BsonId, BsonRequired]
public virtual ObjectId Id { get; set; }
///
- /// Gets or sets the payload of the current token, if applicable.
- /// Note: this property is only used for reference tokens
- /// and may be encrypted for security reasons.
+ /// Gets or sets the payload of the token.
///
+ ///
+ /// Note: this property is only used for reference tokens
+ /// and may be hashed or encrypted for security reasons.
+ ///
[BsonElement("payload"), BsonIgnoreIfNull]
public virtual string? Payload { get; set; }
///
- /// Gets or sets the additional properties associated with the current token.
+ /// Gets or sets the additional properties associated with the token.
///
[BsonElement("properties"), BsonIgnoreIfNull]
public virtual BsonDocument? Properties { get; set; }
///
- /// Gets or sets the UTC redemption date of the current token.
+ /// Gets or sets the UTC redemption date of the token.
///
[BsonElement("redemption_date"), BsonIgnoreIfNull]
public virtual DateTime? RedemptionDate { get; set; }
///
- /// Gets or sets the reference identifier associated
- /// with the current token, if applicable.
+ /// Gets or sets the reference identifier associated with the token.
+ ///
+ ///
/// Note: this property is only used for reference tokens
/// and may be hashed or encrypted for security reasons.
- ///
+ ///
[BsonElement("reference_id"), BsonIgnoreIfNull]
public virtual string? ReferenceId { get; set; }
///
- /// Gets or sets the status of the current token.
+ /// Gets or sets the status of the token.
///
[BsonElement("status"), BsonIgnoreIfNull]
public virtual string? Status { get; set; }
///
- /// Gets or sets the subject associated with the current token.
+ /// Gets or sets the subject associated with the token.
///
[BsonElement("subject"), BsonIgnoreIfNull]
public virtual string? Subject { get; set; }
///
- /// Gets or sets the type of the current token.
+ /// Gets or sets the type of the token.
///
[BsonElement("type"), BsonIgnoreIfNull]
public virtual string? Type { get; set; }
diff --git a/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbApplicationStore.cs b/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbApplicationStore.cs
index a6174f00..a80b3735 100644
--- a/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbApplicationStore.cs
+++ b/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbApplicationStore.cs
@@ -263,12 +263,7 @@ public class OpenIddictMongoDbApplicationStore<
{
ArgumentNullException.ThrowIfNull(application);
- if (application.JsonWebKeySet is null)
- {
- return new(result: null);
- }
-
- return new(JsonWebKeySet.Create(application.JsonWebKeySet.ToJson()));
+ return new(application.JsonWebKeySet is BsonDocument set ? JsonWebKeySet.Create(set.ToJson()) : null);
}
///
diff --git a/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbAuthorizationStore.cs b/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbAuthorizationStore.cs
index 6adaa4de..b350b43c 100644
--- a/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbAuthorizationStore.cs
+++ b/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbAuthorizationStore.cs
@@ -211,12 +211,7 @@ public class OpenIddictMongoDbAuthorizationStore<
{
ArgumentNullException.ThrowIfNull(authorization);
- if (authorization.ApplicationId == ObjectId.Empty)
- {
- return new(result: null);
- }
-
- return new(authorization.ApplicationId.ToString());
+ return new(authorization.ApplicationId != ObjectId.Empty ? authorization.ApplicationId.ToString() : null);
}
///
@@ -237,12 +232,7 @@ public class OpenIddictMongoDbAuthorizationStore<
{
ArgumentNullException.ThrowIfNull(authorization);
- if (authorization.CreationDate is null)
- {
- return new(result: null);
- }
-
- return new(DateTime.SpecifyKind(authorization.CreationDate.Value, DateTimeKind.Utc));
+ return new(authorization.CreationDate is DateTime date ? DateTime.SpecifyKind(date, DateTimeKind.Utc) : null);
}
///
diff --git a/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbTokenStore.cs b/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbTokenStore.cs
index ec935d4c..541c18e4 100644
--- a/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbTokenStore.cs
+++ b/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbTokenStore.cs
@@ -226,12 +226,7 @@ public class OpenIddictMongoDbTokenStore<
{
ArgumentNullException.ThrowIfNull(token);
- if (token.ApplicationId == ObjectId.Empty)
- {
- return new(result: null);
- }
-
- return new(token.ApplicationId.ToString());
+ return new(token.ApplicationId != ObjectId.Empty ? token.ApplicationId.ToString() : null);
}
///
@@ -252,12 +247,7 @@ public class OpenIddictMongoDbTokenStore<
{
ArgumentNullException.ThrowIfNull(token);
- if (token.AuthorizationId == ObjectId.Empty)
- {
- return new(result: null);
- }
-
- return new(token.AuthorizationId.ToString());
+ return new(token.AuthorizationId != ObjectId.Empty ? token.AuthorizationId.ToString() : null);
}
///
@@ -265,12 +255,7 @@ public class OpenIddictMongoDbTokenStore<
{
ArgumentNullException.ThrowIfNull(token);
- if (token.CreationDate is null)
- {
- return new(result: null);
- }
-
- return new(DateTime.SpecifyKind(token.CreationDate.Value, DateTimeKind.Utc));
+ return new(token.CreationDate is DateTime date ? DateTime.SpecifyKind(date, DateTimeKind.Utc) : null);
}
///
@@ -278,12 +263,7 @@ public class OpenIddictMongoDbTokenStore<
{
ArgumentNullException.ThrowIfNull(token);
- if (token.ExpirationDate is null)
- {
- return new(result: null);
- }
-
- return new(DateTime.SpecifyKind(token.ExpirationDate.Value, DateTimeKind.Utc));
+ return new(token.ExpirationDate is DateTime date ? DateTime.SpecifyKind(date, DateTimeKind.Utc) : null);
}
///
@@ -328,12 +308,7 @@ public class OpenIddictMongoDbTokenStore<
{
ArgumentNullException.ThrowIfNull(token);
- if (token.RedemptionDate is null)
- {
- return new(result: null);
- }
-
- return new(DateTime.SpecifyKind(token.RedemptionDate.Value, DateTimeKind.Utc));
+ return new(token.RedemptionDate is DateTime date ? DateTime.SpecifyKind(date, DateTimeKind.Utc) : null);
}
///