Browse Source

Backport the descriptors changes to OpenIddict 1.x

pull/553/head
Kévin Chalet 8 years ago
parent
commit
ffb3203a34
  1. 14
      src/OpenIddict.Core/Descriptors/OpenIddictAuthorizationDescriptor.cs
  2. 6
      src/OpenIddict.Core/Descriptors/OpenIddictScopeDescriptor.cs
  3. 15
      src/OpenIddict.Core/Descriptors/OpenIddictTokenDescriptor.cs
  4. 33
      src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs
  5. 19
      src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs
  6. 47
      src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs
  7. 15
      src/OpenIddict.Core/Stores/IOpenIddictApplicationStore.cs
  8. 11
      src/OpenIddict.Core/Stores/IOpenIddictTokenStore.cs
  9. 60
      src/OpenIddict.Core/Stores/OpenIddictApplicationStore.cs
  10. 21
      src/OpenIddict.Core/Stores/OpenIddictTokenStore.cs
  11. 70
      src/OpenIddict.EntityFramework/Stores/OpenIddictApplicationStore.cs
  12. 68
      src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs
  13. 37
      src/OpenIddict.EntityFramework/Stores/OpenIddictScopeStore.cs
  14. 90
      src/OpenIddict.EntityFramework/Stores/OpenIddictTokenStore.cs
  15. 70
      src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs
  16. 72
      src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs
  17. 37
      src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs
  18. 98
      src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs
  19. 14
      src/OpenIddict/OpenIddictProvider.Helpers.cs

14
src/OpenIddict.Core/Descriptors/OpenIddictAuthorizationDescriptor.cs

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Security.Claims;
namespace OpenIddict.Core
{
@ -13,6 +14,19 @@ namespace OpenIddict.Core
/// </summary>
public string ApplicationId { get; set; }
/// <summary>
/// Gets or sets the optional principal associated with the authorization.
/// Note: this property is not stored by the default authorization stores.
/// </summary>
public ClaimsPrincipal Principal { get; set; }
/// <summary>
/// Gets the optional authentication properties associated with the authorization.
/// Note: this property is not stored by the default authorization stores.
/// </summary>
public IDictionary<string, string> Properties { get; } =
new Dictionary<string, string>(StringComparer.Ordinal);
/// <summary>
/// Gets the scopes associated with the authorization.
/// </summary>

6
src/OpenIddict.Core/Descriptors/OpenIddictScopeDescriptor.cs

@ -5,6 +5,12 @@
/// </summary>
public class OpenIddictScopeDescriptor
{
/// <summary>
/// Gets or sets the description
/// associated with the scope.
/// </summary>
public virtual string Description { get; set; }
/// <summary>
/// Gets or sets the unique name
/// associated with the scope.

15
src/OpenIddict.Core/Descriptors/OpenIddictTokenDescriptor.cs

@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Security.Claims;
namespace OpenIddict.Core
{
@ -37,6 +39,19 @@ namespace OpenIddict.Core
/// </summary>
public string Hash { get; set; }
/// <summary>
/// Gets or sets the optional principal associated with the token.
/// Note: this property is not stored by the default token stores.
/// </summary>
public ClaimsPrincipal Principal { get; set; }
/// <summary>
/// Gets the optional authentication properties associated with the token.
/// Note: this property is not stored by the default token stores.
/// </summary>
public IDictionary<string, string> Properties { get; } =
new Dictionary<string, string>(StringComparer.Ordinal);
/// <summary>
/// Gets or sets the status associated with the token.
/// </summary>

33
src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs

@ -244,8 +244,13 @@ namespace OpenIddict.Core
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the client application corresponding to the identifier.
/// </returns>
public virtual Task<TApplication> FindByIdAsync(string identifier, CancellationToken cancellationToken)
public virtual Task<TApplication> FindByIdAsync([NotNull] string identifier, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(identifier))
{
throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier));
}
return Store.FindByIdAsync(identifier, cancellationToken);
}
@ -258,8 +263,13 @@ namespace OpenIddict.Core
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the client application corresponding to the identifier.
/// </returns>
public virtual Task<TApplication> FindByClientIdAsync(string identifier, CancellationToken cancellationToken)
public virtual Task<TApplication> FindByClientIdAsync([NotNull] string identifier, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(identifier))
{
throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier));
}
return Store.FindByClientIdAsync(identifier, cancellationToken);
}
@ -408,25 +418,6 @@ namespace OpenIddict.Core
return Store.GetIdAsync(application, cancellationToken);
}
/// <summary>
/// Retrieves the token identifiers associated with an application.
/// </summary>
/// <param name="application">The application.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the tokens associated with the application.
/// </returns>
public virtual Task<ImmutableArray<string>> GetTokensAsync([NotNull] TApplication application, CancellationToken cancellationToken)
{
if (application == null)
{
throw new ArgumentNullException(nameof(application));
}
return Store.GetTokensAsync(application, cancellationToken);
}
/// <summary>
/// Determines whether an application is a confidential client.
/// </summary>

