Browse Source

Remove implicit permissions and introduce OpenIddictServerBuilder.IgnoreEndpointPermissions()/IgnoreGrantTypePermissions()/IgnoreScopePermissions()

pull/620/head
Kévin Chalet 8 years ago
parent
commit
7e10bedb73
  1. 17
      samples/Mvc.Server/Startup.cs
  2. 11
      src/OpenIddict.Abstractions/Managers/IOpenIddictApplicationManager.cs
  3. 11
      src/OpenIddict.Abstractions/OpenIddictConstants.cs
  4. 139
      src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs
  5. 129
      src/OpenIddict.Server/Internal/OpenIddictServerProvider.Authentication.cs
  6. 43
      src/OpenIddict.Server/Internal/OpenIddictServerProvider.Exchange.cs
  7. 5
      src/OpenIddict.Server/Internal/OpenIddictServerProvider.Introspection.cs
  8. 3
      src/OpenIddict.Server/Internal/OpenIddictServerProvider.Revocation.cs
  9. 29
      src/OpenIddict.Server/Internal/OpenIddictServerProvider.Session.cs
  10. 24
      src/OpenIddict.Server/OpenIddictServerBuilder.cs
  11. 21
      src/OpenIddict.Server/OpenIddictServerOptions.cs
  12. 91
      test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Authentication.cs
  13. 251
      test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Exchange.cs
  14. 46
      test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Introspection.cs
  15. 24
      test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Revocation.cs
  16. 156
      test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Serialization.cs
  17. 19
      test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Session.cs
  18. 65
      test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.cs

17
samples/Mvc.Server/Startup.cs

@ -126,6 +126,13 @@ namespace Mvc.Server
// that specify non-registered scopes, uncomment the following line: // that specify non-registered scopes, uncomment the following line:
// //
// options.DisableScopeValidation(); // options.DisableScopeValidation();
// Note: if you don't want to use permissions, you can disable
// permission enforcement by uncommenting the following lines:
//
// options.IgnoreEndpointPermissions()
// .IgnoreGrantTypePermissions()
// .IgnoreScopePermissions();
}) })
// Register the OpenIddict validation handler. // Register the OpenIddict validation handler.
@ -180,7 +187,10 @@ namespace Mvc.Server
OpenIddictConstants.Permissions.Endpoints.Logout, OpenIddictConstants.Permissions.Endpoints.Logout,
OpenIddictConstants.Permissions.Endpoints.Token, OpenIddictConstants.Permissions.Endpoints.Token,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode,
OpenIddictConstants.Permissions.GrantTypes.RefreshToken OpenIddictConstants.Permissions.GrantTypes.RefreshToken,
OpenIddictConstants.Permissions.Scopes.Email,
OpenIddictConstants.Permissions.Scopes.Profile,
OpenIddictConstants.Permissions.Scopes.Roles
} }
}; };
@ -207,7 +217,10 @@ namespace Mvc.Server
{ {
OpenIddictConstants.Permissions.Endpoints.Authorization, OpenIddictConstants.Permissions.Endpoints.Authorization,
OpenIddictConstants.Permissions.Endpoints.Token, OpenIddictConstants.Permissions.Endpoints.Token,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode,
OpenIddictConstants.Permissions.Scopes.Email,
OpenIddictConstants.Permissions.Scopes.Profile,
OpenIddictConstants.Permissions.Scopes.Roles
} }
}; };

11
src/OpenIddict.Abstractions/Managers/IOpenIddictApplicationManager.cs

@ -395,17 +395,6 @@ namespace OpenIddict.Abstractions
/// </returns> /// </returns>
Task<bool> ValidateClientSecretAsync([NotNull] object application, string secret, CancellationToken cancellationToken = default); Task<bool> ValidateClientSecretAsync([NotNull] object application, string secret, CancellationToken cancellationToken = default);
/// <summary>
/// Validates the specified post_logout_redirect_uri.
/// </summary>
/// <param name="address">The address that should be compared to the post_logout_redirect_uri stored in the database.</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 a boolean indicating whether the post_logout_redirect_uri was valid.
/// </returns>
Task<bool> ValidatePostLogoutRedirectUriAsync([NotNull] string address, CancellationToken cancellationToken = default);
/// <summary> /// <summary>
/// Validates the redirect_uri to ensure it's associated with an application. /// Validates the redirect_uri to ensure it's associated with an application.
/// </summary> /// </summary>

11
src/OpenIddict.Abstractions/OpenIddictConstants.cs

@ -70,6 +70,17 @@ namespace OpenIddict.Abstractions
public const string GrantType = "gt:"; public const string GrantType = "gt:";
public const string Scope = "scp:"; public const string Scope = "scp:";
} }
public static class Scopes
{
public const string Address = "scp:address";
public const string Email = "scp:email";
public const string OfflineAccess = "scp:offline_access";
public const string OpenId = "scp:openid";
public const string Phone = "scp:phone";
public const string Profile = "scp:profile";
public const string Roles = "scp:roles";
}
} }
public static class Properties public static class Properties

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

