From 995063b60f7df00a7fd51416217a9005d6c85f78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Thu, 5 Oct 2017 19:11:45 +0200 Subject: [PATCH] Introduce new CountAsync()/ListAsync() methods in the stores/managers --- .../Descriptors/OpenIddictScopeDescriptor.cs | 14 ++ .../Managers/OpenIddictApplicationManager.cs | 48 +++++++ .../OpenIddictAuthorizationManager.cs | 66 ++++++++++ .../Managers/OpenIddictScopeManager.cs | 120 ++++++++++++++++++ .../Managers/OpenIddictTokenManager.cs | 48 +++++++ .../Stores/IOpenIddictApplicationStore.cs | 34 +++++ .../Stores/IOpenIddictAuthorizationStore.cs | 44 +++++++ .../Stores/IOpenIddictScopeStore.cs | 74 +++++++++++ .../Stores/IOpenIddictTokenStore.cs | 36 +++++- .../Stores/OpenIddictApplicationStore.cs | 57 +++++++++ .../Stores/OpenIddictAuthorizationStore.cs | 67 ++++++++++ .../Stores/OpenIddictScopeStore.cs | 97 ++++++++++++++ .../Stores/OpenIddictTokenStore.cs | 59 ++++++++- .../Stores/OpenIddictApplicationStore.cs | 20 +++ .../Stores/OpenIddictAuthorizationStore.cs | 45 +++++++ .../Stores/OpenIddictScopeStore.cs | 113 +++++++++++++++++ .../Stores/OpenIddictTokenStore.cs | 22 +++- .../Stores/OpenIddictApplicationStore.cs | 20 +++ .../Stores/OpenIddictAuthorizationStore.cs | 45 +++++++ .../Stores/OpenIddictScopeStore.cs | 112 ++++++++++++++++ .../Stores/OpenIddictTokenStore.cs | 22 +++- src/OpenIddict.Models/OpenIddictScope.cs | 6 + 22 files changed, 1165 insertions(+), 4 deletions(-) create mode 100644 src/OpenIddict.Core/Descriptors/OpenIddictScopeDescriptor.cs diff --git a/src/OpenIddict.Core/Descriptors/OpenIddictScopeDescriptor.cs b/src/OpenIddict.Core/Descriptors/OpenIddictScopeDescriptor.cs new file mode 100644 index 00000000..edcc69d4 --- /dev/null +++ b/src/OpenIddict.Core/Descriptors/OpenIddictScopeDescriptor.cs @@ -0,0 +1,14 @@ +namespace OpenIddict.Core +{ + /// + /// Represents an OpenIddict scope descriptor. + /// + public class OpenIddictScopeDescriptor + { + /// + /// Gets or sets the unique name + /// associated with the scope. + /// + public virtual string Name { get; set; } + } +} diff --git a/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs b/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs index 8a510128..60f8c59a 100644 --- a/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs +++ b/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs @@ -38,6 +38,39 @@ namespace OpenIddict.Core /// protected IOpenIddictApplicationStore Store { get; } + /// + /// Determines the number of applications that exist in the database. + /// + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the number of applications in the database. + /// + public virtual Task CountAsync(CancellationToken cancellationToken) + { + return Store.CountAsync(cancellationToken); + } + + /// + /// Determines the number of applications that match the specified query. + /// + /// The result type. + /// The query to execute. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the number of applications that match the specified query. + /// + public virtual Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + { + if (query == null) + { + throw new ArgumentNullException(nameof(query)); + } + + return Store.CountAsync(query, cancellationToken); + } + /// /// Creates a new application. /// @@ -428,6 +461,21 @@ namespace OpenIddict.Core return string.Equals(type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase); } + /// + /// Executes the specified query. + /// + /// The number of results to return. + /// The number of results to skip. + /// 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([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken) + { + return Store.ListAsync(count, offset, cancellationToken); + } + /// /// Executes the specified query. /// diff --git a/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs b/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs index 284d7ba4..945e1614 100644 --- a/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs +++ b/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs @@ -37,6 +37,39 @@ namespace OpenIddict.Core /// protected IOpenIddictAuthorizationStore Store { get; } + /// + /// Determines the number of authorizations that exist in the database. + /// + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the number of authorizations in the database. + /// + public virtual Task CountAsync(CancellationToken cancellationToken) + { + return Store.CountAsync(cancellationToken); + } + + /// + /// Determines the number of authorizations that match the specified query. + /// + /// The result type. + /// The query to execute. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the number of authorizations that match the specified query. + /// + public virtual Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + { + if (query == null) + { + throw new ArgumentNullException(nameof(query)); + } + + return Store.CountAsync(query, cancellationToken); + } + /// /// Creates a new authorization. /// @@ -75,6 +108,24 @@ namespace OpenIddict.Core return await Store.CreateAsync(descriptor, cancellationToken); } + /// + /// Removes an existing authorization. + /// + /// The authorization to delete. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation. + /// + public virtual Task DeleteAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken) + { + if (authorization == null) + { + throw new ArgumentNullException(nameof(authorization)); + } + + return Store.DeleteAsync(authorization, cancellationToken); + } + /// /// Retrieves an authorization using its associated subject/client. /// @@ -143,6 +194,21 @@ namespace OpenIddict.Core return Store.GetIdAsync(authorization, cancellationToken); } + /// + /// Executes the specified query. + /// + /// The number of results to return. + /// The number of results to skip. + /// 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([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken) + { + return Store.ListAsync(count, offset, cancellationToken); + } + /// /// Executes the specified query. /// diff --git a/src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs b/src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs index 10448be4..92f6655e 100644 --- a/src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs +++ b/src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs @@ -37,6 +37,93 @@ namespace OpenIddict.Core /// protected IOpenIddictScopeStore Store { get; } + /// + /// Determines the number of scopes that exist in the database. + /// + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the number of scopes in the database. + /// + public virtual Task CountAsync(CancellationToken cancellationToken) + { + return Store.CountAsync(cancellationToken); + } + + /// + /// Determines the number of scopes that match the specified query. + /// + /// The result type. + /// The query to execute. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the number of scopes that match the specified query. + /// + public virtual Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + { + if (query == null) + { + throw new ArgumentNullException(nameof(query)); + } + + return Store.CountAsync(query, cancellationToken); + } + + /// + /// Creates a new scope. + /// + /// The scope to create. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, whose result returns the scope. + /// + public virtual Task CreateAsync([NotNull] TScope scope, CancellationToken cancellationToken) + { + if (scope == null) + { + throw new ArgumentNullException(nameof(scope)); + } + + return Store.CreateAsync(scope, cancellationToken); + } + + /// + /// Creates a new scope. + /// + /// The scope descriptor. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, whose result returns the scope. + /// + public virtual Task CreateAsync([NotNull] OpenIddictScopeDescriptor descriptor, CancellationToken cancellationToken) + { + if (descriptor == null) + { + throw new ArgumentNullException(nameof(descriptor)); + } + + return Store.CreateAsync(descriptor, cancellationToken); + } + + /// + /// Removes an existing scope. + /// + /// The scope to delete. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation. + /// + public virtual Task DeleteAsync([NotNull] TScope scope, CancellationToken cancellationToken) + { + if (scope == null) + { + throw new ArgumentNullException(nameof(scope)); + } + + return Store.DeleteAsync(scope, cancellationToken); + } + /// /// Executes the specified query. /// @@ -57,6 +144,21 @@ namespace OpenIddict.Core return Store.GetAsync(query, cancellationToken); } + /// + /// Executes the specified query. + /// + /// The number of results to return. + /// The number of results to skip. + /// 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([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken) + { + return Store.ListAsync(count, offset, cancellationToken); + } + /// /// Executes the specified query. /// @@ -76,5 +178,23 @@ namespace OpenIddict.Core return Store.ListAsync(query, cancellationToken); } + + /// + /// Updates an existing scope. + /// + /// The scope to update. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation. + /// + public virtual Task UpdateAsync([NotNull] TScope scope, CancellationToken cancellationToken) + { + if (scope == null) + { + throw new ArgumentNullException(nameof(scope)); + } + + return Store.UpdateAsync(scope, cancellationToken); + } } } \ No newline at end of file diff --git a/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs b/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs index f6bdb666..4e1a7dc4 100644 --- a/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs +++ b/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs @@ -38,6 +38,39 @@ namespace OpenIddict.Core /// protected IOpenIddictTokenStore Store { get; } + /// + /// Determines the number of tokens that exist in the database. + /// + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the number of tokens in the database. + /// + public virtual Task CountAsync(CancellationToken cancellationToken) + { + return Store.CountAsync(cancellationToken); + } + + /// + /// Determines the number of tokens that match the specified query. + /// + /// The result type. + /// The query to execute. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the number of tokens that match the specified query. + /// + public virtual Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + { + if (query == null) + { + throw new ArgumentNullException(nameof(query)); + } + + return Store.CountAsync(query, cancellationToken); + } + /// /// Creates a new token. /// @@ -371,6 +404,21 @@ namespace OpenIddict.Core return string.Equals(status, OpenIddictConstants.Statuses.Valid, StringComparison.OrdinalIgnoreCase); } + /// + /// Executes the specified query. + /// + /// The number of results to return. + /// The number of results to skip. + /// 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([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken) + { + return Store.ListAsync(count, offset, cancellationToken); + } + /// /// Executes the specified query. /// diff --git a/src/OpenIddict.Core/Stores/IOpenIddictApplicationStore.cs b/src/OpenIddict.Core/Stores/IOpenIddictApplicationStore.cs index 76de9dbe..2b22f014 100644 --- a/src/OpenIddict.Core/Stores/IOpenIddictApplicationStore.cs +++ b/src/OpenIddict.Core/Stores/IOpenIddictApplicationStore.cs @@ -19,6 +19,28 @@ namespace OpenIddict.Core /// The type of the Application entity. public interface IOpenIddictApplicationStore where TApplication : class { + /// + /// Determines the number of applications that exist in the database. + /// + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the number of applications in the database. + /// + Task CountAsync(CancellationToken cancellationToken); + + /// + /// Determines the number of applications that match the specified query. + /// + /// The result type. + /// The query to execute. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the number of applications that match the specified query. + /// + Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken); + /// /// Creates a new application. /// @@ -195,6 +217,18 @@ namespace OpenIddict.Core /// Task GetTokensAsync([NotNull] TApplication application, CancellationToken cancellationToken); + /// + /// Executes the specified query. + /// + /// The number of results to return. + /// The number of results to skip. + /// 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([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken); + /// /// Executes the specified query. /// diff --git a/src/OpenIddict.Core/Stores/IOpenIddictAuthorizationStore.cs b/src/OpenIddict.Core/Stores/IOpenIddictAuthorizationStore.cs index 44b6b506..1449c97f 100644 --- a/src/OpenIddict.Core/Stores/IOpenIddictAuthorizationStore.cs +++ b/src/OpenIddict.Core/Stores/IOpenIddictAuthorizationStore.cs @@ -18,6 +18,28 @@ namespace OpenIddict.Core /// The type of the Authorization entity. public interface IOpenIddictAuthorizationStore where TAuthorization : class { + /// + /// Determines the number of authorizations that exist in the database. + /// + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the number of authorizations in the database. + /// + Task CountAsync(CancellationToken cancellationToken); + + /// + /// Determines the number of authorizations that match the specified query. + /// + /// The result type. + /// The query to execute. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the number of authorizations that match the specified query. + /// + Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken); + /// /// Creates a new authorization. /// @@ -38,6 +60,16 @@ namespace OpenIddict.Core /// Task CreateAsync([NotNull] OpenIddictAuthorizationDescriptor descriptor, CancellationToken cancellationToken); + /// + /// Removes an existing authorization. + /// + /// The authorization to delete. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation. + /// + Task DeleteAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken); + /// /// Retrieves an authorization using its associated subject/client. /// @@ -106,6 +138,18 @@ namespace OpenIddict.Core /// Task GetSubjectAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken); + /// + /// Executes the specified query. + /// + /// The number of results to return. + /// The number of results to skip. + /// 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([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken); + /// /// Executes the specified query. /// diff --git a/src/OpenIddict.Core/Stores/IOpenIddictScopeStore.cs b/src/OpenIddict.Core/Stores/IOpenIddictScopeStore.cs index d1d59ebe..dfff703a 100644 --- a/src/OpenIddict.Core/Stores/IOpenIddictScopeStore.cs +++ b/src/OpenIddict.Core/Stores/IOpenIddictScopeStore.cs @@ -18,6 +18,58 @@ namespace OpenIddict.Core /// The type of the Scope entity. public interface IOpenIddictScopeStore where TScope : class { + /// + /// Determines the number of scopes that exist in the database. + /// + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the number of scopes in the database. + /// + Task CountAsync(CancellationToken cancellationToken); + + /// + /// Determines the number of scopes that match the specified query. + /// + /// The result type. + /// The query to execute. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the number of scopes that match the specified query. + /// + Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken); + + /// + /// Creates a new scope. + /// + /// The scope to create. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, whose result returns the scope. + /// + Task CreateAsync([NotNull] TScope scope, CancellationToken cancellationToken); + + /// + /// Creates a new scope. + /// + /// The scope descriptor. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, whose result returns the scope. + /// + Task CreateAsync([NotNull] OpenIddictScopeDescriptor descriptor, CancellationToken cancellationToken); + + /// + /// Removes an existing scope. + /// + /// The scope to delete. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation. + /// + Task DeleteAsync([NotNull] TScope scope, CancellationToken cancellationToken); + /// /// Executes the specified query. /// @@ -30,6 +82,18 @@ namespace OpenIddict.Core /// Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken); + /// + /// Executes the specified query. + /// + /// The number of results to return. + /// The number of results to skip. + /// 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([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken); + /// /// Executes the specified query. /// @@ -41,5 +105,15 @@ namespace OpenIddict.Core /// whose result returns all the elements returned when executing the specified query. /// Task ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken); + + /// + /// Updates an existing scope. + /// + /// The scope to update. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation. + /// + Task UpdateAsync([NotNull] TScope scope, 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 db25f7e5..63386493 100644 --- a/src/OpenIddict.Core/Stores/IOpenIddictTokenStore.cs +++ b/src/OpenIddict.Core/Stores/IOpenIddictTokenStore.cs @@ -18,6 +18,28 @@ namespace OpenIddict.Core /// The type of the Token entity. public interface IOpenIddictTokenStore where TToken : class { + /// + /// Determines the number of tokens that exist in the database. + /// + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the number of applications in the database. + /// + Task CountAsync(CancellationToken cancellationToken); + + /// + /// Determines the number of tokens that match the specified query. + /// + /// The result type. + /// The query to execute. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the number of tokens that match the specified query. + /// + Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken); + /// /// Creates a new token. /// @@ -29,7 +51,7 @@ namespace OpenIddict.Core Task CreateAsync([NotNull] TToken token, CancellationToken cancellationToken); /// - /// Creates a new token, which is associated with a particular subject. + /// Creates a new token. /// /// The token descriptor. /// The that can be used to abort the operation. @@ -201,6 +223,18 @@ namespace OpenIddict.Core /// Task GetTokenTypeAsync([NotNull] TToken token, CancellationToken cancellationToken); + /// + /// Executes the specified query. + /// + /// The number of results to return. + /// The number of results to skip. + /// 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([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken); + /// /// Executes the specified query. /// diff --git a/src/OpenIddict.Core/Stores/OpenIddictApplicationStore.cs b/src/OpenIddict.Core/Stores/OpenIddictApplicationStore.cs index bec50e1f..51b80ddc 100644 --- a/src/OpenIddict.Core/Stores/OpenIddictApplicationStore.cs +++ b/src/OpenIddict.Core/Stores/OpenIddictApplicationStore.cs @@ -30,6 +30,31 @@ namespace OpenIddict.Core where TToken : OpenIddictToken, new() where TKey : IEquatable { + /// + /// Determines the number of applications that exist in the database. + /// + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the number of applications in the database. + /// + public virtual Task CountAsync(CancellationToken cancellationToken) + { + return CountAsync(applications => applications, cancellationToken); + } + + /// + /// Determines the number of applications that match the specified query. + /// + /// The result type. + /// The query to execute. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the number of applications that match the specified query. + /// + public abstract Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken); + /// /// Creates a new application. /// @@ -421,6 +446,38 @@ namespace OpenIddict.Core return tokens.ToArray(); } + /// + /// Executes the specified query. + /// + /// The number of results to return. + /// The number of results to skip. + /// 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([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken) + { + IQueryable Query(IQueryable applications) + { + var query = applications.OrderBy(application => application.Id).AsQueryable(); + + if (offset.HasValue) + { + query = query.Skip(offset.Value); + } + + if (count.HasValue) + { + query = query.Take(count.Value); + } + + return query; + } + + return ListAsync(Query, cancellationToken); + } + /// /// Executes the specified query. /// diff --git a/src/OpenIddict.Core/Stores/OpenIddictAuthorizationStore.cs b/src/OpenIddict.Core/Stores/OpenIddictAuthorizationStore.cs index 75a1bc80..5af2732f 100644 --- a/src/OpenIddict.Core/Stores/OpenIddictAuthorizationStore.cs +++ b/src/OpenIddict.Core/Stores/OpenIddictAuthorizationStore.cs @@ -28,6 +28,31 @@ namespace OpenIddict.Core where TToken : OpenIddictToken, new() where TKey : IEquatable { + /// + /// Determines the number of authorizations that exist in the database. + /// + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the number of authorizations in the database. + /// + public virtual Task CountAsync(CancellationToken cancellationToken) + { + return CountAsync(authorizations => authorizations, cancellationToken); + } + + /// + /// Determines the number of authorizations that match the specified query. + /// + /// The result type. + /// The query to execute. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the number of authorizations that match the specified query. + /// + public abstract Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken); + /// /// Creates a new authorization. /// @@ -48,6 +73,16 @@ namespace OpenIddict.Core /// public abstract Task CreateAsync([NotNull] OpenIddictAuthorizationDescriptor descriptor, CancellationToken cancellationToken); + /// + /// Removes an existing authorization. + /// + /// The authorization to delete. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation. + /// + public abstract Task DeleteAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken); + /// /// Retrieves an authorization using its associated subject/client. /// @@ -164,6 +199,38 @@ namespace OpenIddict.Core return Task.FromResult(authorization.Subject); } + /// + /// Executes the specified query. + /// + /// The number of results to return. + /// The number of results to skip. + /// 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([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken) + { + IQueryable Query(IQueryable authorizations) + { + var query = authorizations.OrderBy(authorization => authorization.Id).AsQueryable(); + + if (offset.HasValue) + { + query = query.Skip(offset.Value); + } + + if (count.HasValue) + { + query = query.Take(count.Value); + } + + return query; + } + + return ListAsync(Query, cancellationToken); + } + /// /// Executes the specified query. /// diff --git a/src/OpenIddict.Core/Stores/OpenIddictScopeStore.cs b/src/OpenIddict.Core/Stores/OpenIddictScopeStore.cs index 22c4520f..f51755b2 100644 --- a/src/OpenIddict.Core/Stores/OpenIddictScopeStore.cs +++ b/src/OpenIddict.Core/Stores/OpenIddictScopeStore.cs @@ -24,6 +24,61 @@ namespace OpenIddict.Core where TScope : OpenIddictScope, new() where TKey : IEquatable { + /// + /// Determines the number of scopes that exist in the database. + /// + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the number of scopes in the database. + /// + public virtual Task CountAsync(CancellationToken cancellationToken) + { + return CountAsync(scopes => scopes, cancellationToken); + } + + /// + /// Determines the number of scopes that match the specified query. + /// + /// The result type. + /// The query to execute. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the number of scopes that match the specified query. + /// + public abstract Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken); + + /// + /// Creates a new scope. + /// + /// The scope to create. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, whose result returns the scope. + /// + public abstract Task CreateAsync([NotNull] TScope scope, CancellationToken cancellationToken); + + /// + /// Creates a new scope. + /// + /// The scope descriptor. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, whose result returns the scope. + /// + public abstract Task CreateAsync([NotNull] OpenIddictScopeDescriptor descriptor, CancellationToken cancellationToken); + + /// + /// Removes an existing scope. + /// + /// The scope to delete. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation. + /// + public abstract Task DeleteAsync([NotNull] TScope scope, CancellationToken cancellationToken); + /// /// Executes the specified query. /// @@ -36,6 +91,38 @@ namespace OpenIddict.Core /// public abstract Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken); + /// + /// Executes the specified query. + /// + /// The number of results to return. + /// The number of results to skip. + /// 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([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken) + { + IQueryable Query(IQueryable scopes) + { + var query = scopes.OrderBy(scope => scope.Id).AsQueryable(); + + if (offset.HasValue) + { + query = query.Skip(offset.Value); + } + + if (count.HasValue) + { + query = query.Take(count.Value); + } + + return query; + } + + return ListAsync(Query, cancellationToken); + } + /// /// Executes the specified query. /// @@ -48,6 +135,16 @@ namespace OpenIddict.Core /// public abstract Task ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken); + /// + /// Updates an existing scope. + /// + /// The scope to update. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation. + /// + public abstract Task UpdateAsync([NotNull] TScope scope, CancellationToken cancellationToken); + /// /// Converts the provided identifier to a strongly typed key object. /// diff --git a/src/OpenIddict.Core/Stores/OpenIddictTokenStore.cs b/src/OpenIddict.Core/Stores/OpenIddictTokenStore.cs index d98fafdf..a5f7aea5 100644 --- a/src/OpenIddict.Core/Stores/OpenIddictTokenStore.cs +++ b/src/OpenIddict.Core/Stores/OpenIddictTokenStore.cs @@ -28,6 +28,31 @@ namespace OpenIddict.Core where TAuthorization : OpenIddictAuthorization, new() where TKey : IEquatable { + /// + /// Determines the number of tokens that exist in the database. + /// + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the number of applications in the database. + /// + public virtual Task CountAsync(CancellationToken cancellationToken) + { + return CountAsync(tokens => tokens, cancellationToken); + } + + /// + /// Determines the number of tokens that match the specified query. + /// + /// The result type. + /// The query to execute. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the number of tokens that match the specified query. + /// + public abstract Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken); + /// /// Creates a new token. /// @@ -39,7 +64,7 @@ namespace OpenIddict.Core public abstract Task CreateAsync([NotNull] TToken token, CancellationToken cancellationToken); /// - /// Creates a new token, which is associated with a particular subject. + /// Creates a new token. /// /// The token descriptor. /// The that can be used to abort the operation. @@ -329,6 +354,38 @@ namespace OpenIddict.Core return Task.FromResult(token.Type); } + /// + /// Executes the specified query. + /// + /// The number of results to return. + /// The number of results to skip. + /// 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([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken) + { + IQueryable Query(IQueryable tokens) + { + var query = tokens.OrderBy(token => token.Id).AsQueryable(); + + if (offset.HasValue) + { + query = query.Skip(offset.Value); + } + + if (count.HasValue) + { + query = query.Take(count.Value); + } + + return query; + } + + return ListAsync(Query, cancellationToken); + } + /// /// Executes the specified query. /// diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictApplicationStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictApplicationStore.cs index 52cc69b4..16fac810 100644 --- a/src/OpenIddict.EntityFramework/Stores/OpenIddictApplicationStore.cs +++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictApplicationStore.cs @@ -81,6 +81,26 @@ namespace OpenIddict.EntityFramework /// protected DbSet Applications => Context.Set(); + /// + /// Determines the number of applications that match the specified query. + /// + /// The result type. + /// The query to execute. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the number of applications that match the specified query. + /// + public override Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + { + if (query == null) + { + throw new ArgumentNullException(nameof(query)); + } + + return query.Invoke(Applications).LongCountAsync(); + } + /// /// Creates a new application. /// diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs index 217bfeed..f880d828 100644 --- a/src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs +++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs @@ -86,6 +86,26 @@ namespace OpenIddict.EntityFramework /// protected DbSet Authorizations => Context.Set(); + /// + /// Determines the number of authorizations that match the specified query. + /// + /// The result type. + /// The query to execute. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the number of authorizations that match the specified query. + /// + public override Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + { + if (query == null) + { + throw new ArgumentNullException(nameof(query)); + } + + return query.Invoke(Authorizations).LongCountAsync(); + } + /// /// Creates a new authorization. /// @@ -149,6 +169,31 @@ namespace OpenIddict.EntityFramework return await CreateAsync(authorization, cancellationToken); } + /// + /// Removes an existing authorization. + /// + /// The authorization to delete. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation. + /// + public override async Task DeleteAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken) + { + if (authorization == null) + { + throw new ArgumentNullException(nameof(authorization)); + } + + Authorizations.Remove(authorization); + + try + { + await Context.SaveChangesAsync(cancellationToken); + } + + catch (DbUpdateConcurrencyException) { } + } + /// /// Retrieves an authorization using its unique identifier. /// diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictScopeStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictScopeStore.cs index b960fba4..bebf6409 100644 --- a/src/OpenIddict.EntityFramework/Stores/OpenIddictScopeStore.cs +++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictScopeStore.cs @@ -6,10 +6,12 @@ using System; using System.Data.Entity; +using System.Data.Entity.Infrastructure; using System.Linq; using System.Threading; using System.Threading.Tasks; using JetBrains.Annotations; +using OpenIddict.Core; using OpenIddict.Models; namespace OpenIddict.EntityFramework @@ -70,6 +72,91 @@ namespace OpenIddict.EntityFramework /// protected DbSet Scopes => Context.Set(); + /// + /// Determines the number of scopes that match the specified query. + /// + /// The result type. + /// The query to execute. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the number of scopes that match the specified query. + /// + public override Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + { + if (query == null) + { + throw new ArgumentNullException(nameof(query)); + } + + return query.Invoke(Scopes).LongCountAsync(); + } + + /// + /// Creates a new scope. + /// + /// The scope to create. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, whose result returns the scope. + /// + public override async Task CreateAsync([NotNull] TScope scope, CancellationToken cancellationToken) + { + if (scope == null) + { + throw new ArgumentNullException(nameof(scope)); + } + + Scopes.Add(scope); + + await Context.SaveChangesAsync(cancellationToken); + + return scope; + } + + /// + /// Creates a new scope. + /// + /// The scope descriptor. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, whose result returns the scope. + /// + public override Task CreateAsync([NotNull] OpenIddictScopeDescriptor descriptor, CancellationToken cancellationToken) + { + var scope = new TScope + { + Name = descriptor.Name + }; + + return CreateAsync(scope, cancellationToken); + } + + /// + /// Removes an existing scope. + /// + /// The scope to delete. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation. + /// + public override async Task DeleteAsync([NotNull] TScope scope, CancellationToken cancellationToken) + { + if (scope == null) + { + throw new ArgumentNullException(nameof(scope)); + } + + Scopes.Remove(scope); + + try + { + await Context.SaveChangesAsync(cancellationToken); + } + + catch (DbUpdateConcurrencyException) { } + } + /// /// Executes the specified query. /// @@ -109,5 +196,31 @@ namespace OpenIddict.EntityFramework return query.Invoke(Scopes).ToArrayAsync(cancellationToken); } + + /// + /// Updates an existing scope. + /// + /// The scope to update. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation. + /// + public override async Task UpdateAsync([NotNull] TScope scope, CancellationToken cancellationToken) + { + if (scope == null) + { + throw new ArgumentNullException(nameof(scope)); + } + + Scopes.Attach(scope); + Context.Entry(scope).State = EntityState.Modified; + + try + { + await Context.SaveChangesAsync(cancellationToken); + } + + catch (DbUpdateConcurrencyException) { } + } } } \ No newline at end of file diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictTokenStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictTokenStore.cs index 1987e46e..3d8c85c5 100644 --- a/src/OpenIddict.EntityFramework/Stores/OpenIddictTokenStore.cs +++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictTokenStore.cs @@ -91,6 +91,26 @@ namespace OpenIddict.EntityFramework /// protected DbSet Tokens => Context.Set(); + /// + /// Determines the number of tokens that match the specified query. + /// + /// The result type. + /// The query to execute. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the number of tokens that match the specified query. + /// + public override Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + { + if (query == null) + { + throw new ArgumentNullException(nameof(query)); + } + + return query.Invoke(Tokens).LongCountAsync(); + } + /// /// Creates a new token. /// @@ -114,7 +134,7 @@ namespace OpenIddict.EntityFramework } /// - /// Creates a new token, which is associated with a particular subject. + /// Creates a new token. /// /// The token descriptor. /// The that can be used to abort the operation. diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs index d2ebeaf3..750b3de8 100644 --- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs +++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs @@ -80,6 +80,26 @@ namespace OpenIddict.EntityFrameworkCore /// protected DbSet Applications => Context.Set(); + /// + /// Determines the number of applications that match the specified query. + /// + /// The result type. + /// The query to execute. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the number of applications that match the specified query. + /// + public override Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + { + if (query == null) + { + throw new ArgumentNullException(nameof(query)); + } + + return query.Invoke(Applications).LongCountAsync(); + } + /// /// Creates a new application. /// diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs index 35351fa2..df97afd9 100644 --- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs +++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs @@ -85,6 +85,26 @@ namespace OpenIddict.EntityFrameworkCore /// protected DbSet Authorizations => Context.Set(); + /// + /// Determines the number of authorizations that match the specified query. + /// + /// The result type. + /// The query to execute. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the number of authorizations that match the specified query. + /// + public override Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + { + if (query == null) + { + throw new ArgumentNullException(nameof(query)); + } + + return query.Invoke(Authorizations).LongCountAsync(); + } + /// /// Creates a new authorization. /// @@ -148,6 +168,31 @@ namespace OpenIddict.EntityFrameworkCore return await CreateAsync(authorization, cancellationToken); } + /// + /// Removes an existing authorization. + /// + /// The authorization to delete. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation. + /// + public override async Task DeleteAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken) + { + if (authorization == null) + { + throw new ArgumentNullException(nameof(authorization)); + } + + Context.Remove(authorization); + + try + { + await Context.SaveChangesAsync(cancellationToken); + } + + catch (DbUpdateConcurrencyException) { } + } + /// /// Retrieves an authorization using its unique identifier. /// diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs index ccd0b49f..05429eaa 100644 --- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs +++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs @@ -10,6 +10,7 @@ using System.Threading; using System.Threading.Tasks; using JetBrains.Annotations; using Microsoft.EntityFrameworkCore; +using OpenIddict.Core; using OpenIddict.Models; namespace OpenIddict.EntityFrameworkCore @@ -70,6 +71,91 @@ namespace OpenIddict.EntityFrameworkCore /// protected DbSet Scopes => Context.Set(); + /// + /// Determines the number of scopes that match the specified query. + /// + /// The result type. + /// The query to execute. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the number of scopes that match the specified query. + /// + public override Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + { + if (query == null) + { + throw new ArgumentNullException(nameof(query)); + } + + return query.Invoke(Scopes).LongCountAsync(); + } + + /// + /// Creates a new scope. + /// + /// The scope to create. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, whose result returns the scope. + /// + public override async Task CreateAsync([NotNull] TScope scope, CancellationToken cancellationToken) + { + if (scope == null) + { + throw new ArgumentNullException(nameof(scope)); + } + + Scopes.Add(scope); + + await Context.SaveChangesAsync(cancellationToken); + + return scope; + } + + /// + /// Creates a new scope. + /// + /// The scope descriptor. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, whose result returns the scope. + /// + public override Task CreateAsync([NotNull] OpenIddictScopeDescriptor descriptor, CancellationToken cancellationToken) + { + var scope = new TScope + { + Name = descriptor.Name + }; + + return CreateAsync(scope, cancellationToken); + } + + /// + /// Removes an existing scope. + /// + /// The scope to delete. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation. + /// + public override async Task DeleteAsync([NotNull] TScope scope, CancellationToken cancellationToken) + { + if (scope == null) + { + throw new ArgumentNullException(nameof(scope)); + } + + Context.Remove(scope); + + try + { + await Context.SaveChangesAsync(cancellationToken); + } + + catch (DbUpdateConcurrencyException) { } + } + /// /// Executes the specified query. /// @@ -109,5 +195,31 @@ namespace OpenIddict.EntityFrameworkCore return query.Invoke(Scopes).ToArrayAsync(cancellationToken); } + + /// + /// Updates an existing scope. + /// + /// The scope to update. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation. + /// + public override async Task UpdateAsync([NotNull] TScope scope, CancellationToken cancellationToken) + { + if (scope == null) + { + throw new ArgumentNullException(nameof(scope)); + } + + Context.Attach(scope); + Context.Entry(scope).State = EntityState.Modified; + + try + { + await Context.SaveChangesAsync(cancellationToken); + } + + catch (DbUpdateConcurrencyException) { } + } } } \ No newline at end of file diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs index 3dc76866..bb31e34b 100644 --- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs +++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs @@ -90,6 +90,26 @@ namespace OpenIddict.EntityFrameworkCore /// protected DbSet Tokens => Context.Set(); + /// + /// Determines the number of tokens that match the specified query. + /// + /// The result type. + /// The query to execute. + /// The that can be used to abort the operation. + /// + /// A that can be used to monitor the asynchronous operation, + /// whose result returns the number of tokens that match the specified query. + /// + public override Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken) + { + if (query == null) + { + throw new ArgumentNullException(nameof(query)); + } + + return query.Invoke(Tokens).LongCountAsync(); + } + /// /// Creates a new token. /// @@ -113,7 +133,7 @@ namespace OpenIddict.EntityFrameworkCore } /// - /// Creates a new token, which is associated with a particular subject. + /// Creates a new token. /// /// The token descriptor. /// The that can be used to abort the operation. diff --git a/src/OpenIddict.Models/OpenIddictScope.cs b/src/OpenIddict.Models/OpenIddictScope.cs index 10c9c6c4..5def77a9 100644 --- a/src/OpenIddict.Models/OpenIddictScope.cs +++ b/src/OpenIddict.Models/OpenIddictScope.cs @@ -36,5 +36,11 @@ namespace OpenIddict.Models /// associated with the current scope. /// public virtual TKey Id { get; set; } + + /// + /// Gets or sets the unique name + /// associated with the current scope. + /// + public virtual string Name { get; set; } } }