19
src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs

@ -182,8 +182,18 @@ namespace OpenIddict.Core
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the authorization corresponding to the subject/client.
/// </returns>
public virtual Task<TAuthorization> FindAsync(string subject, string client, CancellationToken cancellationToken)
public virtual Task<TAuthorization> FindAsync([NotNull] string subject, [NotNull] string client, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(subject))
{
throw new ArgumentException("The subject cannot be null or empty.", nameof(subject));
}
if (string.IsNullOrEmpty(client))
{
throw new ArgumentException("The client identifier cannot be null or empty.", nameof(client));
}
return Store.FindAsync(subject, client, cancellationToken);
}
@ -196,8 +206,13 @@ namespace OpenIddict.Core
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the authorization corresponding to the identifier.
/// </returns>
public virtual Task<TAuthorization> FindByIdAsync(string identifier, CancellationToken cancellationToken)
public virtual Task<TAuthorization> FindByIdAsync([NotNull] string identifier, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(identifier))
{
throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier));
}
return Store.FindByIdAsync(identifier, cancellationToken);
}

47
src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs

@ -179,6 +179,25 @@ namespace OpenIddict.Core
await UpdateAsync(token, cancellationToken);
}
/// <summary>
/// Retrieves the list of tokens corresponding to the specified application identifier.
/// </summary>
/// <param name="identifier">The application identifier associated with the tokens.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the tokens corresponding to the specified application.
/// </returns>
public virtual Task<ImmutableArray<TToken>> FindByApplicationIdAsync([NotNull] string identifier, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(identifier))
{
throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier));
}
return Store.FindByApplicationIdAsync(identifier, cancellationToken);
}
/// <summary>
/// Retrieves the list of tokens corresponding to the specified authorization identifier.
/// </summary>
@ -188,8 +207,13 @@ namespace OpenIddict.Core
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the tokens corresponding to the specified authorization.
/// </returns>
public virtual Task<ImmutableArray<TToken>> FindByAuthorizationIdAsync(string identifier, CancellationToken cancellationToken)
public virtual Task<ImmutableArray<TToken>> FindByAuthorizationIdAsync([NotNull] string identifier, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(identifier))
{
throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier));
}
return Store.FindByAuthorizationIdAsync(identifier, cancellationToken);
}
@ -202,8 +226,13 @@ namespace OpenIddict.Core
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the tokens corresponding to the specified hash.
/// </returns>
public virtual Task<TToken> FindByHashAsync(string hash, CancellationToken cancellationToken)
public virtual Task<TToken> FindByHashAsync([NotNull] string hash, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(hash))
{
throw new ArgumentException("The hash cannot be null or empty.", nameof(hash));
}
return Store.FindByHashAsync(hash, cancellationToken);
}
@ -216,8 +245,13 @@ namespace OpenIddict.Core
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the token corresponding to the unique identifier.
/// </returns>
public virtual Task<TToken> FindByIdAsync(string identifier, CancellationToken cancellationToken)
public virtual Task<TToken> FindByIdAsync([NotNull] string identifier, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(identifier))
{
throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier));
}
return Store.FindByIdAsync(identifier, cancellationToken);
}
@ -230,8 +264,13 @@ namespace OpenIddict.Core
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the tokens corresponding to the specified subject.
/// </returns>
public virtual Task<ImmutableArray<TToken>> FindBySubjectAsync(string subject, CancellationToken cancellationToken)
public virtual Task<ImmutableArray<TToken>> FindBySubjectAsync([NotNull] string subject, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(subject))
{
throw new ArgumentException("The subject cannot be null or empty.", nameof(subject));
}
return Store.FindBySubjectAsync(subject, cancellationToken);
}

15
src/OpenIddict.Core/Stores/IOpenIddictApplicationStore.cs