@ -583,107 +583,7 @@ namespace OpenIddict.Core
throw new ArgumentException("The permission name cannot be null or empty.", nameof(permission)); throw new ArgumentException("The permission name cannot be null or empty.", nameof(permission));
} }
// Note: all the string-based comparisons used by this method are ordinal (and thus case-sensitive). return (await GetPermissionsAsync(application, cancellationToken)).Contains(permission);
var permissions = await Store.GetPermissionsAsync(application, cancellationToken);
bool HasPermission(string name)
{
if (permissions.IsEmpty)
{
return false;
}
return permissions.Contains(name);
}
bool HasEndpointPermission(string name)
{
// If the requested permission is an "endpoint" permission, return true if it has been
// explicitly granted OR if no other endpoint permission has been explicitly registered.
if (permissions.IsEmpty || HasPermission(name))
{
return true;
}
if (permissions.Any(element => element.StartsWith(OpenIddictConstants.Permissions.Prefixes.Endpoint)))
{
return false;
}
return true;
}
bool HasGrantTypePermission(string name)
{
// If the requested permission is a "grant_type" permission, return true if it has been
// explicitly granted OR if the application is allowed to use the corresponding endpoint
// AND no other grant type permission has been explicitly registered.
if (permissions.IsEmpty || HasPermission(name))
{
return true;
}
if (permissions.Any(element => element.StartsWith(OpenIddictConstants.Permissions.Prefixes.GrantType)))
{
return false;
}
switch (permission)
{
case OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode:
return HasEndpointPermission(OpenIddictConstants.Permissions.Endpoints.Authorization) &&
HasEndpointPermission(OpenIddictConstants.Permissions.Endpoints.Token);
case OpenIddictConstants.Permissions.GrantTypes.Implicit:
return HasEndpointPermission(OpenIddictConstants.Permissions.Endpoints.Authorization);
default:
case OpenIddictConstants.Permissions.GrantTypes.ClientCredentials:
case OpenIddictConstants.Permissions.GrantTypes.Password:
case OpenIddictConstants.Permissions.GrantTypes.RefreshToken:
return HasEndpointPermission(OpenIddictConstants.Permissions.Endpoints.Token);
}
}
bool HasScopePermission(string name)
{
// If the requested permission is a "scope" permission, return true if it has been
// explicitly granted OR if the application is allowed to use the authorization or
// token endpoints AND no other scope permission has been explicitly registered.
if (permissions.IsEmpty || HasPermission(name))
{
return true;
}
if (permissions.Any(element => element.StartsWith(OpenIddictConstants.Permissions.Prefixes.Scope)))
{
return false;
}
return HasEndpointPermission(OpenIddictConstants.Permissions.Endpoints.Authorization) ||
HasEndpointPermission(OpenIddictConstants.Permissions.Endpoints.Token);
}
if (permission.StartsWith(OpenIddictConstants.Permissions.Prefixes.Endpoint))
{
return HasEndpointPermission(permission);
}
if (permission.StartsWith(OpenIddictConstants.Permissions.Prefixes.GrantType))
{
return HasGrantTypePermission(permission);
}
if (permission.StartsWith(OpenIddictConstants.Permissions.Prefixes.Scope))
{
return HasScopePermission(permission);
}
return HasPermission(permission);
} }
/// <summary> /// <summary>
@ -1218,40 +1118,6 @@ namespace OpenIddict.Core
return true; return true;
} }
/// <summary>
/// Validates the specified post_logout_redirect_uri.
/// </summary>
/// <param name="address">The address that should be compared to the post_logout_redirect_uri stored in the database.</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 a boolean indicating whether the post_logout_redirect_uri was valid.
/// </returns>
public virtual async Task<bool> ValidatePostLogoutRedirectUriAsync(
[NotNull] string address, CancellationToken cancellationToken = default)
{
if (string.IsNullOrEmpty(address))
{
throw new ArgumentException("The address cannot be null or empty.", nameof(address));
}
foreach (var application in await FindByPostLogoutRedirectUriAsync(address, cancellationToken))
{
// If the application is not allowed to use the logout endpoint, ignore it and keep iterating.
if (!await HasPermissionAsync(application, OpenIddictConstants.Permissions.Endpoints.Logout, cancellationToken))
{
continue;
}
return true;
}
Logger.LogWarning("Client validation failed because '{PostLogoutRedirectUri}' " +
"was not a valid post_logout_redirect_uri.", address);
return false;
}
/// <summary> /// <summary>
/// Validates the redirect_uri to ensure it's associated with an application. /// Validates the redirect_uri to ensure it's associated with an application.
/// </summary> /// </summary>
@ -1450,9 +1316,6 @@ namespace OpenIddict.Core
Task<bool> IOpenIddictApplicationManager.ValidateClientSecretAsync(object application, string secret, CancellationToken cancellationToken) Task<bool> IOpenIddictApplicationManager.ValidateClientSecretAsync(object application, string secret, CancellationToken cancellationToken)
=> ValidateClientSecretAsync((TApplication) application, secret, cancellationToken); => ValidateClientSecretAsync((TApplication) application, secret, cancellationToken);
Task<bool> IOpenIddictApplicationManager.ValidatePostLogoutRedirectUriAsync(string address, CancellationToken cancellationToken)
=> ValidatePostLogoutRedirectUriAsync(address, cancellationToken);
Task<bool> IOpenIddictApplicationManager.ValidateRedirectUriAsync(object application, string address, CancellationToken cancellationToken) Task<bool> IOpenIddictApplicationManager.ValidateRedirectUriAsync(object application, string address, CancellationToken cancellationToken)
=> ValidateRedirectUriAsync((TApplication) application, address, cancellationToken); => ValidateRedirectUriAsync((TApplication) application, address, cancellationToken);
} }

129
src/OpenIddict.Server/Internal/OpenIddictServerProvider.Authentication.cs

