diff --git a/src/OpenIddict.Core/Descriptors/OpenIddictApplicationDescriptor.cs b/src/OpenIddict.Core/Descriptors/OpenIddictApplicationDescriptor.cs
new file mode 100644
index 00000000..5738113a
--- /dev/null
+++ b/src/OpenIddict.Core/Descriptors/OpenIddictApplicationDescriptor.cs
@@ -0,0 +1,45 @@
+namespace OpenIddict.Core
+{
+ ///
+ /// Represents an OpenIddict application descriptor.
+ ///
+ public class OpenIddictApplicationDescriptor
+ {
+ ///
+ /// Gets or sets the client identifier
+ /// associated with the application.
+ ///
+ public virtual string ClientId { get; set; }
+
+ ///
+ /// Gets or sets the client secret associated with the application.
+ /// Note: depending on the application manager used when creating it,
+ /// this property may be hashed or encrypted for security reasons.
+ ///
+ public virtual string ClientSecret { get; set; }
+
+ ///
+ /// Gets or sets the display name
+ /// associated with the application.
+ ///
+ public virtual string DisplayName { get; set; }
+
+ ///
+ /// Gets or sets the logout callback URL
+ /// associated with the application.
+ ///
+ public virtual string LogoutRedirectUri { get; set; }
+
+ ///
+ /// Gets or sets the callback URL
+ /// associated with the application.
+ ///
+ public virtual string RedirectUri { get; set; }
+
+ ///
+ /// Gets or sets the application type
+ /// associated with the application.
+ ///
+ public virtual string Type { get; set; }
+ }
+}
diff --git a/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs b/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs
index d3bc6abe..8c93a232 100644
--- a/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs
+++ b/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs
@@ -39,12 +39,6 @@ namespace OpenIddict.Core
///
protected IOpenIddictApplicationStore Store { get; }
- ///
- /// Gets the applications as a queryable source,
- /// if supported by the underlying store.
- ///
- public virtual IQueryable Applications => Store.Applications;
-
///
/// Creates a new application.
///
@@ -94,29 +88,69 @@ namespace OpenIddict.Core
OpenIddictConstants.ClientTypes.Confidential, cancellationToken);
}
- if (string.IsNullOrEmpty(secret))
+ // If the client is a confidential application, throw an
+ // exception as the client secret is required in this case.
+ if (string.IsNullOrEmpty(secret) &&
+ string.Equals(type, OpenIddictConstants.ClientTypes.Confidential, StringComparison.OrdinalIgnoreCase))
{
- // If the client is a confidential application, throw an
- // exception as the client secret is required in this case.
- if (string.Equals(type, OpenIddictConstants.ClientTypes.Confidential, StringComparison.OrdinalIgnoreCase))
- {
- throw new InvalidOperationException("A client secret must be provided when creating a confidential application.");
- }
-
- await Store.SetClientSecretAsync(application, null, cancellationToken);
+ throw new InvalidOperationException("A client secret must be provided when creating a confidential application.");
}
- else
+ if (!string.IsNullOrEmpty(secret))
{
secret = await ObfuscateClientSecretAsync(secret, cancellationToken);
await Store.SetClientSecretAsync(application, secret, cancellationToken);
}
await ValidateAsync(application, cancellationToken);
-
return await Store.CreateAsync(application, cancellationToken);
}
+ ///
+ /// Creates a new application.
+ /// Note: the default implementation automatically hashes the client
+ /// secret before storing it in the database, for security reasons.
+ ///
+ /// The application descriptor.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the unique identifier associated with the application.
+ ///
+ public virtual async Task CreateAsync([NotNull] OpenIddictApplicationDescriptor descriptor, CancellationToken cancellationToken)
+ {
+ if (descriptor == null)
+ {
+ throw new ArgumentNullException(nameof(descriptor));
+ }
+
+ // If no client type was specified, assume it's a
+ // public application if no secret was provided.
+ if (string.IsNullOrEmpty(descriptor.Type))
+ {
+ descriptor.Type = string.IsNullOrEmpty(descriptor.ClientSecret) ?
+ OpenIddictConstants.ClientTypes.Public :
+ OpenIddictConstants.ClientTypes.Confidential;
+ }
+
+ // If the client is a confidential application, throw an
+ // exception as the client secret is required in this case.
+ if (string.IsNullOrEmpty(descriptor.ClientSecret) &&
+ string.Equals(descriptor.Type, OpenIddictConstants.ClientTypes.Confidential, StringComparison.OrdinalIgnoreCase))
+ {
+ throw new InvalidOperationException("A client secret must be provided when creating a confidential application.");
+ }
+
+ // Obfuscate the provided client secret.
+ if (!string.IsNullOrEmpty(descriptor.ClientSecret))
+ {
+ descriptor.ClientSecret = await ObfuscateClientSecretAsync(descriptor.ClientSecret, cancellationToken);
+ }
+
+ await ValidateAsync(descriptor, cancellationToken);
+ return await Store.CreateAsync(descriptor, cancellationToken);
+ }
+
///
/// Removes an existing application.
///
@@ -191,6 +225,26 @@ namespace OpenIddict.Core
return Store.FindByRedirectUriAsync(address, cancellationToken);
}
+ ///
+ /// Executes the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the single element returned when executing the specified query.
+ ///
+ public virtual Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken)
+ {
+ if (query == null)
+ {
+ throw new ArgumentNullException(nameof(query));
+ }
+
+ return Store.GetAsync(query, cancellationToken);
+ }
+
///
/// Retrieves the client type associated with an application.
///
@@ -267,7 +321,7 @@ namespace OpenIddict.Core
/// 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)
+ public virtual Task GetTokensAsync([NotNull] TApplication application, CancellationToken cancellationToken)
{
if (application == null)
{
@@ -360,6 +414,26 @@ namespace OpenIddict.Core
return string.Equals(type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase);
}
+ ///
+ /// Executes the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns all the elements returned when executing the specified query.
+ ///
+ public virtual Task ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken)
+ {
+ if (query == null)
+ {
+ throw new ArgumentNullException(nameof(query));
+ }
+
+ return Store.ListAsync(query, cancellationToken);
+ }
+
///
/// Updates an existing application.
///
@@ -409,6 +483,7 @@ namespace OpenIddict.Core
await Store.SetClientSecretAsync(application, secret, cancellationToken);
}
+ await ValidateAsync(application, cancellationToken);
await UpdateAsync(application, cancellationToken);
}
@@ -525,53 +600,72 @@ namespace OpenIddict.Core
///
protected virtual async Task ValidateAsync([NotNull] TApplication application, CancellationToken cancellationToken)
{
- if (application == null)
+ var descriptor = new OpenIddictApplicationDescriptor
{
- throw new ArgumentNullException(nameof(application));
+ ClientId = await Store.GetClientIdAsync(application, cancellationToken),
+ ClientSecret = await Store.GetClientSecretAsync(application, cancellationToken),
+ DisplayName = await Store.GetDisplayNameAsync(application, cancellationToken),
+ LogoutRedirectUri = await Store.GetLogoutRedirectUriAsync(application, cancellationToken),
+ RedirectUri = await Store.GetRedirectUriAsync(application, cancellationToken),
+ Type = await Store.GetClientTypeAsync(application, cancellationToken)
+ };
+
+ await ValidateAsync(descriptor, cancellationToken);
+ }
+
+ ///
+ /// Validates the application descriptor to ensure it's in a consistent state.
+ ///
+ /// 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 ValidateAsync([NotNull] OpenIddictApplicationDescriptor descriptor, CancellationToken cancellationToken)
+ {
+ if (descriptor == null)
+ {
+ throw new ArgumentNullException(nameof(descriptor));
}
- if (string.IsNullOrEmpty(await Store.GetClientIdAsync(application, cancellationToken)))
+ if (string.IsNullOrEmpty(descriptor.ClientId))
{
- throw new ArgumentException("The client identifier cannot be null or empty.", nameof(application));
+ throw new ArgumentException("The client identifier cannot be null or empty.", nameof(descriptor));
}
- var type = await Store.GetClientTypeAsync(application, cancellationToken);
- if (string.IsNullOrEmpty(type))
+ if (string.IsNullOrEmpty(descriptor.Type))
{
- throw new ArgumentException("The client type cannot be null or empty.", nameof(application));
+ throw new ArgumentException("The client type cannot be null or empty.", nameof(descriptor));
}
// Ensure the application type is supported by the manager.
- if (!string.Equals(type, OpenIddictConstants.ClientTypes.Confidential, StringComparison.OrdinalIgnoreCase) &&
- !string.Equals(type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase))
+ if (!string.Equals(descriptor.Type, OpenIddictConstants.ClientTypes.Confidential, StringComparison.OrdinalIgnoreCase) &&
+ !string.Equals(descriptor.Type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase))
{
throw new ArgumentException("Only 'confidential' or 'public' applications are " +
- "supported by the default application manager.", nameof(application));
+ "supported by the default application manager.", nameof(descriptor));
}
- var secret = await Store.GetClientSecretAsync(application, cancellationToken);
-
// Ensure a client secret was specified if the client is a confidential application.
- if (string.IsNullOrEmpty(secret) &&
- string.Equals(type, OpenIddictConstants.ClientTypes.Confidential, StringComparison.OrdinalIgnoreCase))
+ if (string.IsNullOrEmpty(descriptor.ClientSecret) &&
+ string.Equals(descriptor.Type, OpenIddictConstants.ClientTypes.Confidential, StringComparison.OrdinalIgnoreCase))
{
- throw new ArgumentException("The client secret cannot be null or empty for a confidential application.", nameof(application));
+ throw new ArgumentException("The client secret cannot be null or empty for a confidential application.", nameof(descriptor));
}
// Ensure no client secret was specified if the client is a public application.
- else if (!string.IsNullOrEmpty(secret) &&
- string.Equals(type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase))
+ else if (!string.IsNullOrEmpty(descriptor.ClientSecret) &&
+ string.Equals(descriptor.Type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase))
{
- throw new ArgumentException("A client secret cannot be associated with a public application.", nameof(application));
+ throw new ArgumentException("A client secret cannot be associated with a public application.", nameof(descriptor));
}
// When a redirect_uri is specified, ensure it is valid and spec-compliant.
// See https://tools.ietf.org/html/rfc6749#section-3.1 for more information.
- var address = await Store.GetRedirectUriAsync(application, cancellationToken);
- if (!string.IsNullOrEmpty(address))
+ if (!string.IsNullOrEmpty(descriptor.RedirectUri))
{
// Ensure the redirect_uri is a valid and absolute URL.
- if (!Uri.TryCreate(address, UriKind.Absolute, out Uri uri))
+ if (!Uri.TryCreate(descriptor.RedirectUri, UriKind.Absolute, out Uri uri))
{
throw new ArgumentException("The redirect_uri must be an absolute URL.");
}
@@ -584,11 +678,10 @@ namespace OpenIddict.Core
}
// When a post_logout_redirect_uri is specified, ensure it is valid.
- address = await Store.GetLogoutRedirectUriAsync(application, cancellationToken);
- if (!string.IsNullOrEmpty(address))
+ if (!string.IsNullOrEmpty(descriptor.LogoutRedirectUri))
{
// Ensure the post_logout_redirect_uri is a valid and absolute URL.
- if (!Uri.TryCreate(address, UriKind.Absolute, out Uri uri))
+ if (!Uri.TryCreate(descriptor.LogoutRedirectUri, UriKind.Absolute, out Uri uri))
{
throw new ArgumentException("The post_logout_redirect_uri must be an absolute URL.");
}
@@ -599,6 +692,8 @@ namespace OpenIddict.Core
throw new ArgumentException("The post_logout_redirect_uri cannot contain a fragment.");
}
}
+
+ return Task.FromResult(0);
}
///
diff --git a/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs b/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs
index cd249bb0..88738b2f 100644
--- a/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs
+++ b/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs
@@ -5,7 +5,6 @@
*/
using System;
-using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@@ -38,12 +37,6 @@ namespace OpenIddict.Core
///
protected IOpenIddictAuthorizationStore Store { get; }
- ///
- /// Gets the authorizations as a queryable source,
- /// if supported by the underlying store.
- ///
- public virtual IQueryable Authorizations => Store.Authorizations;
-
///
/// Creates a new authorization.
///
@@ -52,14 +45,15 @@ namespace OpenIddict.Core
///
/// A that can be used to monitor the asynchronous operation, whose result returns the authorization.
///
- public virtual Task CreateAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken)
+ public virtual async Task CreateAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken)
{
if (authorization == null)
{
throw new ArgumentNullException(nameof(authorization));
}
- return Store.CreateAsync(authorization, cancellationToken);
+ await ValidateAsync(authorization, cancellationToken);
+ return await Store.CreateAsync(authorization, cancellationToken);
}
///
@@ -70,14 +64,15 @@ namespace OpenIddict.Core
///
/// A that can be used to monitor the asynchronous operation, whose result returns the authorization.
///
- public virtual Task CreateAsync([NotNull] OpenIddictAuthorizationDescriptor descriptor, CancellationToken cancellationToken)
+ public virtual async Task CreateAsync([NotNull] OpenIddictAuthorizationDescriptor descriptor, CancellationToken cancellationToken)
{
if (descriptor == null)
{
throw new ArgumentNullException(nameof(descriptor));
}
- return Store.CreateAsync(descriptor, cancellationToken);
+ await ValidateAsync(descriptor, cancellationToken);
+ return await Store.CreateAsync(descriptor, cancellationToken);
}
///
@@ -109,6 +104,26 @@ namespace OpenIddict.Core
return Store.FindByIdAsync(identifier, cancellationToken);
}
+ ///
+ /// Executes the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the single element returned when executing the specified query.
+ ///
+ public virtual Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken)
+ {
+ if (query == null)
+ {
+ throw new ArgumentNullException(nameof(query));
+ }
+
+ return Store.GetAsync(query, cancellationToken);
+ }
+
///
/// Retrieves the unique identifier associated with an authorization.
///
@@ -128,6 +143,26 @@ namespace OpenIddict.Core
return Store.GetIdAsync(authorization, cancellationToken);
}
+ ///
+ /// Executes the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns all the elements returned when executing the specified query.
+ ///
+ public virtual Task ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken)
+ {
+ if (query == null)
+ {
+ throw new ArgumentNullException(nameof(query));
+ }
+
+ return Store.ListAsync(query, cancellationToken);
+ }
+
///
/// Revokes an authorization.
///
@@ -145,6 +180,7 @@ namespace OpenIddict.Core
if (!string.Equals(status, OpenIddictConstants.Statuses.Revoked, StringComparison.OrdinalIgnoreCase))
{
await Store.SetStatusAsync(authorization, OpenIddictConstants.Statuses.Revoked, cancellationToken);
+ await ValidateAsync(authorization, cancellationToken);
await UpdateAsync(authorization, cancellationToken);
}
}
@@ -157,14 +193,15 @@ namespace OpenIddict.Core
///
/// A that can be used to monitor the asynchronous operation.
///
- public virtual Task UpdateAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken)
+ public virtual async Task UpdateAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken)
{
if (authorization == null)
{
throw new ArgumentNullException(nameof(authorization));
}
- return Store.UpdateAsync(authorization, cancellationToken);
+ await ValidateAsync(authorization, cancellationToken);
+ await Store.UpdateAsync(authorization, cancellationToken);
}
///
@@ -182,10 +219,35 @@ namespace OpenIddict.Core
throw new ArgumentNullException(nameof(authorization));
}
- if (string.IsNullOrEmpty(await Store.GetSubjectAsync(authorization, cancellationToken)))
+ var descriptor = new OpenIddictAuthorizationDescriptor
+ {
+ Subject = await Store.GetSubjectAsync(authorization, cancellationToken)
+ };
+
+ await ValidateAsync(descriptor, cancellationToken);
+ }
+
+ ///
+ /// Validates the authorization descriptor to ensure it's in a consistent state.
+ ///
+ /// The authorization descriptor.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ protected virtual Task ValidateAsync([NotNull] OpenIddictAuthorizationDescriptor descriptor, CancellationToken cancellationToken)
+ {
+ if (descriptor == null)
+ {
+ throw new ArgumentNullException(nameof(descriptor));
+ }
+
+ if (string.IsNullOrEmpty(descriptor.Subject))
{
throw new ArgumentException("The subject cannot be null or empty.");
}
+
+ return Task.FromResult(0);
}
}
}
\ No newline at end of file
diff --git a/src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs b/src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs
index b001add4..10448be4 100644
--- a/src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs
+++ b/src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs
@@ -4,7 +4,10 @@
* the license and the contributors participating to this project.
*/
+using System;
using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging;
@@ -35,9 +38,43 @@ namespace OpenIddict.Core
protected IOpenIddictScopeStore Store { get; }
///
- /// Gets the scopes as a queryable source,
- /// if supported by the underlying store.
+ /// Executes the specified query.
///
- public virtual IQueryable Scopes => Store.Scopes;
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the single element returned when executing the specified query.
+ ///
+ public virtual Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken)
+ {
+ if (query == null)
+ {
+ throw new ArgumentNullException(nameof(query));
+ }
+
+ return Store.GetAsync(query, cancellationToken);
+ }
+
+ ///
+ /// Executes the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns all the elements returned when executing the specified query.
+ ///
+ public virtual Task ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken)
+ {
+ if (query == null)
+ {
+ throw new ArgumentNullException(nameof(query));
+ }
+
+ return Store.ListAsync(query, cancellationToken);
+ }
}
}
\ No newline at end of file
diff --git a/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs b/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs
index 6d32f488..9774e570 100644
--- a/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs
+++ b/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs
@@ -38,12 +38,6 @@ namespace OpenIddict.Core
///
protected IOpenIddictTokenStore Store { get; }
- ///
- /// Gets the tokens as a queryable source,
- /// if supported by the underlying store.
- ///
- public virtual IQueryable Tokens => Store.Tokens;
-
///
/// Creates a new token.
///
@@ -157,6 +151,26 @@ namespace OpenIddict.Core
return Store.FindBySubjectAsync(subject, cancellationToken);
}
+ ///
+ /// Executes the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the single element returned when executing the specified query.
+ ///
+ public virtual Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken)
+ {
+ if (query == null)
+ {
+ throw new ArgumentNullException(nameof(query));
+ }
+
+ return Store.GetAsync(query, cancellationToken);
+ }
+
///
/// Retrieves the optional authorization identifier associated with a token.
///
@@ -356,6 +370,26 @@ namespace OpenIddict.Core
return string.Equals(status, OpenIddictConstants.Statuses.Valid, StringComparison.OrdinalIgnoreCase);
}
+ ///
+ /// Executes the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns all the elements returned when executing the specified query.
+ ///
+ public virtual Task ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken)
+ {
+ if (query == null)
+ {
+ throw new ArgumentNullException(nameof(query));
+ }
+
+ return Store.ListAsync(query, cancellationToken);
+ }
+
///
/// Redeems a token.
///
diff --git a/src/OpenIddict.Core/OpenIddict.Core.csproj b/src/OpenIddict.Core/OpenIddict.Core.csproj
index 41e36a8b..0cb219f0 100644
--- a/src/OpenIddict.Core/OpenIddict.Core.csproj
+++ b/src/OpenIddict.Core/OpenIddict.Core.csproj
@@ -26,6 +26,8 @@
+
+
diff --git a/src/OpenIddict.Core/Stores/IOpenIddictApplicationStore.cs b/src/OpenIddict.Core/Stores/IOpenIddictApplicationStore.cs
index 88281ae9..08965a07 100644
--- a/src/OpenIddict.Core/Stores/IOpenIddictApplicationStore.cs
+++ b/src/OpenIddict.Core/Stores/IOpenIddictApplicationStore.cs
@@ -4,6 +4,7 @@
* the license and the contributors participating to this project.
*/
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
@@ -19,19 +20,24 @@ namespace OpenIddict.Core
public interface IOpenIddictApplicationStore where TApplication : class
{
///
- /// Gets the applications as a queryable source, if supported by the store.
+ /// Creates a new application.
///
- IQueryable Applications { get; }
+ /// The application to create.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation, whose result returns the application.
+ ///
+ Task CreateAsync([NotNull] TApplication application, CancellationToken cancellationToken);
///
/// Creates a new application.
///
- /// The application to create.
+ /// The application descriptor.
/// The that can be used to abort the operation.
///
/// A that can be used to monitor the asynchronous operation, whose result returns the application.
///
- Task CreateAsync([NotNull] TApplication application, CancellationToken cancellationToken);
+ Task CreateAsync([NotNull] OpenIddictApplicationDescriptor descriptor, CancellationToken cancellationToken);
///
/// Removes an existing application.
@@ -87,6 +93,18 @@ namespace OpenIddict.Core
///
Task FindByRedirectUriAsync(string address, CancellationToken cancellationToken);
+ ///
+ /// Executes the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the single element returned when executing the specified query.
+ ///
+ Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken);
+
///
/// Retrieves the client identifier associated with an application.
///
@@ -175,7 +193,19 @@ namespace OpenIddict.Core
/// 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);
+ Task GetTokensAsync([NotNull] TApplication application, CancellationToken cancellationToken);
+
+ ///
+ /// Executes the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns all the elements returned when executing the specified query.
+ ///
+ Task ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken);
///
/// Sets the client secret associated with an application.
diff --git a/src/OpenIddict.Core/Stores/IOpenIddictAuthorizationStore.cs b/src/OpenIddict.Core/Stores/IOpenIddictAuthorizationStore.cs
index bb5395e2..aaf3c41f 100644
--- a/src/OpenIddict.Core/Stores/IOpenIddictAuthorizationStore.cs
+++ b/src/OpenIddict.Core/Stores/IOpenIddictAuthorizationStore.cs
@@ -4,7 +4,7 @@
* the license and the contributors participating to this project.
*/
-using System.Collections.Generic;
+using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@@ -18,11 +18,6 @@ namespace OpenIddict.Core
/// The type of the Authorization entity.
public interface IOpenIddictAuthorizationStore where TAuthorization : class
{
- ///
- /// Gets the authorizations as a queryable source, if supported by the store.
- ///
- IQueryable Authorizations { get; }
-
///
/// Creates a new authorization.
///
@@ -66,6 +61,18 @@ namespace OpenIddict.Core
///
Task FindAsync(string subject, string client, CancellationToken cancellationToken);
+ ///
+ /// Executes the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the single element returned when executing the specified query.
+ ///
+ Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken);
+
///
/// Retrieves the unique identifier associated with an authorization.
///
@@ -99,6 +106,18 @@ namespace OpenIddict.Core
///
Task GetSubjectAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken);
+ ///
+ /// Executes the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns all the elements returned when executing the specified query.
+ ///
+ Task ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken);
+
///
/// Sets the status associated with an authorization.
///
diff --git a/src/OpenIddict.Core/Stores/IOpenIddictScopeStore.cs b/src/OpenIddict.Core/Stores/IOpenIddictScopeStore.cs
index 6c8eea2b..d1d59ebe 100644
--- a/src/OpenIddict.Core/Stores/IOpenIddictScopeStore.cs
+++ b/src/OpenIddict.Core/Stores/IOpenIddictScopeStore.cs
@@ -4,7 +4,11 @@
* the license and the contributors participating to this project.
*/
+using System;
using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using JetBrains.Annotations;
namespace OpenIddict.Core
{
@@ -15,8 +19,27 @@ namespace OpenIddict.Core
public interface IOpenIddictScopeStore where TScope : class
{
///
- /// Gets the scopes as a queryable source, if supported by the store.
+ /// Executes the specified query.
///
- IQueryable Scopes { get; }
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the single element returned when executing the specified query.
+ ///
+ Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken);
+
+ ///
+ /// Executes the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns all the elements returned when executing the specified query.
+ ///
+ Task ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken);
}
}
\ No newline at end of file
diff --git a/src/OpenIddict.Core/Stores/IOpenIddictTokenStore.cs b/src/OpenIddict.Core/Stores/IOpenIddictTokenStore.cs
index 67491003..97512467 100644
--- a/src/OpenIddict.Core/Stores/IOpenIddictTokenStore.cs
+++ b/src/OpenIddict.Core/Stores/IOpenIddictTokenStore.cs
@@ -18,11 +18,6 @@ namespace OpenIddict.Core
/// The type of the Token entity.
public interface IOpenIddictTokenStore where TToken : class
{
- ///
- /// Gets the tokens as a queryable source, if supported by the store.
- ///
- IQueryable Tokens { get; }
-
///
/// Creates a new token.
///
@@ -95,6 +90,18 @@ namespace OpenIddict.Core
///
Task FindBySubjectAsync(string subject, CancellationToken cancellationToken);
+ ///
+ /// Executes the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the single element returned when executing the specified query.
+ ///
+ Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken);
+
///
/// Retrieves the optional authorization identifier associated with a token.
///
@@ -194,6 +201,18 @@ namespace OpenIddict.Core
///
Task GetTokenTypeAsync([NotNull] TToken token, CancellationToken cancellationToken);
+ ///
+ /// Executes the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns all the elements returned when executing the specified query.
+ ///
+ Task ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken);
+
///
/// Sets the authorization associated with a token.
///
diff --git a/src/OpenIddict.Core/Stores/OpenIddictApplicationStore.cs b/src/OpenIddict.Core/Stores/OpenIddictApplicationStore.cs
new file mode 100644
index 00000000..80dcaf0f
--- /dev/null
+++ b/src/OpenIddict.Core/Stores/OpenIddictApplicationStore.cs
@@ -0,0 +1,399 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
+ * See https://github.com/openiddict/openiddict-core for more information concerning
+ * the license and the contributors participating to this project.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using JetBrains.Annotations;
+using OpenIddict.Models;
+
+namespace OpenIddict.Core
+{
+ ///
+ /// Provides methods allowing to manage the applications stored in a database.
+ /// Note: this base class can only be used with the default OpenIddict entities.
+ ///
+ /// The type of the Application entity.
+ /// The type of the Authorization entity.
+ /// The type of the Token entity.
+ /// The type of the entity primary keys.
+ public abstract class OpenIddictApplicationStore : IOpenIddictApplicationStore
+ where TApplication : OpenIddictApplication, new()
+ where TAuthorization : OpenIddictAuthorization, new()
+ where TToken : OpenIddictToken, new()
+ where TKey : IEquatable
+ {
+ ///
+ /// Creates a new application.
+ ///
+ /// The application to create.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation, whose result returns the application.
+ ///
+ public abstract Task CreateAsync([NotNull] TApplication application, CancellationToken cancellationToken);
+
+ ///
+ /// Creates a new application.
+ ///
+ /// The application descriptor.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation, whose result returns the application.
+ ///
+ public abstract Task CreateAsync([NotNull] OpenIddictApplicationDescriptor descriptor, CancellationToken cancellationToken);
+
+ ///
+ /// Removes an existing application.
+ ///
+ /// The application to delete.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ public abstract Task DeleteAsync([NotNull] TApplication application, CancellationToken cancellationToken);
+
+ ///
+ /// Retrieves an application using its unique identifier.
+ ///
+ /// The unique identifier associated with the application.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the client application corresponding to the identifier.
+ ///
+ public virtual Task FindByIdAsync(string identifier, CancellationToken cancellationToken)
+ {
+ var key = ConvertIdentifierFromString(identifier);
+
+ return GetAsync(applications => applications.Where(application => application.Id.Equals(key)), cancellationToken);
+ }
+
+ ///
+ /// Retrieves an application using its client identifier.
+ ///
+ /// The client identifier associated with the application.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the client application corresponding to the identifier.
+ ///
+ public virtual Task FindByClientIdAsync(string identifier, CancellationToken cancellationToken)
+ {
+ return GetAsync(applications => applications.Where(application => application.ClientId.Equals(identifier)), cancellationToken);
+ }
+
+ ///
+ /// Retrieves all the applications associated with the specified post_logout_redirect_uri.
+ ///
+ /// The post_logout_redirect_uri associated with the applications.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation, whose result
+ /// returns the client applications corresponding to the specified post_logout_redirect_uri.
+ ///
+ public virtual Task FindByLogoutRedirectUriAsync(string address, CancellationToken cancellationToken)
+ {
+ return ListAsync(applications => applications.Where(application => application.LogoutRedirectUri == address), cancellationToken);
+ }
+
+ ///
+ /// Retrieves all the applications associated with the specified redirect_uri.
+ ///
+ /// The redirect_uri associated with the applications.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation, whose result
+ /// returns the client applications corresponding to the specified redirect_uri.
+ ///
+ public virtual Task FindByRedirectUriAsync(string address, CancellationToken cancellationToken)
+ {
+ return ListAsync(applications => applications.Where(application => application.RedirectUri == address), cancellationToken);
+ }
+
+ ///
+ /// Executes the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the single element returned when executing the specified query.
+ ///
+ public abstract Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken);
+
+ ///
+ /// Retrieves the client identifier associated with an application.
+ ///
+ /// The application.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the client identifier associated with the application.
+ ///
+ public virtual Task GetClientIdAsync([NotNull] TApplication application, CancellationToken cancellationToken)
+ {
+ if (application == null)
+ {
+ throw new ArgumentNullException(nameof(application));
+ }
+
+ return Task.FromResult(application.ClientId);
+ }
+
+ ///
+ /// Retrieves the client secret associated with an application.
+ /// Note: depending on the manager used to create the application,
+ /// the client secret may be hashed for security reasons.
+ ///
+ /// The application.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the client secret associated with the application.
+ ///
+ public virtual Task GetClientSecretAsync([NotNull] TApplication application, CancellationToken cancellationToken)
+ {
+ if (application == null)
+ {
+ throw new ArgumentNullException(nameof(application));
+ }
+
+ return Task.FromResult(application.ClientSecret);
+ }
+
+ ///
+ /// Retrieves the client type associated with an application.
+ ///
+ /// The application.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the client type of the application (by default, "public").
+ ///
+ public virtual Task GetClientTypeAsync([NotNull] TApplication application, CancellationToken cancellationToken)
+ {
+ if (application == null)
+ {
+ throw new ArgumentNullException(nameof(application));
+ }
+
+ return Task.FromResult(application.Type);
+ }
+
+ ///
+ /// Retrieves the display name associated with an application.
+ ///
+ /// The application.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the display name associated with the application.
+ ///
+ public virtual Task GetDisplayNameAsync([NotNull] TApplication application, CancellationToken cancellationToken)
+ {
+ if (application == null)
+ {
+ throw new ArgumentNullException(nameof(application));
+ }
+
+ return Task.FromResult(application.DisplayName);
+ }
+
+ ///
+ /// Retrieves the unique identifier associated with an application.
+ ///
+ /// The application.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the unique identifier associated with the application.
+ ///
+ public virtual Task GetIdAsync([NotNull] TApplication application, CancellationToken cancellationToken)
+ {
+ if (application == null)
+ {
+ throw new ArgumentNullException(nameof(application));
+ }
+
+ return Task.FromResult(ConvertIdentifierToString(application.Id));
+ }
+
+ ///
+ /// Retrieves the logout callback address 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 post_logout_redirect_uri associated with the application.
+ ///
+ public virtual Task GetLogoutRedirectUriAsync([NotNull] TApplication application, CancellationToken cancellationToken)
+ {
+ if (application == null)
+ {
+ throw new ArgumentNullException(nameof(application));
+ }
+
+ return Task.FromResult(application.LogoutRedirectUri);
+ }
+
+ ///
+ /// Retrieves the callback address 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 redirect_uri associated with the application.
+ ///
+ public virtual Task GetRedirectUriAsync([NotNull] TApplication application, CancellationToken cancellationToken)
+ {
+ if (application == null)
+ {
+ throw new ArgumentNullException(nameof(application));
+ }
+
+ return Task.FromResult(application.RedirectUri);
+ }
+
+ ///
+ /// 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));
+ }
+
+ var tokens = new List();
+
+ foreach (var identifier in await ListAsync(applications =>
+ from entity in applications
+ where entity.Id.Equals(application.Id)
+ from token in entity.Tokens
+ select token.Id, cancellationToken))
+ {
+ tokens.Add(ConvertIdentifierToString(identifier));
+ }
+
+ return tokens.ToArray();
+ }
+
+ ///
+ /// Executes the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns all the elements returned when executing the specified query.
+ ///
+ public abstract Task ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken);
+
+ ///
+ /// Sets the client secret associated with an application.
+ /// Note: depending on the manager used to create the application,
+ /// the client secret may be hashed for security reasons.
+ ///
+ /// The application.
+ /// The client secret associated with the application.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ public virtual Task SetClientSecretAsync([NotNull] TApplication application,
+ [CanBeNull] string secret, CancellationToken cancellationToken)
+ {
+ if (application == null)
+ {
+ throw new ArgumentNullException(nameof(application));
+ }
+
+ application.ClientSecret = secret;
+
+ return Task.FromResult(0);
+ }
+
+ ///
+ /// Sets the client type associated with an application.
+ ///
+ /// The application.
+ /// The client type associated with the application.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ public virtual Task SetClientTypeAsync([NotNull] TApplication application, [NotNull] string type, CancellationToken cancellationToken)
+ {
+ if (application == null)
+ {
+ throw new ArgumentNullException(nameof(application));
+ }
+
+ if (string.IsNullOrEmpty(type))
+ {
+ throw new ArgumentException("The client type cannot be null or empty.", nameof(type));
+ }
+
+ application.Type = type;
+
+ return Task.FromResult(0);
+ }
+
+ ///
+ /// Updates an existing application.
+ ///
+ /// The application to update.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ public abstract Task UpdateAsync([NotNull] TApplication application, CancellationToken cancellationToken);
+
+ ///
+ /// Converts the provided identifier to a strongly typed key object.
+ ///
+ /// The identifier to convert.
+ /// An instance of representing the provided identifier.
+ public virtual TKey ConvertIdentifierFromString([CanBeNull] string identifier)
+ {
+ if (string.IsNullOrEmpty(identifier))
+ {
+ return default(TKey);
+ }
+
+ return (TKey) TypeDescriptor.GetConverter(typeof(TKey)).ConvertFromInvariantString(identifier);
+ }
+
+ ///
+ /// Converts the provided identifier to its string representation.
+ ///
+ /// The identifier to convert.
+ /// A representation of the provided identifier.
+ public virtual string ConvertIdentifierToString([CanBeNull] TKey identifier)
+ {
+ if (Equals(identifier, default(TKey)))
+ {
+ return null;
+ }
+
+ return TypeDescriptor.GetConverter(typeof(TKey)).ConvertToInvariantString(identifier);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/OpenIddict.Core/Stores/OpenIddictAuthorizationStore.cs b/src/OpenIddict.Core/Stores/OpenIddictAuthorizationStore.cs
new file mode 100644
index 00000000..d6e68bd2
--- /dev/null
+++ b/src/OpenIddict.Core/Stores/OpenIddictAuthorizationStore.cs
@@ -0,0 +1,220 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
+ * See https://github.com/openiddict/openiddict-core for more information concerning
+ * the license and the contributors participating to this project.
+ */
+
+using System;
+using System.ComponentModel;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using JetBrains.Annotations;
+using OpenIddict.Models;
+
+namespace OpenIddict.Core
+{
+ ///
+ /// Provides methods allowing to manage the authorizations stored in a database.
+ /// Note: this base class can only be used with the default OpenIddict entities.
+ ///
+ /// The type of the Authorization entity.
+ /// The type of the Application entity.
+ /// The type of the Token entity.
+ /// The type of the entity primary keys.
+ public abstract class OpenIddictAuthorizationStore : IOpenIddictAuthorizationStore
+ where TAuthorization : OpenIddictAuthorization, new()
+ where TApplication : OpenIddictApplication, new()
+ where TToken : OpenIddictToken, new()
+ where TKey : IEquatable
+ {
+ ///
+ /// Creates a new authorization.
+ ///
+ /// The authorization to create.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation, whose result returns the authorization.
+ ///
+ public abstract Task CreateAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken);
+
+ ///
+ /// Creates a new authorization.
+ ///
+ /// The authorization descriptor.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation, whose result returns the authorization.
+ ///
+ public abstract Task CreateAsync([NotNull] OpenIddictAuthorizationDescriptor descriptor, CancellationToken cancellationToken);
+
+ ///
+ /// Retrieves an authorization using its associated subject/client.
+ ///
+ /// The subject associated with the authorization.
+ /// The client associated with the authorization.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the authorization corresponding to the subject/client.
+ ///
+ public virtual Task FindAsync(string subject, string client, CancellationToken cancellationToken)
+ {
+ var key = ConvertIdentifierFromString(client);
+
+ return GetAsync(authorizations =>
+ from authorization in authorizations
+ where authorization.Application.Id.Equals(key)
+ where authorization.Subject == subject
+ select authorization, cancellationToken);
+ }
+
+ ///
+ /// Retrieves an authorization using its unique identifier.
+ ///
+ /// The unique identifier associated with the authorization.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the authorization corresponding to the identifier.
+ ///
+ public virtual Task FindByIdAsync(string identifier, CancellationToken cancellationToken)
+ {
+ var key = ConvertIdentifierFromString(identifier);
+
+ return GetAsync(authorizations => authorizations.Where(authorization => authorization.Id.Equals(key)), cancellationToken);
+ }
+
+ ///
+ /// Executes the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the single element returned when executing the specified query.
+ ///
+ public abstract Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken);
+
+ ///
+ /// Retrieves the unique identifier associated with an authorization.
+ ///
+ /// The authorization.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the unique identifier associated with the authorization.
+ ///
+ public virtual Task GetIdAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken)
+ {
+ if (authorization == null)
+ {
+ throw new ArgumentNullException(nameof(authorization));
+ }
+
+ return Task.FromResult(ConvertIdentifierToString(authorization.Id));
+ }
+
+ ///
+ /// Retrieves the status associated with an authorization.
+ ///
+ /// The authorization.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the status associated with the specified authorization.
+ ///
+ public virtual Task GetStatusAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken)
+ {
+ return Task.FromResult(authorization.Status);
+ }
+
+ ///
+ /// Retrieves the subject associated with an authorization.
+ ///
+ /// The authorization.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the subject associated with the specified authorization.
+ ///
+ public virtual Task GetSubjectAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken)
+ {
+ if (authorization == null)
+ {
+ throw new ArgumentNullException(nameof(authorization));
+ }
+
+ return Task.FromResult(authorization.Subject);
+ }
+
+ ///
+ /// Executes the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns all the elements returned when executing the specified query.
+ ///
+ public abstract Task ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken);
+
+ ///
+ /// Sets the status associated with an authorization.
+ ///
+ /// The authorization.
+ /// The status associated with the authorization.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ public virtual Task SetStatusAsync([NotNull] TAuthorization authorization, [NotNull] string status, CancellationToken cancellationToken)
+ {
+ authorization.Status = status;
+
+ return Task.FromResult(0);
+ }
+
+ ///
+ /// Updates an existing authorization.
+ ///
+ /// The authorization to update.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ public abstract Task UpdateAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken);
+
+ ///
+ /// Converts the provided identifier to a strongly typed key object.
+ ///
+ /// The identifier to convert.
+ /// An instance of representing the provided identifier.
+ public virtual TKey ConvertIdentifierFromString([CanBeNull] string identifier)
+ {
+ if (string.IsNullOrEmpty(identifier))
+ {
+ return default(TKey);
+ }
+
+ return (TKey) TypeDescriptor.GetConverter(typeof(TKey)).ConvertFromInvariantString(identifier);
+ }
+
+ ///
+ /// Converts the provided identifier to its string representation.
+ ///
+ /// The identifier to convert.
+ /// A representation of the provided identifier.
+ public virtual string ConvertIdentifierToString([CanBeNull] TKey identifier)
+ {
+ if (Equals(identifier, default(TKey)))
+ {
+ return null;
+ }
+
+ return TypeDescriptor.GetConverter(typeof(TKey)).ConvertToInvariantString(identifier);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/OpenIddict.Core/Stores/OpenIddictScopeStore.cs b/src/OpenIddict.Core/Stores/OpenIddictScopeStore.cs
new file mode 100644
index 00000000..22c4520f
--- /dev/null
+++ b/src/OpenIddict.Core/Stores/OpenIddictScopeStore.cs
@@ -0,0 +1,81 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
+ * See https://github.com/openiddict/openiddict-core for more information concerning
+ * the license and the contributors participating to this project.
+ */
+
+using System;
+using System.ComponentModel;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using JetBrains.Annotations;
+using OpenIddict.Models;
+
+namespace OpenIddict.Core
+{
+ ///
+ /// Provides methods allowing to manage the scopes stored in a database.
+ /// Note: this base class can only be used with the default OpenIddict entities.
+ ///
+ /// The type of the Scope entity.
+ /// The type of the entity primary keys.
+ public abstract class OpenIddictScopeStore : IOpenIddictScopeStore
+ where TScope : OpenIddictScope, new()
+ where TKey : IEquatable
+ {
+ ///
+ /// Executes the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the single element returned when executing the specified query.
+ ///
+ public abstract Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken);
+
+ ///
+ /// Executes the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns all the elements returned when executing the specified query.
+ ///
+ public abstract Task ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken);
+
+ ///
+ /// Converts the provided identifier to a strongly typed key object.
+ ///
+ /// The identifier to convert.
+ /// An instance of representing the provided identifier.
+ public virtual TKey ConvertIdentifierFromString([CanBeNull] string identifier)
+ {
+ if (string.IsNullOrEmpty(identifier))
+ {
+ return default(TKey);
+ }
+
+ return (TKey) TypeDescriptor.GetConverter(typeof(TKey)).ConvertFromInvariantString(identifier);
+ }
+
+ ///
+ /// Converts the provided identifier to its string representation.
+ ///
+ /// The identifier to convert.
+ /// A representation of the provided identifier.
+ public virtual string ConvertIdentifierToString([CanBeNull] TKey identifier)
+ {
+ if (Equals(identifier, default(TKey)))
+ {
+ return null;
+ }
+
+ return TypeDescriptor.GetConverter(typeof(TKey)).ConvertToInvariantString(identifier);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/OpenIddict.Core/Stores/OpenIddictTokenStore.cs b/src/OpenIddict.Core/Stores/OpenIddictTokenStore.cs
new file mode 100644
index 00000000..f10d782d
--- /dev/null
+++ b/src/OpenIddict.Core/Stores/OpenIddictTokenStore.cs
@@ -0,0 +1,419 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
+ * See https://github.com/openiddict/openiddict-core for more information concerning
+ * the license and the contributors participating to this project.
+ */
+
+using System;
+using System.ComponentModel;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using JetBrains.Annotations;
+using OpenIddict.Models;
+
+namespace OpenIddict.Core
+{
+ ///
+ /// Provides methods allowing to manage the tokens stored in a database.
+ /// Note: this base class can only be used with the default OpenIddict entities.
+ ///
+ /// The type of the Token entity.
+ /// The type of the Application entity.
+ /// The type of the Authorization entity.
+ /// The type of the entity primary keys.
+ public abstract class OpenIddictTokenStore : IOpenIddictTokenStore
+ where TToken : OpenIddictToken, new()
+ where TApplication : OpenIddictApplication, new()
+ where TAuthorization : OpenIddictAuthorization, new()
+ where TKey : IEquatable
+ {
+ ///
+ /// Creates a new token.
+ ///
+ /// The token to create.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation, whose result returns the token.
+ ///
+ public abstract Task CreateAsync([NotNull] TToken token, CancellationToken cancellationToken);
+
+ ///
+ /// Creates a new token, which is associated with a particular subject.
+ ///
+ /// The token descriptor.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation, whose result returns the token.
+ ///
+ public abstract Task CreateAsync([NotNull] OpenIddictTokenDescriptor descriptor, CancellationToken cancellationToken);
+
+ ///
+ /// Removes a token.
+ ///
+ /// The token to delete.
+ /// The that can be used to abort the operation.
+ /// A that can be used to monitor the asynchronous operation.
+ public abstract Task DeleteAsync([NotNull] TToken token, CancellationToken cancellationToken);
+
+ ///
+ /// Retrieves the list of tokens corresponding to the specified authorization identifier.
+ ///
+ /// The authorization identifier associated with the tokens.
+ /// The that can be used to abort the operation.
+ ///
+ /// 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)
+ {
+ var key = ConvertIdentifierFromString(identifier);
+
+ return ListAsync(tokens => tokens.Where(token => token.Authorization.Id.Equals(key)), cancellationToken);
+ }
+
+ ///
+ /// Retrieves the list of tokens corresponding to the specified hash.
+ ///
+ /// The hashed crypto-secure random 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 hash.
+ ///
+ public virtual Task FindByHashAsync(string hash, CancellationToken cancellationToken)
+ {
+ return GetAsync(tokens => tokens.Where(token => token.Hash == hash), cancellationToken);
+ }
+
+ ///
+ /// Retrieves an token using its unique identifier.
+ ///
+ /// The unique identifier associated with the token.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the token corresponding to the unique identifier.
+ ///
+ public virtual Task FindByIdAsync(string identifier, CancellationToken cancellationToken)
+ {
+ var key = ConvertIdentifierFromString(identifier);
+
+ return GetAsync(tokens => tokens.Where(token => token.Id.Equals(key)), cancellationToken);
+ }
+
+ ///
+ /// Retrieves the list of tokens corresponding to the specified subject.
+ ///
+ /// The subject associated with the tokens.
+ /// The that can be used to abort the operation.
+ ///
+ /// 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)
+ {
+ return ListAsync(tokens => tokens.Where(token => token.Subject == subject), cancellationToken);
+ }
+
+ ///
+ /// Executes the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the single element returned when executing the specified query.
+ ///
+ public abstract Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken);
+
+ ///
+ /// Retrieves the optional authorization identifier associated with a token.
+ ///
+ /// The token.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the authorization identifier associated with the token.
+ ///
+ public virtual async Task GetAuthorizationIdAsync([NotNull] TToken token, CancellationToken cancellationToken)
+ {
+ if (token == null)
+ {
+ throw new ArgumentNullException(nameof(token));
+ }
+
+ if (token.Authorization != null)
+ {
+ return ConvertIdentifierToString(token.Authorization.Id);
+ }
+
+ var key = await GetAsync(tokens =>
+ from element in tokens
+ where element.Id.Equals(token.Id)
+ select element.Authorization.Id, cancellationToken);
+
+ return ConvertIdentifierToString(key);
+ }
+
+ ///
+ /// Retrieves the ciphertext associated with a token.
+ ///
+ /// The token.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the ciphertext associated with the specified token.
+ ///
+ public virtual Task GetCiphertextAsync([NotNull] TToken token, CancellationToken cancellationToken)
+ {
+ if (token == null)
+ {
+ throw new ArgumentNullException(nameof(token));
+ }
+
+ return Task.FromResult(token.Ciphertext);
+ }
+
+ ///
+ /// Retrieves the creation date associated with a token.
+ ///
+ /// The token.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the creation date associated with the specified token.
+ ///
+ public virtual Task GetCreationDateAsync([NotNull] TToken token, CancellationToken cancellationToken)
+ {
+ if (token == null)
+ {
+ throw new ArgumentNullException(nameof(token));
+ }
+
+ return Task.FromResult(token.CreationDate);
+ }
+
+ ///
+ /// Retrieves the expiration date associated with a token.
+ ///
+ /// The token.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the expiration date associated with the specified token.
+ ///
+ public virtual Task GetExpirationDateAsync([NotNull] TToken token, CancellationToken cancellationToken)
+ {
+ if (token == null)
+ {
+ throw new ArgumentNullException(nameof(token));
+ }
+
+ return Task.FromResult(token.ExpirationDate);
+ }
+
+ ///
+ /// Retrieves the hashed identifier associated with a token.
+ ///
+ /// The token.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the hashed identifier associated with the specified token.
+ ///
+ public virtual Task GetHashAsync([NotNull] TToken token, CancellationToken cancellationToken)
+ {
+ if (token == null)
+ {
+ throw new ArgumentNullException(nameof(token));
+ }
+
+ return Task.FromResult(token.Hash);
+ }
+
+ ///
+ /// Retrieves the unique identifier associated with a token.
+ ///
+ /// The token.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the unique identifier associated with the token.
+ ///
+ public virtual Task GetIdAsync([NotNull] TToken token, CancellationToken cancellationToken)
+ {
+ if (token == null)
+ {
+ throw new ArgumentNullException(nameof(token));
+ }
+
+ return Task.FromResult(ConvertIdentifierToString(token.Id));
+ }
+
+ ///
+ /// Retrieves the status associated with a token.
+ ///
+ /// The token.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the status associated with the specified token.
+ ///
+ public virtual Task GetStatusAsync([NotNull] TToken token, CancellationToken cancellationToken)
+ {
+ if (token == null)
+ {
+ throw new ArgumentNullException(nameof(token));
+ }
+
+ return Task.FromResult(token.Status);
+ }
+
+ ///
+ /// Retrieves the subject associated with a token.
+ ///
+ /// The token.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the subject associated with the specified token.
+ ///
+ public virtual Task GetSubjectAsync([NotNull] TToken token, CancellationToken cancellationToken)
+ {
+ if (token == null)
+ {
+ throw new ArgumentNullException(nameof(token));
+ }
+
+ return Task.FromResult(token.Subject);
+ }
+
+ ///
+ /// Retrieves the token type associated with a token.
+ ///
+ /// The token.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the token type associated with the specified token.
+ ///
+ public virtual Task GetTokenTypeAsync([NotNull] TToken token, CancellationToken cancellationToken)
+ {
+ if (token == null)
+ {
+ throw new ArgumentNullException(nameof(token));
+ }
+
+ return Task.FromResult(token.Type);
+ }
+
+ ///
+ /// Executes the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns all the elements returned when executing the specified query.
+ ///
+ public abstract Task ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken);
+
+ ///
+ /// Sets the authorization associated with a token.
+ ///
+ /// The token.
+ /// The unique identifier associated with the authorization.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ public abstract Task SetAuthorizationAsync([NotNull] TToken token, [CanBeNull] string identifier, CancellationToken cancellationToken);
+
+ ///
+ /// Sets the client application associated with a token.
+ ///
+ /// The token.
+ /// The unique identifier associated with the client application.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ public abstract Task SetClientAsync([NotNull] TToken token, [CanBeNull] string identifier, CancellationToken cancellationToken);
+
+ ///
+ /// Sets the expiration date associated with a token.
+ ///
+ /// The token.
+ /// The date on which the token will no longer be considered valid.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ public virtual Task SetExpirationDateAsync([NotNull] TToken token,
+ [CanBeNull] DateTimeOffset? date, CancellationToken cancellationToken)
+ {
+ token.ExpirationDate = date;
+
+ return Task.FromResult(0);
+ }
+
+ ///
+ /// Sets the status associated with a token.
+ ///
+ /// The token.
+ /// The status associated with the authorization.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ public virtual Task SetStatusAsync([NotNull] TToken token, [NotNull] string status, CancellationToken cancellationToken)
+ {
+ token.Status = status;
+
+ return Task.FromResult(0);
+ }
+
+ ///
+ /// Updates an existing token.
+ ///
+ /// The token to update.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ public abstract Task UpdateAsync([NotNull] TToken token, CancellationToken cancellationToken);
+
+ ///
+ /// Converts the provided identifier to a strongly typed key object.
+ ///
+ /// The identifier to convert.
+ /// An instance of representing the provided identifier.
+ public virtual TKey ConvertIdentifierFromString([CanBeNull] string identifier)
+ {
+ if (string.IsNullOrEmpty(identifier))
+ {
+ return default(TKey);
+ }
+
+ return (TKey) TypeDescriptor.GetConverter(typeof(TKey)).ConvertFromInvariantString(identifier);
+ }
+
+ ///
+ /// Converts the provided identifier to its string representation.
+ ///
+ /// The identifier to convert.
+ /// A representation of the provided identifier.
+ public virtual string ConvertIdentifierToString([CanBeNull] TKey identifier)
+ {
+ if (Equals(identifier, default(TKey)))
+ {
+ return null;
+ }
+
+ return TypeDescriptor.GetConverter(typeof(TKey)).ConvertToInvariantString(identifier);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/OpenIddict.EntityFrameworkCore/OpenIddict.EntityFrameworkCore.csproj b/src/OpenIddict.EntityFrameworkCore/OpenIddict.EntityFrameworkCore.csproj
index 15217e43..0f5cd493 100644
--- a/src/OpenIddict.EntityFrameworkCore/OpenIddict.EntityFrameworkCore.csproj
+++ b/src/OpenIddict.EntityFrameworkCore/OpenIddict.EntityFrameworkCore.csproj
@@ -21,8 +21,4 @@
-
-
-
-
diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs
index 90c4fb05..0ba5a373 100644
--- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs
+++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs
@@ -5,8 +5,6 @@
*/
using System;
-using System.Collections.Generic;
-using System.ComponentModel;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@@ -19,6 +17,7 @@ namespace OpenIddict.EntityFrameworkCore
{
///
/// Provides methods allowing to manage the applications stored in a database.
+ /// Note: this class can only be used with the default OpenIddict entities.
///
/// The type of the Entity Framework database context.
public class OpenIddictApplicationStore : OpenIddictApplicationStore
/// Provides methods allowing to manage the applications stored in a database.
+ /// Note: this class can only be used with the default OpenIddict entities.
///
/// The type of the Entity Framework database context.
/// The type of the entity primary keys.
@@ -45,13 +45,15 @@ namespace OpenIddict.EntityFrameworkCore
///
/// Provides methods allowing to manage the applications stored in a database.
+ /// Note: this class can only be used with the default OpenIddict entities.
///
/// The type of the Application entity.
/// The type of the Authorization entity.
/// The type of the Token entity.
/// The type of the Entity Framework database context.
/// The type of the entity primary keys.
- public class OpenIddictApplicationStore : IOpenIddictApplicationStore
+ public class OpenIddictApplicationStore :
+ OpenIddictApplicationStore
where TApplication : OpenIddictApplication, new()
where TAuthorization : OpenIddictAuthorization, new()
where TToken : OpenIddictToken, new()
@@ -78,11 +80,6 @@ namespace OpenIddict.EntityFrameworkCore
///
protected DbSet Applications => Context.Set();
- ///
- /// Gets the applications as a queryable source, if supported by the store.
- ///
- IQueryable IOpenIddictApplicationStore.Applications => Applications;
-
///
/// Creates a new application.
///
@@ -91,7 +88,7 @@ namespace OpenIddict.EntityFrameworkCore
///
/// A that can be used to monitor the asynchronous operation, whose result returns the application.
///
- public virtual async Task CreateAsync([NotNull] TApplication application, CancellationToken cancellationToken)
+ public override async Task CreateAsync([NotNull] TApplication application, CancellationToken cancellationToken)
{
if (application == null)
{
@@ -106,302 +103,96 @@ namespace OpenIddict.EntityFrameworkCore
}
///
- /// Removes an existing application.
- ///
- /// The application to delete.
- /// The that can be used to abort the operation.
- ///
- /// A that can be used to monitor the asynchronous operation.
- ///
- public virtual async Task DeleteAsync([NotNull] TApplication application, CancellationToken cancellationToken)
- {
- if (application == null)
- {
- throw new ArgumentNullException(nameof(application));
- }
-
- Context.Remove(application);
-
- try
- {
- await Context.SaveChangesAsync(cancellationToken);
- }
-
- catch (DbUpdateConcurrencyException) { }
- }
-
- ///
- /// Retrieves an application using its unique identifier.
- ///
- /// The unique identifier associated with the application.
- /// The that can be used to abort the operation.
- ///
- /// A that can be used to monitor the asynchronous operation,
- /// whose result returns the client application corresponding to the identifier.
- ///
- public virtual Task FindByIdAsync(string identifier, CancellationToken cancellationToken)
- {
- var key = ConvertIdentifierFromString(identifier);
-
- return Applications.SingleOrDefaultAsync(application => application.Id.Equals(key), cancellationToken);
- }
-
- ///
- /// Retrieves an application using its client identifier.
- ///
- /// The client identifier associated with the application.
- /// The that can be used to abort the operation.
- ///
- /// A that can be used to monitor the asynchronous operation,
- /// whose result returns the client application corresponding to the identifier.
- ///
- public virtual Task FindByClientIdAsync(string identifier, CancellationToken cancellationToken)
- {
- return Applications.SingleOrDefaultAsync(application => application.ClientId.Equals(identifier), cancellationToken);
- }
-
- ///
- /// Retrieves all the applications associated with the specified post_logout_redirect_uri.
- ///
- /// The post_logout_redirect_uri associated with the applications.
- /// The that can be used to abort the operation.
- ///
- /// A that can be used to monitor the asynchronous operation, whose result
- /// returns the client applications corresponding to the specified post_logout_redirect_uri.
- ///
- public virtual Task FindByLogoutRedirectUriAsync(string address, CancellationToken cancellationToken)
- {
- return Applications.Where(application => application.LogoutRedirectUri == address).ToArrayAsync(cancellationToken);
- }
-
- ///
- /// Retrieves all the applications associated with the specified redirect_uri.
- ///
- /// The redirect_uri associated with the applications.
- /// The that can be used to abort the operation.
- ///
- /// A that can be used to monitor the asynchronous operation, whose result
- /// returns the client applications corresponding to the specified redirect_uri.
- ///
- public virtual Task FindByRedirectUriAsync(string address, CancellationToken cancellationToken)
- {
- return Applications.Where(application => application.RedirectUri == address).ToArrayAsync(cancellationToken);
- }
-
- ///
- /// Retrieves the client identifier associated with an application.
- ///
- /// The application.
- /// The that can be used to abort the operation.
- ///
- /// A that can be used to monitor the asynchronous operation,
- /// whose result returns the client identifier associated with the application.
- ///
- public virtual Task GetClientIdAsync([NotNull] TApplication application, CancellationToken cancellationToken)
- {
- if (application == null)
- {
- throw new ArgumentNullException(nameof(application));
- }
-
- return Task.FromResult(application.ClientId);
- }
-
- ///
- /// Retrieves the client secret associated with an application.
- /// Note: depending on the manager used to create the application,
- /// the client secret may be hashed for security reasons.
- ///
- /// The application.
- /// The that can be used to abort the operation.
- ///
- /// A that can be used to monitor the asynchronous operation,
- /// whose result returns the client secret associated with the application.
- ///
- public virtual Task GetClientSecretAsync([NotNull] TApplication application, CancellationToken cancellationToken)
- {
- if (application == null)
- {
- throw new ArgumentNullException(nameof(application));
- }
-
- return Task.FromResult(application.ClientSecret);
- }
-
- ///
- /// Retrieves the client type associated with an application.
+ /// Creates a new application.
///
- /// The application.
+ /// The application descriptor.
/// The that can be used to abort the operation.
///
- /// A that can be used to monitor the asynchronous operation,
- /// whose result returns the client type of the application (by default, "public").
+ /// A that can be used to monitor the asynchronous operation, whose result returns the application.
///
- public virtual Task GetClientTypeAsync([NotNull] TApplication application, CancellationToken cancellationToken)
+ public override Task CreateAsync([NotNull] OpenIddictApplicationDescriptor descriptor, CancellationToken cancellationToken)
{
- if (application == null)
+ if (descriptor == null)
{
- throw new ArgumentNullException(nameof(application));
+ throw new ArgumentNullException(nameof(descriptor));
}
- return Task.FromResult(application.Type);
- }
-
- ///
- /// Retrieves the display name associated with an application.
- ///
- /// The application.
- /// The that can be used to abort the operation.
- ///
- /// A that can be used to monitor the asynchronous operation,
- /// whose result returns the display name associated with the application.
- ///
- public virtual Task GetDisplayNameAsync([NotNull] TApplication application, CancellationToken cancellationToken)
- {
- if (application == null)
+ var application = new TApplication
{
- throw new ArgumentNullException(nameof(application));
- }
+ ClientId = descriptor.ClientId,
+ ClientSecret = descriptor.ClientSecret,
+ DisplayName = descriptor.DisplayName,
+ LogoutRedirectUri = descriptor.LogoutRedirectUri,
+ RedirectUri = descriptor.RedirectUri,
+ Type = descriptor.Type
+ };
- return Task.FromResult(application.DisplayName);
+ return CreateAsync(application, cancellationToken);
}
///
- /// Retrieves the unique identifier associated with an application.
+ /// Removes an existing application.
///
- /// The application.
+ /// The application to delete.
/// The that can be used to abort the operation.
///
- /// A that can be used to monitor the asynchronous operation,
- /// whose result returns the unique identifier associated with the application.
+ /// A that can be used to monitor the asynchronous operation.
///
- public virtual Task GetIdAsync([NotNull] TApplication application, CancellationToken cancellationToken)
+ public override async Task DeleteAsync([NotNull] TApplication application, CancellationToken cancellationToken)
{
if (application == null)
{
throw new ArgumentNullException(nameof(application));
}
- return Task.FromResult(ConvertIdentifierToString(application.Id));
- }
+ Context.Remove(application);
- ///
- /// Retrieves the logout callback address 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 post_logout_redirect_uri associated with the application.
- ///
- public virtual Task GetLogoutRedirectUriAsync([NotNull] TApplication application, CancellationToken cancellationToken)
- {
- if (application == null)
+ try
{
- throw new ArgumentNullException(nameof(application));
+ await Context.SaveChangesAsync(cancellationToken);
}
- return Task.FromResult(application.LogoutRedirectUri);
+ catch (DbUpdateConcurrencyException) { }
}
///
- /// Retrieves the callback address associated with an application.
+ /// Executes the specified query.
///
- /// The application.
+ /// The result type.
+ /// The query to execute.
/// The that can be used to abort the operation.
///
/// A that can be used to monitor the asynchronous operation,
- /// whose result returns the redirect_uri associated with the application.
+ /// whose result returns the single element returned when executing the specified query.
///
- public virtual Task GetRedirectUriAsync([NotNull] TApplication application, CancellationToken cancellationToken)
+ public override Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken)
{
- if (application == null)
+ if (query == null)
{
- throw new ArgumentNullException(nameof(application));
+ throw new ArgumentNullException(nameof(query));
}
- return Task.FromResult(application.RedirectUri);
+ return query.Invoke(Applications).SingleOrDefaultAsync(cancellationToken);
}
///
- /// Retrieves the token identifiers associated with an application.
+ /// Executes the specified query.
///
- /// The application.
+ /// The result type.
+ /// The query to execute.
/// The that can be used to abort the operation.
///
/// A that can be used to monitor the asynchronous operation,
- /// whose result returns the tokens associated with the application.
+ /// whose result returns all the elements returned when executing the specified query.
///
- public virtual async Task> GetTokensAsync([NotNull] TApplication application, CancellationToken cancellationToken)
+ public override Task ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken)
{
- if (application == null)
+ if (query == null)
{
- throw new ArgumentNullException(nameof(application));
+ throw new ArgumentNullException(nameof(query));
}
- var query = from entity in Applications
- where entity.Id.Equals(application.Id)
- from token in entity.Tokens
- select token.Id;
-
- var tokens = new List();
-
- foreach (var identifier in await query.ToArrayAsync())
- {
- tokens.Add(ConvertIdentifierToString(identifier));
- }
-
- return tokens;
- }
-
- ///
- /// Sets the client secret associated with an application.
- /// Note: depending on the manager used to create the application,
- /// the client secret may be hashed for security reasons.
- ///
- /// The application.
- /// The client secret associated with the application.
- /// The that can be used to abort the operation.
- ///
- /// A that can be used to monitor the asynchronous operation.
- ///
- public virtual Task SetClientSecretAsync([NotNull] TApplication application,
- [CanBeNull] string secret, CancellationToken cancellationToken)
- {
- if (application == null)
- {
- throw new ArgumentNullException(nameof(application));
- }
-
- application.ClientSecret = secret;
-
- return Task.FromResult(0);
- }
-
- ///
- /// Sets the client type associated with an application.
- ///
- /// The application.
- /// The client type associated with the application.
- /// The that can be used to abort the operation.
- ///
- /// A that can be used to monitor the asynchronous operation.
- ///
- public virtual Task SetClientTypeAsync([NotNull] TApplication application, [NotNull] string type, CancellationToken cancellationToken)
- {
- if (application == null)
- {
- throw new ArgumentNullException(nameof(application));
- }
-
- if (string.IsNullOrEmpty(type))
- {
- throw new ArgumentException("The client type cannot be null or empty.", nameof(type));
- }
-
- application.Type = type;
-
- return Task.FromResult(0);
+ return query.Invoke(Applications).ToArrayAsync(cancellationToken);
}
///
@@ -412,7 +203,7 @@ namespace OpenIddict.EntityFrameworkCore
///
/// A that can be used to monitor the asynchronous operation.
///
- public virtual async Task UpdateAsync([NotNull] TApplication application, CancellationToken cancellationToken)
+ public override async Task UpdateAsync([NotNull] TApplication application, CancellationToken cancellationToken)
{
if (application == null)
{
@@ -429,37 +220,5 @@ namespace OpenIddict.EntityFrameworkCore
catch (DbUpdateConcurrencyException) { }
}
-
- ///
- /// Converts the provided identifier to a strongly typed key object.
- ///
- /// The identifier to convert.
- /// An instance of representing the provided identifier.
- public virtual TKey ConvertIdentifierFromString([CanBeNull] string identifier)
- {
- if (string.IsNullOrEmpty(identifier))
- {
- return default(TKey);
- }
-
- return (TKey) TypeDescriptor.GetConverter(typeof(TKey))
- .ConvertFromInvariantString(identifier);
- }
-
- ///
- /// Converts the provided identifier to its string representation.
- ///
- /// The identifier to convert.
- /// A representation of the provided identifier.
- public virtual string ConvertIdentifierToString([CanBeNull] TKey identifier)
- {
- if (Equals(identifier, default(TKey)))
- {
- return null;
- }
-
- return TypeDescriptor.GetConverter(typeof(TKey))
- .ConvertToInvariantString(identifier);
- }
}
}
\ No newline at end of file
diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs
index c84d78c7..6a1b7c83 100644
--- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs
+++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs
@@ -5,8 +5,6 @@
*/
using System;
-using System.Collections.Generic;
-using System.ComponentModel;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@@ -19,6 +17,7 @@ namespace OpenIddict.EntityFrameworkCore
{
///
/// Provides methods allowing to manage the authorizations stored in a database.
+ /// Note: this class can only be used with the default OpenIddict entities.
///
/// The type of the Entity Framework database context.
public class OpenIddictAuthorizationStore : OpenIddictAuthorizationStore
/// Provides methods allowing to manage the authorizations stored in a database.
+ /// Note: this class can only be used with the default OpenIddict entities.
///
/// The type of the Entity Framework database context.
/// The type of the entity primary keys.
@@ -45,13 +45,15 @@ namespace OpenIddict.EntityFrameworkCore
///
/// Provides methods allowing to manage the authorizations stored in a database.
+ /// Note: this class can only be used with the default OpenIddict entities.
///
/// The type of the Authorization entity.
/// The type of the Application entity.
/// The type of the Token entity.
/// The type of the Entity Framework database context.
/// The type of the entity primary keys.
- public class OpenIddictAuthorizationStore : IOpenIddictAuthorizationStore
+ public class OpenIddictAuthorizationStore :
+ OpenIddictAuthorizationStore
where TAuthorization : OpenIddictAuthorization, new()
where TApplication : OpenIddictApplication, new()
where TToken : OpenIddictToken, new()
@@ -83,11 +85,6 @@ namespace OpenIddict.EntityFrameworkCore
///
protected DbSet Authorizations => Context.Set();
- ///
- /// Gets the authorizations as a queryable source, if supported by the store.
- ///
- IQueryable IOpenIddictAuthorizationStore.Authorizations => Authorizations;
-
///
/// Creates a new authorization.
///
@@ -96,7 +93,7 @@ namespace OpenIddict.EntityFrameworkCore
///
/// A that can be used to monitor the asynchronous operation, whose result returns the authorization.
///
- public virtual async Task CreateAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken)
+ public override async Task CreateAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken)
{
if (authorization == null)
{
@@ -118,7 +115,7 @@ namespace OpenIddict.EntityFrameworkCore
///
/// A that can be used to monitor the asynchronous operation, whose result returns the authorization.
///
- public virtual async Task CreateAsync([NotNull] OpenIddictAuthorizationDescriptor descriptor, CancellationToken cancellationToken)
+ public override async Task CreateAsync([NotNull] OpenIddictAuthorizationDescriptor descriptor, CancellationToken cancellationToken)
{
if (descriptor == null)
{
@@ -149,108 +146,43 @@ namespace OpenIddict.EntityFrameworkCore
}
///
- /// Retrieves an authorization using its associated subject/client.
- ///
- /// The subject associated with the authorization.
- /// The client associated with the authorization.
- /// The that can be used to abort the operation.
- ///
- /// A that can be used to monitor the asynchronous operation,
- /// whose result returns the authorization corresponding to the subject/client.
- ///
- public virtual Task FindAsync(string subject, string client, CancellationToken cancellationToken)
- {
- var key = ConvertIdentifierFromString(client);
-
- return (from application in Applications
- where application.Id.Equals(key)
- from authorization in application.Authorizations
- where authorization.Subject == subject
- select authorization).FirstOrDefaultAsync();
- }
-
- ///
- /// Retrieves an authorization using its unique identifier.
+ /// Executes the specified query.
///
- /// The unique identifier associated with the authorization.
+ /// The result type.
+ /// The query to execute.
/// The that can be used to abort the operation.
///
/// A that can be used to monitor the asynchronous operation,
- /// whose result returns the authorization corresponding to the identifier.
+ /// whose result returns the single element returned when executing the specified query.
///
- public virtual Task FindByIdAsync(string identifier, CancellationToken cancellationToken)
+ public override Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken)
{
- var key = ConvertIdentifierFromString(identifier);
-
- return Authorizations.SingleOrDefaultAsync(authorization => authorization.Id.Equals(key), cancellationToken);
- }
-
- ///
- /// Retrieves the unique identifier associated with an authorization.
- ///
- /// The authorization.
- /// The that can be used to abort the operation.
- ///
- /// A that can be used to monitor the asynchronous operation,
- /// whose result returns the unique identifier associated with the authorization.
- ///
- public virtual Task GetIdAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken)
- {
- if (authorization == null)
+ if (query == null)
{
- throw new ArgumentNullException(nameof(authorization));
+ throw new ArgumentNullException(nameof(query));
}
- return Task.FromResult(ConvertIdentifierToString(authorization.Id));
- }
-
- ///
- /// Retrieves the status associated with an authorization.
- ///
- /// The authorization.
- /// The that can be used to abort the operation.
- ///
- /// A that can be used to monitor the asynchronous operation,
- /// whose result returns the status associated with the specified authorization.
- ///
- public virtual Task GetStatusAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken)
- {
- return Task.FromResult(authorization.Status);
+ return query.Invoke(Authorizations).SingleOrDefaultAsync(cancellationToken);
}
///
- /// Retrieves the subject associated with an authorization.
+ /// Executes the specified query.
///
- /// The authorization.
+ /// The result type.
+ /// The query to execute.
/// The that can be used to abort the operation.
///
/// A that can be used to monitor the asynchronous operation,
- /// whose result returns the subject associated with the specified authorization.
+ /// whose result returns all the elements returned when executing the specified query.
///
- public virtual Task GetSubjectAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken)
+ public override Task ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken)
{
- if (authorization == null)
+ if (query == null)
{
- throw new ArgumentNullException(nameof(authorization));
+ throw new ArgumentNullException(nameof(query));
}
- return Task.FromResult(authorization.Subject);
- }
-
- ///
- /// Sets the status associated with an authorization.
- ///
- /// The authorization.
- /// The status associated with the authorization.
- /// The that can be used to abort the operation.
- ///
- /// A that can be used to monitor the asynchronous operation.
- ///
- public virtual Task SetStatusAsync([NotNull] TAuthorization authorization, [NotNull] string status, CancellationToken cancellationToken)
- {
- authorization.Status = status;
-
- return Task.FromResult(0);
+ return query.Invoke(Authorizations).ToArrayAsync(cancellationToken);
}
///
@@ -261,7 +193,7 @@ namespace OpenIddict.EntityFrameworkCore
///
/// A that can be used to monitor the asynchronous operation.
///
- public virtual async Task UpdateAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken)
+ public override async Task UpdateAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken)
{
Context.Attach(authorization);
@@ -274,37 +206,5 @@ namespace OpenIddict.EntityFrameworkCore
catch (DbUpdateConcurrencyException) { }
}
-
- ///
- /// Converts the provided identifier to a strongly typed key object.
- ///
- /// The identifier to convert.
- /// An instance of representing the provided identifier.
- public virtual TKey ConvertIdentifierFromString([CanBeNull] string identifier)
- {
- if (string.IsNullOrEmpty(identifier))
- {
- return default(TKey);
- }
-
- return (TKey) TypeDescriptor.GetConverter(typeof(TKey))
- .ConvertFromInvariantString(identifier);
- }
-
- ///
- /// Converts the provided identifier to its string representation.
- ///
- /// The identifier to convert.
- /// A representation of the provided identifier.
- public virtual string ConvertIdentifierToString([CanBeNull] TKey identifier)
- {
- if (Equals(identifier, default(TKey)))
- {
- return null;
- }
-
- return TypeDescriptor.GetConverter(typeof(TKey))
- .ConvertToInvariantString(identifier);
- }
}
}
\ No newline at end of file
diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs
index 7595cf72..ccd0b49f 100644
--- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs
+++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs
@@ -5,17 +5,18 @@
*/
using System;
-using System.ComponentModel;
using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
-using OpenIddict.Core;
using OpenIddict.Models;
namespace OpenIddict.EntityFrameworkCore
{
///
/// Provides methods allowing to manage the scopes stored in a database.
+ /// Note: this class can only be used with the default OpenIddict entities.
///
/// The type of the Entity Framework database context.
public class OpenIddictScopeStore : OpenIddictScopeStore
@@ -26,6 +27,7 @@ namespace OpenIddict.EntityFrameworkCore
///
/// Provides methods allowing to manage the scopes stored in a database.
+ /// Note: this class can only be used with the default OpenIddict entities.
///
/// The type of the Entity Framework database context.
/// The type of the entity primary keys.
@@ -38,11 +40,12 @@ namespace OpenIddict.EntityFrameworkCore
///
/// Provides methods allowing to manage the scopes stored in a database.
+ /// Note: this class can only be used with the default OpenIddict entities.
///
/// The type of the Scope entity.
/// The type of the Entity Framework database context.
/// The type of the entity primary keys.
- public class OpenIddictScopeStore : IOpenIddictScopeStore
+ public class OpenIddictScopeStore : Core.OpenIddictScopeStore
where TScope : OpenIddictScope, new()
where TContext : DbContext
where TKey : IEquatable
@@ -68,40 +71,43 @@ namespace OpenIddict.EntityFrameworkCore
protected DbSet Scopes => Context.Set();
///
- /// Gets the scopes as a queryable source, if supported by the store.
+ /// Executes the specified query.
///
- IQueryable IOpenIddictScopeStore.Scopes => Scopes;
-
- ///
- /// Converts the provided identifier to a strongly typed key object.
- ///
- /// The identifier to convert.
- /// An instance of representing the provided identifier.
- public virtual TKey ConvertIdentifierFromString([CanBeNull] string identifier)
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the single element returned when executing the specified query.
+ ///
+ public override Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken)
{
- if (string.IsNullOrEmpty(identifier))
+ if (query == null)
{
- return default(TKey);
+ throw new ArgumentNullException(nameof(query));
}
- return (TKey) TypeDescriptor.GetConverter(typeof(TKey))
- .ConvertFromInvariantString(identifier);
+ return query.Invoke(Scopes).SingleOrDefaultAsync(cancellationToken);
}
///
- /// Converts the provided identifier to its string representation.
+ /// Executes the specified query.
///
- /// The identifier to convert.
- /// A representation of the provided identifier.
- public virtual string ConvertIdentifierToString([CanBeNull] TKey identifier)
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns all the elements returned when executing the specified query.
+ ///
+ public override Task ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken)
{
- if (Equals(identifier, default(TKey)))
+ if (query == null)
{
- return null;
+ throw new ArgumentNullException(nameof(query));
}
- return TypeDescriptor.GetConverter(typeof(TKey))
- .ConvertToInvariantString(identifier);
+ return query.Invoke(Scopes).ToArrayAsync(cancellationToken);
}
}
}
\ No newline at end of file
diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs
index 573dc4dd..39515293 100644
--- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs
+++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs
@@ -5,7 +5,6 @@
*/
using System;
-using System.ComponentModel;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@@ -18,6 +17,7 @@ namespace OpenIddict.EntityFrameworkCore
{
///
/// Provides methods allowing to manage the tokens stored in a database.
+ /// Note: this class can only be used with the default OpenIddict entities.
///
/// The type of the Entity Framework database context.
public class OpenIddictTokenStore : OpenIddictTokenStore
/// Provides methods allowing to manage the tokens stored in a database.
+ /// Note: this class can only be used with the default OpenIddict entities.
///
/// The type of the Entity Framework database context.
/// The type of the entity primary keys.
@@ -44,13 +45,15 @@ namespace OpenIddict.EntityFrameworkCore
///
/// Provides methods allowing to manage the tokens stored in a database.
+ /// Note: this class can only be used with the default OpenIddict entities.
///
/// The type of the Token entity.
/// The type of the Application entity.
/// The type of the Authorization entity.
/// The type of the Entity Framework database context.
/// The type of the entity primary keys.
- public class OpenIddictTokenStore : IOpenIddictTokenStore
+ public class OpenIddictTokenStore :
+ OpenIddictTokenStore
where TToken : OpenIddictToken, new()
where TApplication : OpenIddictApplication, new()
where TAuthorization : OpenIddictAuthorization, new()
@@ -87,11 +90,6 @@ namespace OpenIddict.EntityFrameworkCore
///
protected DbSet Tokens => Context.Set();
- ///
- /// Gets the tokens as a queryable source, if supported by the store.
- ///
- IQueryable IOpenIddictTokenStore.Tokens => Tokens;
-
///
/// Creates a new token.
///
@@ -100,7 +98,7 @@ namespace OpenIddict.EntityFrameworkCore
///
/// A that can be used to monitor the asynchronous operation, whose result returns the token.
///
- public virtual async Task CreateAsync([NotNull] TToken token, CancellationToken cancellationToken)
+ public override async Task CreateAsync([NotNull] TToken token, CancellationToken cancellationToken)
{
if (token == null)
{
@@ -122,7 +120,7 @@ namespace OpenIddict.EntityFrameworkCore
///
/// A that can be used to monitor the asynchronous operation, whose result returns the token.
///
- public virtual async Task CreateAsync([NotNull] OpenIddictTokenDescriptor descriptor, CancellationToken cancellationToken)
+ public override async Task CreateAsync([NotNull] OpenIddictTokenDescriptor descriptor, CancellationToken cancellationToken)
{
if (descriptor == null)
{
@@ -176,7 +174,7 @@ namespace OpenIddict.EntityFrameworkCore
/// The token to delete.
/// The that can be used to abort the operation.
/// A that can be used to monitor the asynchronous operation.
- public virtual async Task DeleteAsync([NotNull] TToken token, CancellationToken cancellationToken)
+ public override async Task DeleteAsync([NotNull] TToken token, CancellationToken cancellationToken)
{
if (token == null)
{
@@ -194,238 +192,43 @@ namespace OpenIddict.EntityFrameworkCore
}
///
- /// Retrieves the list of tokens corresponding to the specified authorization identifier.
- ///
- /// The authorization identifier associated with the tokens.
- /// The that can be used to abort the operation.
- ///
- /// 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)
- {
- var key = ConvertIdentifierFromString(identifier);
-
- return Tokens.Where(token => token.Authorization.Id.Equals(key)).ToArrayAsync(cancellationToken);
- }
-
- ///
- /// Retrieves the list of tokens corresponding to the specified hash.
- ///
- /// The hashed crypto-secure random 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 hash.
- ///
- public virtual Task FindByHashAsync(string hash, CancellationToken cancellationToken)
- {
- return Tokens.SingleOrDefaultAsync(token => token.Hash == hash, cancellationToken);
- }
-
- ///
- /// Retrieves an token using its unique identifier.
- ///
- /// The unique identifier associated with the token.
- /// The that can be used to abort the operation.
- ///
- /// A that can be used to monitor the asynchronous operation,
- /// whose result returns the token corresponding to the unique identifier.
- ///
- public virtual Task FindByIdAsync(string identifier, CancellationToken cancellationToken)
- {
- var key = ConvertIdentifierFromString(identifier);
-
- return Tokens.SingleOrDefaultAsync(token => token.Id.Equals(key), cancellationToken);
- }
-
- ///
- /// Retrieves the list of tokens corresponding to the specified subject.
- ///
- /// The subject associated with the tokens.
- /// The that can be used to abort the operation.
- ///
- /// 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)
- {
- return Tokens.Where(token => token.Subject == subject).ToArrayAsync();
- }
-
- ///
- /// Retrieves the optional authorization identifier associated with a token.
- ///
- /// The token.
- /// The that can be used to abort the operation.
- ///
- /// A that can be used to monitor the asynchronous operation,
- /// whose result returns the authorization identifier associated with the token.
- ///
- public virtual async Task GetAuthorizationIdAsync([NotNull] TToken token, CancellationToken cancellationToken)
- {
- if (token == null)
- {
- throw new ArgumentNullException(nameof(token));
- }
-
- var key = await (from authorization in Authorizations
- where authorization.Tokens.Any(entity => entity.Id.Equals(token.Id))
- select authorization.Id).SingleOrDefaultAsync();
-
- return ConvertIdentifierToString(key);
- }
-
- ///
- /// Retrieves the ciphertext associated with a token.
- ///
- /// The token.
- /// The that can be used to abort the operation.
- ///
- /// A that can be used to monitor the asynchronous operation,
- /// whose result returns the ciphertext associated with the specified token.
- ///
- public virtual Task GetCiphertextAsync([NotNull] TToken token, CancellationToken cancellationToken)
- {
- if (token == null)
- {
- throw new ArgumentNullException(nameof(token));
- }
-
- return Task.FromResult(token.Ciphertext);
- }
-
- ///
- /// Retrieves the creation date associated with a token.
+ /// Executes the specified query.
///
- /// The token.
- /// The that can be used to abort the operation.
- ///
- /// A that can be used to monitor the asynchronous operation,
- /// whose result returns the creation date associated with the specified token.
- ///
- public virtual Task GetCreationDateAsync([NotNull] TToken token, CancellationToken cancellationToken)
- {
- if (token == null)
- {
- throw new ArgumentNullException(nameof(token));
- }
-
- return Task.FromResult(token.CreationDate);
- }
-
- ///
- /// Retrieves the expiration date associated with a token.
- ///
- /// The token.
+ /// The result type.
+ /// The query to execute.
/// The that can be used to abort the operation.
///
/// A that can be used to monitor the asynchronous operation,
- /// whose result returns the expiration date associated with the specified token.
+ /// whose result returns the single element returned when executing the specified query.
///
- public virtual Task GetExpirationDateAsync([NotNull] TToken token, CancellationToken cancellationToken)
+ public override Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken)
{
- if (token == null)
+ if (query == null)
{
- throw new ArgumentNullException(nameof(token));
+ throw new ArgumentNullException(nameof(query));
}
- return Task.FromResult(token.ExpirationDate);
+ return query.Invoke(Tokens).SingleOrDefaultAsync(cancellationToken);
}
///
- /// Retrieves the hashed identifier associated with a token.
+ /// Executes the specified query.
///
- /// The token.
+ /// The result type.
+ /// The query to execute.
/// The that can be used to abort the operation.
///
/// A that can be used to monitor the asynchronous operation,
- /// whose result returns the hashed identifier associated with the specified token.
+ /// whose result returns all the elements returned when executing the specified query.
///
- public virtual Task GetHashAsync([NotNull] TToken token, CancellationToken cancellationToken)
+ public override Task ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken)
{
- if (token == null)
+ if (query == null)
{
- throw new ArgumentNullException(nameof(token));
+ throw new ArgumentNullException(nameof(query));
}
- return Task.FromResult(token.Hash);
- }
-
- ///
- /// Retrieves the unique identifier associated with a token.
- ///
- /// The token.
- /// The that can be used to abort the operation.
- ///
- /// A that can be used to monitor the asynchronous operation,
- /// whose result returns the unique identifier associated with the token.
- ///
- public virtual Task GetIdAsync([NotNull] TToken token, CancellationToken cancellationToken)
- {
- if (token == null)
- {
- throw new ArgumentNullException(nameof(token));
- }
-
- return Task.FromResult(ConvertIdentifierToString(token.Id));
- }
-
- ///
- /// Retrieves the status associated with a token.
- ///
- /// The token.
- /// The that can be used to abort the operation.
- ///
- /// A that can be used to monitor the asynchronous operation,
- /// whose result returns the status associated with the specified token.
- ///
- public virtual Task GetStatusAsync([NotNull] TToken token, CancellationToken cancellationToken)
- {
- if (token == null)
- {
- throw new ArgumentNullException(nameof(token));
- }
-
- return Task.FromResult(token.Status);
- }
-
- ///
- /// Retrieves the subject associated with a token.
- ///
- /// The token.
- /// The that can be used to abort the operation.
- ///
- /// A that can be used to monitor the asynchronous operation,
- /// whose result returns the subject associated with the specified token.
- ///
- public virtual Task GetSubjectAsync([NotNull] TToken token, CancellationToken cancellationToken)
- {
- if (token == null)
- {
- throw new ArgumentNullException(nameof(token));
- }
-
- return Task.FromResult(token.Subject);
- }
-
- ///
- /// Retrieves the token type associated with a token.
- ///
- /// The token.
- /// The that can be used to abort the operation.
- ///
- /// A that can be used to monitor the asynchronous operation,
- /// whose result returns the token type associated with the specified token.
- ///
- public virtual Task GetTokenTypeAsync([NotNull] TToken token, CancellationToken cancellationToken)
- {
- if (token == null)
- {
- throw new ArgumentNullException(nameof(token));
- }
-
- return Task.FromResult(token.Type);
+ return query.Invoke(Tokens).ToArrayAsync(cancellationToken);
}
///
@@ -437,7 +240,7 @@ namespace OpenIddict.EntityFrameworkCore
///
/// A that can be used to monitor the asynchronous operation.
///
- public virtual async Task SetAuthorizationAsync([NotNull] TToken token, [CanBeNull] string identifier, CancellationToken cancellationToken)
+ public override async Task SetAuthorizationAsync([NotNull] TToken token, [CanBeNull] string identifier, CancellationToken cancellationToken)
{
if (token == null)
{
@@ -480,7 +283,7 @@ namespace OpenIddict.EntityFrameworkCore
///
/// A that can be used to monitor the asynchronous operation.
///
- public virtual async Task SetClientAsync([NotNull] TToken token, [CanBeNull] string identifier, CancellationToken cancellationToken)
+ public override async Task SetClientAsync([NotNull] TToken token, [CanBeNull] string identifier, CancellationToken cancellationToken)
{
if (token == null)
{
@@ -514,39 +317,6 @@ namespace OpenIddict.EntityFrameworkCore
}
}
- ///
- /// Sets the expiration date associated with a token.
- ///
- /// The token.
- /// The date on which the token will no longer be considered valid.
- /// The that can be used to abort the operation.
- ///
- /// A that can be used to monitor the asynchronous operation.
- ///
- public virtual Task SetExpirationDateAsync([NotNull] TToken token,
- [CanBeNull] DateTimeOffset? date, CancellationToken cancellationToken)
- {
- token.ExpirationDate = date;
-
- return Task.FromResult(0);
- }
-
- ///
- /// Sets the status associated with a token.
- ///
- /// The token.
- /// The status associated with the authorization.
- /// The that can be used to abort the operation.
- ///
- /// A that can be used to monitor the asynchronous operation.
- ///
- public virtual Task SetStatusAsync([NotNull] TToken token, [NotNull] string status, CancellationToken cancellationToken)
- {
- token.Status = status;
-
- return Task.FromResult(0);
- }
-
///
/// Updates an existing token.
///
@@ -555,7 +325,7 @@ namespace OpenIddict.EntityFrameworkCore
///
/// A that can be used to monitor the asynchronous operation.
///
- public virtual async Task UpdateAsync([NotNull] TToken token, CancellationToken cancellationToken)
+ public override async Task UpdateAsync([NotNull] TToken token, CancellationToken cancellationToken)
{
if (token == null)
{
@@ -572,37 +342,5 @@ namespace OpenIddict.EntityFrameworkCore
catch (DbUpdateConcurrencyException) { }
}
-
- ///
- /// Converts the provided identifier to a strongly typed key object.
- ///
- /// The identifier to convert.
- /// An instance of representing the provided identifier.
- public virtual TKey ConvertIdentifierFromString([CanBeNull] string identifier)
- {
- if (string.IsNullOrEmpty(identifier))
- {
- return default(TKey);
- }
-
- return (TKey) TypeDescriptor.GetConverter(typeof(TKey))
- .ConvertFromInvariantString(identifier);
- }
-
- ///
- /// Converts the provided identifier to its string representation.
- ///
- /// The identifier to convert.
- /// A representation of the provided identifier.
- public virtual string ConvertIdentifierToString([CanBeNull] TKey identifier)
- {
- if (Equals(identifier, default(TKey)))
- {
- return null;
- }
-
- return TypeDescriptor.GetConverter(typeof(TKey))
- .ConvertToInvariantString(identifier);
- }
}
}
\ No newline at end of file