@ -207,17 +207,6 @@ namespace OpenIddict.Core
/// </returns>
Task<ImmutableArray<string>> GetRedirectUrisAsync([NotNull] TApplication application, CancellationToken cancellationToken);
/// <summary>
/// Retrieves the token identifiers associated with an application.
/// </summary>
/// <param name="application">The application.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the tokens associated with the application.
/// </returns>
Task<ImmutableArray<string>> GetTokensAsync([NotNull] TApplication application, CancellationToken cancellationToken);
/// <summary>
/// Executes the specified query.
/// </summary>
@ -276,7 +265,7 @@ namespace OpenIddict.Core
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation.
/// </returns>
Task SetPostLogoutRedirectUrisAsync([NotNull] TApplication application,
[NotNull] ImmutableArray<string> addresses, CancellationToken cancellationToken);
ImmutableArray<string> addresses, CancellationToken cancellationToken);
/// <summary>
/// Sets the callback addresses associated with an application.
@ -288,7 +277,7 @@ namespace OpenIddict.Core
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation.
/// </returns>
Task SetRedirectUrisAsync([NotNull] TApplication application,
[NotNull] ImmutableArray<string> addresses, CancellationToken cancellationToken);
ImmutableArray<string> addresses, CancellationToken cancellationToken);
/// <summary>
/// Updates an existing application.

11
src/OpenIddict.Core/Stores/IOpenIddictTokenStore.cs

@ -69,6 +69,17 @@ namespace OpenIddict.Core
/// <returns>A <see cref="Task"/> that can be used to monitor the asynchronous operation.</returns>
Task DeleteAsync([NotNull] TToken token, CancellationToken cancellationToken);
/// <summary>
/// Retrieves the list of tokens corresponding to the specified application identifier.
/// </summary>
/// <param name="identifier">The application identifier associated with the tokens.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the tokens corresponding to the specified application.
/// </returns>
Task<ImmutableArray<TToken>> FindByApplicationIdAsync([NotNull] string identifier, CancellationToken cancellationToken);
/// <summary>
/// Retrieves the list of tokens corresponding to the specified authorization identifier.
/// </summary>

60
src/OpenIddict.Core/Stores/OpenIddictApplicationStore.cs

@ -411,46 +411,6 @@ namespace OpenIddict.Core
return Task.FromResult(ImmutableArray.Create(uris));
}
/// <summary>
/// Retrieves the token identifiers associated with an application.
/// </summary>
/// <param name="application">The application.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the tokens associated with the application.
/// </returns>
public virtual async Task<ImmutableArray<string>> GetTokensAsync([NotNull] TApplication application, CancellationToken cancellationToken)
{
if (application == null)
{
throw new ArgumentNullException(nameof(application));
}
IQueryable<TKey> Query(IQueryable<TApplication> applications)
{
return from entity in applications
where entity.Id.Equals(application.Id)
from token in entity.Tokens
select token.Id;
}
var identifiers = await ListAsync(Query, cancellationToken);
if (identifiers.IsDefaultOrEmpty)
{
return ImmutableArray.Create<string>();
}
var builder = ImmutableArray.CreateBuilder<string>(identifiers.Length);
foreach (var identifier in identifiers)
{
builder.Add(ConvertIdentifierToString(identifier));
}
return builder.ToImmutable();
}
/// <summary>
/// Executes the specified query.
/// </summary>
@ -555,16 +515,18 @@ namespace OpenIddict.Core
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation.
/// </returns>
public virtual Task SetPostLogoutRedirectUrisAsync([NotNull] TApplication application,
[NotNull] ImmutableArray<string> addresses, CancellationToken cancellationToken)
ImmutableArray<string> addresses, CancellationToken cancellationToken)
{
if (application == null)
{
throw new ArgumentException(nameof(application));
throw new ArgumentNullException(nameof(application));
}
if (addresses == null)
if (addresses.IsDefaultOrEmpty)
{
throw new ArgumentException(nameof(addresses));
application.PostLogoutRedirectUris = null;
return Task.FromResult(0);
}
if (addresses.Any(address => string.IsNullOrEmpty(address)))
@ -592,16 +554,18 @@ namespace OpenIddict.Core
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation.
/// </returns>
public virtual Task SetRedirectUrisAsync([NotNull] TApplication application,
[NotNull] ImmutableArray<string> addresses, CancellationToken cancellationToken)
ImmutableArray<string> addresses, CancellationToken cancellationToken)
{
if (application == null)
{
throw new ArgumentException(nameof(application));
throw new ArgumentNullException(nameof(application));
}
if (addresses == null)
if (addresses.IsDefaultOrEmpty)
{
throw new ArgumentException(nameof(addresses));
application.RedirectUris = null;
return Task.FromResult(0);
}
if (addresses.Any(address => string.IsNullOrEmpty(address)))

21
src/OpenIddict.Core/Stores/OpenIddictTokenStore.cs

@ -82,6 +82,27 @@ namespace OpenIddict.Core
/// <returns>A <see cref="Task"/> that can be used to monitor the asynchronous operation.</returns>
public abstract Task DeleteAsync([NotNull] TToken token, CancellationToken cancellationToken);
/// <summary>
/// Retrieves the list of tokens corresponding to the specified application identifier.
/// </summary>
/// <param name="identifier">The application identifier associated with the tokens.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation,
/// whose result returns the tokens corresponding to the specified application.
/// </returns>
public virtual Task<ImmutableArray<TToken>> FindByApplicationIdAsync([NotNull] string identifier, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(identifier))
{
throw new ArgumentException("The identifier cannot be null or empty.", nameof(identifier));
}
var key = ConvertIdentifierFromString(identifier);
return ListAsync(tokens => tokens.Where(token => token.Application.Id.Equals(key)), cancellationToken);
}
/// <summary>
/// Retrieves the list of tokens corresponding to the specified authorization identifier.
/// </summary>