@ -316,7 +316,8 @@ namespace OpenIddict.Server
} }
// Reject the request if the application is not allowed to use the authorization endpoint. // Reject the request if the application is not allowed to use the authorization endpoint.
if (!await _applicationManager.HasPermissionAsync(application, OpenIddictConstants.Permissions.Endpoints.Authorization)) if (!options.IgnoreEndpointPermissions &&
!await _applicationManager.HasPermissionAsync(application, OpenIddictConstants.Permissions.Endpoints.Authorization))
{ {
_logger.LogError("The authorization request was rejected because the application '{ClientId}' " + _logger.LogError("The authorization request was rejected because the application '{ClientId}' " +
"was not allowed to use the authorization endpoint.", context.ClientId); "was not allowed to use the authorization endpoint.", context.ClientId);
@ -328,62 +329,65 @@ namespace OpenIddict.Server
return; return;
} }
// Reject the request if the application is not allowed to use the authorization code flow. if (!options.IgnoreGrantTypePermissions)
if (context.Request.IsAuthorizationCodeFlow() && !await _applicationManager.HasPermissionAsync(
application, OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode))
{ {
_logger.LogError("The authorization request was rejected because the application '{ClientId}' " + // Reject the request if the application is not allowed to use the authorization code flow.
"was not allowed to use the authorization code flow.", context.ClientId); if (context.Request.IsAuthorizationCodeFlow() && !await _applicationManager.HasPermissionAsync(
application, OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode))
{
_logger.LogError("The authorization request was rejected because the application '{ClientId}' " +
"was not allowed to use the authorization code flow.", context.ClientId);
context.Reject( context.Reject(
error: OpenIdConnectConstants.Errors.UnauthorizedClient, error: OpenIdConnectConstants.Errors.UnauthorizedClient,
description: "The client application is not allowed to use the authorization code flow."); description: "The client application is not allowed to use the authorization code flow.");
return; return;
} }
// Reject the request if the application is not allowed to use the implicit flow. // Reject the request if the application is not allowed to use the implicit flow.
if (context.Request.IsImplicitFlow() && !await _applicationManager.HasPermissionAsync( if (context.Request.IsImplicitFlow() && !await _applicationManager.HasPermissionAsync(
application, OpenIddictConstants.Permissions.GrantTypes.Implicit)) application, OpenIddictConstants.Permissions.GrantTypes.Implicit))
{ {
_logger.LogError("The authorization request was rejected because the application '{ClientId}' " + _logger.LogError("The authorization request was rejected because the application '{ClientId}' " +
"was not allowed to use the implicit flow.", context.ClientId); "was not allowed to use the implicit flow.", context.ClientId);
context.Reject( context.Reject(
error: OpenIdConnectConstants.Errors.UnauthorizedClient, error: OpenIdConnectConstants.Errors.UnauthorizedClient,
description: "The client application is not allowed to use the implicit flow."); description: "The client application is not allowed to use the implicit flow.");
return; return;
} }
// Reject the request if the application is not allowed to use the authorization code/implicit flows. // Reject the request if the application is not allowed to use the authorization code/implicit flows.
if (context.Request.IsHybridFlow() && if (context.Request.IsHybridFlow() &&
(!await _applicationManager.HasPermissionAsync(application, OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode) || (!await _applicationManager.HasPermissionAsync(application, OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode) ||
!await _applicationManager.HasPermissionAsync(application, OpenIddictConstants.Permissions.GrantTypes.Implicit))) !await _applicationManager.HasPermissionAsync(application, OpenIddictConstants.Permissions.GrantTypes.Implicit)))
{ {
_logger.LogError("The authorization request was rejected because the application '{ClientId}' " + _logger.LogError("The authorization request was rejected because the application '{ClientId}' " +
"was not allowed to use the hybrid flow.", context.ClientId); "was not allowed to use the hybrid flow.", context.ClientId);
context.Reject( context.Reject(
error: OpenIdConnectConstants.Errors.UnauthorizedClient, error: OpenIdConnectConstants.Errors.UnauthorizedClient,
description: "The client application is not allowed to use the hybrid flow."); description: "The client application is not allowed to use the hybrid flow.");
return; return;
} }
// Reject the request if the offline_access scope was request and if the // Reject the request if the offline_access scope was request and if the
// application is not allowed to use the authorization code/implicit flows. // application is not allowed to use the authorization code/implicit flows.
if (context.Request.HasScope(OpenIdConnectConstants.Scopes.OfflineAccess) && if (context.Request.HasScope(OpenIdConnectConstants.Scopes.OfflineAccess) &&
!await _applicationManager.HasPermissionAsync(application, OpenIddictConstants.Permissions.GrantTypes.RefreshToken)) !await _applicationManager.HasPermissionAsync(application, OpenIddictConstants.Permissions.GrantTypes.RefreshToken))
{ {
_logger.LogError("The authorization request was rejected because the application '{ClientId}' " + _logger.LogError("The authorization request was rejected because the application '{ClientId}' " +
"was not allowed to request the 'offline_access' scope.", context.ClientId); "was not allowed to request the 'offline_access' scope.", context.ClientId);
context.Reject( context.Reject(
error: OpenIdConnectConstants.Errors.InvalidRequest, error: OpenIdConnectConstants.Errors.InvalidRequest,
description: "The client application is not allowed to use the 'offline_access' scope."); description: "The client application is not allowed to use the 'offline_access' scope.");
return; return;
}
} }
// Ensure that the specified redirect_uri is valid and is associated with the client application. // Ensure that the specified redirect_uri is valid and is associated with the client application.
@ -399,26 +403,31 @@ namespace OpenIddict.Server
return; return;
} }
foreach (var scope in context.Request.GetScopes()) // Unless permission enforcement was explicitly disabled, ensure
// the client application is allowed to use the specified scopes.
if (!options.IgnoreScopePermissions)
{ {
// Avoid validating the "openid" and "offline_access" scopes as they represent protocol scopes. foreach (var scope in context.Request.GetScopes())
if (string.Equals(scope, OpenIdConnectConstants.Scopes.OfflineAccess, StringComparison.Ordinal) ||
string.Equals(scope, OpenIdConnectConstants.Scopes.OpenId, StringComparison.Ordinal))
{ {
continue; // Avoid validating the "openid" and "offline_access" scopes as they represent protocol scopes.
} if (string.Equals(scope, OpenIdConnectConstants.Scopes.OfflineAccess, StringComparison.Ordinal) ||
string.Equals(scope, OpenIdConnectConstants.Scopes.OpenId, StringComparison.Ordinal))
{
continue;
}
// Reject the request if the application is not allowed to use the iterated scope. // Reject the request if the application is not allowed to use the iterated scope.
if (!await _applicationManager.HasPermissionAsync(application, OpenIddictConstants.Permissions.Prefixes.Scope + scope)) if (!await _applicationManager.HasPermissionAsync(application, OpenIddictConstants.Permissions.Prefixes.Scope + scope))
{ {
_logger.LogError("The authorization request was rejected because the application '{ClientId}' " + _logger.LogError("The authorization request was rejected because the application '{ClientId}' " +
"was not allowed to use the scope {Scope}.", context.ClientId, scope); "was not allowed to use the scope {Scope}.", context.ClientId, scope);
context.Reject( context.Reject(
error: OpenIdConnectConstants.Errors.InvalidRequest, error: OpenIdConnectConstants.Errors.InvalidRequest,
description: "This client application is not allowed to use the specified scope."); description: "This client application is not allowed to use the specified scope.");
return; return;
}
} }
} }

43
src/OpenIddict.Server/Internal/OpenIddictServerProvider.Exchange.cs

