diff --git a/src/OpenIddict.Core/Descriptors/OpenIddictAuthorizationDescriptor.cs b/src/OpenIddict.Core/Descriptors/OpenIddictAuthorizationDescriptor.cs
index 292de19e..a34603f9 100644
--- a/src/OpenIddict.Core/Descriptors/OpenIddictAuthorizationDescriptor.cs
+++ b/src/OpenIddict.Core/Descriptors/OpenIddictAuthorizationDescriptor.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Security.Claims;
namespace OpenIddict.Core
{
@@ -13,6 +14,19 @@ namespace OpenIddict.Core
///
public string ApplicationId { get; set; }
+ ///
+ /// Gets or sets the optional principal associated with the authorization.
+ /// Note: this property is not stored by the default authorization stores.
+ ///
+ public ClaimsPrincipal Principal { get; set; }
+
+ ///
+ /// Gets the optional authentication properties associated with the authorization.
+ /// Note: this property is not stored by the default authorization stores.
+ ///
+ public IDictionary Properties { get; } =
+ new Dictionary(StringComparer.Ordinal);
+
///
/// Gets the scopes associated with the authorization.
///
diff --git a/src/OpenIddict.Core/Descriptors/OpenIddictScopeDescriptor.cs b/src/OpenIddict.Core/Descriptors/OpenIddictScopeDescriptor.cs
index edcc69d4..9900a704 100644
--- a/src/OpenIddict.Core/Descriptors/OpenIddictScopeDescriptor.cs
+++ b/src/OpenIddict.Core/Descriptors/OpenIddictScopeDescriptor.cs
@@ -5,6 +5,12 @@
///
public class OpenIddictScopeDescriptor
{
+ ///
+ /// Gets or sets the description
+ /// associated with the scope.
+ ///
+ public virtual string Description { get; set; }
+
///
/// Gets or sets the unique name
/// associated with the scope.
diff --git a/src/OpenIddict.Core/Descriptors/OpenIddictTokenDescriptor.cs b/src/OpenIddict.Core/Descriptors/OpenIddictTokenDescriptor.cs
index 258713a9..370ccd07 100644
--- a/src/OpenIddict.Core/Descriptors/OpenIddictTokenDescriptor.cs
+++ b/src/OpenIddict.Core/Descriptors/OpenIddictTokenDescriptor.cs
@@ -1,4 +1,6 @@
using System;
+using System.Collections.Generic;
+using System.Security.Claims;
namespace OpenIddict.Core
{
@@ -37,6 +39,19 @@ namespace OpenIddict.Core
///
public string Hash { get; set; }
+ ///
+ /// Gets or sets the optional principal associated with the token.
+ /// Note: this property is not stored by the default token stores.
+ ///
+ public ClaimsPrincipal Principal { get; set; }
+
+ ///
+ /// Gets the optional authentication properties associated with the token.
+ /// Note: this property is not stored by the default token stores.
+ ///
+ public IDictionary Properties { get; } =
+ new Dictionary(StringComparer.Ordinal);
+
///
/// Gets or sets the status associated with the token.
///
diff --git a/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs b/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs
index c5848836..a16ccc00 100644
--- a/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs
+++ b/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs
@@ -244,8 +244,13 @@ namespace OpenIddict.Core
/// A that can be used to monitor the asynchronous operation,
/// whose result returns the client application corresponding to the identifier.
///
- public virtual Task FindByIdAsync(string identifier, CancellationToken cancellationToken)
+ public virtual Task FindByIdAsync([NotNull] string identifier, CancellationToken cancellationToken)
{
+ if (string.IsNullOrEmpty(identifier))
+ {
+ throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier));
+ }
+
return Store.FindByIdAsync(identifier, cancellationToken);
}
@@ -258,8 +263,13 @@ namespace OpenIddict.Core
/// A that can be used to monitor the asynchronous operation,
/// whose result returns the client application corresponding to the identifier.
///
- public virtual Task FindByClientIdAsync(string identifier, CancellationToken cancellationToken)
+ public virtual Task FindByClientIdAsync([NotNull] string identifier, CancellationToken cancellationToken)
{
+ if (string.IsNullOrEmpty(identifier))
+ {
+ throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier));
+ }
+
return Store.FindByClientIdAsync(identifier, cancellationToken);
}
@@ -408,25 +418,6 @@ namespace OpenIddict.Core
return Store.GetIdAsync(application, cancellationToken);
}
- ///
- /// Retrieves the token identifiers associated with an application.
- ///
- /// The application.
- /// The that can be used to abort the operation.
- ///
- /// A that can be used to monitor the asynchronous operation,
- /// whose result returns the tokens associated with the application.
- ///
- public virtual Task> GetTokensAsync([NotNull] TApplication application, CancellationToken cancellationToken)
- {
- if (application == null)
- {
- throw new ArgumentNullException(nameof(application));
- }
-
- return Store.GetTokensAsync(application, cancellationToken);
- }
-
///
/// Determines whether an application is a confidential client.
///
diff --git a/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs b/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs
index c2ba9021..96989e46 100644
--- a/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs
+++ b/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs
@@ -182,8 +182,18 @@ namespace OpenIddict.Core
/// A that can be used to monitor the asynchronous operation,
/// whose result returns the authorization corresponding to the subject/client.
///
- public virtual Task FindAsync(string subject, string client, CancellationToken cancellationToken)
+ public virtual Task FindAsync([NotNull] string subject, [NotNull] string client, CancellationToken cancellationToken)
{
+ if (string.IsNullOrEmpty(subject))
+ {
+ throw new ArgumentException("The subject cannot be null or empty.", nameof(subject));
+ }
+
+ if (string.IsNullOrEmpty(client))
+ {
+ throw new ArgumentException("The client identifier cannot be null or empty.", nameof(client));
+ }
+
return Store.FindAsync(subject, client, cancellationToken);
}
@@ -196,8 +206,13 @@ namespace OpenIddict.Core
/// A that can be used to monitor the asynchronous operation,
/// whose result returns the authorization corresponding to the identifier.
///
- public virtual Task FindByIdAsync(string identifier, CancellationToken cancellationToken)
+ public virtual Task FindByIdAsync([NotNull] string identifier, CancellationToken cancellationToken)
{
+ if (string.IsNullOrEmpty(identifier))
+ {
+ throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier));
+ }
+
return Store.FindByIdAsync(identifier, cancellationToken);
}
diff --git a/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs b/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs
index 8956a2d4..a67f547e 100644
--- a/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs
+++ b/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs
@@ -179,6 +179,25 @@ namespace OpenIddict.Core
await UpdateAsync(token, cancellationToken);
}
+ ///
+ /// Retrieves the list of tokens corresponding to the specified application identifier.
+ ///
+ /// The application identifier associated with the tokens.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the tokens corresponding to the specified application.
+ ///
+ public virtual Task> FindByApplicationIdAsync([NotNull] string identifier, CancellationToken cancellationToken)
+ {
+ if (string.IsNullOrEmpty(identifier))
+ {
+ throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier));
+ }
+
+ return Store.FindByApplicationIdAsync(identifier, cancellationToken);
+ }
+
///
/// Retrieves the list of tokens corresponding to the specified authorization identifier.
///
@@ -188,8 +207,13 @@ namespace OpenIddict.Core
/// A that can be used to monitor the asynchronous operation,
/// whose result returns the tokens corresponding to the specified authorization.
///
- public virtual Task> FindByAuthorizationIdAsync(string identifier, CancellationToken cancellationToken)
+ public virtual Task> FindByAuthorizationIdAsync([NotNull] string identifier, CancellationToken cancellationToken)
{
+ if (string.IsNullOrEmpty(identifier))
+ {
+ throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier));
+ }
+
return Store.FindByAuthorizationIdAsync(identifier, cancellationToken);
}
@@ -202,8 +226,13 @@ namespace OpenIddict.Core
/// A that can be used to monitor the asynchronous operation,
/// whose result returns the tokens corresponding to the specified hash.
///
- public virtual Task FindByHashAsync(string hash, CancellationToken cancellationToken)
+ public virtual Task FindByHashAsync([NotNull] string hash, CancellationToken cancellationToken)
{
+ if (string.IsNullOrEmpty(hash))
+ {
+ throw new ArgumentException("The hash cannot be null or empty.", nameof(hash));
+ }
+
return Store.FindByHashAsync(hash, cancellationToken);
}
@@ -216,8 +245,13 @@ namespace OpenIddict.Core
/// A that can be used to monitor the asynchronous operation,
/// whose result returns the token corresponding to the unique identifier.
///
- public virtual Task FindByIdAsync(string identifier, CancellationToken cancellationToken)
+ public virtual Task FindByIdAsync([NotNull] string identifier, CancellationToken cancellationToken)
{
+ if (string.IsNullOrEmpty(identifier))
+ {
+ throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier));
+ }
+
return Store.FindByIdAsync(identifier, cancellationToken);
}
@@ -230,8 +264,13 @@ namespace OpenIddict.Core
/// A that can be used to monitor the asynchronous operation,
/// whose result returns the tokens corresponding to the specified subject.
///
- public virtual Task> FindBySubjectAsync(string subject, CancellationToken cancellationToken)
+ public virtual Task> FindBySubjectAsync([NotNull] string subject, CancellationToken cancellationToken)
{
+ if (string.IsNullOrEmpty(subject))
+ {
+ throw new ArgumentException("The subject cannot be null or empty.", nameof(subject));
+ }
+
return Store.FindBySubjectAsync(subject, cancellationToken);
}
diff --git a/src/OpenIddict.Core/Stores/IOpenIddictApplicationStore.cs b/src/OpenIddict.Core/Stores/IOpenIddictApplicationStore.cs
index b228dd2b..43157bc3 100644
--- a/src/OpenIddict.Core/Stores/IOpenIddictApplicationStore.cs
+++ b/src/OpenIddict.Core/Stores/IOpenIddictApplicationStore.cs
@@ -207,17 +207,6 @@ namespace OpenIddict.Core
///
Task> GetRedirectUrisAsync([NotNull] TApplication application, CancellationToken cancellationToken);
- ///
- /// Retrieves the token identifiers associated with an application.
- ///
- /// The application.
- /// The that can be used to abort the operation.
- ///
- /// A that can be used to monitor the asynchronous operation,
- /// whose result returns the tokens associated with the application.
- ///
- Task> GetTokensAsync([NotNull] TApplication application, CancellationToken cancellationToken);
-
///
/// Executes the specified query.
///
@@ -276,7 +265,7 @@ namespace OpenIddict.Core
/// A that can be used to monitor the asynchronous operation.
///
Task SetPostLogoutRedirectUrisAsync([NotNull] TApplication application,
- [NotNull] ImmutableArray addresses, CancellationToken cancellationToken);
+ ImmutableArray addresses, CancellationToken cancellationToken);
///
/// Sets the callback addresses associated with an application.
@@ -288,7 +277,7 @@ namespace OpenIddict.Core
/// A that can be used to monitor the asynchronous operation.
///
Task SetRedirectUrisAsync([NotNull] TApplication application,
- [NotNull] ImmutableArray addresses, CancellationToken cancellationToken);
+ ImmutableArray addresses, CancellationToken cancellationToken);
///
/// Updates an existing application.
diff --git a/src/OpenIddict.Core/Stores/IOpenIddictTokenStore.cs b/src/OpenIddict.Core/Stores/IOpenIddictTokenStore.cs
index d35402f9..56f4430b 100644
--- a/src/OpenIddict.Core/Stores/IOpenIddictTokenStore.cs
+++ b/src/OpenIddict.Core/Stores/IOpenIddictTokenStore.cs
@@ -69,6 +69,17 @@ namespace OpenIddict.Core
/// A that can be used to monitor the asynchronous operation.
Task DeleteAsync([NotNull] TToken token, CancellationToken cancellationToken);
+ ///
+ /// Retrieves the list of tokens corresponding to the specified application identifier.
+ ///
+ /// The application identifier associated with the tokens.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the tokens corresponding to the specified application.
+ ///
+ Task> FindByApplicationIdAsync([NotNull] string identifier, CancellationToken cancellationToken);
+
///
/// Retrieves the list of tokens corresponding to the specified authorization identifier.
///
diff --git a/src/OpenIddict.Core/Stores/OpenIddictApplicationStore.cs b/src/OpenIddict.Core/Stores/OpenIddictApplicationStore.cs
index a1beae13..b0778bb8 100644
--- a/src/OpenIddict.Core/Stores/OpenIddictApplicationStore.cs
+++ b/src/OpenIddict.Core/Stores/OpenIddictApplicationStore.cs
@@ -411,46 +411,6 @@ namespace OpenIddict.Core
return Task.FromResult(ImmutableArray.Create(uris));
}
- ///
- /// Retrieves the token identifiers associated with an application.
- ///
- /// The application.
- /// The that can be used to abort the operation.
- ///
- /// A that can be used to monitor the asynchronous operation,
- /// whose result returns the tokens associated with the application.
- ///
- public virtual async Task> GetTokensAsync([NotNull] TApplication application, CancellationToken cancellationToken)
- {
- if (application == null)
- {
- throw new ArgumentNullException(nameof(application));
- }
-
- IQueryable Query(IQueryable applications)
- {
- return from entity in applications
- where entity.Id.Equals(application.Id)
- from token in entity.Tokens
- select token.Id;
- }
-
- var identifiers = await ListAsync(Query, cancellationToken);
- if (identifiers.IsDefaultOrEmpty)
- {
- return ImmutableArray.Create();
- }
-
- var builder = ImmutableArray.CreateBuilder(identifiers.Length);
-
- foreach (var identifier in identifiers)
- {
- builder.Add(ConvertIdentifierToString(identifier));
- }
-
- return builder.ToImmutable();
- }
-
///
/// Executes the specified query.
///
@@ -555,16 +515,18 @@ namespace OpenIddict.Core
/// A that can be used to monitor the asynchronous operation.
///
public virtual Task SetPostLogoutRedirectUrisAsync([NotNull] TApplication application,
- [NotNull] ImmutableArray addresses, CancellationToken cancellationToken)
+ ImmutableArray addresses, CancellationToken cancellationToken)
{
if (application == null)
{
- throw new ArgumentException(nameof(application));
+ throw new ArgumentNullException(nameof(application));
}
- if (addresses == null)
+ if (addresses.IsDefaultOrEmpty)
{
- throw new ArgumentException(nameof(addresses));
+ application.PostLogoutRedirectUris = null;
+
+ return Task.FromResult(0);
}
if (addresses.Any(address => string.IsNullOrEmpty(address)))
@@ -592,16 +554,18 @@ namespace OpenIddict.Core
/// A that can be used to monitor the asynchronous operation.
///
public virtual Task SetRedirectUrisAsync([NotNull] TApplication application,
- [NotNull] ImmutableArray addresses, CancellationToken cancellationToken)
+ ImmutableArray addresses, CancellationToken cancellationToken)
{
if (application == null)
{
- throw new ArgumentException(nameof(application));
+ throw new ArgumentNullException(nameof(application));
}
- if (addresses == null)
+ if (addresses.IsDefaultOrEmpty)
{
- throw new ArgumentException(nameof(addresses));
+ application.RedirectUris = null;
+
+ return Task.FromResult(0);
}
if (addresses.Any(address => string.IsNullOrEmpty(address)))
diff --git a/src/OpenIddict.Core/Stores/OpenIddictTokenStore.cs b/src/OpenIddict.Core/Stores/OpenIddictTokenStore.cs
index c6dc11d4..ff786bf4 100644
--- a/src/OpenIddict.Core/Stores/OpenIddictTokenStore.cs
+++ b/src/OpenIddict.Core/Stores/OpenIddictTokenStore.cs
@@ -82,6 +82,27 @@ namespace OpenIddict.Core
/// A that can be used to monitor the asynchronous operation.
public abstract Task DeleteAsync([NotNull] TToken token, CancellationToken cancellationToken);
+ ///
+ /// Retrieves the list of tokens corresponding to the specified application identifier.
+ ///
+ /// The application identifier associated with the tokens.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the tokens corresponding to the specified application.
+ ///
+ public virtual Task> FindByApplicationIdAsync([NotNull] string identifier, CancellationToken cancellationToken)
+ {
+ if (string.IsNullOrEmpty(identifier))
+ {
+ throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier));
+ }
+
+ var key = ConvertIdentifierFromString(identifier);
+
+ return ListAsync(tokens => tokens.Where(token => token.Application.Id.Equals(key)), cancellationToken);
+ }
+
///
/// Retrieves the list of tokens corresponding to the specified authorization identifier.
///
diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictApplicationStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictApplicationStore.cs
index ae9a1652..da54319a 100644
--- a/src/OpenIddict.EntityFramework/Stores/OpenIddictApplicationStore.cs
+++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictApplicationStore.cs
@@ -141,36 +141,17 @@ namespace OpenIddict.EntityFramework
///
/// A that can be used to monitor the asynchronous operation, whose result returns the application.
///
- public override Task CreateAsync([NotNull] OpenIddictApplicationDescriptor descriptor, CancellationToken cancellationToken)
+ public override async Task CreateAsync([NotNull] OpenIddictApplicationDescriptor descriptor, CancellationToken cancellationToken)
{
if (descriptor == null)
{
throw new ArgumentNullException(nameof(descriptor));
}
- var application = new TApplication
- {
- ClientId = descriptor.ClientId,
- ClientSecret = descriptor.ClientSecret,
- DisplayName = descriptor.DisplayName,
- Type = descriptor.Type
- };
-
- if (descriptor.PostLogoutRedirectUris.Count != 0)
- {
- application.PostLogoutRedirectUris = string.Join(
- OpenIddictConstants.Separators.Space,
- descriptor.PostLogoutRedirectUris.Select(uri => uri.OriginalString));
- }
-
- if (descriptor.RedirectUris.Count != 0)
- {
- application.RedirectUris = string.Join(
- OpenIddictConstants.Separators.Space,
- descriptor.RedirectUris.Select(uri => uri.OriginalString));
- }
+ var application = new TApplication();
- return CreateAsync(application, cancellationToken);
+ await BindAsync(application, descriptor, cancellationToken);
+ return await CreateAsync(application, cancellationToken);
}
///
@@ -304,5 +285,48 @@ namespace OpenIddict.EntityFramework
return Context.SaveChangesAsync(cancellationToken);
}
+
+ ///
+ /// Sets the application properties based on the specified descriptor.
+ ///
+ /// The application to update.
+ /// The application descriptor.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ protected virtual Task BindAsync([NotNull] TApplication application, [NotNull] OpenIddictApplicationDescriptor descriptor, CancellationToken cancellationToken)
+ {
+ if (application == null)
+ {
+ throw new ArgumentNullException(nameof(application));
+ }
+
+ if (descriptor == null)
+ {
+ throw new ArgumentNullException(nameof(descriptor));
+ }
+
+ application.ClientId = descriptor.ClientId;
+ application.ClientSecret = descriptor.ClientSecret;
+ application.DisplayName = descriptor.DisplayName;
+ application.Type = descriptor.Type;
+
+ if (descriptor.PostLogoutRedirectUris.Count != 0)
+ {
+ application.PostLogoutRedirectUris = string.Join(
+ OpenIddictConstants.Separators.Space,
+ descriptor.PostLogoutRedirectUris.Select(uri => uri.OriginalString));
+ }
+
+ if (descriptor.RedirectUris.Count != 0)
+ {
+ application.RedirectUris = string.Join(
+ OpenIddictConstants.Separators.Space,
+ descriptor.RedirectUris.Select(uri => uri.OriginalString));
+ }
+
+ return Task.FromResult(0);
+ }
}
}
\ No newline at end of file
diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs
index f93d8a60..1778ca94 100644
--- a/src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs
+++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs
@@ -148,30 +148,9 @@ namespace OpenIddict.EntityFramework
throw new ArgumentNullException(nameof(descriptor));
}
- var authorization = new TAuthorization
- {
- Status = descriptor.Status,
- Subject = descriptor.Subject,
- Type = descriptor.Type
- };
-
- if (descriptor.Scopes.Count != 0)
- {
- authorization.Scopes = string.Join(OpenIddictConstants.Separators.Space, descriptor.Scopes);
- }
-
- // Bind the authorization to the specified application, if applicable.
- if (!string.IsNullOrEmpty(descriptor.ApplicationId))
- {
- var application = await Applications.FindAsync(cancellationToken, ConvertIdentifierFromString(descriptor.ApplicationId));
- if (application == null)
- {
- throw new InvalidOperationException("The application associated with the authorization cannot be found.");
- }
-
- authorization.Application = application;
- }
+ var authorization = new TAuthorization();
+ await BindAsync(authorization, descriptor, cancellationToken);
return await CreateAsync(authorization, cancellationToken);
}
@@ -356,5 +335,48 @@ namespace OpenIddict.EntityFramework
return Context.SaveChangesAsync(cancellationToken);
}
+
+ ///
+ /// Sets the authorization properties based on the specified descriptor.
+ ///
+ /// The authorization to update.
+ /// The authorization descriptor.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ protected virtual async Task BindAsync([NotNull] TAuthorization authorization, [NotNull] OpenIddictAuthorizationDescriptor descriptor, CancellationToken cancellationToken)
+ {
+ if (authorization == null)
+ {
+ throw new ArgumentNullException(nameof(authorization));
+ }
+
+ if (descriptor == null)
+ {
+ throw new ArgumentNullException(nameof(descriptor));
+ }
+
+ authorization.Status = descriptor.Status;
+ authorization.Subject = descriptor.Subject;
+ authorization.Type = descriptor.Type;
+
+ if (descriptor.Scopes.Count != 0)
+ {
+ authorization.Scopes = string.Join(OpenIddictConstants.Separators.Space, descriptor.Scopes);
+ }
+
+ // Bind the authorization to the specified application, if applicable.
+ if (!string.IsNullOrEmpty(descriptor.ApplicationId))
+ {
+ var application = await Applications.FindAsync(new object[] { ConvertIdentifierFromString(descriptor.ApplicationId) }, cancellationToken);
+ if (application == null)
+ {
+ throw new InvalidOperationException("The application associated with the authorization cannot be found.");
+ }
+
+ authorization.Application = application;
+ }
+ }
}
}
\ No newline at end of file
diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictScopeStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictScopeStore.cs
index 4732f7b8..7abf429e 100644
--- a/src/OpenIddict.EntityFramework/Stores/OpenIddictScopeStore.cs
+++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictScopeStore.cs
@@ -122,14 +122,12 @@ namespace OpenIddict.EntityFramework
///
/// A that can be used to monitor the asynchronous operation, whose result returns the scope.
///
- public override Task CreateAsync([NotNull] OpenIddictScopeDescriptor descriptor, CancellationToken cancellationToken)
+ public override async Task CreateAsync([NotNull] OpenIddictScopeDescriptor descriptor, CancellationToken cancellationToken)
{
- var scope = new TScope
- {
- Name = descriptor.Name
- };
+ var scope = new TScope();
- return CreateAsync(scope, cancellationToken);
+ await BindAsync(scope, descriptor, cancellationToken);
+ return await CreateAsync(scope, cancellationToken);
}
///
@@ -212,5 +210,32 @@ namespace OpenIddict.EntityFramework
return Context.SaveChangesAsync(cancellationToken);
}
+
+ ///
+ /// Sets the scope properties based on the specified descriptor.
+ ///
+ /// The scope to update.
+ /// The scope descriptor.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ protected virtual Task BindAsync([NotNull] TScope scope, [NotNull] OpenIddictScopeDescriptor descriptor, CancellationToken cancellationToken)
+ {
+ if (scope == null)
+ {
+ throw new ArgumentNullException(nameof(scope));
+ }
+
+ if (descriptor == null)
+ {
+ throw new ArgumentNullException(nameof(descriptor));
+ }
+
+ scope.Description = descriptor.Description;
+ scope.Name = descriptor.Name;
+
+ return Task.FromResult(0);
+ }
}
}
\ No newline at end of file
diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictTokenStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictTokenStore.cs
index 5d7c4f06..1e6135b8 100644
--- a/src/OpenIddict.EntityFramework/Stores/OpenIddictTokenStore.cs
+++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictTokenStore.cs
@@ -148,41 +148,9 @@ namespace OpenIddict.EntityFramework
throw new ArgumentNullException(nameof(descriptor));
}
- var token = new TToken
- {
- Ciphertext = descriptor.Ciphertext,
- CreationDate = descriptor.CreationDate,
- ExpirationDate = descriptor.ExpirationDate,
- Hash = descriptor.Hash,
- Status = descriptor.Status,
- Subject = descriptor.Subject,
- Type = descriptor.Type
- };
-
- // Bind the token to the specified client application, if applicable.
- if (!string.IsNullOrEmpty(descriptor.ApplicationId))
- {
- var application = await Applications.FindAsync(cancellationToken, ConvertIdentifierFromString(descriptor.ApplicationId));
- if (application == null)
- {
- throw new InvalidOperationException("The application associated with the token cannot be found.");
- }
-
- token.Application = application;
- }
-
- // Bind the token to the specified authorization, if applicable.
- if (!string.IsNullOrEmpty(descriptor.AuthorizationId))
- {
- var authorization = await Authorizations.FindAsync(cancellationToken, ConvertIdentifierFromString(descriptor.AuthorizationId));
- if (authorization == null)
- {
- throw new InvalidOperationException("The authorization associated with the token cannot be found.");
- }
-
- token.Authorization = authorization;
- }
+ var token = new TToken();
+ await BindAsync(token, descriptor, cancellationToken);
return await CreateAsync(token, cancellationToken);
}
@@ -429,5 +397,59 @@ namespace OpenIddict.EntityFramework
return Context.SaveChangesAsync(cancellationToken);
}
+
+ ///
+ /// Sets the token properties based on the specified descriptor.
+ ///
+ /// The token to update.
+ /// The token descriptor.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ protected virtual async Task BindAsync([NotNull] TToken token, [NotNull] OpenIddictTokenDescriptor descriptor, CancellationToken cancellationToken)
+ {
+ if (token == null)
+ {
+ throw new ArgumentNullException(nameof(token));
+ }
+
+ if (descriptor == null)
+ {
+ throw new ArgumentNullException(nameof(descriptor));
+ }
+
+ token.Ciphertext = descriptor.Ciphertext;
+ token.CreationDate = descriptor.CreationDate;
+ token.ExpirationDate = descriptor.ExpirationDate;
+ token.Hash = descriptor.Hash;
+ token.Status = descriptor.Status;
+ token.Subject = descriptor.Subject;
+ token.Type = descriptor.Type;
+
+ // Bind the token to the specified client application, if applicable.
+ if (!string.IsNullOrEmpty(descriptor.ApplicationId))
+ {
+ var application = await Applications.FindAsync(new object[] { ConvertIdentifierFromString(descriptor.ApplicationId) }, cancellationToken);
+ if (application == null)
+ {
+ throw new InvalidOperationException("The application associated with the token cannot be found.");
+ }
+
+ token.Application = application;
+ }
+
+ // Bind the token to the specified authorization, if applicable.
+ if (!string.IsNullOrEmpty(descriptor.AuthorizationId))
+ {
+ var authorization = await Authorizations.FindAsync(new object[] { ConvertIdentifierFromString(descriptor.AuthorizationId) }, cancellationToken);
+ if (authorization == null)
+ {
+ throw new InvalidOperationException("The authorization associated with the token cannot be found.");
+ }
+
+ token.Authorization = authorization;
+ }
+ }
}
}
\ No newline at end of file
diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs
index 133704a6..4bffb758 100644
--- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs
+++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs
@@ -141,36 +141,17 @@ namespace OpenIddict.EntityFrameworkCore
///
/// A that can be used to monitor the asynchronous operation, whose result returns the application.
///
- public override Task CreateAsync([NotNull] OpenIddictApplicationDescriptor descriptor, CancellationToken cancellationToken)
+ public override async Task CreateAsync([NotNull] OpenIddictApplicationDescriptor descriptor, CancellationToken cancellationToken)
{
if (descriptor == null)
{
throw new ArgumentNullException(nameof(descriptor));
}
- var application = new TApplication
- {
- ClientId = descriptor.ClientId,
- ClientSecret = descriptor.ClientSecret,
- DisplayName = descriptor.DisplayName,
- Type = descriptor.Type
- };
-
- if (descriptor.PostLogoutRedirectUris.Count != 0)
- {
- application.PostLogoutRedirectUris = string.Join(
- OpenIddictConstants.Separators.Space,
- descriptor.PostLogoutRedirectUris.Select(uri => uri.OriginalString));
- }
-
- if (descriptor.RedirectUris.Count != 0)
- {
- application.RedirectUris = string.Join(
- OpenIddictConstants.Separators.Space,
- descriptor.RedirectUris.Select(uri => uri.OriginalString));
- }
+ var application = new TApplication();
- return CreateAsync(application, cancellationToken);
+ await BindAsync(application, descriptor, cancellationToken);
+ return await CreateAsync(application, cancellationToken);
}
///
@@ -285,5 +266,48 @@ namespace OpenIddict.EntityFrameworkCore
return Context.SaveChangesAsync(cancellationToken);
}
+
+ ///
+ /// Sets the application properties based on the specified descriptor.
+ ///
+ /// The application to update.
+ /// The application descriptor.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ protected virtual Task BindAsync([NotNull] TApplication application, [NotNull] OpenIddictApplicationDescriptor descriptor, CancellationToken cancellationToken)
+ {
+ if (application == null)
+ {
+ throw new ArgumentNullException(nameof(application));
+ }
+
+ if (descriptor == null)
+ {
+ throw new ArgumentNullException(nameof(descriptor));
+ }
+
+ application.ClientId = descriptor.ClientId;
+ application.ClientSecret = descriptor.ClientSecret;
+ application.DisplayName = descriptor.DisplayName;
+ application.Type = descriptor.Type;
+
+ if (descriptor.PostLogoutRedirectUris.Count != 0)
+ {
+ application.PostLogoutRedirectUris = string.Join(
+ OpenIddictConstants.Separators.Space,
+ descriptor.PostLogoutRedirectUris.Select(uri => uri.OriginalString));
+ }
+
+ if (descriptor.RedirectUris.Count != 0)
+ {
+ application.RedirectUris = string.Join(
+ OpenIddictConstants.Separators.Space,
+ descriptor.RedirectUris.Select(uri => uri.OriginalString));
+ }
+
+ return Task.FromResult(0);
+ }
}
}
\ No newline at end of file
diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs
index 3dfbc1c7..89006cd9 100644
--- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs
+++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs
@@ -148,32 +148,9 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentNullException(nameof(descriptor));
}
- var authorization = new TAuthorization
- {
- Status = descriptor.Status,
- Subject = descriptor.Subject,
- Type = descriptor.Type
- };
-
- if (descriptor.Scopes.Count != 0)
- {
- authorization.Scopes = string.Join(OpenIddictConstants.Separators.Space, descriptor.Scopes);
- }
-
- // Bind the authorization to the specified application, if applicable.
- if (!string.IsNullOrEmpty(descriptor.ApplicationId))
- {
- var key = ConvertIdentifierFromString(descriptor.ApplicationId);
-
- var application = await Applications.SingleOrDefaultAsync(entity => entity.Id.Equals(key));
- if (application == null)
- {
- throw new InvalidOperationException("The application associated with the authorization cannot be found.");
- }
-
- authorization.Application = application;
- }
+ var authorization = new TAuthorization();
+ await BindAsync(authorization, descriptor, cancellationToken);
return await CreateAsync(authorization, cancellationToken);
}
@@ -309,5 +286,50 @@ namespace OpenIddict.EntityFrameworkCore
return Context.SaveChangesAsync(cancellationToken);
}
+
+ ///
+ /// Sets the authorization properties based on the specified descriptor.
+ ///
+ /// The authorization to update.
+ /// The authorization descriptor.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ protected virtual async Task BindAsync([NotNull] TAuthorization authorization, [NotNull] OpenIddictAuthorizationDescriptor descriptor, CancellationToken cancellationToken)
+ {
+ if (authorization == null)
+ {
+ throw new ArgumentNullException(nameof(authorization));
+ }
+
+ if (descriptor == null)
+ {
+ throw new ArgumentNullException(nameof(descriptor));
+ }
+
+ authorization.Status = descriptor.Status;
+ authorization.Subject = descriptor.Subject;
+ authorization.Type = descriptor.Type;
+
+ if (descriptor.Scopes.Count != 0)
+ {
+ authorization.Scopes = string.Join(OpenIddictConstants.Separators.Space, descriptor.Scopes);
+ }
+
+ // Bind the authorization to the specified application, if applicable.
+ if (!string.IsNullOrEmpty(descriptor.ApplicationId))
+ {
+ var key = ConvertIdentifierFromString(descriptor.ApplicationId);
+
+ var application = await Applications.SingleOrDefaultAsync(entity => entity.Id.Equals(key));
+ if (application == null)
+ {
+ throw new InvalidOperationException("The application associated with the authorization cannot be found.");
+ }
+
+ authorization.Application = application;
+ }
+ }
}
}
\ No newline at end of file
diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs
index 4520f532..79a9abac 100644
--- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs
+++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs
@@ -122,14 +122,12 @@ namespace OpenIddict.EntityFrameworkCore
///
/// A that can be used to monitor the asynchronous operation, whose result returns the scope.
///
- public override Task CreateAsync([NotNull] OpenIddictScopeDescriptor descriptor, CancellationToken cancellationToken)
+ public override async Task CreateAsync([NotNull] OpenIddictScopeDescriptor descriptor, CancellationToken cancellationToken)
{
- var scope = new TScope
- {
- Name = descriptor.Name
- };
+ var scope = new TScope();
- return CreateAsync(scope, cancellationToken);
+ await BindAsync(scope, descriptor, cancellationToken);
+ return await CreateAsync(scope, cancellationToken);
}
///
@@ -212,5 +210,32 @@ namespace OpenIddict.EntityFrameworkCore
return Context.SaveChangesAsync(cancellationToken);
}
+
+ ///
+ /// Sets the scope properties based on the specified descriptor.
+ ///
+ /// The scope to update.
+ /// The scope descriptor.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ protected virtual Task BindAsync([NotNull] TScope scope, [NotNull] OpenIddictScopeDescriptor descriptor, CancellationToken cancellationToken)
+ {
+ if (scope == null)
+ {
+ throw new ArgumentNullException(nameof(scope));
+ }
+
+ if (descriptor == null)
+ {
+ throw new ArgumentNullException(nameof(descriptor));
+ }
+
+ scope.Description = descriptor.Description;
+ scope.Name = descriptor.Name;
+
+ return Task.FromResult(0);
+ }
}
}
\ No newline at end of file
diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs
index 46a97c04..51ac5efc 100644
--- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs
+++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs
@@ -148,45 +148,9 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentNullException(nameof(descriptor));
}
- var token = new TToken
- {
- Ciphertext = descriptor.Ciphertext,
- CreationDate = descriptor.CreationDate,
- ExpirationDate = descriptor.ExpirationDate,
- Hash = descriptor.Hash,
- Status = descriptor.Status,
- Subject = descriptor.Subject,
- Type = descriptor.Type
- };
-
- // Bind the token to the specified client application, if applicable.
- if (!string.IsNullOrEmpty(descriptor.ApplicationId))
- {
- var key = ConvertIdentifierFromString(descriptor.ApplicationId);
-
- var application = await Applications.SingleOrDefaultAsync(entity => entity.Id.Equals(key));
- if (application == null)
- {
- throw new InvalidOperationException("The application associated with the token cannot be found.");
- }
-
- token.Application = application;
- }
-
- // Bind the token to the specified authorization, if applicable.
- if (!string.IsNullOrEmpty(descriptor.AuthorizationId))
- {
- var key = ConvertIdentifierFromString(descriptor.AuthorizationId);
-
- var authorization = await Authorizations.SingleOrDefaultAsync(entity => entity.Id.Equals(key));
- if (authorization == null)
- {
- throw new InvalidOperationException("The authorization associated with the token cannot be found.");
- }
-
- token.Authorization = authorization;
- }
+ var token = new TToken();
+ await BindAsync(token, descriptor, cancellationToken);
return await CreateAsync(token, cancellationToken);
}
@@ -354,5 +318,63 @@ namespace OpenIddict.EntityFrameworkCore
return Context.SaveChangesAsync(cancellationToken);
}
+
+ ///
+ /// Sets the token properties based on the specified descriptor.
+ ///
+ /// The token to update.
+ /// The token descriptor.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ protected virtual async Task BindAsync([NotNull] TToken token, [NotNull] OpenIddictTokenDescriptor descriptor, CancellationToken cancellationToken)
+ {
+ if (token == null)
+ {
+ throw new ArgumentNullException(nameof(token));
+ }
+
+ if (descriptor == null)
+ {
+ throw new ArgumentNullException(nameof(descriptor));
+ }
+
+ token.Ciphertext = descriptor.Ciphertext;
+ token.CreationDate = descriptor.CreationDate;
+ token.ExpirationDate = descriptor.ExpirationDate;
+ token.Hash = descriptor.Hash;
+ token.Status = descriptor.Status;
+ token.Subject = descriptor.Subject;
+ token.Type = descriptor.Type;
+
+ // Bind the token to the specified client application, if applicable.
+ if (!string.IsNullOrEmpty(descriptor.ApplicationId))
+ {
+ var key = ConvertIdentifierFromString(descriptor.ApplicationId);
+
+ var application = await Applications.SingleOrDefaultAsync(entity => entity.Id.Equals(key));
+ if (application == null)
+ {
+ throw new InvalidOperationException("The application associated with the token cannot be found.");
+ }
+
+ token.Application = application;
+ }
+
+ // Bind the token to the specified authorization, if applicable.
+ if (!string.IsNullOrEmpty(descriptor.AuthorizationId))
+ {
+ var key = ConvertIdentifierFromString(descriptor.AuthorizationId);
+
+ var authorization = await Authorizations.SingleOrDefaultAsync(entity => entity.Id.Equals(key));
+ if (authorization == null)
+ {
+ throw new InvalidOperationException("The authorization associated with the token cannot be found.");
+ }
+
+ token.Authorization = authorization;
+ }
+ }
}
}
\ No newline at end of file
diff --git a/src/OpenIddict/OpenIddictProvider.Helpers.cs b/src/OpenIddict/OpenIddictProvider.Helpers.cs
index 6b0ee4f2..808a0695 100644
--- a/src/OpenIddict/OpenIddictProvider.Helpers.cs
+++ b/src/OpenIddict/OpenIddictProvider.Helpers.cs
@@ -38,12 +38,18 @@ namespace OpenIddict
var descriptor = new OpenIddictAuthorizationDescriptor
{
+ Principal = ticket.Principal,
Status = OpenIddictConstants.Statuses.Valid,
Subject = ticket.Principal.GetClaim(OpenIdConnectConstants.Claims.Subject),
Type = OpenIddictConstants.AuthorizationTypes.AdHoc
};
- foreach (var scope in request.GetScopes())
+ foreach (var property in ticket.Properties.Items)
+ {
+ descriptor.Properties.Add(property);
+ }
+
+ foreach (var scope in ticket.GetScopes())
{
descriptor.Scopes.Add(scope);
}
@@ -124,11 +130,17 @@ namespace OpenIddict
AuthorizationId = ticket.GetProperty(OpenIddictConstants.Properties.AuthorizationId),
CreationDate = ticket.Properties.IssuedUtc,
ExpirationDate = ticket.Properties.ExpiresUtc,
+ Principal = ticket.Principal,
Status = OpenIddictConstants.Statuses.Valid,
Subject = ticket.Principal.GetClaim(OpenIdConnectConstants.Claims.Subject),
Type = type
};
+ foreach (var property in ticket.Properties.Items)
+ {
+ descriptor.Properties.Add(property);
+ }
+
string result = null;
// When reference tokens are enabled or when the token is an authorization code or a