70
src/OpenIddict.EntityFramework/Stores/OpenIddictApplicationStore.cs

@ -141,36 +141,17 @@ namespace OpenIddict.EntityFramework
/// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, whose result returns the application.
/// </returns>
public override Task<TApplication> CreateAsync([NotNull] OpenIddictApplicationDescriptor descriptor, CancellationToken cancellationToken)
public override async Task<TApplication> CreateAsync([NotNull] OpenIddictApplicationDescriptor descriptor, CancellationToken cancellationToken)
{
if (descriptor == null)
{
throw new ArgumentNullException(nameof(descriptor));
}
var application = new TApplication
{
ClientId = descriptor.ClientId,
ClientSecret = descriptor.ClientSecret,
DisplayName = descriptor.DisplayName,
Type = descriptor.Type
};
if (descriptor.PostLogoutRedirectUris.Count != 0)
{
application.PostLogoutRedirectUris = string.Join(
OpenIddictConstants.Separators.Space,
descriptor.PostLogoutRedirectUris.Select(uri => uri.OriginalString));
}
if (descriptor.RedirectUris.Count != 0)
{
application.RedirectUris = string.Join(
OpenIddictConstants.Separators.Space,
descriptor.RedirectUris.Select(uri => uri.OriginalString));
}
var application = new TApplication();
return CreateAsync(application, cancellationToken);
await BindAsync(application, descriptor, cancellationToken);
return await CreateAsync(application, cancellationToken);
}
/// <summary>
@ -304,5 +285,48 @@ namespace OpenIddict.EntityFramework
return Context.SaveChangesAsync(cancellationToken);
}
/// <summary>
/// Sets the application properties based on the specified descriptor.
/// </summary>
/// <param name="application">The application to update.</param>
/// <param name="descriptor">The application descriptor.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation.
/// </returns>
protected virtual Task BindAsync([NotNull] TApplication application, [NotNull] OpenIddictApplicationDescriptor descriptor, CancellationToken cancellationToken)
{
if (application == null)
{
throw new ArgumentNullException(nameof(application));
}
if (descriptor == null)
{
throw new ArgumentNullException(nameof(descriptor));
}
application.ClientId = descriptor.ClientId;
application.ClientSecret = descriptor.ClientSecret;
application.DisplayName = descriptor.DisplayName;
application.Type = descriptor.Type;
if (descriptor.PostLogoutRedirectUris.Count != 0)
{
application.PostLogoutRedirectUris = string.Join(
OpenIddictConstants.Separators.Space,
descriptor.PostLogoutRedirectUris.Select(uri => uri.OriginalString));
}
if (descriptor.RedirectUris.Count != 0)
{
application.RedirectUris = string.Join(
OpenIddictConstants.Separators.Space,
descriptor.RedirectUris.Select(uri => uri.OriginalString));
}
return Task.FromResult(0);
}
}
}

68
src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs

@ -148,30 +148,9 @@ namespace OpenIddict.EntityFramework
throw new ArgumentNullException(nameof(descriptor));
}
var authorization = new TAuthorization
{
Status = descriptor.Status,
Subject = descriptor.Subject,
Type = descriptor.Type
};
if (descriptor.Scopes.Count != 0)
{
authorization.Scopes = string.Join(OpenIddictConstants.Separators.Space, descriptor.Scopes);
}
// Bind the authorization to the specified application, if applicable.
if (!string.IsNullOrEmpty(descriptor.ApplicationId))
{
var application = await Applications.FindAsync(cancellationToken, ConvertIdentifierFromString(descriptor.ApplicationId));
if (application == null)
{
throw new InvalidOperationException("The application associated with the authorization cannot be found.");
}
authorization.Application = application;
}
var authorization = new TAuthorization();
await BindAsync(authorization, descriptor, cancellationToken);
return await CreateAsync(authorization, cancellationToken);
}
@ -356,5 +335,48 @@ namespace OpenIddict.EntityFramework
return Context.SaveChangesAsync(cancellationToken);
}
/// <summary>
/// Sets the authorization properties based on the specified descriptor.
/// </summary>
/// <param name="authorization">The authorization to update.</param>
/// <param name="descriptor">The authorization descriptor.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation.
/// </returns>
protected virtual async Task BindAsync([NotNull] TAuthorization authorization, [NotNull] OpenIddictAuthorizationDescriptor descriptor, CancellationToken cancellationToken)
{
if (authorization == null)
{
throw new ArgumentNullException(nameof(authorization));
}
if (descriptor == null)
{
throw new ArgumentNullException(nameof(descriptor));
}
authorization.Status = descriptor.Status;
authorization.Subject = descriptor.Subject;
authorization.Type = descriptor.Type;
if (descriptor.Scopes.Count != 0)
{
authorization.Scopes = string.Join(OpenIddictConstants.Separators.Space, descriptor.Scopes);
}
// Bind the authorization to the specified application, if applicable.
if (!string.IsNullOrEmpty(descriptor.ApplicationId))
{
var application = await Applications.FindAsync(new object[] { ConvertIdentifierFromString(descriptor.ApplicationId) }, cancellationToken);
if (application == null)
{
throw new InvalidOperationException("The application associated with the authorization cannot be found.");
}
authorization.Application = application;
}
}
}
}

37
src/OpenIddict.EntityFramework/Stores/OpenIddictScopeStore.cs

@ -122,14 +122,12 @@ namespace OpenIddict.EntityFramework
/// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, whose result returns the scope.
/// </returns>
public override Task<TScope> CreateAsync([NotNull] OpenIddictScopeDescriptor descriptor, CancellationToken cancellationToken)
public override async Task<TScope> CreateAsync([NotNull] OpenIddictScopeDescriptor descriptor, CancellationToken cancellationToken)
{
var scope = new TScope
{
Name = descriptor.Name
};
var scope = new TScope();
return CreateAsync(scope, cancellationToken);
await BindAsync(scope, descriptor, cancellationToken);
return await CreateAsync(scope, cancellationToken);
}
/// <summary>
@ -212,5 +210,32 @@ namespace OpenIddict.EntityFramework
return Context.SaveChangesAsync(cancellationToken);
}
/// <summary>
/// Sets the scope properties based on the specified descriptor.
/// </summary>
/// <param name="scope">The scope to update.</param>
/// <param name="descriptor">The scope descriptor.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation.
/// </returns>
protected virtual Task BindAsync([NotNull] TScope scope, [NotNull] OpenIddictScopeDescriptor descriptor, CancellationToken cancellationToken)
{
if (scope == null)
{
throw new ArgumentNullException(nameof(scope));
}
if (descriptor == null)
{
throw new ArgumentNullException(nameof(descriptor));
}
scope.Description = descriptor.Description;
scope.Name = descriptor.Name;
return Task.FromResult(0);
}
}
}

90
src/OpenIddict.EntityFramework/Stores/OpenIddictTokenStore.cs