@ -166,7 +166,8 @@ namespace OpenIddict.Server
context.Request.SetProperty($"{OpenIddictConstants.Properties.Application}:{context.ClientId}", application); context.Request.SetProperty($"{OpenIddictConstants.Properties.Application}:{context.ClientId}", application);
// Reject the request if the application is not allowed to use the token endpoint. // Reject the request if the application is not allowed to use the token endpoint.
if (!await _applicationManager.HasPermissionAsync(application, OpenIddictConstants.Permissions.Endpoints.Token)) if (!options.IgnoreEndpointPermissions &&
!await _applicationManager.HasPermissionAsync(application, OpenIddictConstants.Permissions.Endpoints.Token))
{ {
_logger.LogError("The token request was rejected because the application '{ClientId}' " + _logger.LogError("The token request was rejected because the application '{ClientId}' " +
"was not allowed to use the token endpoint.", context.ClientId); "was not allowed to use the token endpoint.", context.ClientId);
@ -179,7 +180,8 @@ namespace OpenIddict.Server
} }
// Reject the request if the application is not allowed to use the specified grant type. // Reject the request if the application is not allowed to use the specified grant type.
if (!await _applicationManager.HasPermissionAsync(application, if (!options.IgnoreGrantTypePermissions &&
!await _applicationManager.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Prefixes.GrantType + context.Request.GrantType)) OpenIddictConstants.Permissions.Prefixes.GrantType + context.Request.GrantType))
{ {
_logger.LogError("The token request was rejected because the application '{ClientId}' was not allowed to " + _logger.LogError("The token request was rejected because the application '{ClientId}' was not allowed to " +
@ -256,27 +258,32 @@ namespace OpenIddict.Server
return; return;
} }
foreach (var scope in context.Request.GetScopes()) // Unless permission enforcement was explicitly disabled, ensure
// the client application is allowed to use the specified scopes.
if (!options.IgnoreScopePermissions)
{ {
// Avoid validating the "openid" and "offline_access" scopes as they represent protocol scopes. foreach (var scope in context.Request.GetScopes())
if (string.Equals(scope, OpenIdConnectConstants.Scopes.OfflineAccess, StringComparison.Ordinal) ||
string.Equals(scope, OpenIdConnectConstants.Scopes.OpenId, StringComparison.Ordinal))
{ {
continue; // Avoid validating the "openid" and "offline_access" scopes as they represent protocol scopes.
} if (string.Equals(scope, OpenIdConnectConstants.Scopes.OfflineAccess, StringComparison.Ordinal) ||
string.Equals(scope, OpenIdConnectConstants.Scopes.OpenId, StringComparison.Ordinal))
{
continue;
}
// Reject the request if the application is not allowed to use the iterated scope. // Reject the request if the application is not allowed to use the iterated scope.
if (!await _applicationManager.HasPermissionAsync(application, if (!await _applicationManager.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Prefixes.Scope + scope)) OpenIddictConstants.Permissions.Prefixes.Scope + scope))
{ {
_logger.LogError("The token request was rejected because the application '{ClientId}' " + _logger.LogError("The token request was rejected because the application '{ClientId}' " +
"was not allowed to use the scope {Scope}.", context.ClientId, scope); "was not allowed to use the scope {Scope}.", context.ClientId, scope);
context.Reject( context.Reject(
error: OpenIdConnectConstants.Errors.InvalidRequest, error: OpenIdConnectConstants.Errors.InvalidRequest,
description: "This client application is not allowed to use the specified scope."); description: "This client application is not allowed to use the specified scope.");
return; return;
}
} }
} }

5
src/OpenIddict.Server/Internal/OpenIddictServerProvider.Introspection.cs

@ -19,6 +19,8 @@ namespace OpenIddict.Server
{ {
public override async Task ValidateIntrospectionRequest([NotNull] ValidateIntrospectionRequestContext context) public override async Task ValidateIntrospectionRequest([NotNull] ValidateIntrospectionRequestContext context)
{ {
var options = (OpenIddictServerOptions) context.Options;
// Note: the OpenID Connect server middleware supports unauthenticated introspection requests // Note: the OpenID Connect server middleware supports unauthenticated introspection requests
// but OpenIddict uses a stricter policy preventing unauthenticated/public applications // but OpenIddict uses a stricter policy preventing unauthenticated/public applications
// from using the introspection endpoint, as required by the specifications. // from using the introspection endpoint, as required by the specifications.
@ -51,7 +53,8 @@ namespace OpenIddict.Server
context.Request.SetProperty($"{OpenIddictConstants.Properties.Application}:{context.ClientId}", application); context.Request.SetProperty($"{OpenIddictConstants.Properties.Application}:{context.ClientId}", application);
// Reject the request if the application is not allowed to use the introspection endpoint. // Reject the request if the application is not allowed to use the introspection endpoint.
if (!await _applicationManager.HasPermissionAsync(application, OpenIddictConstants.Permissions.Endpoints.Introspection)) if (!options.IgnoreEndpointPermissions &&
!await _applicationManager.HasPermissionAsync(application, OpenIddictConstants.Permissions.Endpoints.Introspection))
{ {
_logger.LogError("The introspection request was rejected because the application '{ClientId}' " + _logger.LogError("The introspection request was rejected because the application '{ClientId}' " +
"was not allowed to use the introspection endpoint.", context.ClientId); "was not allowed to use the introspection endpoint.", context.ClientId);

3
src/OpenIddict.Server/Internal/OpenIddictServerProvider.Revocation.cs

@ -94,7 +94,8 @@ namespace OpenIddict.Server
context.Request.SetProperty($"{OpenIddictConstants.Properties.Application}:{context.ClientId}", application); context.Request.SetProperty($"{OpenIddictConstants.Properties.Application}:{context.ClientId}", application);
// Reject the request if the application is not allowed to use the revocation endpoint. // Reject the request if the application is not allowed to use the revocation endpoint.
if (!await _applicationManager.HasPermissionAsync(application, OpenIddictConstants.Permissions.Endpoints.Revocation)) if (!options.IgnoreEndpointPermissions &&
!await _applicationManager.HasPermissionAsync(application, OpenIddictConstants.Permissions.Endpoints.Revocation))
{ {
_logger.LogError("The revocation request was rejected because the application '{ClientId}' " + _logger.LogError("The revocation request was rejected because the application '{ClientId}' " +
"was not allowed to use the revocation endpoint.", context.ClientId); "was not allowed to use the revocation endpoint.", context.ClientId);

29
src/OpenIddict.Server/Internal/OpenIddictServerProvider.Session.cs

@ -82,6 +82,8 @@ namespace OpenIddict.Server
public override async Task ValidateLogoutRequest([NotNull] ValidateLogoutRequestContext context) public override async Task ValidateLogoutRequest([NotNull] ValidateLogoutRequestContext context)
{ {
var options = (OpenIddictServerOptions) context.Options;
// If an optional post_logout_redirect_uri was provided, validate it. // If an optional post_logout_redirect_uri was provided, validate it.
if (!string.IsNullOrEmpty(context.PostLogoutRedirectUri)) if (!string.IsNullOrEmpty(context.PostLogoutRedirectUri))
{ {
@ -109,7 +111,32 @@ namespace OpenIddict.Server
return; return;
} }
if (!await _applicationManager.ValidatePostLogoutRedirectUriAsync(context.PostLogoutRedirectUri)) async Task<bool> ValidatePostLogoutRedirectUriAsync(string address)
{
var applications = await _applicationManager.FindByPostLogoutRedirectUriAsync(address);
if (applications.IsDefaultOrEmpty)
{
return false;
}
if (options.IgnoreEndpointPermissions)
{
return true;
}
foreach (var application in applications)
{
if (await _applicationManager.HasPermissionAsync(
application, OpenIddictConstants.Permissions.Endpoints.Logout))
{
return true;
}
}
return false;
}
if (!await ValidatePostLogoutRedirectUriAsync(context.PostLogoutRedirectUri))
{ {
_logger.LogError("The logout request was rejected because the specified post_logout_redirect_uri " + _logger.LogError("The logout request was rejected because the specified post_logout_redirect_uri " +
"was unknown: {PostLogoutRedirectUri}.", context.PostLogoutRedirectUri); "was unknown: {PostLogoutRedirectUri}.", context.PostLogoutRedirectUri);

24
src/OpenIddict.Server/OpenIddictServerBuilder.cs

@ -507,6 +507,30 @@ namespace Microsoft.Extensions.DependencyInjection
return Configure(options => options.UserinfoEndpointPath = path); return Configure(options => options.UserinfoEndpointPath = path);
} }
/// <summary>
/// Disables endpoint permissions enforcement. Calling this method is NOT recommended,
/// unless all the clients are first-party applications you own, control and fully trust.
/// </summary>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder IgnoreEndpointPermissions()
=> Configure(options => options.IgnoreEndpointPermissions = true);
/// <summary>
/// Disables grant type permissions enforcement. Calling this method is NOT recommended,
/// unless all the clients are first-party applications you own, control and fully trust.
/// </summary>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder IgnoreGrantTypePermissions()
=> Configure(options => options.IgnoreGrantTypePermissions = true);
/// <summary>
/// Disables scope permissions enforcement. Calling this method is NOT recommended,
/// unless all the clients are first-party applications you own, control and fully trust.
/// </summary>
/// <returns>The <see cref="OpenIddictServerBuilder"/>.</returns>
public OpenIddictServerBuilder IgnoreScopePermissions()
=> Configure(options => options.IgnoreScopePermissions = true);
/// <summary> /// <summary>
/// Registers the specified claims as supported claims so /// Registers the specified claims as supported claims so
/// they can be returned as part of the discovery document. /// they can be returned as part of the discovery document.

21
src/OpenIddict.Server/OpenIddictServerOptions.cs

@ -100,6 +100,27 @@ namespace OpenIddict.Server
/// </summary> /// </summary>
public ISet<string> GrantTypes { get; } = new HashSet<string>(StringComparer.Ordinal); public ISet<string> GrantTypes { get; } = new HashSet<string>(StringComparer.Ordinal);
/// <summary>
/// Gets or sets a boolean indicating whether endpoint permissions should be ignored.
/// Setting this property to <c>true</c> is NOT recommended, unless all
/// the clients are first-party applications you own, control and fully trust.
/// </summary>
public bool IgnoreEndpointPermissions { get; set; }
/// <summary>
/// Gets or sets a boolean indicating whether grant type permissions should be ignored.
/// Setting this property to <c>true</c> is NOT recommended, unless all
/// the clients are first-party applications you own, control and fully trust.
/// </summary>
public bool IgnoreGrantTypePermissions { get; set; }
/// <summary>
/// Gets or sets a boolean indicating whether scope permissions should be ignored.
/// Setting this property to <c>true</c> is NOT recommended, unless all
/// the clients are first-party applications you own, control and fully trust.
/// </summary>
public bool IgnoreScopePermissions { get; set; }
/// <summary> /// <summary>
/// Gets or sets the random number generator used to generate crypto-secure identifiers. /// Gets or sets the random number generator used to generate crypto-secure identifiers.
/// </summary> /// </summary>

91
test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Authentication.cs

@ -241,18 +241,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public));
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.Implicit, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Prefixes.Scope + "registered_scope", It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
})); }));
builder.RegisterScopes("registered_scope"); builder.RegisterScopes("registered_scope");
@ -308,22 +296,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public));
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.Implicit, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Prefixes.Scope + "scope_registered_in_database", It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Prefixes.Scope + "scope_registered_in_options", It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
})); }));
builder.RegisterScopes("scope_registered_in_options"); builder.RegisterScopes("scope_registered_in_options");
@ -586,6 +558,8 @@ namespace OpenIddict.Server.Tests
var server = CreateAuthorizationServer(builder => var server = CreateAuthorizationServer(builder =>
{ {
builder.Services.AddSingleton(manager); builder.Services.AddSingleton(manager);
builder.Configure(options => options.IgnoreEndpointPermissions = false);
}); });
var client = new OpenIdConnectClient(server.CreateClient()); var client = new OpenIdConnectClient(server.CreateClient());
@ -647,10 +621,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
foreach (var permission in permissions) foreach (var permission in permissions)
{ {
instance.Setup(mock => mock.HasPermissionAsync(application, permission, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.HasPermissionAsync(application, permission, It.IsAny<CancellationToken>()))
@ -661,6 +631,8 @@ namespace OpenIddict.Server.Tests
var server = CreateAuthorizationServer(builder => var server = CreateAuthorizationServer(builder =>
{ {
builder.Services.AddSingleton(manager); builder.Services.AddSingleton(manager);
builder.Configure(options => options.IgnoreGrantTypePermissions = false);
}); });
var client = new OpenIdConnectClient(server.CreateClient()); var client = new OpenIdConnectClient(server.CreateClient());
@ -680,8 +652,6 @@ namespace OpenIddict.Server.Tests
Assert.Equal(description, response.ErrorDescription); Assert.Equal(description, response.ErrorDescription);
Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()), Times.Once()); Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()), Times.Once());
Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny<CancellationToken>()), Times.Once());
Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application, permissions[0], It.IsAny<CancellationToken>()), Times.Once()); Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application, permissions[0], It.IsAny<CancellationToken>()), Times.Once());
} }
@ -696,14 +666,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>()))
.ReturnsAsync(false); .ReturnsAsync(false);
}); });
@ -728,10 +690,6 @@ namespace OpenIddict.Server.Tests
Assert.Equal("The specified 'redirect_uri' parameter is not valid for this client application.", response.ErrorDescription); Assert.Equal("The specified 'redirect_uri' parameter is not valid for this client application.", response.ErrorDescription);
Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()), Times.Once()); Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()), Times.Once());
Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny<CancellationToken>()), Times.Once());
Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()), Times.Once());
Mock.Get(manager).Verify(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>()), Times.Once()); Mock.Get(manager).Verify(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>()), Times.Once());
} }
@ -746,18 +704,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.RefreshToken, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>()))
.ReturnsAsync(true); .ReturnsAsync(true);
@ -776,6 +722,7 @@ namespace OpenIddict.Server.Tests
{ {
builder.Services.AddSingleton(manager); builder.Services.AddSingleton(manager);
builder.RegisterScopes(OpenIdConnectConstants.Scopes.Email, OpenIdConnectConstants.Scopes.Profile); builder.RegisterScopes(OpenIdConnectConstants.Scopes.Email, OpenIdConnectConstants.Scopes.Profile);
builder.Configure(options => options.IgnoreScopePermissions = false);
}); });
var client = new OpenIdConnectClient(server.CreateClient()); var client = new OpenIdConnectClient(server.CreateClient());
@ -823,14 +770,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.Implicit, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>()))
.ReturnsAsync(true); .ReturnsAsync(true);
@ -890,18 +829,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.Implicit, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>()))
.ReturnsAsync(true); .ReturnsAsync(true);
@ -978,14 +905,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.Implicit, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>()))
.ReturnsAsync(true); .ReturnsAsync(true);

251
test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Exchange.cs

@ -320,6 +320,8 @@ namespace OpenIddict.Server.Tests
var server = CreateAuthorizationServer(builder => var server = CreateAuthorizationServer(builder =>
{ {
builder.Services.AddSingleton(manager); builder.Services.AddSingleton(manager);
builder.Configure(options => options.IgnoreEndpointPermissions = false);
}); });
var client = new OpenIdConnectClient(server.CreateClient()); var client = new OpenIdConnectClient(server.CreateClient());
@ -353,10 +355,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application, instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.Password, It.IsAny<CancellationToken>())) OpenIddictConstants.Permissions.GrantTypes.Password, It.IsAny<CancellationToken>()))
.ReturnsAsync(false); .ReturnsAsync(false);
@ -365,6 +363,8 @@ namespace OpenIddict.Server.Tests
var server = CreateAuthorizationServer(builder => var server = CreateAuthorizationServer(builder =>
{ {
builder.Services.AddSingleton(manager); builder.Services.AddSingleton(manager);
builder.Configure(options => options.IgnoreGrantTypePermissions = false);
}); });
var client = new OpenIdConnectClient(server.CreateClient()); var client = new OpenIdConnectClient(server.CreateClient());
@ -383,8 +383,6 @@ namespace OpenIddict.Server.Tests
Assert.Equal("This client application is not allowed to use the specified grant type.", response.ErrorDescription); Assert.Equal("This client application is not allowed to use the specified grant type.", response.ErrorDescription);
Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()), Times.Once()); Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()), Times.Once());
Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()), Times.Once());
Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application, Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.Password, It.IsAny<CancellationToken>()), Times.Once()); OpenIddictConstants.Permissions.GrantTypes.Password, It.IsAny<CancellationToken>()), Times.Once());
} }
@ -400,14 +398,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.ClientCredentials, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public));
}); });
@ -432,10 +422,6 @@ namespace OpenIddict.Server.Tests
Assert.Equal("The specified 'grant_type' parameter is not valid for this client application.", response.ErrorDescription); Assert.Equal("The specified 'grant_type' parameter is not valid for this client application.", response.ErrorDescription);
Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()), Times.Once()); Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()), Times.Once());
Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()), Times.Once());
Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.ClientCredentials, It.IsAny<CancellationToken>()), Times.Once());
Mock.Get(manager).Verify(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()), Times.Once()); Mock.Get(manager).Verify(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()), Times.Once());
} }
@ -450,14 +436,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.Password, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public));
}); });
@ -484,10 +462,6 @@ namespace OpenIddict.Server.Tests
Assert.Equal("The 'client_secret' parameter is not valid for this client application.", response.ErrorDescription); Assert.Equal("The 'client_secret' parameter is not valid for this client application.", response.ErrorDescription);
Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()), Times.Once()); Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()), Times.Once());
Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()), Times.Once());
Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.Password, It.IsAny<CancellationToken>()), Times.Once());
Mock.Get(manager).Verify(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()), Times.Once()); Mock.Get(manager).Verify(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()), Times.Once());
} }
@ -502,14 +476,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.Password, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential));
}); });
@ -536,10 +502,6 @@ namespace OpenIddict.Server.Tests
Assert.Equal("The 'client_secret' parameter required for this client application is missing.", response.ErrorDescription); Assert.Equal("The 'client_secret' parameter required for this client application is missing.", response.ErrorDescription);
Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()), Times.Once()); Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()), Times.Once());
Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()), Times.Once());
Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.Password, It.IsAny<CancellationToken>()), Times.Once());
Mock.Get(manager).Verify(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()), Times.Once()); Mock.Get(manager).Verify(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()), Times.Once());
} }
@ -554,14 +516,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.Password, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Hybrid)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Hybrid));
}); });
@ -588,10 +542,6 @@ namespace OpenIddict.Server.Tests
Assert.Equal("The 'client_secret' parameter required for this client application is missing.", response.ErrorDescription); Assert.Equal("The 'client_secret' parameter required for this client application is missing.", response.ErrorDescription);
Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()), Times.Once()); Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()), Times.Once());
Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()), Times.Once());
Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.Password, It.IsAny<CancellationToken>()), Times.Once());
Mock.Get(manager).Verify(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()), Times.Once()); Mock.Get(manager).Verify(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()), Times.Once());
} }
@ -606,14 +556,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.Password, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential));
@ -643,10 +585,6 @@ namespace OpenIddict.Server.Tests
Assert.Equal("The specified client credentials are invalid.", response.ErrorDescription); Assert.Equal("The specified client credentials are invalid.", response.ErrorDescription);
Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()), Times.Once()); Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()), Times.Once());
Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()), Times.Once());
Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.Password, It.IsAny<CancellationToken>()), Times.Once());
Mock.Get(manager).Verify(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()), Times.Once()); Mock.Get(manager).Verify(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()), Times.Once());
Mock.Get(manager).Verify(mock => mock.ValidateClientSecretAsync(application, "7Fjfp0ZBr1KtDRbnfVdmIw", It.IsAny<CancellationToken>()), Times.Once()); Mock.Get(manager).Verify(mock => mock.ValidateClientSecretAsync(application, "7Fjfp0ZBr1KtDRbnfVdmIw", It.IsAny<CancellationToken>()), Times.Once());
} }
@ -662,18 +600,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.Password, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.RefreshToken, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential));
@ -698,6 +624,7 @@ namespace OpenIddict.Server.Tests
{ {
builder.Services.AddSingleton(manager); builder.Services.AddSingleton(manager);
builder.RegisterScopes(OpenIdConnectConstants.Scopes.Email, OpenIdConnectConstants.Scopes.Profile); builder.RegisterScopes(OpenIdConnectConstants.Scopes.Email, OpenIdConnectConstants.Scopes.Profile);
builder.Configure(options => options.IgnoreScopePermissions = false);
}); });
var client = new OpenIdConnectClient(server.CreateClient()); var client = new OpenIdConnectClient(server.CreateClient());
@ -758,14 +685,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public));
})); }));
@ -818,14 +737,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.RefreshToken, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public));
})); }));
@ -883,14 +794,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public));
})); }));
@ -950,14 +853,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.RefreshToken, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public));
})); }));
@ -1024,14 +919,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public));
})); }));
@ -1100,14 +987,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.RefreshToken, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public));
})); }));
@ -1170,14 +1049,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public));
})); }));
@ -1261,14 +1132,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.RefreshToken, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public));
})); }));
@ -1372,14 +1235,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public));
})); }));
@ -1475,14 +1330,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.RefreshToken, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public));
})); }));
@ -1564,14 +1411,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public));
})); }));
@ -1644,14 +1483,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.RefreshToken, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public));
})); }));
@ -1711,14 +1542,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public));
})); }));
@ -1802,14 +1625,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public));
})); }));
@ -1891,14 +1706,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public));
})); }));
@ -1984,14 +1791,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public));
})); }));
@ -2073,14 +1872,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.RefreshToken, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public));
})); }));
@ -2164,14 +1955,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.RefreshToken, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public));
})); }));
@ -2280,30 +2063,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.ClientCredentials, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.Password, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.RefreshToken, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
"gt:urn:ietf:params:oauth:grant-type:custom_grant", It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential));