@ -148,41 +148,9 @@ namespace OpenIddict.EntityFramework
throw new ArgumentNullException(nameof(descriptor));
}
var token = new TToken
{
Ciphertext = descriptor.Ciphertext,
CreationDate = descriptor.CreationDate,
ExpirationDate = descriptor.ExpirationDate,
Hash = descriptor.Hash,
Status = descriptor.Status,
Subject = descriptor.Subject,
Type = descriptor.Type
};
// Bind the token to the specified client application, if applicable.
if (!string.IsNullOrEmpty(descriptor.ApplicationId))
{
var application = await Applications.FindAsync(cancellationToken, ConvertIdentifierFromString(descriptor.ApplicationId));
if (application == null)
{
throw new InvalidOperationException("The application associated with the token cannot be found.");
}
token.Application = application;
}
// Bind the token to the specified authorization, if applicable.
if (!string.IsNullOrEmpty(descriptor.AuthorizationId))
{
var authorization = await Authorizations.FindAsync(cancellationToken, ConvertIdentifierFromString(descriptor.AuthorizationId));
if (authorization == null)
{
throw new InvalidOperationException("The authorization associated with the token cannot be found.");
}
token.Authorization = authorization;
}
var token = new TToken();
await BindAsync(token, descriptor, cancellationToken);
return await CreateAsync(token, cancellationToken);
}
@ -429,5 +397,59 @@ namespace OpenIddict.EntityFramework
return Context.SaveChangesAsync(cancellationToken);
}
/// <summary>
/// Sets the token properties based on the specified descriptor.
/// </summary>
/// <param name="token">The token to update.</param>
/// <param name="descriptor">The token descriptor.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation.
/// </returns>
protected virtual async Task BindAsync([NotNull] TToken token, [NotNull] OpenIddictTokenDescriptor descriptor, CancellationToken cancellationToken)
{
if (token == null)
{
throw new ArgumentNullException(nameof(token));
}
if (descriptor == null)
{
throw new ArgumentNullException(nameof(descriptor));
}
token.Ciphertext = descriptor.Ciphertext;
token.CreationDate = descriptor.CreationDate;
token.ExpirationDate = descriptor.ExpirationDate;
token.Hash = descriptor.Hash;
token.Status = descriptor.Status;
token.Subject = descriptor.Subject;
token.Type = descriptor.Type;
// Bind the token to the specified client application, if applicable.
if (!string.IsNullOrEmpty(descriptor.ApplicationId))
{
var application = await Applications.FindAsync(new object[] { ConvertIdentifierFromString(descriptor.ApplicationId) }, cancellationToken);
if (application == null)
{
throw new InvalidOperationException("The application associated with the token cannot be found.");
}
token.Application = application;
}
// Bind the token to the specified authorization, if applicable.
if (!string.IsNullOrEmpty(descriptor.AuthorizationId))
{
var authorization = await Authorizations.FindAsync(new object[] { ConvertIdentifierFromString(descriptor.AuthorizationId) }, cancellationToken);
if (authorization == null)
{
throw new InvalidOperationException("The authorization associated with the token cannot be found.");
}
token.Authorization = authorization;
}
}
}
}

70
src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs

@ -141,36 +141,17 @@ namespace OpenIddict.EntityFrameworkCore
/// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, whose result returns the application.
/// </returns>
public override Task<TApplication> CreateAsync([NotNull] OpenIddictApplicationDescriptor descriptor, CancellationToken cancellationToken)
public override async Task<TApplication> CreateAsync([NotNull] OpenIddictApplicationDescriptor descriptor, CancellationToken cancellationToken)
{
if (descriptor == null)
{
throw new ArgumentNullException(nameof(descriptor));
}
var application = new TApplication
{
ClientId = descriptor.ClientId,
ClientSecret = descriptor.ClientSecret,
DisplayName = descriptor.DisplayName,
Type = descriptor.Type
};
if (descriptor.PostLogoutRedirectUris.Count != 0)
{
application.PostLogoutRedirectUris = string.Join(
OpenIddictConstants.Separators.Space,
descriptor.PostLogoutRedirectUris.Select(uri => uri.OriginalString));
}
if (descriptor.RedirectUris.Count != 0)
{
application.RedirectUris = string.Join(
OpenIddictConstants.Separators.Space,
descriptor.RedirectUris.Select(uri => uri.OriginalString));
}
var application = new TApplication();
return CreateAsync(application, cancellationToken);
await BindAsync(application, descriptor, cancellationToken);
return await CreateAsync(application, cancellationToken);
}
/// <summary>
@ -285,5 +266,48 @@ namespace OpenIddict.EntityFrameworkCore
return Context.SaveChangesAsync(cancellationToken);
}
/// <summary>
/// Sets the application properties based on the specified descriptor.
/// </summary>
/// <param name="application">The application to update.</param>
/// <param name="descriptor">The application descriptor.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation.
/// </returns>
protected virtual Task BindAsync([NotNull] TApplication application, [NotNull] OpenIddictApplicationDescriptor descriptor, CancellationToken cancellationToken)
{
if (application == null)
{
throw new ArgumentNullException(nameof(application));
}
if (descriptor == null)
{
throw new ArgumentNullException(nameof(descriptor));
}
application.ClientId = descriptor.ClientId;
application.ClientSecret = descriptor.ClientSecret;
application.DisplayName = descriptor.DisplayName;
application.Type = descriptor.Type;
if (descriptor.PostLogoutRedirectUris.Count != 0)
{
application.PostLogoutRedirectUris = string.Join(
OpenIddictConstants.Separators.Space,
descriptor.PostLogoutRedirectUris.Select(uri => uri.OriginalString));
}
if (descriptor.RedirectUris.Count != 0)
{
application.RedirectUris = string.Join(
OpenIddictConstants.Separators.Space,
descriptor.RedirectUris.Select(uri => uri.OriginalString));
}
return Task.FromResult(0);
}
}
}