46
test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Introspection.cs

@ -94,6 +94,8 @@ namespace OpenIddict.Server.Tests
var server = CreateAuthorizationServer(builder => var server = CreateAuthorizationServer(builder =>
{ {
builder.Services.AddSingleton(manager); builder.Services.AddSingleton(manager);
builder.Configure(options => options.IgnoreEndpointPermissions = false);
}); });
var client = new OpenIdConnectClient(server.CreateClient()); var client = new OpenIdConnectClient(server.CreateClient());
@ -126,10 +128,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public));
}); });
@ -154,8 +152,6 @@ namespace OpenIddict.Server.Tests
Assert.Equal("This client application is not allowed to use the introspection endpoint.", response.ErrorDescription); Assert.Equal("This client application is not allowed to use the introspection endpoint.", response.ErrorDescription);
Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()), Times.Once()); Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()), Times.Once());
Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny<CancellationToken>()), Times.Once());
Mock.Get(manager).Verify(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()), Times.Once()); Mock.Get(manager).Verify(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()), Times.Once());
} }
@ -170,10 +166,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential));
@ -201,8 +193,6 @@ namespace OpenIddict.Server.Tests
Assert.Equal("The specified client credentials are invalid.", response.ErrorDescription); Assert.Equal("The specified client credentials are invalid.", response.ErrorDescription);
Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()), Times.Once()); Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()), Times.Once());
Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny<CancellationToken>()), Times.Once());
Mock.Get(manager).Verify(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()), Times.Once()); Mock.Get(manager).Verify(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()), Times.Once());
Mock.Get(manager).Verify(mock => mock.ValidateClientSecretAsync(application, "7Fjfp0ZBr1KtDRbnfVdmIw", It.IsAny<CancellationToken>()), Times.Once()); Mock.Get(manager).Verify(mock => mock.ValidateClientSecretAsync(application, "7Fjfp0ZBr1KtDRbnfVdmIw", It.IsAny<CancellationToken>()), Times.Once());
} }
@ -239,10 +229,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential));
@ -297,10 +283,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential));
@ -356,10 +338,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential));
@ -407,10 +385,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential));
@ -477,10 +451,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential));
@ -572,10 +542,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential));
@ -671,10 +637,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential));
@ -780,10 +742,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential));

24
test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Revocation.cs

@ -119,6 +119,8 @@ namespace OpenIddict.Server.Tests
var server = CreateAuthorizationServer(builder => var server = CreateAuthorizationServer(builder =>
{ {
builder.Services.AddSingleton(manager); builder.Services.AddSingleton(manager);
builder.Configure(options => options.IgnoreEndpointPermissions = false);
}); });
var client = new OpenIdConnectClient(server.CreateClient()); var client = new OpenIdConnectClient(server.CreateClient());
@ -152,10 +154,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Revocation, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public));
}); });
@ -181,8 +179,6 @@ namespace OpenIddict.Server.Tests
Assert.Equal("The 'client_secret' parameter is not valid for this client application.", response.ErrorDescription); Assert.Equal("The 'client_secret' parameter is not valid for this client application.", response.ErrorDescription);
Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()), Times.Once()); Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()), Times.Once());
Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Revocation, It.IsAny<CancellationToken>()), Times.Once());
Mock.Get(manager).Verify(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()), Times.Once()); Mock.Get(manager).Verify(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()), Times.Once());
} }
@ -197,10 +193,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Revocation, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential));
}); });
@ -226,8 +218,6 @@ namespace OpenIddict.Server.Tests
Assert.Equal("The 'client_secret' parameter required for this client application is missing.", response.ErrorDescription); Assert.Equal("The 'client_secret' parameter required for this client application is missing.", response.ErrorDescription);
Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()), Times.Once()); Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()), Times.Once());
Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Revocation, It.IsAny<CancellationToken>()), Times.Once());
Mock.Get(manager).Verify(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()), Times.Once()); Mock.Get(manager).Verify(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()), Times.Once());
} }
@ -242,10 +232,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Revocation, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Hybrid)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Hybrid));
}); });
@ -271,8 +257,6 @@ namespace OpenIddict.Server.Tests
Assert.Equal("The 'client_secret' parameter required for this client application is missing.", response.ErrorDescription); Assert.Equal("The 'client_secret' parameter required for this client application is missing.", response.ErrorDescription);
Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()), Times.Once()); Mock.Get(manager).Verify(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()), Times.Once());
Mock.Get(manager).Verify(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Revocation, It.IsAny<CancellationToken>()), Times.Once());
Mock.Get(manager).Verify(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()), Times.Once()); Mock.Get(manager).Verify(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()), Times.Once());
} }
@ -287,10 +271,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Revocation, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential));

156
test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Serialization.cs

@ -38,10 +38,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential));
@ -116,10 +112,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential));
@ -174,10 +166,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential));
@ -236,10 +224,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential));
@ -303,10 +287,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential));
@ -396,10 +376,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential));
@ -458,14 +434,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential));
@ -543,14 +511,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential));
@ -606,14 +566,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential));
@ -673,14 +625,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential));
@ -745,14 +689,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential));
@ -842,14 +778,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential));
@ -916,14 +844,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential));
@ -969,14 +889,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential));
@ -1055,14 +967,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential));
@ -1116,10 +1020,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Introspection, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Confidential));
@ -1663,14 +1563,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.Password, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public));
@ -1772,14 +1664,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>()))
.ReturnsAsync(true); .ReturnsAsync(true);
@ -1837,14 +1721,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>()))
.ReturnsAsync(true); .ReturnsAsync(true);
@ -1916,14 +1792,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>()))
.ReturnsAsync(true); .ReturnsAsync(true);
@ -1997,14 +1865,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>()))
.ReturnsAsync(true); .ReturnsAsync(true);
@ -2063,14 +1923,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>()))
.ReturnsAsync(true); .ReturnsAsync(true);
@ -2354,14 +2206,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.Password, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public));