72
src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs

@ -148,32 +148,9 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentNullException(nameof(descriptor));
}
var authorization = new TAuthorization
{
Status = descriptor.Status,
Subject = descriptor.Subject,
Type = descriptor.Type
};
if (descriptor.Scopes.Count != 0)
{
authorization.Scopes = string.Join(OpenIddictConstants.Separators.Space, descriptor.Scopes);
}
// Bind the authorization to the specified application, if applicable.
if (!string.IsNullOrEmpty(descriptor.ApplicationId))
{
var key = ConvertIdentifierFromString(descriptor.ApplicationId);
var application = await Applications.SingleOrDefaultAsync(entity => entity.Id.Equals(key));
if (application == null)
{
throw new InvalidOperationException("The application associated with the authorization cannot be found.");
}
authorization.Application = application;
}
var authorization = new TAuthorization();
await BindAsync(authorization, descriptor, cancellationToken);
return await CreateAsync(authorization, cancellationToken);
}
@ -309,5 +286,50 @@ namespace OpenIddict.EntityFrameworkCore
return Context.SaveChangesAsync(cancellationToken);
}
/// <summary>
/// Sets the authorization properties based on the specified descriptor.
/// </summary>
/// <param name="authorization">The authorization to update.</param>
/// <param name="descriptor">The authorization descriptor.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation.
/// </returns>
protected virtual async Task BindAsync([NotNull] TAuthorization authorization, [NotNull] OpenIddictAuthorizationDescriptor descriptor, CancellationToken cancellationToken)
{
if (authorization == null)
{
throw new ArgumentNullException(nameof(authorization));
}
if (descriptor == null)
{
throw new ArgumentNullException(nameof(descriptor));
}
authorization.Status = descriptor.Status;
authorization.Subject = descriptor.Subject;
authorization.Type = descriptor.Type;
if (descriptor.Scopes.Count != 0)
{
authorization.Scopes = string.Join(OpenIddictConstants.Separators.Space, descriptor.Scopes);
}
// Bind the authorization to the specified application, if applicable.
if (!string.IsNullOrEmpty(descriptor.ApplicationId))
{
var key = ConvertIdentifierFromString(descriptor.ApplicationId);
var application = await Applications.SingleOrDefaultAsync(entity => entity.Id.Equals(key));
if (application == null)
{
throw new InvalidOperationException("The application associated with the authorization cannot be found.");
}
authorization.Application = application;
}
}
}
}

37
src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs

@ -122,14 +122,12 @@ namespace OpenIddict.EntityFrameworkCore
/// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation, whose result returns the scope.
/// </returns>
public override Task<TScope> CreateAsync([NotNull] OpenIddictScopeDescriptor descriptor, CancellationToken cancellationToken)
public override async Task<TScope> CreateAsync([NotNull] OpenIddictScopeDescriptor descriptor, CancellationToken cancellationToken)
{
var scope = new TScope
{
Name = descriptor.Name
};
var scope = new TScope();
return CreateAsync(scope, cancellationToken);
await BindAsync(scope, descriptor, cancellationToken);
return await CreateAsync(scope, cancellationToken);
}
/// <summary>
@ -212,5 +210,32 @@ namespace OpenIddict.EntityFrameworkCore
return Context.SaveChangesAsync(cancellationToken);
}
/// <summary>
/// Sets the scope properties based on the specified descriptor.
/// </summary>
/// <param name="scope">The scope to update.</param>
/// <param name="descriptor">The scope descriptor.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation.
/// </returns>
protected virtual Task BindAsync([NotNull] TScope scope, [NotNull] OpenIddictScopeDescriptor descriptor, CancellationToken cancellationToken)
{
if (scope == null)
{
throw new ArgumentNullException(nameof(scope));
}
if (descriptor == null)
{
throw new ArgumentNullException(nameof(descriptor));
}
scope.Description = descriptor.Description;
scope.Name = descriptor.Name;
return Task.FromResult(0);
}
}
}

98
src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs

@ -148,45 +148,9 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentNullException(nameof(descriptor));
}
var token = new TToken
{
Ciphertext = descriptor.Ciphertext,
CreationDate = descriptor.CreationDate,
ExpirationDate = descriptor.ExpirationDate,
Hash = descriptor.Hash,
Status = descriptor.Status,
Subject = descriptor.Subject,
Type = descriptor.Type
};
// Bind the token to the specified client application, if applicable.
if (!string.IsNullOrEmpty(descriptor.ApplicationId))
{
var key = ConvertIdentifierFromString(descriptor.ApplicationId);
var application = await Applications.SingleOrDefaultAsync(entity => entity.Id.Equals(key));
if (application == null)
{
throw new InvalidOperationException("The application associated with the token cannot be found.");
}
token.Application = application;
}
// Bind the token to the specified authorization, if applicable.
if (!string.IsNullOrEmpty(descriptor.AuthorizationId))
{
var key = ConvertIdentifierFromString(descriptor.AuthorizationId);
var authorization = await Authorizations.SingleOrDefaultAsync(entity => entity.Id.Equals(key));
if (authorization == null)
{
throw new InvalidOperationException("The authorization associated with the token cannot be found.");
}
token.Authorization = authorization;
}
var token = new TToken();
await BindAsync(token, descriptor, cancellationToken);
return await CreateAsync(token, cancellationToken);
}
@ -354,5 +318,63 @@ namespace OpenIddict.EntityFrameworkCore
return Context.SaveChangesAsync(cancellationToken);
}
/// <summary>
/// Sets the token properties based on the specified descriptor.
/// </summary>
/// <param name="token">The token to update.</param>
/// <param name="descriptor">The token descriptor.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> that can be used to abort the operation.</param>
/// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation.
/// </returns>
protected virtual async Task BindAsync([NotNull] TToken token, [NotNull] OpenIddictTokenDescriptor descriptor, CancellationToken cancellationToken)
{
if (token == null)
{
throw new ArgumentNullException(nameof(token));
}
if (descriptor == null)
{
throw new ArgumentNullException(nameof(descriptor));
}
token.Ciphertext = descriptor.Ciphertext;
token.CreationDate = descriptor.CreationDate;
token.ExpirationDate = descriptor.ExpirationDate;
token.Hash = descriptor.Hash;
token.Status = descriptor.Status;
token.Subject = descriptor.Subject;
token.Type = descriptor.Type;
// Bind the token to the specified client application, if applicable.
if (!string.IsNullOrEmpty(descriptor.ApplicationId))
{
var key = ConvertIdentifierFromString(descriptor.ApplicationId);
var application = await Applications.SingleOrDefaultAsync(entity => entity.Id.Equals(key));
if (application == null)
{
throw new InvalidOperationException("The application associated with the token cannot be found.");
}
token.Application = application;
}
// Bind the token to the specified authorization, if applicable.
if (!string.IsNullOrEmpty(descriptor.AuthorizationId))
{
var key = ConvertIdentifierFromString(descriptor.AuthorizationId);
var authorization = await Authorizations.SingleOrDefaultAsync(entity => entity.Id.Equals(key));
if (authorization == null)
{
throw new InvalidOperationException("The authorization associated with the token cannot be found.");
}
token.Authorization = authorization;
}
}
}
}

14
src/OpenIddict/OpenIddictProvider.Helpers.cs

@ -38,12 +38,18 @@ namespace OpenIddict
var descriptor = new OpenIddictAuthorizationDescriptor
{
Principal = ticket.Principal,
Status = OpenIddictConstants.Statuses.Valid,
Subject = ticket.Principal.GetClaim(OpenIdConnectConstants.Claims.Subject),
Type = OpenIddictConstants.AuthorizationTypes.AdHoc
};
foreach (var scope in request.GetScopes())
foreach (var property in ticket.Properties.Items)
{
descriptor.Properties.Add(property);
}
foreach (var scope in ticket.GetScopes())
{
descriptor.Scopes.Add(scope);
}
@ -124,11 +130,17 @@ namespace OpenIddict
AuthorizationId = ticket.GetProperty(OpenIddictConstants.Properties.AuthorizationId),
CreationDate = ticket.Properties.IssuedUtc,
ExpirationDate = ticket.Properties.ExpiresUtc,
Principal = ticket.Principal,
Status = OpenIddictConstants.Statuses.Valid,
Subject = ticket.Principal.GetClaim(OpenIdConnectConstants.Claims.Subject),
Type = type
};
foreach (var property in ticket.Properties.Items)
{
descriptor.Properties.Add(property);
}
string result = null;
// When reference tokens are enabled or when the token is an authorization code or a

Loading…
Cancel
Save