19
test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.Session.cs

@ -4,6 +4,7 @@
* the license and the contributors participating to this project. * the license and the contributors participating to this project.
*/ */
using System.Collections.Immutable;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -91,8 +92,8 @@ namespace OpenIddict.Server.Tests
// Arrange // Arrange
var manager = CreateApplicationManager(instance => var manager = CreateApplicationManager(instance =>
{ {
instance.Setup(mock => mock.ValidatePostLogoutRedirectUriAsync("http://www.fabrikam.com/path", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByPostLogoutRedirectUriAsync("http://www.fabrikam.com/path", It.IsAny<CancellationToken>()))
.ReturnsAsync(false); .ReturnsAsync(ImmutableArray.Create<OpenIddictApplication>());
}); });
var server = CreateAuthorizationServer(builder => var server = CreateAuthorizationServer(builder =>
@ -112,7 +113,7 @@ namespace OpenIddict.Server.Tests
Assert.Equal(OpenIdConnectConstants.Errors.InvalidRequest, response.Error); Assert.Equal(OpenIdConnectConstants.Errors.InvalidRequest, response.Error);
Assert.Equal("The specified 'post_logout_redirect_uri' parameter is not valid.", response.ErrorDescription); Assert.Equal("The specified 'post_logout_redirect_uri' parameter is not valid.", response.ErrorDescription);
Mock.Get(manager).Verify(mock => mock.ValidatePostLogoutRedirectUriAsync("http://www.fabrikam.com/path", It.IsAny<CancellationToken>()), Times.Once()); Mock.Get(manager).Verify(mock => mock.FindByPostLogoutRedirectUriAsync("http://www.fabrikam.com/path", It.IsAny<CancellationToken>()), Times.Once());
} }
[Fact] [Fact]
@ -126,8 +127,8 @@ namespace OpenIddict.Server.Tests
{ {
builder.Services.AddSingleton(CreateApplicationManager(instance => builder.Services.AddSingleton(CreateApplicationManager(instance =>
{ {
instance.Setup(mock => mock.ValidatePostLogoutRedirectUriAsync("http://www.fabrikam.com/path", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByPostLogoutRedirectUriAsync("http://www.fabrikam.com/path", It.IsAny<CancellationToken>()))
.ReturnsAsync(true); .ReturnsAsync(ImmutableArray.Create(new OpenIddictApplication()));
})); }));
builder.Services.AddSingleton(cache.Object); builder.Services.AddSingleton(cache.Object);
@ -168,8 +169,8 @@ namespace OpenIddict.Server.Tests
{ {
builder.Services.AddSingleton(CreateApplicationManager(instance => builder.Services.AddSingleton(CreateApplicationManager(instance =>
{ {
instance.Setup(mock => mock.ValidatePostLogoutRedirectUriAsync("http://www.fabrikam.com/path", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByPostLogoutRedirectUriAsync("http://www.fabrikam.com/path", It.IsAny<CancellationToken>()))
.ReturnsAsync(true); .ReturnsAsync(ImmutableArray.Create(new OpenIddictApplication()));
})); }));
}); });
@ -194,8 +195,8 @@ namespace OpenIddict.Server.Tests
{ {
builder.Services.AddSingleton(CreateApplicationManager(instance => builder.Services.AddSingleton(CreateApplicationManager(instance =>
{ {
instance.Setup(mock => mock.ValidatePostLogoutRedirectUriAsync("http://www.fabrikam.com/path", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByPostLogoutRedirectUriAsync("http://www.fabrikam.com/path", It.IsAny<CancellationToken>()))
.ReturnsAsync(false); .ReturnsAsync(ImmutableArray.Create(new OpenIddictApplication()));
})); }));
builder.EnableAuthorizationEndpoint("/logout-status-code-middleware"); builder.EnableAuthorizationEndpoint("/logout-status-code-middleware");

65
test/OpenIddict.Server.Tests/Internal/OpenIddictServerProviderTests.cs

@ -57,14 +57,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>()))
.ReturnsAsync(true); .ReturnsAsync(true);
@ -241,14 +233,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public));
})); }));
@ -440,14 +424,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public));
})); }));
@ -520,14 +496,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Token, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>())) instance.Setup(mock => mock.GetClientTypeAsync(application, It.IsAny<CancellationToken>()))
.Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public)); .Returns(new ValueTask<string>(OpenIddictConstants.ClientTypes.Public));
})); }));
@ -1159,14 +1127,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>()))
.ReturnsAsync(true); .ReturnsAsync(true);
@ -1231,14 +1191,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>()))
.ReturnsAsync(true); .ReturnsAsync(true);
@ -1292,14 +1244,6 @@ namespace OpenIddict.Server.Tests
instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny<CancellationToken>()))
.ReturnsAsync(application); .ReturnsAsync(application);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.Endpoints.Authorization, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.HasPermissionAsync(application,
OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode, It.IsAny<CancellationToken>()))
.ReturnsAsync(true);
instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.ValidateRedirectUriAsync(application, "http://www.fabrikam.com/path", It.IsAny<CancellationToken>()))
.ReturnsAsync(true); .ReturnsAsync(true);
@ -1398,8 +1342,8 @@ namespace OpenIddict.Server.Tests
{ {
builder.Services.AddSingleton(CreateApplicationManager(instance => builder.Services.AddSingleton(CreateApplicationManager(instance =>
{ {
instance.Setup(mock => mock.ValidatePostLogoutRedirectUriAsync("http://www.fabrikam.com/path", It.IsAny<CancellationToken>())) instance.Setup(mock => mock.FindByPostLogoutRedirectUriAsync("http://www.fabrikam.com/path", It.IsAny<CancellationToken>()))
.ReturnsAsync(true); .ReturnsAsync(ImmutableArray.Create(new OpenIddictApplication()));
})); }));
}); });
@ -1453,6 +1397,11 @@ namespace OpenIddict.Server.Tests
// Accept anonymous clients by default. // Accept anonymous clients by default.
options.AcceptAnonymousClients(); options.AcceptAnonymousClients();
// Disable permission enforcement by default.
options.IgnoreEndpointPermissions()
.IgnoreGrantTypePermissions()
.IgnoreScopePermissions();
// Disable the transport security requirement during testing. // Disable the transport security requirement during testing.
options.DisableHttpsRequirement(); options.DisableHttpsRequirement();

Loading…
Cancel
Save