diff --git a/.editorconfig b/.editorconfig index b78ba8ada..e02201537 100644 --- a/.editorconfig +++ b/.editorconfig @@ -95,10 +95,22 @@ csharp_using_directive_placement = outside_namespace [*.{cs,vb}] dotnet_code_quality_unused_parameters = all -dotnet_diagnostic.CA1510.severity = suggestion +dotnet_diagnostic.CA1510.severity = none +dotnet_diagnostic.CA1873.severity = none dotnet_diagnostic.CA2254.severity = none dotnet_diagnostic.IDE0002.severity = none +dotnet_diagnostic.IDE0042.severity = none dotnet_diagnostic.IDE0305.severity = none +dotnet_diagnostic.MA0003.severity = none +dotnet_diagnostic.MA0004.severity = none +dotnet_diagnostic.MA0007.severity = none +dotnet_diagnostic.MA0016.severity = none +dotnet_diagnostic.MA0029.severity = none +dotnet_diagnostic.MA0048.severity = none +dotnet_diagnostic.MA0051.severity = none +dotnet_diagnostic.MA0056.severity = none +dotnet_diagnostic.MA0084.severity = none +dotnet_diagnostic.MA0100.severity = none dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface diff --git a/Directory.Packages.props b/Directory.Packages.props index c0b25826e..02431b72d 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -4,17 +4,14 @@ Note: to cover as many platforms as possible and reduce the number of package references, OpenIddict extensively uses multi-targeting and per-framework package references. As such, package versions must be carefully chosen to ensure they are consistent and compatible with - the TFMs supported by OpenIddict (e.g for .NET 10, only Microsoft.AspNetCore.* packages within + the TFMs supported by OpenIddict (e.g for .NET 10, only Microsoft.Extensions.* packages within the [10.0.0,11.0.0) range are allowed). Special care must also be taken when selecting versions to ensure that transitive references also respect the same constraints (e.g for the .NET 10 TFM, a package must only depend on Microsoft.Extensions.* packages within the [10.0.0,11.0.0) range). --> - + diff --git a/gen/OpenIddict.Client.WebIntegration.Generators/OpenIddictClientWebIntegrationGenerator.cs b/gen/OpenIddict.Client.WebIntegration.Generators/OpenIddictClientWebIntegrationGenerator.cs index 379f1d6d7..757d3fd66 100644 --- a/gen/OpenIddict.Client.WebIntegration.Generators/OpenIddictClientWebIntegrationGenerator.cs +++ b/gen/OpenIddict.Client.WebIntegration.Generators/OpenIddictClientWebIntegrationGenerator.cs @@ -897,7 +897,7 @@ public static class ProviderTypes Name = (string) constant.Attribute("Name"), Value = (string) constant.Attribute("Value") }) - .GroupBy(static constant => constant.Class) + .GroupBy(static constant => constant.Class, StringComparer.Ordinal) .ToList(), }) .ToList() @@ -1600,7 +1600,7 @@ public sealed class {{ provider.name }} static TemplateContext CreateTemplateContext(object model) { - var context = new TemplateContext + var context = new TemplateContext(StringComparer.OrdinalIgnoreCase) { LimitToString = 128 * 1024 * 1024, LoopLimit = 100_000 diff --git a/sandbox/OpenIddict.Sandbox.AspNet.Client/Controllers/AuthenticationController.cs b/sandbox/OpenIddict.Sandbox.AspNet.Client/Controllers/AuthenticationController.cs index 01b3f3f6e..ba3ef7db2 100644 --- a/sandbox/OpenIddict.Sandbox.AspNet.Client/Controllers/AuthenticationController.cs +++ b/sandbox/OpenIddict.Sandbox.AspNet.Client/Controllers/AuthenticationController.cs @@ -31,7 +31,7 @@ public async Task LogIn(string provider, string returnUrl) // the user is directly redirected to GitHub (in this case, no login page is shown). if (string.Equals(provider, "Local+GitHub", StringComparison.Ordinal)) { - var properties = new AuthenticationProperties(new Dictionary + var properties = new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) { // Note: when only one client is registered in the client options, // specifying the issuer URI or the provider name is not required. @@ -61,7 +61,7 @@ public async Task LogIn(string provider, string returnUrl) return new HttpStatusCodeResult(400); } - var properties = new AuthenticationProperties(new Dictionary + var properties = new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) { // Note: when only one client is registered in the client options, // specifying the issuer URI or the provider name is not required. @@ -100,7 +100,7 @@ public async Task LogOut(string returnUrl) if (identity.FindFirst(Claims.Private.RegistrationId)?.Value is string identifier && await _service.GetServerConfigurationByRegistrationIdAsync(identifier) is { EndSessionEndpoint: Uri }) { - var properties = new AuthenticationProperties(new Dictionary + var properties = new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) { [OpenIddictClientOwinConstants.Properties.RegistrationId] = identifier, @@ -195,7 +195,7 @@ or Claims.Private.RegistrationId or Claims.Private.ProviderName OpenIddictClientOwinConstants.Tokens.BackchannelAccessToken or OpenIddictClientOwinConstants.Tokens.BackchannelIdentityToken or OpenIddictClientOwinConstants.Tokens.RefreshToken) - .ToDictionary(pair => pair.Key, pair => pair.Value)) + .ToDictionary(pair => pair.Key, pair => pair.Value, StringComparer.Ordinal)) { // Set the creation and expiration dates of the ticket to null to decorrelate the lifetime // of the resulting authentication cookie from the lifetime of the identity token returned by diff --git a/sandbox/OpenIddict.Sandbox.AspNet.Server/Controllers/AuthenticationController.cs b/sandbox/OpenIddict.Sandbox.AspNet.Server/Controllers/AuthenticationController.cs index c512e6744..10503cf5b 100644 --- a/sandbox/OpenIddict.Sandbox.AspNet.Server/Controllers/AuthenticationController.cs +++ b/sandbox/OpenIddict.Sandbox.AspNet.Server/Controllers/AuthenticationController.cs @@ -86,7 +86,7 @@ or Claims.Private.RegistrationId or Claims.Private.ProviderName // If needed, the tokens returned by the authorization server can be stored in the authentication cookie. OpenIddictClientOwinConstants.Tokens.BackchannelAccessToken or OpenIddictClientOwinConstants.Tokens.RefreshToken) - .ToDictionary(pair => pair.Key, pair => pair.Value)) + .ToDictionary(pair => pair.Key, pair => pair.Value, StringComparer.Ordinal)) { // Set the creation and expiration dates of the ticket to null to decorrelate the lifetime // of the resulting authentication cookie from the lifetime of the identity token returned by diff --git a/sandbox/OpenIddict.Sandbox.AspNet.Server/Controllers/AuthorizationController.cs b/sandbox/OpenIddict.Sandbox.AspNet.Server/Controllers/AuthorizationController.cs index 7f31fdcfc..20be17f6e 100644 --- a/sandbox/OpenIddict.Sandbox.AspNet.Server/Controllers/AuthorizationController.cs +++ b/sandbox/OpenIddict.Sandbox.AspNet.Server/Controllers/AuthorizationController.cs @@ -92,7 +92,7 @@ public async Task Authorize() { context.Authentication.Challenge( authenticationTypes: OpenIddictServerOwinDefaults.AuthenticationType, - properties: new AuthenticationProperties(new Dictionary + properties: new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) { [OpenIddictServerOwinConstants.Properties.Error] = Errors.InvalidRequest, [OpenIddictServerOwinConstants.Properties.ErrorDescription] = @@ -102,7 +102,7 @@ public async Task Authorize() return new EmptyResult(); } - var properties = new AuthenticationProperties(new Dictionary + var properties = new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) { // Note: when only one client is registered in the client options, // specifying the issuer URI or the provider name is not required. @@ -154,7 +154,7 @@ public async Task Authorize() case ConsentTypes.External when authorizations.Count is 0: context.Authentication.Challenge( authenticationTypes: OpenIddictServerOwinDefaults.AuthenticationType, - properties: new AuthenticationProperties(new Dictionary + properties: new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) { [OpenIddictServerOwinConstants.Properties.Error] = Errors.ConsentRequired, [OpenIddictServerOwinConstants.Properties.ErrorDescription] = @@ -231,7 +231,7 @@ public async Task Authorize() case ConsentTypes.Systematic when request.HasPromptValue(PromptValues.None): context.Authentication.Challenge( authenticationTypes: OpenIddictServerOwinDefaults.AuthenticationType, - properties: new AuthenticationProperties(new Dictionary + properties: new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) { [OpenIddictServerOwinConstants.Properties.Error] = Errors.ConsentRequired, [OpenIddictServerOwinConstants.Properties.ErrorDescription] = @@ -277,7 +277,7 @@ public async Task Accept() { context.Authentication.Challenge( authenticationTypes: OpenIddictServerOwinDefaults.AuthenticationType, - properties: new AuthenticationProperties(new Dictionary + properties: new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) { [OpenIddictServerOwinConstants.Properties.Error] = Errors.LoginRequired, [OpenIddictServerOwinConstants.Properties.ErrorDescription] = @@ -307,7 +307,7 @@ public async Task Accept() { context.Authentication.Challenge( authenticationTypes: OpenIddictServerOwinDefaults.AuthenticationType, - properties: new AuthenticationProperties(new Dictionary + properties: new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) { [OpenIddictServerOwinConstants.Properties.Error] = Errors.ConsentRequired, [OpenIddictServerOwinConstants.Properties.ErrorDescription] = @@ -425,7 +425,7 @@ public async Task Exchange() { context.Authentication.Challenge( authenticationTypes: OpenIddictServerOwinDefaults.AuthenticationType, - properties: new AuthenticationProperties(new Dictionary + properties: new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) { [OpenIddictServerOwinConstants.Properties.Error] = Errors.InvalidGrant, [OpenIddictServerOwinConstants.Properties.ErrorDescription] = "The token is no longer valid." @@ -439,7 +439,7 @@ public async Task Exchange() { context.Authentication.Challenge( authenticationTypes: OpenIddictServerOwinDefaults.AuthenticationType, - properties: new AuthenticationProperties(new Dictionary + properties: new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) { [OpenIddictServerOwinConstants.Properties.Error] = Errors.InvalidGrant, [OpenIddictServerOwinConstants.Properties.ErrorDescription] = "The user is no longer allowed to sign in." diff --git a/sandbox/OpenIddict.Sandbox.AspNet.Server/Controllers/ManageController.cs b/sandbox/OpenIddict.Sandbox.AspNet.Server/Controllers/ManageController.cs index d375429b6..e442c27dc 100644 --- a/sandbox/OpenIddict.Sandbox.AspNet.Server/Controllers/ManageController.cs +++ b/sandbox/OpenIddict.Sandbox.AspNet.Server/Controllers/ManageController.cs @@ -289,7 +289,7 @@ public async Task ManageLogins(ManageMessageId? message) return View("Error"); } var userLogins = await UserManager.GetLoginsAsync(User.Identity.GetUserId()); - var otherLogins = AuthenticationManager.GetExternalAuthenticationTypes().Where(auth => userLogins.All(ul => auth.AuthenticationType != ul.LoginProvider)).ToList(); + var otherLogins = AuthenticationManager.GetExternalAuthenticationTypes().Where(auth => userLogins.All(ul => !string.Equals(auth.AuthenticationType, ul.LoginProvider, System.StringComparison.Ordinal))).ToList(); ViewBag.ShowRemoveButton = user.PasswordHash != null || userLogins.Count > 1; return View(new ManageLoginsViewModel { diff --git a/sandbox/OpenIddict.Sandbox.AspNet.Server/Controllers/ResourceController.cs b/sandbox/OpenIddict.Sandbox.AspNet.Server/Controllers/ResourceController.cs index 98968c5bd..7e551af19 100644 --- a/sandbox/OpenIddict.Sandbox.AspNet.Server/Controllers/ResourceController.cs +++ b/sandbox/OpenIddict.Sandbox.AspNet.Server/Controllers/ResourceController.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Net; using System.Net.Http; using System.Security.Claims; @@ -27,7 +28,7 @@ public async Task GetMessage() { context.Authentication.Challenge( authenticationTypes: OpenIddictValidationOwinDefaults.AuthenticationType, - properties: new AuthenticationProperties(new Dictionary + properties: new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) { [OpenIddictValidationOwinConstants.Properties.Scope] = "demo_api", [OpenIddictValidationOwinConstants.Properties.Error] = Errors.InsufficientScope, @@ -43,7 +44,7 @@ public async Task GetMessage() { context.Authentication.Challenge( authenticationTypes: OpenIddictValidationOwinDefaults.AuthenticationType, - properties: new AuthenticationProperties(new Dictionary + properties: new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) { [OpenIddictValidationOwinConstants.Properties.Error] = Errors.InvalidToken, [OpenIddictValidationOwinConstants.Properties.ErrorDescription] = diff --git a/sandbox/OpenIddict.Sandbox.AspNetCore.Client/Controllers/AuthenticationController.cs b/sandbox/OpenIddict.Sandbox.AspNetCore.Client/Controllers/AuthenticationController.cs index 91491bb54..e8b965062 100644 --- a/sandbox/OpenIddict.Sandbox.AspNetCore.Client/Controllers/AuthenticationController.cs +++ b/sandbox/OpenIddict.Sandbox.AspNetCore.Client/Controllers/AuthenticationController.cs @@ -24,7 +24,7 @@ public async Task LogIn(string provider, string returnUrl) // the user is directly redirected to GitHub (in this case, no login page is shown). if (string.Equals(provider, "Local+GitHub", StringComparison.Ordinal)) { - var properties = new AuthenticationProperties(new Dictionary + var properties = new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) { // Note: when only one client is registered in the client options, // specifying the issuer URI or the provider name is not required. @@ -54,7 +54,7 @@ public async Task LogIn(string provider, string returnUrl) return BadRequest(); } - var properties = new AuthenticationProperties(new Dictionary + var properties = new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) { // Note: when only one client is registered in the client options, // specifying the issuer URI or the provider name is not required. @@ -96,7 +96,7 @@ public async Task LogOut(string returnUrl) if (identity.FindFirst(Claims.Private.RegistrationId)?.Value is string identifier && await _service.GetServerConfigurationByRegistrationIdAsync(identifier) is { EndSessionEndpoint: Uri }) { - var properties = new AuthenticationProperties(new Dictionary + var properties = new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) { [OpenIddictClientAspNetCoreConstants.Properties.RegistrationId] = identifier, diff --git a/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/AccountController.cs b/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/AccountController.cs index 18f10aecf..a4f91562c 100644 --- a/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/AccountController.cs +++ b/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/AccountController.cs @@ -71,11 +71,9 @@ public async Task Login(LoginViewModel model, string returnUrl = { return View("Lockout"); } - else - { - ModelState.AddModelError(string.Empty, "Invalid login attempt."); - return View(model); - } + + ModelState.AddModelError(string.Empty, "Invalid login attempt."); + return View(model); } // If we got this far, something failed, redisplay form @@ -173,14 +171,12 @@ public async Task ExternalLoginCallback(string returnUrl = null) { return View("Lockout"); } - else - { - // If the user does not have an account, then ask the user to create an account. - ViewData["ReturnUrl"] = returnUrl; - ViewData["LoginProvider"] = info.LoginProvider; - var email = info.Principal.FindFirstValue(ClaimTypes.Email); - return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { Email = email }); - } + + // If the user does not have an account, then ask the user to create an account. + ViewData["ReturnUrl"] = returnUrl; + ViewData["LoginProvider"] = info.LoginProvider; + var email = info.Principal.FindFirstValue(ClaimTypes.Email); + return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { Email = email }); } // @@ -367,11 +363,11 @@ public async Task SendCode(SendCodeViewModel model) } var message = "Your security code is: " + code; - if (model.SelectedProvider == "Email") + if (string.Equals(model.SelectedProvider, "Email", StringComparison.Ordinal)) { await _emailSender.SendEmailAsync(await _userManager.GetEmailAsync(user), "Security Code", message); } - else if (model.SelectedProvider == "Phone") + else if (string.Equals(model.SelectedProvider, "Phone", StringComparison.Ordinal)) { await _smsSender.SendSmsAsync(await _userManager.GetPhoneNumberAsync(user), message); } @@ -418,11 +414,9 @@ public async Task VerifyCode(VerifyCodeViewModel model) { return View("Lockout"); } - else - { - ModelState.AddModelError("", "Invalid code."); - return View(model); - } + + ModelState.AddModelError("", "Invalid code."); + return View(model); } #region Helpers @@ -460,10 +454,8 @@ private IActionResult RedirectToLocal(string returnUrl) { return Redirect(returnUrl); } - else - { - return RedirectToAction(nameof(HomeController.Index), "Home"); - } + + return RedirectToAction(nameof(HomeController.Index), "Home"); } #endregion diff --git a/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/AuthorizationController.cs b/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/AuthorizationController.cs index ef32ad5e6..c03472615 100644 --- a/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/AuthorizationController.cs +++ b/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/AuthorizationController.cs @@ -4,6 +4,7 @@ * the license and the contributors participating to this project. */ +using System.Globalization; using System.Security.Claims; using System.Text.Json.Nodes; using Microsoft.AspNetCore; @@ -91,7 +92,7 @@ public async Task Authorize() { return Forbid( authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, - properties: new AuthenticationProperties(new Dictionary + properties: new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) { [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.LoginRequired, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "The user is not logged in." @@ -117,7 +118,7 @@ public async Task Authorize() { return Forbid( authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, - properties: new AuthenticationProperties(new Dictionary + properties: new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) { [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.InvalidRequest, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = @@ -181,7 +182,7 @@ public async Task Authorize() case ConsentTypes.External when authorizations.Count is 0: return Forbid( authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, - properties: new AuthenticationProperties(new Dictionary + properties: new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) { [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.ConsentRequired, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = @@ -255,7 +256,7 @@ public async Task Authorize() case ConsentTypes.Systematic when request.HasPromptValue(PromptValues.None): return Forbid( authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, - properties: new AuthenticationProperties(new Dictionary + properties: new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) { [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.ConsentRequired, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = @@ -265,7 +266,7 @@ public async Task Authorize() // In every other case, render the consent form. default: return View(new AuthorizeViewModel { - ApplicationName = await _applicationManager.GetLocalizedDisplayNameAsync(application), + ApplicationName = await _applicationManager.GetLocalizedDisplayNameAsync(application, CultureInfo.CurrentCulture), Scope = request.Scope }); } @@ -289,7 +290,7 @@ public async Task Accept() { return Forbid( authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, - properties: new AuthenticationProperties(new Dictionary + properties: new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) { [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.LoginRequired, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = @@ -317,7 +318,7 @@ public async Task Accept() { return Forbid( authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, - properties: new AuthenticationProperties(new Dictionary + properties: new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) { [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.ConsentRequired, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = @@ -406,15 +407,13 @@ public async Task Verify() // Render a form asking the user to confirm the authorization demand. return View(new VerifyViewModel { - ApplicationName = await _applicationManager.GetLocalizedDisplayNameAsync(application), - Scope = string.Join(" ", result.Principal.GetScopes()), + ApplicationName = await _applicationManager.GetLocalizedDisplayNameAsync(application, CultureInfo.CurrentCulture), + Scope = string.Join(Separators.Space[0], result.Principal.GetScopes()), UserCode = result.Properties.GetTokenValue(OpenIddictServerAspNetCoreConstants.Tokens.UserCode) }); } - // If a user code was specified (e.g as part of the verification_uri_complete) - // but is not valid, render a form asking the user to enter the user code manually. - else if (!string.IsNullOrEmpty(result.Properties?.GetTokenValue(OpenIddictServerAspNetCoreConstants.Tokens.UserCode))) + if (!string.IsNullOrEmpty(result.Properties?.GetTokenValue(OpenIddictServerAspNetCoreConstants.Tokens.UserCode))) { return View(new VerifyViewModel { @@ -437,7 +436,7 @@ public async Task VerifyAccept() { return Forbid( authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, - properties: new AuthenticationProperties(new Dictionary + properties: new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) { [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.LoginRequired, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = @@ -544,7 +543,7 @@ public async Task Exchange() { return Forbid( authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, - properties: new AuthenticationProperties(new Dictionary + properties: new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) { [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.InvalidGrant, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "The username/password couple is invalid." @@ -557,7 +556,7 @@ public async Task Exchange() { return Forbid( authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, - properties: new AuthenticationProperties(new Dictionary + properties: new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) { [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.InvalidGrant, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "The username/password couple is invalid." @@ -599,7 +598,7 @@ public async Task Exchange() { return Forbid( authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, - properties: new AuthenticationProperties(new Dictionary + properties: new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) { [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.InvalidGrant, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "The token is no longer valid." @@ -611,7 +610,7 @@ public async Task Exchange() { return Forbid( authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, - properties: new AuthenticationProperties(new Dictionary + properties: new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) { [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.InvalidGrant, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "The user is no longer allowed to sign in." @@ -657,7 +656,7 @@ public async Task Exchange() { return Forbid( authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, - properties: new AuthenticationProperties(new Dictionary + properties: new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) { [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.InvalidGrant, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "The token is no longer valid." @@ -669,7 +668,7 @@ public async Task Exchange() { return Forbid( authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, - properties: new AuthenticationProperties(new Dictionary + properties: new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) { [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.InvalidGrant, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "The user is no longer allowed to sign in." diff --git a/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/ManageController.cs b/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/ManageController.cs index 859db0e29..13771b634 100644 --- a/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/ManageController.cs +++ b/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/ManageController.cs @@ -271,7 +271,7 @@ public async Task ManageLogins(ManageMessageId? message = null) return View("Error"); } var userLogins = await _userManager.GetLoginsAsync(user); - var otherLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).Where(auth => userLogins.All(ul => auth.Name != ul.LoginProvider)).ToList(); + var otherLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).Where(auth => userLogins.All(ul => !string.Equals(auth.Name, ul.LoginProvider, StringComparison.Ordinal))).ToList(); ViewData["ShowRemoveButton"] = user.PasswordHash is not null || userLogins.Count > 1; return View(new ManageLoginsViewModel { diff --git a/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/ResourceController.cs b/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/ResourceController.cs index c044dd99d..f461386fe 100644 --- a/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/ResourceController.cs +++ b/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/ResourceController.cs @@ -28,7 +28,7 @@ public async Task GetMessage() { return Forbid( authenticationSchemes: OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme, - properties: new AuthenticationProperties(new Dictionary + properties: new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) { [OpenIddictValidationAspNetCoreConstants.Properties.Scope] = "demo_api", [OpenIddictValidationAspNetCoreConstants.Properties.Error] = Errors.InsufficientScope, @@ -42,7 +42,7 @@ public async Task GetMessage() { return Challenge( authenticationSchemes: OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme, - properties: new AuthenticationProperties(new Dictionary + properties: new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) { [OpenIddictValidationAspNetCoreConstants.Properties.Error] = Errors.InvalidToken, [OpenIddictValidationAspNetCoreConstants.Properties.ErrorDescription] = diff --git a/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/UserinfoController.cs b/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/UserinfoController.cs index 63447c085..1470adbc4 100644 --- a/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/UserinfoController.cs +++ b/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Controllers/UserinfoController.cs @@ -26,7 +26,7 @@ public async Task UserInfo() { return Challenge( authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme, - properties: new AuthenticationProperties(new Dictionary + properties: new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) { [OpenIddictServerAspNetCoreConstants.Properties.Error] = Errors.InvalidToken, [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = diff --git a/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Program.cs b/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Program.cs index baf9e5a19..80e5f2cfe 100644 --- a/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Program.cs +++ b/sandbox/OpenIddict.Sandbox.AspNetCore.Server/Program.cs @@ -370,8 +370,8 @@ static ValueTask GetServerAuthenticationOptionsA ServerCertificate = store.Certificates .Find(X509FindType.FindByExtension, "1.3.6.1.4.1.311.84.1.1", validOnly: false) .Cast() - .Where(static certificate => certificate.NotBefore < TimeProvider.System.GetLocalNow()) - .Where(static certificate => certificate.NotAfter > TimeProvider.System.GetLocalNow()) + .Where(static certificate => new DateTimeOffset(certificate.NotBefore) < TimeProvider.System.GetLocalNow()) + .Where(static certificate => new DateTimeOffset(certificate.NotAfter) > TimeProvider.System.GetLocalNow()) .OrderByDescending(static certificate => certificate.NotAfter) .FirstOrDefault() ?? throw new InvalidOperationException("The ASP.NET Core HTTPS development certificate was not found.") diff --git a/sandbox/OpenIddict.Sandbox.Console.Client/InteractiveService.cs b/sandbox/OpenIddict.Sandbox.Console.Client/InteractiveService.cs index b96d123a8..479ee652f 100644 --- a/sandbox/OpenIddict.Sandbox.Console.Client/InteractiveService.cs +++ b/sandbox/OpenIddict.Sandbox.Console.Client/InteractiveService.cs @@ -502,13 +502,13 @@ async Task PromptAsync() => AnsiConsole.Prompt(new SelectionPrompt choices = []; var types = configuration.ResponseTypesSupported.Select(static type => - new HashSet(type.Split(Separators.Space, StringSplitOptions.RemoveEmptyEntries))); + new HashSet(type.Split(Separators.Space, StringSplitOptions.RemoveEmptyEntries), StringComparer.Ordinal)); if (configuration.GrantTypesSupported.Contains(GrantTypes.AuthorizationCode) && (registration.GrantTypes.Count is 0 || registration.GrantTypes.Contains(GrantTypes.AuthorizationCode)) && types.Any(static type => type.Count is 1 && type.Contains(ResponseTypes.Code)) && (registration.ResponseTypes.Count is 0 || registration.ResponseTypes - .Select(static type => new HashSet(type.Split(Separators.Space, StringSplitOptions.RemoveEmptyEntries))) + .Select(static type => new HashSet(type.Split(Separators.Space, StringSplitOptions.RemoveEmptyEntries), StringComparer.Ordinal)) .Any(static type => type.Count is 1 && type.Contains(ResponseTypes.Code)))) { choices.Add((( @@ -521,7 +521,7 @@ async Task PromptAsync() => AnsiConsole.Prompt(new SelectionPrompt type.Count is 1 && type.Contains(ResponseTypes.IdToken)) && (registration.ResponseTypes.Count is 0 || registration.ResponseTypes - .Select(static type => new HashSet(type.Split(Separators.Space, StringSplitOptions.RemoveEmptyEntries))) + .Select(static type => new HashSet(type.Split(Separators.Space, StringSplitOptions.RemoveEmptyEntries), StringComparer.Ordinal)) .Any(static type => type.Count is 1 && type.Contains(ResponseTypes.IdToken)))) { choices.Add((( @@ -532,7 +532,7 @@ async Task PromptAsync() => AnsiConsole.Prompt(new SelectionPrompt type.Count is 2 && type.Contains(ResponseTypes.IdToken) && type.Contains(ResponseTypes.Token)) && (registration.ResponseTypes.Count is 0 || registration.ResponseTypes - .Select(static type => new HashSet(type.Split(Separators.Space, StringSplitOptions.RemoveEmptyEntries))) + .Select(static type => new HashSet(type.Split(Separators.Space, StringSplitOptions.RemoveEmptyEntries), StringComparer.Ordinal)) .Any(static type => type.Count is 2 && type.Contains(ResponseTypes.IdToken) && type.Contains(ResponseTypes.Token)))) { @@ -550,7 +550,7 @@ async Task PromptAsync() => AnsiConsole.Prompt(new SelectionPrompt type.Count is 2 && type.Contains(ResponseTypes.Code) && type.Contains(ResponseTypes.IdToken)) && (registration.ResponseTypes.Count is 0 || registration.ResponseTypes - .Select(static type => new HashSet(type.Split(Separators.Space, StringSplitOptions.RemoveEmptyEntries))) + .Select(static type => new HashSet(type.Split(Separators.Space, StringSplitOptions.RemoveEmptyEntries), StringComparer.Ordinal)) .Any(static type => type.Count is 2 && type.Contains(ResponseTypes.Code) && type.Contains(ResponseTypes.IdToken)))) { @@ -563,7 +563,7 @@ async Task PromptAsync() => AnsiConsole.Prompt(new SelectionPrompt new HashSet(type.Split(Separators.Space, StringSplitOptions.RemoveEmptyEntries))) + .Select(static type => new HashSet(type.Split(Separators.Space, StringSplitOptions.RemoveEmptyEntries), StringComparer.Ordinal)) .Any(static type => type.Count is 3 && type.Contains(ResponseTypes.Code) && type.Contains(ResponseTypes.IdToken) && type.Contains(ResponseTypes.Token)))) @@ -577,7 +577,7 @@ async Task PromptAsync() => AnsiConsole.Prompt(new SelectionPrompt type.Count is 2 && type.Contains(ResponseTypes.Code) && type.Contains(ResponseTypes.Token)) && (registration.ResponseTypes.Count is 0 || registration.ResponseTypes - .Select(static type => new HashSet(type.Split(Separators.Space, StringSplitOptions.RemoveEmptyEntries))) + .Select(static type => new HashSet(type.Split(Separators.Space, StringSplitOptions.RemoveEmptyEntries), StringComparer.Ordinal)) .Any(static type => type.Count is 2 && type.Contains(ResponseTypes.Code) && type.Contains(ResponseTypes.Token)))) { @@ -589,7 +589,7 @@ async Task PromptAsync() => AnsiConsole.Prompt(new SelectionPrompt type.Count is 1 && type.Contains(ResponseTypes.None)) && (registration.ResponseTypes.Count is 0 || registration.ResponseTypes - .Select(static type => new HashSet(type.Split(Separators.Space, StringSplitOptions.RemoveEmptyEntries))) + .Select(static type => new HashSet(type.Split(Separators.Space, StringSplitOptions.RemoveEmptyEntries), StringComparer.Ordinal)) .Any(static type => type.Count is 1 && type.Contains(ResponseTypes.None)))) { choices.Add((( @@ -873,7 +873,9 @@ static X509Certificate2 GenerateEphemeralTlsClientCertificate() // // In a real world application, the certificate wouldn't be embedded in the source code // and would be installed in the certificate store, making this workaround unnecessary. +#pragma warning disable MA0144 if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) +#pragma warning restore MA0144 { certificate = X509CertificateLoader.LoadPkcs12( data: certificate.Export(X509ContentType.Pfx, string.Empty), diff --git a/sandbox/OpenIddict.Sandbox.Maui.Client/MainPage.xaml.cs b/sandbox/OpenIddict.Sandbox.Maui.Client/MainPage.xaml.cs index 311145222..5c11bc794 100644 --- a/sandbox/OpenIddict.Sandbox.Maui.Client/MainPage.xaml.cs +++ b/sandbox/OpenIddict.Sandbox.Maui.Client/MainPage.xaml.cs @@ -22,7 +22,7 @@ private async void OnLocalLoginButtonClicked(object sender, EventArgs e) => await LogInAsync("Local"); private async void OnLocalLoginWithGitHubButtonClicked(object sender, EventArgs e) - => await LogInAsync("Local", new() + => await LogInAsync("Local", new(StringComparer.Ordinal) { [Parameters.IdentityProvider] = Providers.GitHub }); diff --git a/sandbox/OpenIddict.Sandbox.Maui.Client/MauiProgram.cs b/sandbox/OpenIddict.Sandbox.Maui.Client/MauiProgram.cs index d15264940..b160b43a8 100644 --- a/sandbox/OpenIddict.Sandbox.Maui.Client/MauiProgram.cs +++ b/sandbox/OpenIddict.Sandbox.Maui.Client/MauiProgram.cs @@ -57,8 +57,10 @@ public static MauiApp CreateMauiApp() #if IOS // Warning: server certificate validation is disabled to simplify testing the MAUI // application with the iOS simulator: in production, it SHOULD NEVER be disabled. +#pragma warning disable MA0039 .ConfigureHttpClientHandler("Local", handler => handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator) +#pragma warning restore MA0039 #endif ; diff --git a/sandbox/OpenIddict.Sandbox.WinForms.Client/MainForm.cs b/sandbox/OpenIddict.Sandbox.WinForms.Client/MainForm.cs index 9aaf0f287..2590205b3 100644 --- a/sandbox/OpenIddict.Sandbox.WinForms.Client/MainForm.cs +++ b/sandbox/OpenIddict.Sandbox.WinForms.Client/MainForm.cs @@ -22,7 +22,7 @@ private async void LocalLoginButton_Click(object sender, EventArgs e) => await LogInAsync("Local"); private async void LocalLoginWithGitHubButton_Click(object sender, EventArgs e) - => await LogInAsync("Local", new() + => await LogInAsync("Local", new(StringComparer.Ordinal) { [Parameters.IdentityProvider] = Providers.GitHub }); diff --git a/sandbox/OpenIddict.Sandbox.Wpf.Client/MainWindow.xaml.cs b/sandbox/OpenIddict.Sandbox.Wpf.Client/MainWindow.xaml.cs index ff916a8f8..5e28d59e6 100644 --- a/sandbox/OpenIddict.Sandbox.Wpf.Client/MainWindow.xaml.cs +++ b/sandbox/OpenIddict.Sandbox.Wpf.Client/MainWindow.xaml.cs @@ -23,7 +23,7 @@ private async void LocalLoginButton_Click(object sender, RoutedEventArgs e) => await LogInAsync("Local"); private async void LocalLoginWithGitHubButton_Click(object sender, RoutedEventArgs e) - => await LogInAsync("Local", new() + => await LogInAsync("Local", new(StringComparer.Ordinal) { [Parameters.IdentityProvider] = Providers.GitHub }); diff --git a/shared/OpenIddict.Extensions/OpenIddictHelpers.cs b/shared/OpenIddict.Extensions/OpenIddictHelpers.cs index f7dd1287a..9bacb8511 100644 --- a/shared/OpenIddict.Extensions/OpenIddictHelpers.cs +++ b/shared/OpenIddict.Extensions/OpenIddictHelpers.cs @@ -276,8 +276,8 @@ public static IReadOnlyDictionary ParseQuery(string query) Key: parts[0] is string key ? Uri.UnescapeDataString(key) : null, Value: parts.Length is > 1 && parts[1] is string value ? Uri.UnescapeDataString(value) : null)) .Where(static pair => !string.IsNullOrEmpty(pair.Key)) - .GroupBy(static pair => pair.Key) - .ToDictionary(static pair => pair.Key!, static pair => new StringValues([.. pair.Select(parts => parts.Value)])); + .GroupBy(static pair => pair.Key, StringComparer.Ordinal) + .ToDictionary(static pair => pair.Key!, static pair => new StringValues([.. pair.Select(parts => parts.Value)]), StringComparer.Ordinal); } /// @@ -297,8 +297,8 @@ public static IReadOnlyDictionary ParseFragment(string fra Key: parts[0] is string key ? Uri.UnescapeDataString(key) : null, Value: parts.Length is > 1 && parts[1] is string value ? Uri.UnescapeDataString(value) : null)) .Where(static pair => !string.IsNullOrEmpty(pair.Key)) - .GroupBy(static pair => pair.Key) - .ToDictionary(static pair => pair.Key!, static pair => new StringValues([.. pair.Select(parts => parts.Value)])); + .GroupBy(static pair => pair.Key, StringComparer.Ordinal) + .ToDictionary(static pair => pair.Key!, static pair => new StringValues([.. pair.Select(parts => parts.Value)]), StringComparer.Ordinal); } /// @@ -345,7 +345,7 @@ public static async ValueTask> ParseFo while (enumerator.MoveNext()) { var element = enumerator.GetTextElement(); - if (charset.Contains(element)) + if (charset.Contains(element, StringComparer.Ordinal)) { builder.Append(element); } diff --git a/src/OpenIddict.Abstractions/OpenIddictConstants.cs b/src/OpenIddict.Abstractions/OpenIddictConstants.cs index cbc3369ef..b297b1373 100644 --- a/src/OpenIddict.Abstractions/OpenIddictConstants.cs +++ b/src/OpenIddict.Abstractions/OpenIddictConstants.cs @@ -560,6 +560,7 @@ public static class Separators public static readonly char[] DoubleQuote = ['"']; public static readonly char[] EqualsSign = ['=']; public static readonly char[] Hash = ['#']; + public static readonly char[] Plus = ['+']; public static readonly char[] QuestionMark = ['?']; public static readonly char[] Semicolon = [';']; public static readonly char[] Space = [' ']; diff --git a/src/OpenIddict.Abstractions/Primitives/OpenIddictExtensions.cs b/src/OpenIddict.Abstractions/Primitives/OpenIddictExtensions.cs index 556456381..94ee1b264 100644 --- a/src/OpenIddict.Abstractions/Primitives/OpenIddictExtensions.cs +++ b/src/OpenIddict.Abstractions/Primitives/OpenIddictExtensions.cs @@ -308,9 +308,7 @@ public static bool IsImplicitFlow(this OpenIddictRequest request) continue; } - // Note: though the OIDC core specs does not include the OAuth 2.0-inherited response_type=token, - // it is considered as a valid response_type for the implicit flow for backward compatibility. - else if (segment.Equals(ResponseTypes.Token, StringComparison.Ordinal)) + if (segment.Equals(ResponseTypes.Token, StringComparison.Ordinal)) { flags |= /* token */ 0x02; @@ -359,14 +357,14 @@ public static bool IsHybridFlow(this OpenIddictRequest request) continue; } - else if (segment.Equals(ResponseTypes.IdToken, StringComparison.Ordinal)) + if (segment.Equals(ResponseTypes.IdToken, StringComparison.Ordinal)) { flags |= /* id_token: */ 0x02; continue; } - else if (segment.Equals(ResponseTypes.Token, StringComparison.Ordinal)) + if (segment.Equals(ResponseTypes.Token, StringComparison.Ordinal)) { flags |= /* token: */ 0x04; @@ -678,7 +676,7 @@ public static ImmutableDictionary> GetDestination var builder = ImmutableDictionary.CreateBuilder>(StringComparer.Ordinal); - foreach (var group in identity.Claims.GroupBy(claim => claim.Type)) + foreach (var group in identity.Claims.GroupBy(claim => claim.Type, StringComparer.Ordinal)) { var claims = group.ToList(); @@ -712,7 +710,7 @@ public static ImmutableDictionary> GetDestination var builder = ImmutableDictionary.CreateBuilder>(StringComparer.Ordinal); - foreach (var group in principal.Claims.GroupBy(claim => claim.Type)) + foreach (var group in principal.Claims.GroupBy(claim => claim.Type, StringComparer.Ordinal)) { var claims = group.ToList(); @@ -749,7 +747,8 @@ public static ClaimsIdentity SetDestinations(this ClaimsIdentity identity, foreach (var destination in destinations) { - foreach (var claim in identity.Claims.Where(claim => claim.Type == destination.Key)) + foreach (var claim in identity.Claims.Where(claim => + string.Equals(claim.Type, destination.Key, StringComparison.Ordinal))) { claim.SetDestinations(destination.Value); } @@ -772,7 +771,8 @@ public static ClaimsPrincipal SetDestinations(this ClaimsPrincipal principal, foreach (var destination in destinations) { - foreach (var claim in principal.Claims.Where(claim => claim.Type == destination.Key)) + foreach (var claim in principal.Claims.Where(claim => + string.Equals(claim.Type, destination.Key, StringComparison.Ordinal))) { claim.SetDestinations(destination.Value); } diff --git a/src/OpenIddict.Abstractions/Primitives/OpenIddictMessage.cs b/src/OpenIddict.Abstractions/Primitives/OpenIddictMessage.cs index d0456b708..90ebbf84f 100644 --- a/src/OpenIddict.Abstractions/Primitives/OpenIddictMessage.cs +++ b/src/OpenIddict.Abstractions/Primitives/OpenIddictMessage.cs @@ -121,7 +121,7 @@ public OpenIddictMessage(IEnumerable> parameters) { ArgumentNullException.ThrowIfNull(parameters); - foreach (var parameter in parameters.GroupBy(parameter => parameter.Key)) + foreach (var parameter in parameters.GroupBy(parameter => parameter.Key, StringComparer.Ordinal)) { // Ignore parameters whose name is null or empty. if (string.IsNullOrEmpty(parameter.Key)) diff --git a/src/OpenIddict.Abstractions/Primitives/OpenIddictParameter.cs b/src/OpenIddict.Abstractions/Primitives/OpenIddictParameter.cs index f578d4961..fa5289989 100644 --- a/src/OpenIddict.Abstractions/Primitives/OpenIddictParameter.cs +++ b/src/OpenIddict.Abstractions/Primitives/OpenIddictParameter.cs @@ -205,7 +205,7 @@ public bool Equals(OpenIddictParameter other) (string left, string right) => string.Equals(left, right, StringComparison.Ordinal), // If the two parameters are string arrays, use SequenceEqual(). - (string?[] left, string?[] right) => Enumerable.SequenceEqual(left, right), + (string?[] left, string?[] right) => Enumerable.SequenceEqual(left, right, StringComparer.Ordinal), // If one of the two parameters is an undefined JsonElement, treat it // as a null value and return true if the other parameter is null too. @@ -323,7 +323,7 @@ JsonValue value when value.TryGetValue(out bool result) => result.GetHashCode(), JsonValue value when value.TryGetValue(out int result) => result.GetHashCode(), JsonValue value when value.TryGetValue(out long result) => result.GetHashCode(), - JsonValue value when value.TryGetValue(out string? result) => result.GetHashCode(), + JsonValue value when value.TryGetValue(out string? result) => result.GetHashCode(StringComparison.Ordinal), // When the parameter is a JsonNode (e.g a JsonValue wrapping a non-primitive type), // serialize it to a JsonElement first to determine its actual JSON representation @@ -342,7 +342,7 @@ static int GetHashCodeFromArray(string?[] array) for (var index = 0; index < array.Length; index++) { - hash.Add(array[index]); + hash.Add(array[index], StringComparer.Ordinal); } return hash.ToHashCode(); @@ -368,10 +368,10 @@ static int GetHashCodeFromJsonElement(JsonElement element) return result.GetHashCode(); case JsonValueKind.Number: - return element.GetRawText().GetHashCode(); + return element.GetRawText().GetHashCode(StringComparison.Ordinal); case JsonValueKind.String: - return element.GetString()!.GetHashCode(); + return element.GetString()!.GetHashCode(StringComparison.Ordinal); case JsonValueKind.Array: { @@ -391,7 +391,7 @@ static int GetHashCodeFromJsonElement(JsonElement element) foreach (var property in element.EnumerateObject()) { - hash.Add(property.Name); + hash.Add(property.Name, StringComparer.Ordinal); hash.Add(GetHashCodeFromJsonElement(property.Value)); } @@ -441,7 +441,7 @@ JsonNode value when JsonSerializer.SerializeToElement(value, OpenIddictSerialize is JsonElement { ValueKind: JsonValueKind.Object } element => GetParametersFromJsonElement(element), - _ => ImmutableDictionary.Create(StringComparer.Ordinal) + _ => ImmutableDictionary.Empty }; static IReadOnlyDictionary GetParametersFromJsonElement(JsonElement element) diff --git a/src/OpenIddict.Abstractions/Stores/IOpenIddictTokenStore.cs b/src/OpenIddict.Abstractions/Stores/IOpenIddictTokenStore.cs index 784e85da3..bcac5ea1b 100644 --- a/src/OpenIddict.Abstractions/Stores/IOpenIddictTokenStore.cs +++ b/src/OpenIddict.Abstractions/Stores/IOpenIddictTokenStore.cs @@ -323,7 +323,7 @@ IAsyncEnumerable ListAsync( /// The application identifier associated with the tokens. /// The that can be used to abort the operation. /// The number of tokens associated with the specified application that were marked as revoked. - ValueTask RevokeByApplicationIdAsync(string identifier, CancellationToken cancellationToken = default); + ValueTask RevokeByApplicationIdAsync(string identifier, CancellationToken cancellationToken); /// /// Revokes all the tokens associated with the specified authorization identifier. @@ -339,7 +339,7 @@ IAsyncEnumerable ListAsync( /// The subject associated with the tokens. /// The that can be used to abort the operation. /// The number of tokens associated with the specified subject that were marked as revoked. - ValueTask RevokeBySubjectAsync(string subject, CancellationToken cancellationToken = default); + ValueTask RevokeBySubjectAsync(string subject, CancellationToken cancellationToken); /// /// Sets the application identifier associated with a token. diff --git a/src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreConfiguration.cs b/src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreConfiguration.cs index 28683114f..e08d00bf8 100644 --- a/src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreConfiguration.cs +++ b/src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreConfiguration.cs @@ -66,7 +66,7 @@ public void PostConfigure(string? name, OpenIddictClientAspNetCoreOptions option foreach (var (provider, registrations) in _provider.GetRequiredService>() .CurrentValue.Registrations .Where(static registration => !string.IsNullOrEmpty(registration.ProviderName)) - .GroupBy(static registration => registration.ProviderName) + .GroupBy(static registration => registration.ProviderName, StringComparer.Ordinal) .Select(static group => (ProviderName: group.Key, Registrations: group.ToList()))) { // If an explicit mapping was already added, don't overwrite it. @@ -148,7 +148,7 @@ public ValidateOptionsResult Validate(string? name, AuthenticationOptions option // Ensure the forwarded authentication schemes are mapped to the OpenIddict client forwarder. foreach (var group in _provider.GetRequiredService>() .CurrentValue.ForwardedAuthenticationSchemes - .GroupBy(static scheme => scheme.Name) + .GroupBy(static scheme => scheme.Name, StringComparer.Ordinal) .Where(group => !ValidateHandlerType(options.SchemeMap, group.Key))) { builder.AddError(SR.FormatID0414(group.Key)); @@ -195,7 +195,7 @@ public ValidateOptionsResult Validate(string? name, OpenIddictClientAspNetCoreOp foreach (var (provider, registrations) in _provider.GetRequiredService>() .CurrentValue.Registrations .Where(static registration => !string.IsNullOrEmpty(registration.ProviderName)) - .GroupBy(static registration => registration.ProviderName) + .GroupBy(static registration => registration.ProviderName, StringComparer.Ordinal) .Select(static group => (ProviderName: group.Key, Registrations: group.ToList())) .Where(static group => group.Registrations.Count is > 1)) { diff --git a/src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreForwarder.cs b/src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreForwarder.cs index 2d746f85e..edc4b44f8 100644 --- a/src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreForwarder.cs +++ b/src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreForwarder.cs @@ -54,7 +54,7 @@ public async Task ChallengeAsync(AuthenticationProperties? properties) await _context.ChallengeAsync( scheme: OpenIddictClientAspNetCoreDefaults.AuthenticationScheme, properties: new AuthenticationProperties( - items: new Dictionary(properties?.Items ?? ImmutableDictionary.Create()) + items: new Dictionary(properties?.Items ?? ImmutableDictionary.Empty, StringComparer.Ordinal) { [Properties.ProviderName] = _scheme.Name }, @@ -76,7 +76,7 @@ public async Task ForbidAsync(AuthenticationProperties? properties) await _context.ForbidAsync( scheme: OpenIddictClientAspNetCoreDefaults.AuthenticationScheme, properties: new AuthenticationProperties( - items: new Dictionary(properties?.Items ?? ImmutableDictionary.Create()) + items: new Dictionary(properties?.Items ?? ImmutableDictionary.Empty, StringComparer.Ordinal) { [Properties.ProviderName] = _scheme.Name }, @@ -98,7 +98,7 @@ public async Task SignOutAsync(AuthenticationProperties? properties) await _context.SignOutAsync( scheme: OpenIddictClientAspNetCoreDefaults.AuthenticationScheme, properties: new AuthenticationProperties( - items: new Dictionary(properties?.Items ?? ImmutableDictionary.Create()) + items: new Dictionary(properties?.Items ?? ImmutableDictionary.Empty, StringComparer.Ordinal) { [Properties.ProviderName] = _scheme.Name }, diff --git a/src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreHandler.cs b/src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreHandler.cs index f704f287e..87645a200 100644 --- a/src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreHandler.cs +++ b/src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreHandler.cs @@ -76,12 +76,12 @@ public async Task HandleRequestAsync() return true; } - else if (context.IsRequestSkipped) + if (context.IsRequestSkipped) { return false; } - else if (context.IsRejected) + if (context.IsRejected) { var notification = new ProcessErrorContext(transaction) { @@ -98,7 +98,7 @@ public async Task HandleRequestAsync() return true; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { return false; } @@ -133,7 +133,7 @@ protected override async Task HandleAuthenticateAsync() return AuthenticateResult.NoResult(); } - else if (context.IsRejected) + if (context.IsRejected) { // Note: the missing_token error is special-cased to indicate to ASP.NET Core // that no authentication result could be produced due to the lack of token. @@ -390,7 +390,7 @@ protected override async Task HandleChallengeAsync(AuthenticationProperties? pro return; } - else if (context.IsRejected) + if (context.IsRejected) { var notification = new ProcessErrorContext(transaction) { @@ -436,7 +436,7 @@ public async Task SignOutAsync(AuthenticationProperties? properties) return; } - else if (context.IsRejected) + if (context.IsRejected) { var notification = new ProcessErrorContext(transaction) { diff --git a/src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreHandlers.cs b/src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreHandlers.cs index f46f25eb9..28729103f 100644 --- a/src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreHandlers.cs +++ b/src/OpenIddict.Client.AspNetCore/OpenIddictClientAspNetCoreHandlers.cs @@ -572,8 +572,7 @@ public ValueTask HandleAsync(ProcessChallengeContext context) context.Issuer = uri; } - if (properties.Items.TryGetValue(Properties.Scope, out string? scope) && - !string.IsNullOrEmpty(scope)) + if (properties.Items.TryGetValue(Properties.Scope, out string? scope) && !string.IsNullOrEmpty(scope)) { context.Scopes.UnionWith(scope.Split(Separators.Space, StringSplitOptions.RemoveEmptyEntries)); } diff --git a/src/OpenIddict.Client.DataProtection/OpenIddictClientDataProtectionFormatter.cs b/src/OpenIddict.Client.DataProtection/OpenIddictClientDataProtectionFormatter.cs index ddf227363..b0abdf994 100644 --- a/src/OpenIddict.Client.DataProtection/OpenIddictClientDataProtectionFormatter.cs +++ b/src/OpenIddict.Client.DataProtection/OpenIddictClientDataProtectionFormatter.cs @@ -182,7 +182,7 @@ public void WriteToken(BinaryWriter writer, ClaimsPrincipal principal) ArgumentNullException.ThrowIfNull(writer); ArgumentNullException.ThrowIfNull(principal); - var properties = new Dictionary(); + var properties = new Dictionary(StringComparer.Ordinal); // Unlike ASP.NET Core Data Protection-based tokens, tokens serialized using the new format // can't include authentication properties. To ensure tokens can be used with previous versions diff --git a/src/OpenIddict.Client.Owin/OpenIddictClientOwinConfiguration.cs b/src/OpenIddict.Client.Owin/OpenIddictClientOwinConfiguration.cs index cd5af07d5..21110aa34 100644 --- a/src/OpenIddict.Client.Owin/OpenIddictClientOwinConfiguration.cs +++ b/src/OpenIddict.Client.Owin/OpenIddictClientOwinConfiguration.cs @@ -61,7 +61,7 @@ public void PostConfigure(string? name, OpenIddictClientOwinOptions options) foreach (var (provider, registrations) in _provider.GetRequiredService>() .CurrentValue.Registrations .Where(static registration => !string.IsNullOrEmpty(registration.ProviderName)) - .GroupBy(static registration => registration.ProviderName) + .GroupBy(static registration => registration.ProviderName, StringComparer.Ordinal) .Select(static group => (ProviderName: group.Key, Registrations: group.ToList()))) { // If an explicit mapping was already added, don't overwrite it. @@ -109,7 +109,7 @@ public ValidateOptionsResult Validate(string? name, OpenIddictClientOwinOptions foreach (var (provider, registrations) in _provider.GetRequiredService>() .CurrentValue.Registrations .Where(static registration => !string.IsNullOrEmpty(registration.ProviderName)) - .GroupBy(static registration => registration.ProviderName) + .GroupBy(static registration => registration.ProviderName, StringComparer.Ordinal) .Select(static group => (ProviderName: group.Key, Registrations: group.ToList())) .Where(static group => group.Registrations.Count is > 1)) { diff --git a/src/OpenIddict.Client.Owin/OpenIddictClientOwinHandler.cs b/src/OpenIddict.Client.Owin/OpenIddictClientOwinHandler.cs index 9ec920de1..774da6c38 100644 --- a/src/OpenIddict.Client.Owin/OpenIddictClientOwinHandler.cs +++ b/src/OpenIddict.Client.Owin/OpenIddictClientOwinHandler.cs @@ -95,12 +95,12 @@ public override async Task InvokeAsync() return true; } - else if (context.IsRequestSkipped) + if (context.IsRequestSkipped) { return false; } - else if (context.IsRejected) + if (context.IsRejected) { var notification = new ProcessErrorContext(transaction) { @@ -117,7 +117,7 @@ public override async Task InvokeAsync() return true; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { return false; } @@ -152,7 +152,7 @@ public override async Task InvokeAsync() return null; } - else if (context.IsRejected) + if (context.IsRejected) { // Note: the missing_token error is special-cased to indicate to Katana // that no authentication result could be produced due to the lack of token. @@ -315,7 +315,7 @@ protected override async Task TeardownCoreAsync() return; } - else if (context.IsRejected) + if (context.IsRejected) { var notification = new ProcessErrorContext(transaction) { @@ -359,7 +359,7 @@ protected override async Task TeardownCoreAsync() return; } - else if (context.IsRejected) + if (context.IsRejected) { var notification = new ProcessErrorContext(transaction) { @@ -408,7 +408,7 @@ protected override async Task TeardownCoreAsync() authenticationTypes: [OpenIddictClientOwinDefaults.AuthenticationType], properties : new AuthenticationProperties(dictionary: new Dictionary( manager.AuthenticationResponseChallenge.Properties.Dictionary - ?? ImmutableDictionary.Create()) + ?? ImmutableDictionary.Empty, StringComparer.Ordinal) { [Properties.ProviderName] = type })); @@ -447,7 +447,7 @@ protected override async Task TeardownCoreAsync() authenticationTypes: [OpenIddictClientOwinDefaults.AuthenticationType], properties : new AuthenticationProperties(dictionary: new Dictionary( manager.AuthenticationResponseRevoke.Properties.Dictionary - ?? ImmutableDictionary.Create()) + ?? ImmutableDictionary.Empty, StringComparer.Ordinal) { [Properties.ProviderName] = type })); diff --git a/src/OpenIddict.Client.Owin/OpenIddictClientOwinHandlers.cs b/src/OpenIddict.Client.Owin/OpenIddictClientOwinHandlers.cs index 95559fce2..c5e628f3e 100644 --- a/src/OpenIddict.Client.Owin/OpenIddictClientOwinHandlers.cs +++ b/src/OpenIddict.Client.Owin/OpenIddictClientOwinHandlers.cs @@ -578,8 +578,7 @@ public ValueTask HandleAsync(ProcessChallengeContext context) context.Issuer = uri; } - if (properties.Dictionary.TryGetValue(Properties.Scope, out string? scope) && - !string.IsNullOrEmpty(scope)) + if (properties.Dictionary.TryGetValue(Properties.Scope, out string? scope) && !string.IsNullOrEmpty(scope)) { context.Scopes.UnionWith(scope.Split(Separators.Space, StringSplitOptions.RemoveEmptyEntries)); } diff --git a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.Authentication.cs b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.Authentication.cs index 5b7d24ba6..ff210830e 100644 --- a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.Authentication.cs +++ b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.Authentication.cs @@ -228,7 +228,8 @@ NSUrl CreateUrl() => OpenIddictHelpers.AddQueryStringParameters( uri: new Uri(context.AuthorizationEndpoint, UriKind.Absolute), parameters: context.Request.GetParameters().ToDictionary( static parameter => parameter.Key, - static parameter => (StringValues) parameter.Value))!; + static parameter => (StringValues) parameter.Value, + StringComparer.Ordinal))!; void HandleCallback(NSUrl? url, NSError? error) { @@ -346,7 +347,8 @@ public async ValueTask HandleAsync(ApplyAuthorizationRequestContext context) uri: new Uri(context.AuthorizationEndpoint, UriKind.Absolute), parameters: context.Request.GetParameters().ToDictionary( static parameter => parameter.Key, - static parameter => (StringValues) parameter.Value)).AbsoluteUri)!); + static parameter => (StringValues) parameter.Value, + StringComparer.Ordinal)).AbsoluteUri)!); context.HandleRequest(); #else @@ -424,7 +426,8 @@ public async ValueTask HandleAsync(ApplyAuthorizationRequestContext context) uri: new Uri(context.AuthorizationEndpoint, UriKind.Absolute), parameters: context.Request.GetParameters().ToDictionary( static parameter => parameter.Key, - static parameter => (StringValues) parameter.Value)), + static parameter => (StringValues) parameter.Value, + StringComparer.Ordinal)), callbackUri: new Uri(context.RedirectUri, UriKind.Absolute))) { case { ResponseStatus: WebAuthenticationStatus.Success } result @@ -530,7 +533,8 @@ public async ValueTask HandleAsync(ApplyAuthorizationRequestContext context) uri: new Uri(context.AuthorizationEndpoint, UriKind.Absolute), parameters: context.Request.GetParameters().ToDictionary( static parameter => parameter.Key, - static parameter => (StringValues) parameter.Value)); + static parameter => (StringValues) parameter.Value, + StringComparer.Ordinal)); if (OperatingSystem.IsWindows()) { diff --git a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.Session.cs b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.Session.cs index 85950f40d..7f2ecade6 100644 --- a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.Session.cs +++ b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.Session.cs @@ -228,7 +228,8 @@ NSUrl CreateUrl() => OpenIddictHelpers.AddQueryStringParameters( uri: new Uri(context.EndSessionEndpoint, UriKind.Absolute), parameters: context.Request.GetParameters().ToDictionary( static parameter => parameter.Key, - static parameter => (StringValues) parameter.Value))!; + static parameter => (StringValues) parameter.Value, + StringComparer.Ordinal))!; void HandleCallback(NSUrl? url, NSError? error) { @@ -346,7 +347,8 @@ public async ValueTask HandleAsync(ApplyEndSessionRequestContext context) uri: new Uri(context.EndSessionEndpoint, UriKind.Absolute), parameters: context.Request.GetParameters().ToDictionary( static parameter => parameter.Key, - static parameter => (StringValues) parameter.Value)).AbsoluteUri)!); + static parameter => (StringValues) parameter.Value, + StringComparer.Ordinal)).AbsoluteUri)!); context.HandleRequest(); #else @@ -424,7 +426,8 @@ public async ValueTask HandleAsync(ApplyEndSessionRequestContext context) uri: new Uri(context.EndSessionEndpoint, UriKind.Absolute), parameters: context.Request.GetParameters().ToDictionary( static parameter => parameter.Key, - static parameter => (StringValues) parameter.Value)), + static parameter => (StringValues) parameter.Value, + StringComparer.Ordinal)), callbackUri: new Uri(context.PostLogoutRedirectUri, UriKind.Absolute))) { case { ResponseStatus: WebAuthenticationStatus.Success } result @@ -530,7 +533,8 @@ public async ValueTask HandleAsync(ApplyEndSessionRequestContext context) uri: new Uri(context.EndSessionEndpoint, UriKind.Absolute), parameters: context.Request.GetParameters().ToDictionary( static parameter => parameter.Key, - static parameter => (StringValues) parameter.Value)); + static parameter => (StringValues) parameter.Value, + StringComparer.Ordinal)); if (OperatingSystem.IsWindows()) { diff --git a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.cs b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.cs index 138e4bd6f..ac56bfa77 100644 --- a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.cs +++ b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.cs @@ -655,13 +655,13 @@ public async ValueTask HandleAsync(ProcessAuthenticationContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, diff --git a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationMarshal.cs b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationMarshal.cs index b8dbc3714..e5d1a43da 100644 --- a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationMarshal.cs +++ b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationMarshal.cs @@ -19,7 +19,7 @@ public sealed class OpenIddictClientSystemIntegrationMarshal private readonly ConcurrentDictionary TaskCompletionSource)>> _tracker = new(); + TaskCompletionSource TaskCompletionSource)>> _tracker = new(StringComparer.Ordinal); /// /// Determines whether the authentication demand corresponding to the specified nonce is tracked. diff --git a/src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.cs b/src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.cs index 8819d0ece..f47dc1b72 100644 --- a/src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.cs +++ b/src/OpenIddict.Client.SystemNetHttp/OpenIddictClientSystemNetHttpHandlers.cs @@ -374,7 +374,7 @@ context.ClientAuthenticationMethod is ClientAuthenticationMethods.ClientSecretBa return ValueTask.CompletedTask; static string? EscapeDataString(string? value) - => value is not null ? Uri.EscapeDataString(value).Replace("%20", "+") : null; + => value is not null ? Uri.EscapeDataString(value).Replace("%20", "+", StringComparison.Ordinal) : null; } } @@ -417,7 +417,8 @@ public ValueTask HandleAsync(TContext context) request.RequestUri = OpenIddictHelpers.AddQueryStringParameters(request.RequestUri, context.Transaction.Request.GetParameters().ToDictionary( static parameter => parameter.Key, - static parameter => (StringValues) parameter.Value)); + static parameter => (StringValues) parameter.Value, + StringComparer.Ordinal)); } // For POST requests, attach the request parameters to the request form by default. @@ -609,7 +610,7 @@ public async ValueTask HandleAsync(TContext context) continue; } - else if (string.Equals(encoding, ContentEncodings.Gzip, StringComparison.OrdinalIgnoreCase)) + if (string.Equals(encoding, ContentEncodings.Gzip, StringComparison.OrdinalIgnoreCase)) { stream ??= await response.Content.ReadAsStreamAsync().WaitAsync(context.CancellationToken); stream = new GZipStream(stream, CompressionMode.Decompress); diff --git a/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationExtensions.cs b/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationExtensions.cs index 6c9fa75d3..0ba5652c7 100644 --- a/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationExtensions.cs +++ b/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationExtensions.cs @@ -14,7 +14,7 @@ namespace Microsoft.Extensions.DependencyInjection; /// /// Exposes extensions allowing to register the OpenIddict client Web integration services. /// -public static partial class OpenIddictClientWebIntegrationExtensions +public static class OpenIddictClientWebIntegrationExtensions { /// /// Registers the OpenIddict client Web integration services in the DI container. diff --git a/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Exchange.cs b/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Exchange.cs index 77802d7f2..f796c2338 100644 --- a/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Exchange.cs +++ b/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Exchange.cs @@ -270,7 +270,7 @@ public ValueTask HandleAsync(PrepareTokenRequestContext context) { request.RequestUri = OpenIddictHelpers.AddQueryStringParameters( uri: request.RequestUri, - parameters: new Dictionary + parameters: new Dictionary(StringComparer.Ordinal) { ["chat_os_type"] = "bot", ["chat_version"] = "1.30.0" diff --git a/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Introspection.cs b/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Introspection.cs index f15f8c66b..422ff6f99 100644 --- a/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Introspection.cs +++ b/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.Introspection.cs @@ -66,7 +66,7 @@ public ValueTask HandleAsync(ExtractIntrospectionResponseContext context) } } - context.Response.Scope = string.Join(" ", scopes); + context.Response.Scope = string.Join(Separators.Space[0], scopes); } return ValueTask.CompletedTask; diff --git a/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.cs b/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.cs index adbf18819..d95e6bf47 100644 --- a/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.cs +++ b/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.cs @@ -161,13 +161,11 @@ public ValueTask HandleAsync(ProcessAuthenticationContext context) // // See https://shopify.dev/docs/apps/auth/oauth/getting-started#remove-the-hmac-parameter-from-the-query-string // for more information. - foreach (var (name, value) in - from parameter in OpenIddictHelpers.ParseQuery(context.RequestUri!.Query) - where !string.IsNullOrEmpty(parameter.Key) - where !string.Equals(parameter.Key, "hmac", StringComparison.Ordinal) - orderby parameter.Key ascending - from value in parameter.Value - select (Name: parameter.Key, Value: value)) + foreach (var (name, value) in OpenIddictHelpers.ParseQuery(context.RequestUri!.Query) + .Where(static parameter => !string.IsNullOrEmpty(parameter.Key)) + .Where(static parameter => !string.Equals(parameter.Key, "hmac", StringComparison.Ordinal)) + .OrderBy(static parameter => parameter.Key, StringComparer.Ordinal) + .SelectMany(static parameter => parameter.Value, static (parameter, value) => (Name: parameter.Key, Value: value))) { if (builder.Length is > 0) { @@ -1187,7 +1185,7 @@ public ValueTask HandleAsync(ProcessAuthenticationContext context) { var settings = context.Registration.GetDailymotionSettings(); - context.UserInfoRequest["fields"] = string.Join(",", settings.UserFields); + context.UserInfoRequest["fields"] = string.Join(Separators.Comma[0], settings.UserFields); } // Disqus requires sending the client identifier (called "public @@ -1204,7 +1202,7 @@ public ValueTask HandleAsync(ProcessAuthenticationContext context) { var settings = context.Registration.GetFacebookSettings(); - context.UserInfoRequest["fields"] = string.Join(",", settings.Fields); + context.UserInfoRequest["fields"] = string.Join(Separators.Comma[0], settings.Fields); } // Linear's userinfo endpoint is a GraphQL implementation that requires @@ -1213,7 +1211,7 @@ public ValueTask HandleAsync(ProcessAuthenticationContext context) { var settings = context.Registration.GetLinearSettings(); - context.UserInfoRequest["query"] = $"query {{ viewer {{ {string.Join(" ", settings.UserFields)} }} }}"; + context.UserInfoRequest["query"] = $"query {{ viewer {{ {string.Join(Separators.Space[0], settings.UserFields)} }} }}"; } // Meetup's userinfo endpoint is a GraphQL implementation that requires @@ -1222,7 +1220,7 @@ public ValueTask HandleAsync(ProcessAuthenticationContext context) { var settings = context.Registration.GetMeetupSettings(); - context.UserInfoRequest["query"] = $"query {{ self {{ {string.Join(" ", settings.UserFields)} }} }}"; + context.UserInfoRequest["query"] = $"query {{ self {{ {string.Join(Separators.Space[0], settings.UserFields)} }} }}"; } // Patreon limits the number of fields returned by the userinfo endpoint @@ -1232,7 +1230,7 @@ public ValueTask HandleAsync(ProcessAuthenticationContext context) { var settings = context.Registration.GetPatreonSettings(); - context.UserInfoRequest["fields[user]"] = string.Join(",", settings.UserFields); + context.UserInfoRequest["fields[user]"] = string.Join(Separators.Comma[0], settings.UserFields); } // StackOverflow requires sending an application key and a site parameter @@ -1274,9 +1272,9 @@ public ValueTask HandleAsync(ProcessAuthenticationContext context) { var settings = context.Registration.GetTwitterSettings(); - context.UserInfoRequest["expansions"] = string.Join(",", settings.Expansions); - context.UserInfoRequest["tweet.fields"] = string.Join(",", settings.TweetFields); - context.UserInfoRequest["user.fields"] = string.Join(",", settings.UserFields); + context.UserInfoRequest["expansions"] = string.Join(Separators.Comma[0], settings.Expansions); + context.UserInfoRequest["tweet.fields"] = string.Join(Separators.Comma[0], settings.TweetFields); + context.UserInfoRequest["user.fields"] = string.Join(Separators.Comma[0], settings.UserFields); } // Weibo requires sending the user identifier as part of the userinfo request. @@ -1880,11 +1878,11 @@ public ValueTask HandleAsync(ProcessChallengeContext context) // the standard format (that requires using a space as the scope separator): ProviderTypes.Deezer or ProviderTypes.Disqus or ProviderTypes.Shopify or ProviderTypes.Strava or ProviderTypes.Todoist or ProviderTypes.Weibo - => string.Join(",", context.Scopes), + => string.Join(Separators.Comma[0], context.Scopes), // The following providers are known to use plus-separated scopes instead of // the standard format (that requires using a space as the scope separator): - ProviderTypes.Trovo => string.Join("+", context.Scopes), + ProviderTypes.Trovo => string.Join(Separators.Plus[0], context.Scopes), _ => context.Request.Scope }; diff --git a/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationOptions.cs b/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationOptions.cs index a87181ab0..8e219e020 100644 --- a/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationOptions.cs +++ b/src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationOptions.cs @@ -9,6 +9,6 @@ namespace OpenIddict.Client.WebIntegration; /// /// Provides various settings needed to configure the OpenIddict client Web integration. /// -public sealed partial class OpenIddictClientWebIntegrationOptions +public sealed class OpenIddictClientWebIntegrationOptions { } diff --git a/src/OpenIddict.Client/OpenIddictClientHandlers.Authentication.cs b/src/OpenIddict.Client/OpenIddictClientHandlers.Authentication.cs index 9173eb8b4..c2d571209 100644 --- a/src/OpenIddict.Client/OpenIddictClientHandlers.Authentication.cs +++ b/src/OpenIddict.Client/OpenIddictClientHandlers.Authentication.cs @@ -89,7 +89,7 @@ public async ValueTask HandleAsync(ProcessChallengeContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; @@ -138,13 +138,13 @@ public async ValueTask HandleAsync(ProcessChallengeContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -419,13 +419,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -478,13 +478,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -531,13 +531,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -585,7 +585,7 @@ public async ValueTask HandleAsync(TContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; @@ -676,13 +676,13 @@ public async ValueTask HandleAsync(ValidateRedirectionRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, diff --git a/src/OpenIddict.Client/OpenIddictClientHandlers.Protection.cs b/src/OpenIddict.Client/OpenIddictClientHandlers.Protection.cs index aba7b694a..e26f67474 100644 --- a/src/OpenIddict.Client/OpenIddictClientHandlers.Protection.cs +++ b/src/OpenIddict.Client/OpenIddictClientHandlers.Protection.cs @@ -410,7 +410,7 @@ public async ValueTask HandleAsync(ValidateTokenContext context) foreach (var claim in result.ClaimsIdentity.Claims) { // Exclude claims starting with "oi_" from tokens that are not fully trusted. - if (claim.Type.StartsWith(Claims.Prefixes.Private)) + if (claim.Type.StartsWith(Claims.Prefixes.Private, StringComparison.Ordinal)) { continue; } @@ -424,7 +424,7 @@ public async ValueTask HandleAsync(ValidateTokenContext context) identity = result.ClaimsIdentity.Clone(claim => claim switch { // Exclude claims starting with "oi_", unless the token is a state token. - { Type: string type } when type.StartsWith(Claims.Prefixes.Private) && + { Type: string type } when type.StartsWith(Claims.Prefixes.Private, StringComparison.Ordinal) && result.TokenType is not JsonWebTokenTypes.Private.StateToken => false, _ => true // Allow any other claim. diff --git a/src/OpenIddict.Client/OpenIddictClientHandlers.Session.cs b/src/OpenIddict.Client/OpenIddictClientHandlers.Session.cs index 84518daee..aa8bea7f1 100644 --- a/src/OpenIddict.Client/OpenIddictClientHandlers.Session.cs +++ b/src/OpenIddict.Client/OpenIddictClientHandlers.Session.cs @@ -74,7 +74,7 @@ public async ValueTask HandleAsync(ProcessSignOutContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; @@ -121,13 +121,13 @@ public async ValueTask HandleAsync(ProcessSignOutContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -210,13 +210,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -269,13 +269,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -322,13 +322,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -376,7 +376,7 @@ public async ValueTask HandleAsync(TContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; @@ -425,13 +425,13 @@ public async ValueTask HandleAsync(ValidatePostLogoutRedirectionRequestContext c return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, diff --git a/src/OpenIddict.Client/OpenIddictClientHandlers.cs b/src/OpenIddict.Client/OpenIddictClientHandlers.cs index 76dd0a4e3..389bd25ce 100644 --- a/src/OpenIddict.Client/OpenIddictClientHandlers.cs +++ b/src/OpenIddict.Client/OpenIddictClientHandlers.cs @@ -713,13 +713,13 @@ public async ValueTask HandleAsync(ProcessAuthenticationContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { if (context.RejectStateToken) { @@ -1626,13 +1626,13 @@ public async ValueTask HandleAsync(ProcessAuthenticationContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { if (context.RejectFrontchannelIdentityToken) { @@ -1674,8 +1674,8 @@ public ValueTask HandleAsync(ProcessAuthenticationContext context) Debug.Assert(context.FrontchannelIdentityTokenPrincipal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006)); foreach (var group in context.FrontchannelIdentityTokenPrincipal.Claims - .GroupBy(static claim => claim.Type) - .ToDictionary(static group => group.Key, group => group.ToList()) + .GroupBy(static claim => claim.Type, StringComparer.Ordinal) + .ToDictionary(static group => group.Key, group => group.ToList(), StringComparer.Ordinal) .Where(static group => !ValidateClaimGroup(group.Key, group.Value))) { context.Reject( @@ -1806,7 +1806,8 @@ public ValueTask HandleAsync(ProcessAuthenticationContext context) // In any case, the client identifier of the application MUST be included in the audiences. // See https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation for more information. var audiences = context.FrontchannelIdentityTokenPrincipal.GetClaims(Claims.Audience); - if (!string.IsNullOrEmpty(context.Registration.ClientId) && !audiences.Contains(context.Registration.ClientId)) + if (!string.IsNullOrEmpty(context.Registration.ClientId) && + !audiences.Contains(context.Registration.ClientId, StringComparer.Ordinal)) { context.Reject( error: Errors.InvalidRequest, @@ -2150,13 +2151,13 @@ public async ValueTask HandleAsync(ProcessAuthenticationContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { if (context.RejectFrontchannelAccessToken) { @@ -2221,13 +2222,13 @@ public async ValueTask HandleAsync(ProcessAuthenticationContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { if (context.RejectAuthorizationCode) { @@ -2697,7 +2698,7 @@ public ValueTask HandleAsync(ProcessAuthenticationContext context) // Note: the final OAuth 2.0 specification requires using a space as the scope separator. // Clients that need to deal with older or non-compliant implementations can register // a custom handler to use a different separator (typically, a comma). - context.TokenRequest.Scope = string.Join(" ", context.Scopes); + context.TokenRequest.Scope = string.Join(Separators.Space[0], context.Scopes); } } @@ -2908,13 +2909,13 @@ public async ValueTask HandleAsync(ProcessAuthenticationContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -3363,13 +3364,13 @@ public async ValueTask HandleAsync(ProcessAuthenticationContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { if (context.RejectBackchannelIdentityToken) { @@ -3411,8 +3412,8 @@ public ValueTask HandleAsync(ProcessAuthenticationContext context) Debug.Assert(context.BackchannelIdentityTokenPrincipal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006)); foreach (var group in context.BackchannelIdentityTokenPrincipal.Claims - .GroupBy(static claim => claim.Type) - .ToDictionary(static group => group.Key, group => group.ToList()) + .GroupBy(static claim => claim.Type, StringComparer.Ordinal) + .ToDictionary(static group => group.Key, group => group.ToList(), StringComparer.Ordinal) .Where(static group => !ValidateClaimGroup(group.Key, group.Value))) { context.Reject( @@ -3543,7 +3544,8 @@ public ValueTask HandleAsync(ProcessAuthenticationContext context) // In any case, the client identifier of the application MUST be included in the audiences. // See https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation for more information. var audiences = context.BackchannelIdentityTokenPrincipal.GetClaims(Claims.Audience); - if (!string.IsNullOrEmpty(context.Registration.ClientId) && !audiences.Contains(context.Registration.ClientId)) + if (!string.IsNullOrEmpty(context.Registration.ClientId) && + !audiences.Contains(context.Registration.ClientId, StringComparer.Ordinal)) { context.Reject( error: Errors.InvalidRequest, @@ -3851,13 +3853,13 @@ public async ValueTask HandleAsync(ProcessAuthenticationContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { if (context.RejectBackchannelAccessToken) { @@ -3920,13 +3922,13 @@ public async ValueTask HandleAsync(ProcessAuthenticationContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { if (context.RejectIssuedToken) { @@ -3991,13 +3993,13 @@ public async ValueTask HandleAsync(ProcessAuthenticationContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { if (context.RejectRefreshToken) { @@ -4493,13 +4495,13 @@ public async ValueTask HandleAsync(ProcessAuthenticationContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { if (context.RejectUserInfoToken) { @@ -4542,8 +4544,8 @@ public ValueTask HandleAsync(ProcessAuthenticationContext context) Debug.Assert(context.UserInfoTokenPrincipal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006)); foreach (var group in context.UserInfoTokenPrincipal.Claims - .GroupBy(static claim => claim.Type) - .ToDictionary(static group => group.Key, group => group.ToList()) + .GroupBy(static claim => claim.Type, StringComparer.Ordinal) + .ToDictionary(static group => group.Key, group => group.ToList(), StringComparer.Ordinal) .Where(static group => !ValidateClaimGroup(group.Key, group.Value))) { context.Reject( @@ -4907,8 +4909,8 @@ public ValueTask HandleAsync(ProcessChallengeContext context) } foreach (var group in context.Principal.Claims - .GroupBy(static claim => claim.Type) - .ToDictionary(static group => group.Key, static group => group.ToList()) + .GroupBy(static claim => claim.Type, StringComparer.Ordinal) + .ToDictionary(static group => group.Key, static group => group.ToList(), StringComparer.Ordinal) .Where(static group => !ValidateClaimGroup(group.Key, group.Value))) { throw new InvalidOperationException(SR.FormatID0424(group.Key)); @@ -5848,13 +5850,13 @@ public async ValueTask HandleAsync(ProcessChallengeContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -5912,7 +5914,7 @@ public ValueTask HandleAsync(ProcessChallengeContext context) // Note: the final OAuth 2.0 specification requires using a space as the scope separator. // Clients that need to deal with older or non-compliant implementations can register // a custom handler to use a different separator (typically, a comma). - context.Request.Scope = string.Join(" ", context.Scopes); + context.Request.Scope = string.Join(Separators.Space[0], context.Scopes); } // If a nonce was generated and the request is an OpenID Connect request where an authorization @@ -6275,7 +6277,7 @@ public ValueTask HandleAsync(ProcessChallengeContext context) // Note: the final OAuth 2.0 specification requires using a space as the scope separator. // Clients that need to deal with older or non-compliant implementations can register // a custom handler to use a different separator (typically, a comma). - context.DeviceAuthorizationRequest.Scope = string.Join(" ", context.Scopes); + context.DeviceAuthorizationRequest.Scope = string.Join(Separators.Space[0], context.Scopes); } return ValueTask.CompletedTask; @@ -6737,13 +6739,13 @@ public async ValueTask HandleAsync(ProcessChallengeContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -7900,13 +7902,13 @@ public async ValueTask HandleAsync(ProcessIntrospectionContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -8705,13 +8707,13 @@ public async ValueTask HandleAsync(ProcessRevocationContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -8908,8 +8910,8 @@ public ValueTask HandleAsync(ProcessSignOutContext context) } foreach (var group in context.Principal.Claims - .GroupBy(static claim => claim.Type) - .ToDictionary(static group => group.Key, static group => group.ToList()) + .GroupBy(static claim => claim.Type, StringComparer.Ordinal) + .ToDictionary(static group => group.Key, static group => group.ToList(), StringComparer.Ordinal) .Where(static group => !ValidateClaimGroup(group.Key, group.Value))) { throw new InvalidOperationException(SR.FormatID0424(group.Key)); @@ -9358,13 +9360,13 @@ public async ValueTask HandleAsync(ProcessSignOutContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, diff --git a/src/OpenIddict.Client/OpenIddictClientService.cs b/src/OpenIddict.Client/OpenIddictClientService.cs index 34bcb79dd..ec2f5ef4c 100644 --- a/src/OpenIddict.Client/OpenIddictClientService.cs +++ b/src/OpenIddict.Client/OpenIddictClientService.cs @@ -294,30 +294,27 @@ public async ValueTask AuthenticateInteractivel context.Error, context.ErrorDescription, context.ErrorUri); } - else - { - Debug.Assert(context.Registration.Issuer is { IsAbsoluteUri: true }, SR.GetResourceString(SR.ID4013)); - - return new() - { - AuthorizationCode = context.AuthorizationCode, - AuthorizationResponse = context.Request is not null ? new(context.Request.GetParameters()) : new(), - BackchannelAccessToken = context.BackchannelAccessToken, - BackchannelAccessTokenExpirationDate = context.BackchannelAccessTokenExpirationDate, - BackchannelIdentityToken = context.BackchannelIdentityToken, - BackchannelIdentityTokenPrincipal = context.BackchannelIdentityTokenPrincipal, - FrontchannelAccessToken = context.FrontchannelAccessToken, - FrontchannelAccessTokenExpirationDate = context.FrontchannelAccessTokenExpirationDate, - FrontchannelIdentityToken = context.FrontchannelIdentityToken, - FrontchannelIdentityTokenPrincipal = context.FrontchannelIdentityTokenPrincipal, - Principal = context.MergedPrincipal, - Properties = context.Properties, - RefreshToken = context.RefreshToken, - StateTokenPrincipal = context.StateTokenPrincipal, - TokenResponse = context.TokenResponse ?? new(), - UserInfoTokenPrincipal = context.UserInfoTokenPrincipal - }; - } + Debug.Assert(context.Registration.Issuer is { IsAbsoluteUri: true }, SR.GetResourceString(SR.ID4013)); + + return new() + { + AuthorizationCode = context.AuthorizationCode, + AuthorizationResponse = context.Request is not null ? new(context.Request.GetParameters()) : new(), + BackchannelAccessToken = context.BackchannelAccessToken, + BackchannelAccessTokenExpirationDate = context.BackchannelAccessTokenExpirationDate, + BackchannelIdentityToken = context.BackchannelIdentityToken, + BackchannelIdentityTokenPrincipal = context.BackchannelIdentityTokenPrincipal, + FrontchannelAccessToken = context.FrontchannelAccessToken, + FrontchannelAccessTokenExpirationDate = context.FrontchannelAccessTokenExpirationDate, + FrontchannelIdentityToken = context.FrontchannelIdentityToken, + FrontchannelIdentityTokenPrincipal = context.FrontchannelIdentityTokenPrincipal, + Principal = context.MergedPrincipal, + Properties = context.Properties, + RefreshToken = context.RefreshToken, + StateTokenPrincipal = context.StateTokenPrincipal, + TokenResponse = context.TokenResponse ?? new(), + UserInfoTokenPrincipal = context.UserInfoTokenPrincipal + }; } /// @@ -652,24 +649,21 @@ public async ValueTask AuthenticateWithDeviceAsync(D context.Error, context.ErrorDescription, context.ErrorUri); } - else - { - Debug.Assert(context.Registration.Issuer is { IsAbsoluteUri: true }, SR.GetResourceString(SR.ID4013)); + Debug.Assert(context.Registration.Issuer is { IsAbsoluteUri: true }, SR.GetResourceString(SR.ID4013)); - return new() - { - AccessToken = context.BackchannelAccessToken!, - AccessTokenExpirationDate = context.BackchannelAccessTokenExpirationDate, - IdentityToken = context.BackchannelIdentityToken, - IdentityTokenPrincipal = context.BackchannelIdentityTokenPrincipal, - Principal = context.MergedPrincipal, - Properties = context.Properties, - RefreshToken = context.RefreshToken, - TokenResponse = context.TokenResponse ?? new(), - UserInfoToken = context.UserInfoToken, - UserInfoTokenPrincipal = context.UserInfoTokenPrincipal - }; - } + return new() + { + AccessToken = context.BackchannelAccessToken!, + AccessTokenExpirationDate = context.BackchannelAccessTokenExpirationDate, + IdentityToken = context.BackchannelIdentityToken, + IdentityTokenPrincipal = context.BackchannelIdentityTokenPrincipal, + Principal = context.MergedPrincipal, + Properties = context.Properties, + RefreshToken = context.RefreshToken, + TokenResponse = context.TokenResponse ?? new(), + UserInfoToken = context.UserInfoToken, + UserInfoTokenPrincipal = context.UserInfoTokenPrincipal + }; } catch (ProtocolException exception) when (exception.Error is Errors.AuthorizationPending) diff --git a/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs b/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs index fe1b58c3e..49f9fbd88 100644 --- a/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs +++ b/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs @@ -582,13 +582,7 @@ public virtual async ValueTask> GetDisp { ArgumentNullException.ThrowIfNull(application); - var names = await Store.GetDisplayNamesAsync(application, cancellationToken); - if (names is not { Count: > 0 }) - { - return ImmutableDictionary.Create(); - } - - return names; + return await Store.GetDisplayNamesAsync(application, cancellationToken) is { IsEmpty: false } names ? names : []; } /// @@ -2007,7 +2001,9 @@ ValueTask> IOpenIddictApplicationManage /// ValueTask IOpenIddictApplicationManager.GetLocalizedDisplayNameAsync(object application, CancellationToken cancellationToken) +#pragma warning disable MA0011 => GetLocalizedDisplayNameAsync((TApplication) application, cancellationToken); +#pragma warning restore MA0011 /// ValueTask IOpenIddictApplicationManager.GetLocalizedDisplayNameAsync(object application, CultureInfo culture, CancellationToken cancellationToken) diff --git a/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs b/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs index 901a18d1f..fd823537f 100644 --- a/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs +++ b/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs @@ -896,7 +896,7 @@ async IAsyncEnumerable ExecuteAsync([EnumeratorCancellation] C break; } - if (scope.Contains(Separators.Space[0])) + if (scope.Contains(Separators.Space[0], StringComparison.Ordinal)) { yield return new ValidationResult(SR.GetResourceString(SR.ID2042)); diff --git a/src/OpenIddict.Core/Managers/OpenIddictResourceManager.cs b/src/OpenIddict.Core/Managers/OpenIddictResourceManager.cs index c4cc73a25..a24d0929b 100644 --- a/src/OpenIddict.Core/Managers/OpenIddictResourceManager.cs +++ b/src/OpenIddict.Core/Managers/OpenIddictResourceManager.cs @@ -12,6 +12,7 @@ using System.Text.Json; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; +using static System.Net.Mime.MediaTypeNames; using ValidationException = OpenIddict.Abstractions.OpenIddictExceptions.ValidationException; namespace OpenIddict.Core; @@ -385,13 +386,7 @@ public virtual async ValueTask> GetDesc { ArgumentNullException.ThrowIfNull(resource); - var descriptions = await Store.GetDescriptionsAsync(resource, cancellationToken); - if (descriptions is not { Count: > 0 }) - { - return ImmutableDictionary.Create(); - } - - return descriptions; + return await Store.GetDescriptionsAsync(resource, cancellationToken) is { IsEmpty: false } descriptions ? descriptions : []; } /// @@ -424,13 +419,7 @@ public virtual async ValueTask> GetDisp { ArgumentNullException.ThrowIfNull(resource); - var names = await Store.GetDisplayNamesAsync(resource, cancellationToken); - if (names is not { Count: > 0 }) - { - return ImmutableDictionary.Create(); - } - - return names; + return await Store.GetDisplayNamesAsync(resource, cancellationToken) is { IsEmpty: false } names ? names : []; } /// @@ -880,7 +869,9 @@ ValueTask> IOpenIddictResourceManager.G /// ValueTask IOpenIddictResourceManager.GetLocalizedDescriptionAsync(object resource, CancellationToken cancellationToken) +#pragma warning disable MA0011 => GetLocalizedDescriptionAsync((TResource) resource, cancellationToken); +#pragma warning restore MA0011 /// ValueTask IOpenIddictResourceManager.GetLocalizedDescriptionAsync(object resource, CultureInfo culture, CancellationToken cancellationToken) @@ -888,7 +879,9 @@ ValueTask> IOpenIddictResourceManager.G /// ValueTask IOpenIddictResourceManager.GetLocalizedDisplayNameAsync(object resource, CancellationToken cancellationToken) +#pragma warning disable MA0011 => GetLocalizedDisplayNameAsync((TResource) resource, cancellationToken); +#pragma warning restore MA0011 /// ValueTask IOpenIddictResourceManager.GetLocalizedDisplayNameAsync(object resource, CultureInfo culture, CancellationToken cancellationToken) diff --git a/src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs b/src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs index bf5414862..832fd58ca 100644 --- a/src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs +++ b/src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs @@ -424,13 +424,7 @@ public virtual async ValueTask> GetDesc { ArgumentNullException.ThrowIfNull(scope); - var descriptions = await Store.GetDescriptionsAsync(scope, cancellationToken); - if (descriptions is not { Count: > 0 }) - { - return ImmutableDictionary.Create(); - } - - return descriptions; + return await Store.GetDescriptionsAsync(scope, cancellationToken) is { IsEmpty: false } descriptions ? descriptions : []; } /// @@ -463,13 +457,7 @@ public virtual async ValueTask> GetDisp { ArgumentNullException.ThrowIfNull(scope); - var names = await Store.GetDisplayNamesAsync(scope, cancellationToken); - if (names is not { Count: > 0 }) - { - return ImmutableDictionary.Create(); - } - - return names; + return await Store.GetDisplayNamesAsync(scope, cancellationToken) is { IsEmpty: false } names ? names : []; } /// @@ -870,7 +858,7 @@ async IAsyncEnumerable ExecuteAsync([EnumeratorCancellation] C yield return new ValidationResult(SR.GetResourceString(SR.ID2044)); } - else if (name.Contains(Separators.Space[0])) + else if (name.Contains(Separators.Space[0], StringComparison.Ordinal)) { yield return new ValidationResult(SR.GetResourceString(SR.ID2045)); } @@ -962,7 +950,9 @@ ValueTask> IOpenIddictScopeManager.GetD /// ValueTask IOpenIddictScopeManager.GetLocalizedDescriptionAsync(object scope, CancellationToken cancellationToken) +#pragma warning disable MA0011 => GetLocalizedDescriptionAsync((TScope) scope, cancellationToken); +#pragma warning restore MA0011 /// ValueTask IOpenIddictScopeManager.GetLocalizedDescriptionAsync(object scope, CultureInfo culture, CancellationToken cancellationToken) @@ -970,7 +960,9 @@ ValueTask> IOpenIddictScopeManager.GetD /// ValueTask IOpenIddictScopeManager.GetLocalizedDisplayNameAsync(object scope, CancellationToken cancellationToken) +#pragma warning disable MA0011 => GetLocalizedDisplayNameAsync((TScope) scope, cancellationToken); +#pragma warning restore MA0011 /// ValueTask IOpenIddictScopeManager.GetLocalizedDisplayNameAsync(object scope, CultureInfo culture, CancellationToken cancellationToken) diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkApplicationStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkApplicationStore.cs index dc8d91bc3..1a668a7de 100644 --- a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkApplicationStore.cs +++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkApplicationStore.cs @@ -352,7 +352,7 @@ public virtual ValueTask> GetDisplayNam if (string.IsNullOrEmpty(application.DisplayNames)) { - return new(ImmutableDictionary.Create()); + return new([]); } // Note: parsing the stringified display names is an expensive operation. @@ -498,7 +498,7 @@ public virtual ValueTask> GetProperties if (string.IsNullOrEmpty(application.Properties)) { - return new(ImmutableDictionary.Create()); + return new([]); } // Note: parsing the stringified properties is an expensive operation. @@ -510,7 +510,7 @@ public virtual ValueTask> GetProperties .SetSlidingExpiration(TimeSpan.FromMinutes(1)); using var document = JsonDocument.Parse(application.Properties); - var builder = ImmutableDictionary.CreateBuilder(); + var builder = ImmutableDictionary.CreateBuilder(StringComparer.Ordinal); foreach (var property in document.RootElement.EnumerateObject()) { @@ -606,7 +606,7 @@ public virtual ValueTask> GetSettingsAsync(T if (string.IsNullOrEmpty(application.Settings)) { - return new(ImmutableDictionary.Create()); + return new([]); } // Note: parsing the stringified settings is an expensive operation. @@ -618,7 +618,7 @@ public virtual ValueTask> GetSettingsAsync(T .SetSlidingExpiration(TimeSpan.FromMinutes(1)); using var document = JsonDocument.Parse(application.Settings); - var builder = ImmutableDictionary.CreateBuilder(); + var builder = ImmutableDictionary.CreateBuilder(StringComparer.Ordinal); foreach (var property in document.RootElement.EnumerateObject()) { @@ -1060,17 +1060,14 @@ public virtual async ValueTask UpdateAsync(TApplication application, Cancellatio return (TKey?) (object?) identifier; } - else - { - var converter = + var converter = #if NET - TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); + TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); #else - TypeDescriptor.GetConverter(typeof(TKey)); + TypeDescriptor.GetConverter(typeof(TKey)); #endif - return (TKey?) converter.ConvertFromInvariantString(identifier); - } + return (TKey?) converter.ConvertFromInvariantString(identifier); } /// @@ -1091,16 +1088,13 @@ public virtual async ValueTask UpdateAsync(TApplication application, Cancellatio return value; } - else - { - var converter = + var converter = #if NET - TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); + TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); #else - TypeDescriptor.GetConverter(typeof(TKey)); + TypeDescriptor.GetConverter(typeof(TKey)); #endif - return converter.ConvertToInvariantString(identifier); - } + return converter.ConvertToInvariantString(identifier); } } diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkAuthorizationStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkAuthorizationStore.cs index b6c60f8c7..6519f5ed1 100644 --- a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkAuthorizationStore.cs +++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkAuthorizationStore.cs @@ -302,7 +302,7 @@ async IAsyncEnumerable ExecuteAsync([EnumeratorCancellation] Can { ArgumentNullException.ThrowIfNull(authorization); - return new(authorization.CreationDate is DateTime date ? DateTime.SpecifyKind(date, DateTimeKind.Utc) : null); + return new(authorization.CreationDate is DateTime date ? new DateTimeOffset(DateTime.SpecifyKind(date, DateTimeKind.Utc)) : null); } /// @@ -320,7 +320,7 @@ public virtual ValueTask> GetProperties if (string.IsNullOrEmpty(authorization.Properties)) { - return new(ImmutableDictionary.Create()); + return new([]); } // Note: parsing the stringified properties is an expensive operation. @@ -332,7 +332,7 @@ public virtual ValueTask> GetProperties .SetSlidingExpiration(TimeSpan.FromMinutes(1)); using var document = JsonDocument.Parse(authorization.Properties); - var builder = ImmutableDictionary.CreateBuilder(); + var builder = ImmutableDictionary.CreateBuilder(StringComparer.Ordinal); foreach (var property in document.RootElement.EnumerateObject()) { @@ -894,17 +894,14 @@ public virtual async ValueTask UpdateAsync(TAuthorization authorization, Cancell return (TKey?) (object?) identifier; } - else - { - var converter = + var converter = #if NET - TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); + TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); #else - TypeDescriptor.GetConverter(typeof(TKey)); + TypeDescriptor.GetConverter(typeof(TKey)); #endif - return (TKey?) converter.ConvertFromInvariantString(identifier); - } + return (TKey?) converter.ConvertFromInvariantString(identifier); } /// @@ -925,16 +922,13 @@ public virtual async ValueTask UpdateAsync(TAuthorization authorization, Cancell return value; } - else - { - var converter = + var converter = #if NET - TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); + TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); #else - TypeDescriptor.GetConverter(typeof(TKey)); + TypeDescriptor.GetConverter(typeof(TKey)); #endif - return converter.ConvertToInvariantString(identifier); - } + return converter.ConvertToInvariantString(identifier); } } diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkResourceStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkResourceStore.cs index 783e52498..afa49a1ff 100644 --- a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkResourceStore.cs +++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkResourceStore.cs @@ -210,7 +210,7 @@ public virtual ValueTask> GetDescriptio if (string.IsNullOrEmpty(resource.Descriptions)) { - return new(ImmutableDictionary.Create()); + return new([]); } // Note: parsing the stringified descriptions is an expensive operation. @@ -256,7 +256,7 @@ public virtual ValueTask> GetDisplayNam if (string.IsNullOrEmpty(resource.DisplayNames)) { - return new(ImmutableDictionary.Create()); + return new([]); } // Note: parsing the stringified display names is an expensive operation. @@ -310,7 +310,7 @@ public virtual ValueTask> GetProperties if (string.IsNullOrEmpty(resource.Properties)) { - return new(ImmutableDictionary.Create()); + return new([]); } // Note: parsing the stringified properties is an expensive operation. @@ -322,7 +322,7 @@ public virtual ValueTask> GetProperties .SetSlidingExpiration(TimeSpan.FromMinutes(1)); using var document = JsonDocument.Parse(resource.Properties); - var builder = ImmutableDictionary.CreateBuilder(); + var builder = ImmutableDictionary.CreateBuilder(StringComparer.Ordinal); foreach (var property in document.RootElement.EnumerateObject()) { @@ -579,17 +579,14 @@ public virtual async ValueTask UpdateAsync(TResource resource, CancellationToken return (TKey?) (object?) identifier; } - else - { - var converter = + var converter = #if NET - TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); + TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); #else - TypeDescriptor.GetConverter(typeof(TKey)); + TypeDescriptor.GetConverter(typeof(TKey)); #endif - return (TKey?) converter.ConvertFromInvariantString(identifier); - } + return (TKey?) converter.ConvertFromInvariantString(identifier); } /// @@ -610,16 +607,13 @@ public virtual async ValueTask UpdateAsync(TResource resource, CancellationToken return value; } - else - { - var converter = + var converter = #if NET - TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); + TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); #else - TypeDescriptor.GetConverter(typeof(TKey)); + TypeDescriptor.GetConverter(typeof(TKey)); #endif - return converter.ConvertToInvariantString(identifier); - } + return converter.ConvertToInvariantString(identifier); } } diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkScopeStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkScopeStore.cs index da3efa927..7c339a04f 100644 --- a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkScopeStore.cs +++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkScopeStore.cs @@ -242,7 +242,7 @@ public virtual ValueTask> GetDescriptio if (string.IsNullOrEmpty(scope.Descriptions)) { - return new(ImmutableDictionary.Create()); + return new([]); } // Note: parsing the stringified descriptions is an expensive operation. @@ -288,7 +288,7 @@ public virtual ValueTask> GetDisplayNam if (string.IsNullOrEmpty(scope.DisplayNames)) { - return new(ImmutableDictionary.Create()); + return new([]); } // Note: parsing the stringified display names is an expensive operation. @@ -342,7 +342,7 @@ public virtual ValueTask> GetProperties if (string.IsNullOrEmpty(scope.Properties)) { - return new(ImmutableDictionary.Create()); + return new([]); } // Note: parsing the stringified properties is an expensive operation. @@ -354,7 +354,7 @@ public virtual ValueTask> GetProperties .SetSlidingExpiration(TimeSpan.FromMinutes(1)); using var document = JsonDocument.Parse(scope.Properties); - var builder = ImmutableDictionary.CreateBuilder(); + var builder = ImmutableDictionary.CreateBuilder(StringComparer.Ordinal); foreach (var property in document.RootElement.EnumerateObject()) { @@ -683,17 +683,14 @@ public virtual async ValueTask UpdateAsync(TScope scope, CancellationToken cance return (TKey?) (object?) identifier; } - else - { - var converter = + var converter = #if NET - TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); + TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); #else - TypeDescriptor.GetConverter(typeof(TKey)); + TypeDescriptor.GetConverter(typeof(TKey)); #endif - return (TKey?) converter.ConvertFromInvariantString(identifier); - } + return (TKey?) converter.ConvertFromInvariantString(identifier); } /// @@ -714,16 +711,13 @@ public virtual async ValueTask UpdateAsync(TScope scope, CancellationToken cance return value; } - else - { - var converter = + var converter = #if NET - TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); + TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); #else - TypeDescriptor.GetConverter(typeof(TKey)); + TypeDescriptor.GetConverter(typeof(TKey)); #endif - return converter.ConvertToInvariantString(identifier); - } + return converter.ConvertToInvariantString(identifier); } } diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkSessionStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkSessionStore.cs index 9e0639959..52cf53fcd 100644 --- a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkSessionStore.cs +++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkSessionStore.cs @@ -343,7 +343,7 @@ async IAsyncEnumerable ExecuteAsync([EnumeratorCancellation] Cancellat { ArgumentNullException.ThrowIfNull(session); - return new(session.CreationDate is DateTime date ? DateTime.SpecifyKind(date, DateTimeKind.Utc) : null); + return new(session.CreationDate is DateTime date ? new DateTimeOffset(DateTime.SpecifyKind(date, DateTimeKind.Utc)) : null); } /// @@ -369,7 +369,7 @@ public virtual ValueTask> GetProperties if (string.IsNullOrEmpty(session.Properties)) { - return new(ImmutableDictionary.Create()); + return new([]); } // Note: parsing the stringified properties is an expensive operation. @@ -381,7 +381,7 @@ public virtual ValueTask> GetProperties .SetSlidingExpiration(TimeSpan.FromMinutes(1)); using var document = JsonDocument.Parse(session.Properties); - var builder = ImmutableDictionary.CreateBuilder(); + var builder = ImmutableDictionary.CreateBuilder(StringComparer.Ordinal); foreach (var property in document.RootElement.EnumerateObject()) { @@ -660,17 +660,14 @@ public virtual async ValueTask UpdateAsync(TSession session, CancellationToken c return (TKey?) (object?) identifier; } - else - { - var converter = + var converter = #if NET - TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); + TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); #else - TypeDescriptor.GetConverter(typeof(TKey)); + TypeDescriptor.GetConverter(typeof(TKey)); #endif - return (TKey?) converter.ConvertFromInvariantString(identifier); - } + return (TKey?) converter.ConvertFromInvariantString(identifier); } /// @@ -691,16 +688,13 @@ public virtual async ValueTask UpdateAsync(TSession session, CancellationToken c return value; } - else - { - var converter = + var converter = #if NET - TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); + TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); #else - TypeDescriptor.GetConverter(typeof(TKey)); + TypeDescriptor.GetConverter(typeof(TKey)); #endif - return converter.ConvertToInvariantString(identifier); - } + return converter.ConvertToInvariantString(identifier); } } diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkTokenStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkTokenStore.cs index 3cb832e02..ee6307ff0 100644 --- a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkTokenStore.cs +++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkTokenStore.cs @@ -342,7 +342,7 @@ async IAsyncEnumerable ExecuteAsync([EnumeratorCancellation] Cancellatio { ArgumentNullException.ThrowIfNull(token); - return new(token.CreationDate is DateTime date ? DateTime.SpecifyKind(date, DateTimeKind.Utc) : null); + return new(token.CreationDate is DateTime date ? new DateTimeOffset(DateTime.SpecifyKind(date, DateTimeKind.Utc)) : null); } /// @@ -350,7 +350,7 @@ async IAsyncEnumerable ExecuteAsync([EnumeratorCancellation] Cancellatio { ArgumentNullException.ThrowIfNull(token); - return new(token.ExpirationDate is DateTime date ? DateTime.SpecifyKind(date, DateTimeKind.Utc) : null); + return new(token.ExpirationDate is DateTime date ? new DateTimeOffset(DateTime.SpecifyKind(date, DateTimeKind.Utc)) : null); } /// @@ -376,7 +376,7 @@ public virtual ValueTask> GetProperties if (string.IsNullOrEmpty(token.Properties)) { - return new(ImmutableDictionary.Create()); + return new([]); } // Note: parsing the stringified properties is an expensive operation. @@ -388,7 +388,7 @@ public virtual ValueTask> GetProperties .SetSlidingExpiration(TimeSpan.FromMinutes(1)); using var document = JsonDocument.Parse(token.Properties); - var builder = ImmutableDictionary.CreateBuilder(); + var builder = ImmutableDictionary.CreateBuilder(StringComparer.Ordinal); foreach (var property in document.RootElement.EnumerateObject()) { @@ -406,7 +406,7 @@ public virtual ValueTask> GetProperties { ArgumentNullException.ThrowIfNull(token); - return new(token.RedemptionDate is DateTime date ? DateTime.SpecifyKind(date, DateTimeKind.Utc) : null); + return new(token.RedemptionDate is DateTime date ? new DateTimeOffset(DateTime.SpecifyKind(date, DateTimeKind.Utc)) : null); } /// @@ -1016,17 +1016,14 @@ public virtual async ValueTask UpdateAsync(TToken token, CancellationToken cance return (TKey?) (object?) identifier; } - else - { - var converter = + var converter = #if NET - TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); + TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); #else - TypeDescriptor.GetConverter(typeof(TKey)); + TypeDescriptor.GetConverter(typeof(TKey)); #endif - return (TKey?) converter.ConvertFromInvariantString(identifier); - } + return (TKey?) converter.ConvertFromInvariantString(identifier); } /// @@ -1047,16 +1044,13 @@ public virtual async ValueTask UpdateAsync(TToken token, CancellationToken cance return value; } - else - { - var converter = + var converter = #if NET - TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); + TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); #else - TypeDescriptor.GetConverter(typeof(TKey)); + TypeDescriptor.GetConverter(typeof(TKey)); #endif - return converter.ConvertToInvariantString(identifier); - } + return converter.ConvertToInvariantString(identifier); } } diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreApplicationStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreApplicationStore.cs index c43a71b4d..c8caaa2bf 100644 --- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreApplicationStore.cs +++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreApplicationStore.cs @@ -587,7 +587,7 @@ public virtual ValueTask SetDisplayNamesAsync(TApplication application, ArgumentNullException.ThrowIfNull(application); application.DisplayNames = names is { IsEmpty: false } - ? names.ToImmutableDictionary(static pair => pair.Key.Name, static pair => pair.Value) + ? names.ToImmutableDictionary(static pair => pair.Key.Name, static pair => pair.Value, StringComparer.Ordinal) : null; return ValueTask.CompletedTask; @@ -714,12 +714,9 @@ public virtual async ValueTask UpdateAsync(TApplication application, Cancellatio return (TKey?) (object?) identifier; } - else - { - var converter = TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); + var converter = TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); - return (TKey?) converter.ConvertFromInvariantString(identifier); - } + return (TKey?) converter.ConvertFromInvariantString(identifier); } /// @@ -740,12 +737,9 @@ public virtual async ValueTask UpdateAsync(TApplication application, Cancellatio return value; } - else - { - var converter = TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); + var converter = TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); - return converter.ConvertToInvariantString(identifier); - } + return converter.ConvertToInvariantString(identifier); } /// diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreAuthorizationStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreAuthorizationStore.cs index a5e4303db..7f6939eb8 100644 --- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreAuthorizationStore.cs +++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreAuthorizationStore.cs @@ -361,7 +361,7 @@ async IAsyncEnumerable ExecuteAsync([EnumeratorCancellation] Can { ArgumentNullException.ThrowIfNull(authorization); - return new(authorization.CreationDate is DateTime date ? DateTime.SpecifyKind(date, DateTimeKind.Utc) : null); + return new(authorization.CreationDate is DateTime date ? new DateTimeOffset(DateTime.SpecifyKind(date, DateTimeKind.Utc)) : null); } /// @@ -931,12 +931,9 @@ public virtual async ValueTask UpdateAsync(TAuthorization authorization, Cancell return (TKey?) (object?) identifier; } - else - { - var converter = TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); + var converter = TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); - return (TKey?) converter.ConvertFromInvariantString(identifier); - } + return (TKey?) converter.ConvertFromInvariantString(identifier); } /// @@ -957,12 +954,9 @@ public virtual async ValueTask UpdateAsync(TAuthorization authorization, Cancell return value; } - else - { - var converter = TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); + var converter = TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); - return converter.ConvertToInvariantString(identifier); - } + return converter.ConvertToInvariantString(identifier); } /// diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreResourceStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreResourceStore.cs index 8a6a83385..eb35b1bc8 100644 --- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreResourceStore.cs +++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreResourceStore.cs @@ -334,7 +334,7 @@ public virtual ValueTask SetDescriptionsAsync(TResource resource, ArgumentNullException.ThrowIfNull(resource); resource.Descriptions = descriptions is { IsEmpty: false } - ? descriptions.ToImmutableDictionary(static pair => pair.Key.Name, static pair => pair.Value) + ? descriptions.ToImmutableDictionary(static pair => pair.Key.Name, static pair => pair.Value, StringComparer.Ordinal) : null; return ValueTask.CompletedTask; @@ -357,7 +357,7 @@ public virtual ValueTask SetDisplayNamesAsync(TResource resource, ArgumentNullException.ThrowIfNull(resource); resource.DisplayNames = names is { IsEmpty: false } - ? names.ToImmutableDictionary(static pair => pair.Key.Name, static pair => pair.Value) + ? names.ToImmutableDictionary(static pair => pair.Key.Name, static pair => pair.Value, StringComparer.Ordinal) : null; return ValueTask.CompletedTask; @@ -431,12 +431,9 @@ public virtual async ValueTask UpdateAsync(TResource resource, CancellationToken return (TKey?) (object?) identifier; } - else - { - var converter = TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); + var converter = TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); - return (TKey?) converter.ConvertFromInvariantString(identifier); - } + return (TKey?) converter.ConvertFromInvariantString(identifier); } /// @@ -457,11 +454,8 @@ public virtual async ValueTask UpdateAsync(TResource resource, CancellationToken return value; } - else - { - var converter = TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); + var converter = TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); - return converter.ConvertToInvariantString(identifier); - } + return converter.ConvertToInvariantString(identifier); } } diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreScopeStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreScopeStore.cs index c02bc7072..e81878559 100644 --- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreScopeStore.cs +++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreScopeStore.cs @@ -233,7 +233,7 @@ public virtual ValueTask> GetDescriptio return new(scope.Descriptions is { Count: > 0 } descriptions ? descriptions.ToImmutableDictionary(static pair => CultureInfo.GetCultureInfo(pair.Key), static pair => pair.Value) - : ImmutableDictionary.Create()); + : []); } /// @@ -362,7 +362,7 @@ public virtual ValueTask SetDescriptionsAsync(TScope scope, ArgumentNullException.ThrowIfNull(scope); scope.Descriptions = descriptions is { IsEmpty: false } - ? descriptions.ToImmutableDictionary(static pair => pair.Key.Name, static pair => pair.Value) + ? descriptions.ToImmutableDictionary(static pair => pair.Key.Name, static pair => pair.Value, StringComparer.Ordinal) : null; return ValueTask.CompletedTask; @@ -385,7 +385,7 @@ public virtual ValueTask SetDisplayNamesAsync(TScope scope, ArgumentNullException.ThrowIfNull(scope); scope.DisplayNames = names is { IsEmpty: false } - ? names.ToImmutableDictionary(static pair => pair.Key.Name, static pair => pair.Value) + ? names.ToImmutableDictionary(static pair => pair.Key.Name, static pair => pair.Value, StringComparer.Ordinal) : null; return ValueTask.CompletedTask; @@ -469,12 +469,9 @@ public virtual async ValueTask UpdateAsync(TScope scope, CancellationToken cance return (TKey?) (object?) identifier; } - else - { - var converter = TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); + var converter = TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); - return (TKey?) converter.ConvertFromInvariantString(identifier); - } + return (TKey?) converter.ConvertFromInvariantString(identifier); } /// @@ -495,11 +492,8 @@ public virtual async ValueTask UpdateAsync(TScope scope, CancellationToken cance return value; } - else - { - var converter = TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); + var converter = TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); - return converter.ConvertToInvariantString(identifier); - } + return converter.ConvertToInvariantString(identifier); } } diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreSessionStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreSessionStore.cs index 51e9a9e06..95e45734d 100644 --- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreSessionStore.cs +++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreSessionStore.cs @@ -364,7 +364,7 @@ async IAsyncEnumerable ExecuteAsync([EnumeratorCancellation] Cancellat { ArgumentNullException.ThrowIfNull(session); - return new(session.CreationDate is DateTime date ? DateTime.SpecifyKind(date, DateTimeKind.Utc) : null); + return new(session.CreationDate is DateTime date ? new DateTimeOffset(DateTime.SpecifyKind(date, DateTimeKind.Utc)) : null); } /// @@ -632,12 +632,9 @@ public virtual async ValueTask UpdateAsync(TSession session, CancellationToken c return (TKey?) (object?) identifier; } - else - { - var converter = TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); + var converter = TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); - return (TKey?) converter.ConvertFromInvariantString(identifier); - } + return (TKey?) converter.ConvertFromInvariantString(identifier); } /// @@ -658,11 +655,8 @@ public virtual async ValueTask UpdateAsync(TSession session, CancellationToken c return value; } - else - { - var converter = TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); + var converter = TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); - return converter.ConvertToInvariantString(identifier); - } + return converter.ConvertToInvariantString(identifier); } } diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreTokenStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreTokenStore.cs index aed21f5a1..1b4050e4e 100644 --- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreTokenStore.cs +++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreTokenStore.cs @@ -358,7 +358,7 @@ async IAsyncEnumerable ExecuteAsync([EnumeratorCancellation] Cancellatio { ArgumentNullException.ThrowIfNull(token); - return new(token.CreationDate is DateTime date ? DateTime.SpecifyKind(date, DateTimeKind.Utc) : null); + return new(token.CreationDate is DateTime date ? new DateTimeOffset(DateTime.SpecifyKind(date, DateTimeKind.Utc)) : null); } /// @@ -366,7 +366,7 @@ async IAsyncEnumerable ExecuteAsync([EnumeratorCancellation] Cancellatio { ArgumentNullException.ThrowIfNull(token); - return new(token.ExpirationDate is DateTime date ? DateTime.SpecifyKind(date, DateTimeKind.Utc) : null); + return new(token.ExpirationDate is DateTime date ? new DateTimeOffset(DateTime.SpecifyKind(date, DateTimeKind.Utc)) : null); } /// @@ -398,7 +398,7 @@ public virtual ValueTask> GetProperties { ArgumentNullException.ThrowIfNull(token); - return new(token.RedemptionDate is DateTime date ? DateTime.SpecifyKind(date, DateTimeKind.Utc) : null); + return new(token.RedemptionDate is DateTime date ? new DateTimeOffset(DateTime.SpecifyKind(date, DateTimeKind.Utc)) : null); } /// @@ -1080,12 +1080,9 @@ public virtual async ValueTask UpdateAsync(TToken token, CancellationToken cance return (TKey?) (object?) identifier; } - else - { - var converter = TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); + var converter = TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); - return (TKey?) converter.ConvertFromInvariantString(identifier); - } + return (TKey?) converter.ConvertFromInvariantString(identifier); } /// @@ -1106,12 +1103,9 @@ public virtual async ValueTask UpdateAsync(TToken token, CancellationToken cance return value; } - else - { - var converter = TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); + var converter = TypeDescriptor.GetConverterFromRegisteredType(typeof(TKey)); - return converter.ConvertToInvariantString(identifier); - } + return converter.ConvertToInvariantString(identifier); } /// diff --git a/src/OpenIddict.MongoDb.Models/OpenIddictMongoDbSession.cs b/src/OpenIddict.MongoDb.Models/OpenIddictMongoDbSession.cs index be3b8dfaa..8be258e2b 100644 --- a/src/OpenIddict.MongoDb.Models/OpenIddictMongoDbSession.cs +++ b/src/OpenIddict.MongoDb.Models/OpenIddictMongoDbSession.cs @@ -11,7 +11,7 @@ namespace OpenIddict.MongoDb.Models; /// /// Represents an OpenIddict session. /// -[DebuggerDisplay("Id = {Id.ToString(),nq} ; Name = {Name,nq}")] +[DebuggerDisplay("Id = {Id.ToString(),nq} ; Subject = {Subject,nq} ; LoginId = {LoginId,nq} ; Status = {Status,nq}")] public class OpenIddictMongoDbSession { /// diff --git a/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbApplicationStore.cs b/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbApplicationStore.cs index 2d84c50b0..aa85878e7 100644 --- a/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbApplicationStore.cs +++ b/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbApplicationStore.cs @@ -291,11 +291,11 @@ public virtual ValueTask> GetProperties if (application.Properties is null) { - return new(ImmutableDictionary.Create()); + return new([]); } using var document = JsonDocument.Parse(application.Properties.ToJson()); - var builder = ImmutableDictionary.CreateBuilder(); + var builder = ImmutableDictionary.CreateBuilder(StringComparer.Ordinal); foreach (var property in document.RootElement.EnumerateObject()) { @@ -464,7 +464,7 @@ public virtual ValueTask SetDisplayNamesAsync(TApplication application, ArgumentNullException.ThrowIfNull(application); application.DisplayNames = names is { Count: > 0 } - ? names.ToImmutableDictionary(static pair => pair.Key.Name, static pair => pair.Value) + ? names.ToImmutableDictionary(static pair => pair.Key.Name, static pair => pair.Value, StringComparer.Ordinal) : null; return ValueTask.CompletedTask; diff --git a/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbAuthorizationStore.cs b/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbAuthorizationStore.cs index 44b857ee7..87076cef7 100644 --- a/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbAuthorizationStore.cs +++ b/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbAuthorizationStore.cs @@ -229,7 +229,7 @@ async IAsyncEnumerable ExecuteAsync([EnumeratorCancellation] Can { ArgumentNullException.ThrowIfNull(authorization); - return new(authorization.CreationDate is DateTime date ? DateTime.SpecifyKind(date, DateTimeKind.Utc) : null); + return new(authorization.CreationDate is DateTime date ? new DateTimeOffset(DateTime.SpecifyKind(date, DateTimeKind.Utc)) : null); } /// @@ -247,11 +247,11 @@ public virtual ValueTask> GetProperties if (authorization.Properties is null) { - return new(ImmutableDictionary.Create()); + return new([]); } using var document = JsonDocument.Parse(authorization.Properties.ToJson()); - var builder = ImmutableDictionary.CreateBuilder(); + var builder = ImmutableDictionary.CreateBuilder(StringComparer.Ordinal); foreach (var property in document.RootElement.EnumerateObject()) { diff --git a/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbResourceStore.cs b/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbResourceStore.cs index 1ddf5b886..6f727f8fe 100644 --- a/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbResourceStore.cs +++ b/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbResourceStore.cs @@ -221,11 +221,11 @@ public virtual ValueTask> GetProperties if (resource.Properties is null) { - return new(ImmutableDictionary.Create()); + return new([]); } using var document = JsonDocument.Parse(resource.Properties.ToJson()); - var builder = ImmutableDictionary.CreateBuilder(); + var builder = ImmutableDictionary.CreateBuilder(StringComparer.Ordinal); foreach (var property in document.RootElement.EnumerateObject()) { @@ -313,7 +313,7 @@ public virtual ValueTask SetDescriptionsAsync(TResource resource, ArgumentNullException.ThrowIfNull(resource); resource.Descriptions = descriptions is { Count: > 0 } - ? descriptions.ToImmutableDictionary(static pair => pair.Key.Name, static pair => pair.Value) + ? descriptions.ToImmutableDictionary(static pair => pair.Key.Name, static pair => pair.Value, StringComparer.Ordinal) : null; return ValueTask.CompletedTask; @@ -326,7 +326,7 @@ public virtual ValueTask SetDisplayNamesAsync(TResource resource, ArgumentNullException.ThrowIfNull(resource); resource.DisplayNames = names is { Count: > 0 } - ? names.ToImmutableDictionary(static pair => pair.Key.Name, static pair => pair.Value) + ? names.ToImmutableDictionary(static pair => pair.Key.Name, static pair => pair.Value, StringComparer.Ordinal) : null; return ValueTask.CompletedTask; diff --git a/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbScopeStore.cs b/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbScopeStore.cs index 7d41778b8..b887392cf 100644 --- a/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbScopeStore.cs +++ b/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbScopeStore.cs @@ -240,11 +240,11 @@ public virtual ValueTask> GetProperties if (scope.Properties is null) { - return new(ImmutableDictionary.Create()); + return new([]); } using var document = JsonDocument.Parse(scope.Properties.ToJson()); - var builder = ImmutableDictionary.CreateBuilder(); + var builder = ImmutableDictionary.CreateBuilder(StringComparer.Ordinal); foreach (var property in document.RootElement.EnumerateObject()) { @@ -340,7 +340,7 @@ public virtual ValueTask SetDescriptionsAsync(TScope scope, ArgumentNullException.ThrowIfNull(scope); scope.Descriptions = descriptions is { Count: > 0 } - ? descriptions.ToImmutableDictionary(static pair => pair.Key.Name, static pair => pair.Value) + ? descriptions.ToImmutableDictionary(static pair => pair.Key.Name, static pair => pair.Value, StringComparer.Ordinal) : null; return ValueTask.CompletedTask; @@ -353,7 +353,7 @@ public virtual ValueTask SetDisplayNamesAsync(TScope scope, ArgumentNullException.ThrowIfNull(scope); scope.DisplayNames = names is { Count: > 0 } - ? names.ToImmutableDictionary(static pair => pair.Key.Name, static pair => pair.Value) + ? names.ToImmutableDictionary(static pair => pair.Key.Name, static pair => pair.Value, StringComparer.Ordinal) : null; return ValueTask.CompletedTask; diff --git a/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbSessionStore.cs b/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbSessionStore.cs index 33c43c913..a40e6e6eb 100644 --- a/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbSessionStore.cs +++ b/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbSessionStore.cs @@ -263,7 +263,7 @@ async IAsyncEnumerable ExecuteAsync([EnumeratorCancellation] Cancellat { ArgumentNullException.ThrowIfNull(session); - return new(session.CreationDate is DateTime date ? DateTime.SpecifyKind(date, DateTimeKind.Utc) : null); + return new(session.CreationDate is DateTime date ? new DateTimeOffset(DateTime.SpecifyKind(date, DateTimeKind.Utc)) : null); } /// @@ -289,11 +289,11 @@ public virtual ValueTask> GetProperties if (session.Properties is null) { - return new(ImmutableDictionary.Create()); + return new([]); } using var document = JsonDocument.Parse(session.Properties.ToJson()); - var builder = ImmutableDictionary.CreateBuilder(); + var builder = ImmutableDictionary.CreateBuilder(StringComparer.Ordinal); foreach (var property in document.RootElement.EnumerateObject()) { diff --git a/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbTokenStore.cs b/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbTokenStore.cs index 00d0f25f5..d44e9ed1f 100644 --- a/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbTokenStore.cs +++ b/src/OpenIddict.MongoDb/Stores/OpenIddictMongoDbTokenStore.cs @@ -255,7 +255,7 @@ async IAsyncEnumerable ExecuteAsync([EnumeratorCancellation] Cancellatio { ArgumentNullException.ThrowIfNull(token); - return new(token.CreationDate is DateTime date ? DateTime.SpecifyKind(date, DateTimeKind.Utc) : null); + return new(token.CreationDate is DateTime date ? new DateTimeOffset(DateTime.SpecifyKind(date, DateTimeKind.Utc)) : null); } /// @@ -263,7 +263,7 @@ async IAsyncEnumerable ExecuteAsync([EnumeratorCancellation] Cancellatio { ArgumentNullException.ThrowIfNull(token); - return new(token.ExpirationDate is DateTime date ? DateTime.SpecifyKind(date, DateTimeKind.Utc) : null); + return new(token.ExpirationDate is DateTime date ? new DateTimeOffset(DateTime.SpecifyKind(date, DateTimeKind.Utc)) : null); } /// @@ -289,11 +289,11 @@ public virtual ValueTask> GetProperties if (token.Properties is null) { - return new(ImmutableDictionary.Create()); + return new([]); } using var document = JsonDocument.Parse(token.Properties.ToJson()); - var builder = ImmutableDictionary.CreateBuilder(); + var builder = ImmutableDictionary.CreateBuilder(StringComparer.Ordinal); foreach (var property in document.RootElement.EnumerateObject()) { @@ -308,7 +308,7 @@ public virtual ValueTask> GetProperties { ArgumentNullException.ThrowIfNull(token); - return new(token.RedemptionDate is DateTime date ? DateTime.SpecifyKind(date, DateTimeKind.Utc) : null); + return new(token.RedemptionDate is DateTime date ? new DateTimeOffset(DateTime.SpecifyKind(date, DateTimeKind.Utc)) : null); } /// diff --git a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandler.cs b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandler.cs index ef08d9f7e..35d69def6 100644 --- a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandler.cs +++ b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandler.cs @@ -76,12 +76,12 @@ public async Task HandleRequestAsync() return true; } - else if (context.IsRequestSkipped) + if (context.IsRequestSkipped) { return false; } - else if (context.IsRejected) + if (context.IsRejected) { var notification = new ProcessErrorContext(transaction) { @@ -98,7 +98,7 @@ public async Task HandleRequestAsync() return true; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { return false; } @@ -133,7 +133,7 @@ protected override async Task HandleAuthenticateAsync() return AuthenticateResult.NoResult(); } - else if (context.IsRejected) + if (context.IsRejected) { // Note: the missing_token error is special-cased to indicate to ASP.NET Core // that no authentication result could be produced due to the lack of token. @@ -405,7 +405,7 @@ protected override async Task HandleChallengeAsync(AuthenticationProperties? pro return; } - else if (context.IsRejected) + if (context.IsRejected) { var notification = new ProcessErrorContext(transaction) { @@ -453,7 +453,7 @@ public async Task SignInAsync(ClaimsPrincipal user, AuthenticationProperties? pr return; } - else if (context.IsRejected) + if (context.IsRejected) { var notification = new ProcessErrorContext(transaction) { @@ -494,7 +494,7 @@ public async Task SignOutAsync(AuthenticationProperties? properties) return; } - else if (context.IsRejected) + if (context.IsRejected) { var notification = new ProcessErrorContext(transaction) { diff --git a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.cs b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.cs index d2c342338..7bd5b3615 100644 --- a/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.cs +++ b/src/OpenIddict.Server.AspNetCore/OpenIddictServerAspNetCoreHandlers.cs @@ -768,7 +768,7 @@ public ValueTask HandleAsync(TContext context) var value = header["Basic ".Length..].Trim(); var data = Encoding.ASCII.GetString(Convert.FromBase64String(value)); - var index = data.IndexOf(':'); + var index = data.IndexOf(':', StringComparison.Ordinal); if (index is < 0) { context.Reject( @@ -803,7 +803,7 @@ public ValueTask HandleAsync(TContext context) return null; } - return Uri.UnescapeDataString(data.Replace("+", "%20")); + return Uri.UnescapeDataString(data.Replace("+", "%20", StringComparison.Ordinal)); } } } @@ -1102,7 +1102,7 @@ Parameters.ErrorDescription or builder.Append(parameter.Key); builder.Append('='); builder.Append('"'); - builder.Append(parameter.Value.Replace("\"", "\\\"")); + builder.Append(parameter.Value.Replace("\"", "\\\"", StringComparison.Ordinal)); builder.Append('"'); builder.Append(','); } diff --git a/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionFormatter.cs b/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionFormatter.cs index d792d6b7f..4c5d347e2 100644 --- a/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionFormatter.cs +++ b/src/OpenIddict.Server.DataProtection/OpenIddictServerDataProtectionFormatter.cs @@ -192,7 +192,7 @@ public void WriteToken(BinaryWriter writer, ClaimsPrincipal principal) ArgumentNullException.ThrowIfNull(writer); ArgumentNullException.ThrowIfNull(principal); - var properties = new Dictionary(); + var properties = new Dictionary(StringComparer.Ordinal); // Unlike ASP.NET Core Data Protection-based tokens, tokens serialized using the new format // can't include authentication properties. To ensure tokens can be used with previous versions diff --git a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandler.cs b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandler.cs index 10f5383f9..93dce5a9f 100644 --- a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandler.cs +++ b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandler.cs @@ -86,12 +86,12 @@ public override async Task InvokeAsync() return true; } - else if (context.IsRequestSkipped) + if (context.IsRequestSkipped) { return false; } - else if (context.IsRejected) + if (context.IsRejected) { var notification = new ProcessErrorContext(transaction) { @@ -108,7 +108,7 @@ public override async Task InvokeAsync() return true; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { return false; } @@ -143,7 +143,7 @@ public override async Task InvokeAsync() return null; } - else if (context.IsRejected) + if (context.IsRejected) { // Note: the missing_token error is special-cased to indicate to Katana // that no authentication result could be produced due to the lack of token. @@ -302,7 +302,7 @@ protected override async Task TeardownCoreAsync() return; } - else if (context.IsRejected) + if (context.IsRejected) { var notification = new ProcessErrorContext(transaction) { @@ -344,7 +344,7 @@ protected override async Task TeardownCoreAsync() return; } - else if (context.IsRejected) + if (context.IsRejected) { var notification = new ProcessErrorContext(transaction) { @@ -385,7 +385,7 @@ protected override async Task TeardownCoreAsync() return; } - else if (context.IsRejected) + if (context.IsRejected) { var notification = new ProcessErrorContext(transaction) { diff --git a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.cs b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.cs index 29ff2a08e..02b7eddba 100644 --- a/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.cs +++ b/src/OpenIddict.Server.Owin/OpenIddictServerOwinHandlers.cs @@ -845,7 +845,7 @@ public ValueTask HandleAsync(TContext context) var value = header["Basic ".Length..].Trim(); var data = Encoding.ASCII.GetString(Convert.FromBase64String(value)); - var index = data.IndexOf(':'); + var index = data.IndexOf(':', StringComparison.Ordinal); if (index is < 0) { context.Reject( @@ -880,7 +880,7 @@ public ValueTask HandleAsync(TContext context) return null; } - return Uri.UnescapeDataString(data.Replace("+", "%20")); + return Uri.UnescapeDataString(data.Replace("+", "%20", StringComparison.Ordinal)); } } } @@ -1293,7 +1293,7 @@ Parameters.ErrorDescription or builder.Append(parameter.Key); builder.Append('='); builder.Append('"'); - builder.Append(parameter.Value.Replace("\"", "\\\"")); + builder.Append(parameter.Value.Replace("\"", "\\\"", StringComparison.Ordinal)); builder.Append('"'); builder.Append(','); } diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Authentication.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Authentication.cs index 5231b99f1..fb84140c7 100644 --- a/src/OpenIddict.Server/OpenIddictServerHandlers.Authentication.cs +++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Authentication.cs @@ -154,13 +154,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -217,13 +217,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -276,13 +276,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -315,13 +315,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (@event.IsRequestSkipped) + if (@event.IsRequestSkipped) { context.SkipRequest(); return; } - else if (@event.IsRejected) + if (@event.IsRejected) { context.Reject( error: @event.Error ?? Errors.InvalidRequest, @@ -356,13 +356,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (@event.IsRequestSkipped) + if (@event.IsRequestSkipped) { context.SkipRequest(); return; } - else if (@event.IsRejected) + if (@event.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -411,7 +411,7 @@ public async ValueTask HandleAsync(TContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; @@ -605,13 +605,13 @@ public async ValueTask HandleAsync(ValidateAuthorizationRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -2369,13 +2369,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -2433,13 +2433,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -2493,13 +2493,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -2539,13 +2539,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (@event.IsRequestSkipped) + if (@event.IsRequestSkipped) { context.SkipRequest(); return; } - else if (@event.IsRejected) + if (@event.IsRejected) { context.Reject( error: @event.Error ?? Errors.InvalidGrant, @@ -2592,7 +2592,7 @@ public async ValueTask HandleAsync(TContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; @@ -3392,13 +3392,13 @@ public async ValueTask HandleAsync(ValidatePushedAuthorizationRequestContext con return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Device.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Device.cs index ca052ea46..d48d6fbbe 100644 --- a/src/OpenIddict.Server/OpenIddictServerHandlers.Device.cs +++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Device.cs @@ -98,13 +98,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -157,13 +157,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -211,13 +211,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -257,13 +257,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (@event.IsRequestSkipped) + if (@event.IsRequestSkipped) { context.SkipRequest(); return; } - else if (@event.IsRejected) + if (@event.IsRejected) { context.Reject( error: @event.Error ?? Errors.InvalidGrant, @@ -309,7 +309,7 @@ public async ValueTask HandleAsync(TContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; @@ -544,13 +544,13 @@ public async ValueTask HandleAsync(ValidateDeviceAuthorizationRequestContext con return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -778,13 +778,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -841,13 +841,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -895,13 +895,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -934,13 +934,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (@event.IsRequestSkipped) + if (@event.IsRequestSkipped) { context.SkipRequest(); return; } - else if (@event.IsRejected) + if (@event.IsRejected) { context.Reject( error: @event.Error ?? Errors.InvalidGrant, @@ -989,7 +989,7 @@ public async ValueTask HandleAsync(TContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; @@ -1037,13 +1037,13 @@ public async ValueTask HandleAsync(ValidateEndUserVerificationRequestContext con return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Discovery.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Discovery.cs index 0992a38ba..c7769de40 100644 --- a/src/OpenIddict.Server/OpenIddictServerHandlers.Discovery.cs +++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Discovery.cs @@ -99,13 +99,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -158,13 +158,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -212,13 +212,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -339,7 +339,7 @@ public async ValueTask HandleAsync(TContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; @@ -902,13 +902,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -961,13 +961,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -1015,13 +1015,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -1166,7 +1166,7 @@ public async ValueTask HandleAsync(TContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; @@ -1257,7 +1257,7 @@ SecurityAlgorithms.RsaSsaPssSha512 or SecurityAlgorithms.RsaSsaPssSha512Signatur if (credentials.Key.IsSupportedAlgorithm(SecurityAlgorithms.EcdsaSha256) || credentials.Key.IsSupportedAlgorithm(SecurityAlgorithms.EcdsaSha384) || credentials.Key.IsSupportedAlgorithm(SecurityAlgorithms.EcdsaSha512)) - {; + { if (!TryGetECParameters(credentials.Key, out var parameters)) { context.Logger.LogWarning(6074, SR.GetResourceString(SR.ID6074), credentials.Key.GetType().Name); diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Exchange.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Exchange.cs index 6d22cf526..2d2f6d83e 100644 --- a/src/OpenIddict.Server/OpenIddictServerHandlers.Exchange.cs +++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Exchange.cs @@ -110,13 +110,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -173,13 +173,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -227,13 +227,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidGrant, @@ -266,13 +266,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (@event.IsRequestSkipped) + if (@event.IsRequestSkipped) { context.SkipRequest(); return; } - else if (@event.IsRejected) + if (@event.IsRejected) { context.Reject( error: @event.Error ?? Errors.InvalidRequest, @@ -321,7 +321,7 @@ public async ValueTask HandleAsync(TContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; @@ -1226,13 +1226,13 @@ public async ValueTask HandleAsync(ValidateTokenRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -2099,11 +2099,7 @@ public ValueTask HandleAsync(ValidateTokenRequestContext context) return ValueTask.CompletedTask; } - // When an explicit scope parameter has been included in the token request, - // the authorization server MUST ensure that it doesn't contain scopes - // that were not granted during the initial authorization/token request. - // See https://tools.ietf.org/html/rfc6749#section-6 for more information. - else if (!scopes.IsSupersetOf(context.Request.GetScopes())) + if (!scopes.IsSupersetOf(context.Request.GetScopes())) { context.Logger.LogInformation(6095, SR.GetResourceString(SR.ID6095), Parameters.Scope); @@ -2172,7 +2168,7 @@ public ValueTask HandleAsync(HandleTokenRequestContext context) // reused as-is and that a new ad-hoc authorization, separate from the one attached // to the subject token will be created and attached to the issued token by OpenIddict. GrantTypes.TokenExchange => notification.SubjectTokenPrincipal - ?.Clone(claim => !claim.Type.StartsWith(Claims.Prefixes.Private)), + ?.Clone(claim => !claim.Type.StartsWith(Claims.Prefixes.Private, StringComparison.Ordinal)), _ => null }; diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Introspection.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Introspection.cs index 51f1eac2e..0de32866d 100644 --- a/src/OpenIddict.Server/OpenIddictServerHandlers.Introspection.cs +++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Introspection.cs @@ -91,13 +91,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -154,13 +154,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -208,13 +208,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -229,7 +229,7 @@ public async ValueTask HandleAsync(ProcessRequestContext context) [Claims.Issuer] = notification.Issuer?.AbsoluteUri, [Claims.Username] = notification.Username, [Claims.Subject] = notification.Subject, - [Claims.Scope] = string.Join(" ", notification.Scopes), + [Claims.Scope] = string.Join(Separators.Space[0], notification.Scopes), [Claims.JwtId] = notification.TokenId, [Claims.TokenType] = notification.TokenType, [Claims.TokenUsage] = notification.TokenUsage, @@ -313,7 +313,7 @@ public async ValueTask HandleAsync(TContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; @@ -474,13 +474,13 @@ public async ValueTask HandleAsync(ValidateIntrospectionRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -830,7 +830,7 @@ public async ValueTask HandleAsync(HandleIntrospectionRequestContext context) context.Username = context.GenericTokenPrincipal.Identity.Name; context.Scopes.UnionWith(context.GenericTokenPrincipal.GetScopes()); - foreach (var group in context.GenericTokenPrincipal.Claims.GroupBy(claim => claim.Type)) + foreach (var group in context.GenericTokenPrincipal.Claims.GroupBy(claim => claim.Type, StringComparer.Ordinal)) { // Exclude standard claims, that are already handled via strongly-typed properties. // Make sure to always update this list when adding new built-in claim properties. diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Protection.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Protection.cs index dbbc0a8f0..5c4cf8cbb 100644 --- a/src/OpenIddict.Server/OpenIddictServerHandlers.Protection.cs +++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Protection.cs @@ -587,7 +587,7 @@ JsonWebTokenTypes.ClientAuthentication or // retrieved as a Dictionary and converted to ImmutableDictionary. if (token.TryGetPayloadValue(Claims.Private.ClaimDestinationsMap, out Dictionary destinations)) { - var builder = ImmutableDictionary.CreateBuilder>(); + var builder = ImmutableDictionary.CreateBuilder>(StringComparer.Ordinal); foreach (var destination in destinations) { @@ -640,7 +640,7 @@ public ValueTask HandleAsync(ValidateTokenContext context) var scopes = context.Principal.GetClaims(Claims.Scope); if (scopes.Length is > 1) { - context.Principal.SetClaim(Claims.Scope, string.Join(" ", scopes)); + context.Principal.SetClaim(Claims.Scope, string.Join(Separators.Space[0], scopes)); } return ValueTask.CompletedTask; @@ -1700,7 +1700,7 @@ public ValueTask HandleAsync(GenerateTokenContext context) var scopes = context.Principal.GetScopes(); if (scopes.Any()) { - claims.Add(Claims.Scope, string.Join(" ", scopes)); + claims.Add(Claims.Scope, string.Join(Separators.Space[0], scopes)); } claims.Add(Claims.JwtId, Guid.NewGuid().ToString()); diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Revocation.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Revocation.cs index c08954c9e..b89b50131 100644 --- a/src/OpenIddict.Server/OpenIddictServerHandlers.Revocation.cs +++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Revocation.cs @@ -83,13 +83,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -146,13 +146,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -200,13 +200,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -254,7 +254,7 @@ public async ValueTask HandleAsync(TContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; @@ -415,13 +415,13 @@ public async ValueTask HandleAsync(ValidateRevocationRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Session.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Session.cs index b148823dd..5fc9a54eb 100644 --- a/src/OpenIddict.Server/OpenIddictServerHandlers.Session.cs +++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Session.cs @@ -90,13 +90,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -153,13 +153,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -207,13 +207,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -245,13 +245,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (@event.IsRequestSkipped) + if (@event.IsRequestSkipped) { context.SkipRequest(); return; } - else if (@event.IsRejected) + if (@event.IsRejected) { context.Reject( error: @event.Error ?? Errors.InvalidRequest, @@ -286,13 +286,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (@event.IsRequestSkipped) + if (@event.IsRequestSkipped) { context.SkipRequest(); return; } - else if (@event.IsRejected) + if (@event.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -341,7 +341,7 @@ public async ValueTask HandleAsync(TContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; @@ -488,13 +488,13 @@ public async ValueTask HandleAsync(ValidateEndSessionRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Userinfo.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Userinfo.cs index a023e3d79..5f0b90ec4 100644 --- a/src/OpenIddict.Server/OpenIddictServerHandlers.Userinfo.cs +++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Userinfo.cs @@ -76,13 +76,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -139,13 +139,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -193,13 +193,13 @@ public async ValueTask HandleAsync(ProcessRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -282,7 +282,7 @@ public async ValueTask HandleAsync(TContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; @@ -366,13 +366,13 @@ public async ValueTask HandleAsync(ValidateUserInfoRequestContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.cs index 39be5ef86..5ef3669a7 100644 --- a/src/OpenIddict.Server/OpenIddictServerHandlers.cs +++ b/src/OpenIddict.Server/OpenIddictServerHandlers.cs @@ -662,13 +662,13 @@ public async ValueTask HandleAsync(ProcessAuthenticationContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { if (context.RejectClientAssertion) { @@ -710,8 +710,8 @@ public ValueTask HandleAsync(ProcessAuthenticationContext context) Debug.Assert(context.ClientAssertionPrincipal is { Identity: ClaimsIdentity }, SR.GetResourceString(SR.ID4006)); foreach (var group in context.ClientAssertionPrincipal.Claims - .GroupBy(static claim => claim.Type) - .ToDictionary(static group => group.Key, group => group.ToList()) + .GroupBy(static claim => claim.Type, StringComparer.Ordinal) + .ToDictionary(static group => group.Key, group => group.ToList(), StringComparer.Ordinal) .Where(static group => !ValidateClaimGroup(group.Key, group.Value))) { context.Reject( @@ -1545,13 +1545,13 @@ public async ValueTask HandleAsync(ProcessAuthenticationContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { if (context.RejectRequestToken) { @@ -1667,13 +1667,13 @@ public async ValueTask HandleAsync(ProcessAuthenticationContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { if (context.RejectAccessToken) { @@ -1746,13 +1746,13 @@ public async ValueTask HandleAsync(ProcessAuthenticationContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { if (context.RejectAuthorizationCode) { @@ -1825,13 +1825,13 @@ public async ValueTask HandleAsync(ProcessAuthenticationContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { if (context.RejectDeviceCode) { @@ -1921,13 +1921,13 @@ public async ValueTask HandleAsync(ProcessAuthenticationContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { if (context.RejectGenericToken) { @@ -2007,13 +2007,13 @@ OpenIddictServerEndpointType.EndSession or return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { if (context.RejectIdentityToken) { @@ -2086,13 +2086,13 @@ public async ValueTask HandleAsync(ProcessAuthenticationContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { if (context.RejectRefreshToken) { @@ -2192,13 +2192,13 @@ when context.EndpointType is OpenIddictServerEndpointType.Token && return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { if (context.RejectSubjectToken) { @@ -2298,13 +2298,13 @@ when context.EndpointType is OpenIddictServerEndpointType.Token && return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { if (context.RejectActorToken) { @@ -2377,13 +2377,13 @@ public async ValueTask HandleAsync(ProcessAuthenticationContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { if (context.RejectUserCode) { @@ -2840,8 +2840,8 @@ when context.Options.EnableEndSessionRequestCaching && } foreach (var group in context.Principal.Claims - .GroupBy(static claim => claim.Type) - .ToDictionary(static group => group.Key, static group => group.ToList()) + .GroupBy(static claim => claim.Type, StringComparer.Ordinal) + .ToDictionary(static group => group.Key, static group => group.ToList(), StringComparer.Ordinal) .Where(static group => !ValidateClaimGroup(group.Key, group.Value))) { throw new InvalidOperationException(SR.FormatID0424(group.Key)); @@ -3089,11 +3089,11 @@ OpenIddictServerEndpointType.Token when context.Request.IsRefreshTokenGrantType( // Restore the internal claims resolved from the token. foreach (var claims in principal.Claims - .Where(claim => claim.Type.StartsWith(Claims.Prefixes.Private, StringComparison.OrdinalIgnoreCase)) - .GroupBy(claim => claim.Type)) + .Where(claim => claim.Type.StartsWith(Claims.Prefixes.Private, StringComparison.Ordinal)) + .GroupBy(claim => claim.Type, StringComparer.Ordinal)) { // If the specified principal already contains one claim of the iterated type, ignore them. - if (context.Principal.Claims.Any(claim => claim.Type == claims.Key)) + if (context.Principal.Claims.Any(claim => string.Equals(claim.Type, claims.Key, StringComparison.Ordinal))) { continue; } @@ -3652,7 +3652,7 @@ public async ValueTask HandleAsync(ProcessSignInContext context) context.Request.IsRefreshTokenGrantType() && !string.IsNullOrEmpty(context.Request.Scope)) { var scopes = context.Request.GetScopes(); - principal.SetScopes(scopes.Intersect(context.Principal.GetScopes())); + principal.SetScopes(scopes.Intersect(context.Principal.GetScopes(), StringComparer.Ordinal)); context.Logger.LogDebug(6010, SR.GetResourceString(SR.ID6010), scopes); } @@ -4807,13 +4807,13 @@ public async ValueTask HandleAsync(ProcessSignInContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -4871,13 +4871,13 @@ public async ValueTask HandleAsync(ProcessSignInContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -4949,13 +4949,13 @@ public async ValueTask HandleAsync(ProcessSignInContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -5025,13 +5025,13 @@ public async ValueTask HandleAsync(ProcessSignInContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -5089,13 +5089,13 @@ public async ValueTask HandleAsync(ProcessSignInContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -5155,13 +5155,13 @@ public async ValueTask HandleAsync(ProcessSignInContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -5436,13 +5436,13 @@ public async ValueTask HandleAsync(ProcessSignInContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -5501,13 +5501,13 @@ public async ValueTask HandleAsync(ProcessSignInContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -5622,7 +5622,7 @@ public ValueTask HandleAsync(ProcessSignInContext context) context.Request.IsAuthorizationCodeGrantType()) || !scopes.SetEquals(context.Request.GetScopes())) { - context.Response.Scope = string.Join(" ", scopes); + context.Response.Scope = string.Join(Separators.Space[0], scopes); } } } diff --git a/src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandler.cs b/src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandler.cs index 953fabc5d..e9807f6c6 100644 --- a/src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandler.cs +++ b/src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandler.cs @@ -74,12 +74,12 @@ public async Task HandleRequestAsync() return true; } - else if (context.IsRequestSkipped) + if (context.IsRequestSkipped) { return false; } - else if (context.IsRejected) + if (context.IsRejected) { var notification = new ProcessErrorContext(transaction) { @@ -96,7 +96,7 @@ public async Task HandleRequestAsync() return true; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { return false; } @@ -131,7 +131,7 @@ protected override async Task HandleAuthenticateAsync() return AuthenticateResult.NoResult(); } - else if (context.IsRejected) + if (context.IsRejected) { // Note: the missing_token error is special-cased to indicate to ASP.NET Core // that no authentication result could be produced due to the lack of token. @@ -226,7 +226,7 @@ protected override async Task HandleChallengeAsync(AuthenticationProperties? pro return; } - else if (context.IsRejected) + if (context.IsRejected) { var notification = new ProcessErrorContext(transaction) { diff --git a/src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandlers.cs b/src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandlers.cs index a91401ba0..fabf4d918 100644 --- a/src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandlers.cs +++ b/src/OpenIddict.Validation.AspNetCore/OpenIddictValidationAspNetCoreHandlers.cs @@ -23,7 +23,7 @@ namespace OpenIddict.Validation.AspNetCore; [EditorBrowsable(EditorBrowsableState.Never)] -public static partial class OpenIddictValidationAspNetCoreHandlers +public static class OpenIddictValidationAspNetCoreHandlers { public static ImmutableArray DefaultHandlers { get; } = [ @@ -601,7 +601,7 @@ Parameters.ErrorDescription or builder.Append(parameter.Key); builder.Append('='); builder.Append('"'); - builder.Append(parameter.Value.Replace("\"", "\\\"")); + builder.Append(parameter.Value.Replace("\"", "\\\"", StringComparison.Ordinal)); builder.Append('"'); builder.Append(','); } diff --git a/src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandler.cs b/src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandler.cs index cb4251a22..d6612fa8b 100644 --- a/src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandler.cs +++ b/src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandler.cs @@ -86,12 +86,12 @@ public override async Task InvokeAsync() return true; } - else if (context.IsRequestSkipped) + if (context.IsRequestSkipped) { return false; } - else if (context.IsRejected) + if (context.IsRejected) { var notification = new ProcessErrorContext(transaction) { @@ -108,7 +108,7 @@ public override async Task InvokeAsync() return true; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { return false; } @@ -143,7 +143,7 @@ public override async Task InvokeAsync() return null; } - else if (context.IsRejected) + if (context.IsRejected) { // Note: the missing_token error is special-cased to indicate to Katana // that no authentication result could be produced due to the lack of token. @@ -234,7 +234,7 @@ protected override async Task TeardownCoreAsync() return; } - else if (context.IsRejected) + if (context.IsRejected) { var notification = new ProcessErrorContext(transaction) { diff --git a/src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandlers.cs b/src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandlers.cs index 38fdb4d33..1b54378d5 100644 --- a/src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandlers.cs +++ b/src/OpenIddict.Validation.Owin/OpenIddictValidationOwinHandlers.cs @@ -20,7 +20,7 @@ namespace OpenIddict.Validation.Owin; [EditorBrowsable(EditorBrowsableState.Never)] -public static partial class OpenIddictValidationOwinHandlers +public static class OpenIddictValidationOwinHandlers { public static ImmutableArray DefaultHandlers { get; } = [ @@ -752,7 +752,7 @@ Parameters.ErrorDescription or builder.Append(parameter.Key); builder.Append('='); builder.Append('"'); - builder.Append(parameter.Value.Replace("\"", "\\\"")); + builder.Append(parameter.Value.Replace("\"", "\\\"", StringComparison.Ordinal)); builder.Append('"'); builder.Append(','); } diff --git a/src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHandlers.cs b/src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHandlers.cs index 37bed9450..f3ee4a9f5 100644 --- a/src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHandlers.cs +++ b/src/OpenIddict.Validation.SystemNetHttp/OpenIddictValidationSystemNetHttpHandlers.cs @@ -370,7 +370,7 @@ context.ClientAuthenticationMethod is ClientAuthenticationMethods.ClientSecretBa return ValueTask.CompletedTask; static string? EscapeDataString(string? value) - => value is not null ? Uri.EscapeDataString(value).Replace("%20", "+") : null; + => value is not null ? Uri.EscapeDataString(value).Replace("%20", "+", StringComparison.Ordinal) : null; } } @@ -413,7 +413,8 @@ public ValueTask HandleAsync(TContext context) request.RequestUri = OpenIddictHelpers.AddQueryStringParameters(request.RequestUri, context.Transaction.Request.GetParameters().ToDictionary( static parameter => parameter.Key, - static parameter => (StringValues) parameter.Value)); + static parameter => (StringValues) parameter.Value, + StringComparer.Ordinal)); } // For POST requests, attach the request parameters to the request form by default. @@ -605,7 +606,7 @@ public async ValueTask HandleAsync(TContext context) continue; } - else if (string.Equals(encoding, ContentEncodings.Gzip, StringComparison.OrdinalIgnoreCase)) + if (string.Equals(encoding, ContentEncodings.Gzip, StringComparison.OrdinalIgnoreCase)) { stream ??= await response.Content.ReadAsStreamAsync().WaitAsync(context.CancellationToken); stream = new GZipStream(stream, CompressionMode.Decompress); diff --git a/src/OpenIddict.Validation/OpenIddictValidationHandlers.Protection.cs b/src/OpenIddict.Validation/OpenIddictValidationHandlers.Protection.cs index 1a49d0490..e9d241ecd 100644 --- a/src/OpenIddict.Validation/OpenIddictValidationHandlers.Protection.cs +++ b/src/OpenIddict.Validation/OpenIddictValidationHandlers.Protection.cs @@ -410,7 +410,7 @@ public ValueTask HandleAsync(ValidateTokenContext context) var scopes = context.Principal.GetClaims(Claims.Scope); if (scopes.Length is > 1) { - context.Principal.SetClaim(Claims.Scope, string.Join(" ", scopes)); + context.Principal.SetClaim(Claims.Scope, string.Join(Separators.Space[0], scopes)); } return ValueTask.CompletedTask; diff --git a/src/OpenIddict.Validation/OpenIddictValidationHandlers.cs b/src/OpenIddict.Validation/OpenIddictValidationHandlers.cs index 02c452570..5705a8a95 100644 --- a/src/OpenIddict.Validation/OpenIddictValidationHandlers.cs +++ b/src/OpenIddict.Validation/OpenIddictValidationHandlers.cs @@ -602,13 +602,13 @@ public async ValueTask HandleAsync(ProcessAuthenticationContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { context.Reject( error: notification.Error ?? Errors.InvalidRequest, @@ -993,13 +993,13 @@ public async ValueTask HandleAsync(ProcessAuthenticationContext context) return; } - else if (notification.IsRequestSkipped) + if (notification.IsRequestSkipped) { context.SkipRequest(); return; } - else if (notification.IsRejected) + if (notification.IsRejected) { if (context.RejectAccessToken) { diff --git a/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictConverterTests.cs b/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictConverterTests.cs index a64fa4a10..4bb020f15 100644 --- a/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictConverterTests.cs +++ b/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictConverterTests.cs @@ -85,7 +85,7 @@ public void Read_ThrowsAnExceptionForUnsupportedType(Type type) return converter.Read(ref reader, type, options: null!); }); - Assert.StartsWith(SR.GetResourceString(SR.ID0176), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0176), exception.Message, StringComparison.Ordinal); Assert.Equal("typeToConvert", exception.ParamName); } diff --git a/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictExtensionsTests.cs b/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictExtensionsTests.cs index 2f4271d09..e1e4a921b 100644 --- a/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictExtensionsTests.cs +++ b/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictExtensionsTests.cs @@ -46,7 +46,7 @@ public void GetAcrValues_ReturnsExpectedAcrValues(string? value, string[] values }; // Act and assert - Assert.Equal(values, request.GetAcrValues()); + Assert.Equal(values, request.GetAcrValues(), StringComparer.Ordinal); } [Fact] @@ -107,7 +107,7 @@ public void GetPromptValues_ReturnsExpectedPrompts(string? value, string[] value }; // Act and assert - Assert.Equal(values, request.GetPromptValues()); + Assert.Equal(values, request.GetPromptValues(), StringComparer.Ordinal); } [Fact] @@ -168,7 +168,7 @@ public void GetResponseTypes_ReturnsExpectedResponseTypes(string? value, string[ }; // Act and assert - Assert.Equal(values, request.GetResponseTypes()); + Assert.Equal(values, request.GetResponseTypes(), StringComparer.Ordinal); } [Fact] @@ -203,7 +203,7 @@ public void GetScopes_ReturnsExpectedScopes(string? scope, string[] scopes) }; // Act and assert - Assert.Equal(scopes, request.GetScopes()); + Assert.Equal(scopes, request.GetScopes(), StringComparer.Ordinal); } [Fact] @@ -1091,7 +1091,7 @@ public void Claim_GetDestinations_ReturnsExpectedDestinations(string? destinatio claim.Properties[Properties.Destinations] = destination!; // Act and assert - Assert.Equal(destinations, claim.GetDestinations()); + Assert.Equal(destinations, claim.GetDestinations(), StringComparer.Ordinal); } [Fact] @@ -1185,7 +1185,7 @@ public void Claim_SetDestinations_ThrowsAnExceptionForNullOrEmptyDestinations(st var exception = Assert.Throws(() => claim.SetDestinations(destination!)); Assert.Equal("destinations", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0182), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0182), exception.Message, StringComparison.Ordinal); } [Theory] @@ -1606,7 +1606,7 @@ public void ClaimsIdentity_Clone_ReturnsDifferentInstanceWithFilteredClaims() identity.AddClaim(new Claim(Claims.ClientId, "B56BF6CE-8D8C-4290-A0E7-A4F8EE0A9FC4")); // Act - var clone = identity.Clone(claim => claim.Type == Claims.Name); + var clone = identity.Clone(claim => claim.Type is Claims.Name); clone.AddClaim(new Claim("clone_claim", "value")); // Assert @@ -1626,7 +1626,7 @@ public void ClaimsPrincipal_Clone_ReturnsDifferentInstanceWithFilteredClaims() var principal = new ClaimsPrincipal(identity); // Act - var clone = principal.Clone(claim => claim.Type == Claims.Name); + var clone = principal.Clone(claim => claim.Type is Claims.Name); ((ClaimsIdentity) clone.Identity!).AddClaim(new Claim("clone_claim", "value")); // Assert @@ -1645,7 +1645,7 @@ public void ClaimsIdentity_Clone_ExcludesUnwantedClaims() identity.AddClaim(new Claim(Claims.Subject, "D8F1A010-BD46-4F8F-AD4E-05582307F8F4")); // Act - var clone = identity.Clone(claim => claim.Type == Claims.Name); + var clone = identity.Clone(claim => claim.Type is Claims.Name); // Assert Assert.Single(clone.Claims); @@ -1663,7 +1663,7 @@ public void ClaimsPrincipal_Clone_ExcludesUnwantedClaims() var principal = new ClaimsPrincipal(identity); // Act - var clone = principal.Clone(claim => claim.Type == Claims.Name); + var clone = principal.Clone(claim => claim.Type is Claims.Name); // Assert Assert.Single(clone.Claims); @@ -1683,7 +1683,7 @@ public void ClaimsIdentity_Clone_ExcludesUnwantedClaimsFromActor() identity.Actor.AddClaim(new Claim(Claims.Subject, "D8F1A010-BD46-4F8F-AD4E-05582307F8F4")); // Act - var clone = identity.Clone(claim => claim.Type == Claims.Name); + var clone = identity.Clone(claim => claim.Type is Claims.Name); // Assert Assert.Single(clone.Actor!.Claims); @@ -1704,7 +1704,7 @@ public void ClaimsPrincipal_Clone_ExcludesUnwantedClaimsFromActor() var principal = new ClaimsPrincipal(identity); // Act - var clone = principal.Clone(claim => claim.Type == Claims.Name); + var clone = principal.Clone(claim => claim.Type is Claims.Name); // Assert Assert.Single(((ClaimsIdentity) clone.Identity!).Actor!.Claims); @@ -1746,7 +1746,7 @@ public void ClaimsPrincipal_AddClaimWithString_ThrowsAnExceptionForNullIdentity( var exception = Assert.Throws(() => principal.AddClaim(Claims.Name, "Bob le Bricoleur")); Assert.Equal("principal", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message, StringComparison.Ordinal); } [Theory] @@ -1837,7 +1837,7 @@ public void ClaimsPrincipal_AddClaimWithBoolean_ThrowsAnExceptionForNullIdentity var exception = Assert.Throws(() => principal.AddClaim(Claims.Name, true)); Assert.Equal("principal", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message, StringComparison.Ordinal); } [Theory] @@ -1928,7 +1928,7 @@ public void ClaimsPrincipal_AddClaimWithInteger_ThrowsAnExceptionForNullIdentity var exception = Assert.Throws(() => principal.AddClaim(Claims.Name, 42L)); Assert.Equal("principal", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message, StringComparison.Ordinal); } [Theory] @@ -1992,7 +1992,7 @@ public void ClaimsIdentity_AddClaimWithDictionary_ThrowsAnExceptionForNullIdenti var identity = (ClaimsIdentity) null!; // Act and assert - var exception = Assert.Throws(() => identity.AddClaim(Claims.Name, new Dictionary())); + var exception = Assert.Throws(() => identity.AddClaim(Claims.Name, new Dictionary(StringComparer.Ordinal))); Assert.Equal("identity", exception.ParamName); } @@ -2004,7 +2004,7 @@ public void ClaimsPrincipal_AddClaimWithDictionary_ThrowsAnExceptionForNullPrinc var principal = (ClaimsPrincipal) null!; // Act and assert - var exception = Assert.Throws(() => principal.AddClaim(Claims.Name, new Dictionary())); + var exception = Assert.Throws(() => principal.AddClaim(Claims.Name, new Dictionary(StringComparer.Ordinal))); Assert.Equal("principal", exception.ParamName); } @@ -2016,10 +2016,10 @@ public void ClaimsPrincipal_AddClaimWithDictionary_ThrowsAnExceptionForNullIdent var principal = new ClaimsPrincipal(); // Act and assert - var exception = Assert.Throws(() => principal.AddClaim(Claims.Name, new Dictionary())); + var exception = Assert.Throws(() => principal.AddClaim(Claims.Name, new Dictionary(StringComparer.Ordinal))); Assert.Equal("principal", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message, StringComparison.Ordinal); } [Theory] @@ -2031,7 +2031,7 @@ public void ClaimsIdentity_AddClaimWithDictionary_ThrowsAnExceptionForNullOrEmpt var identity = new ClaimsIdentity(); // Act and assert - var exception = Assert.ThrowsAny(() => identity.AddClaim(type!, new Dictionary())); + var exception = Assert.ThrowsAny(() => identity.AddClaim(type!, new Dictionary(StringComparer.Ordinal))); Assert.Equal("type", exception.ParamName); } @@ -2045,7 +2045,7 @@ public void ClaimsPrincipal_AddClaimWithDictionary_ThrowsAnExceptionForNullOrEmp var principal = new ClaimsPrincipal(new ClaimsIdentity()); // Act and assert - var exception = Assert.ThrowsAny(() => principal.AddClaim(type!, new Dictionary())); + var exception = Assert.ThrowsAny(() => principal.AddClaim(type!, new Dictionary(StringComparer.Ordinal))); Assert.Equal("type", exception.ParamName); } @@ -2057,7 +2057,7 @@ public void ClaimsIdentity_AddClaimWithDictionary_AddsExpectedClaim() var identity = new ClaimsIdentity(); // Act - identity.AddClaim("type", new Dictionary + identity.AddClaim("type", new Dictionary(StringComparer.Ordinal) { ["parameter"] = "value" }); @@ -2073,7 +2073,7 @@ public void ClaimsPrincipal_AddClaimWithDictionary_AddsExpectedClaim() var principal = new ClaimsPrincipal(new ClaimsIdentity()); // Act - principal.AddClaim("type", new Dictionary + principal.AddClaim("type", new Dictionary(StringComparer.Ordinal) { ["parameter"] = "value" }); @@ -2116,7 +2116,7 @@ public void ClaimsPrincipal_AddClaimWithJsonElement_ThrowsAnExceptionForNullIden var exception = Assert.Throws(() => principal.AddClaim(Claims.Name, default(JsonElement))); Assert.Equal("principal", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message, StringComparison.Ordinal); } [Theory] @@ -2158,7 +2158,7 @@ public void ClaimsIdentity_AddClaimWithJsonElement_ThrowsAnExceptionForIncompati JsonSerializer.Deserialize(@"[""Fabrikam"",""Contoso""]"))); Assert.Equal("value", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0185), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0185), exception.Message, StringComparison.Ordinal); } [Fact] @@ -2172,7 +2172,7 @@ public void ClaimsPrincipal_AddClaimWithJsonElement_ThrowsAnExceptionForIncompat JsonSerializer.Deserialize(@"[""Fabrikam"",""Contoso""]"))); Assert.Equal("value", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0185), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0185), exception.Message, StringComparison.Ordinal); } [Fact] @@ -2235,7 +2235,7 @@ public void ClaimsPrincipal_AddClaimWithJsonNode_ThrowsAnExceptionForNullIdentit var exception = Assert.Throws(() => principal.AddClaim(Claims.Name, (JsonNode) null!)); Assert.Equal("principal", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message, StringComparison.Ordinal); } [Theory] @@ -2301,7 +2301,7 @@ public void ClaimsIdentity_AddClaimWithJsonNode_ThrowsAnExceptionForIncompatible new JsonArray(["Fabrikam", "Contoso"]))); Assert.Equal("value", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0185), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0185), exception.Message, StringComparison.Ordinal); } [Fact] @@ -2315,7 +2315,7 @@ public void ClaimsPrincipal_AddClaimWithJsonNode_ThrowsAnExceptionForIncompatibl new JsonArray(["Fabrikam", "Contoso"]))); Assert.Equal("value", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0185), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0185), exception.Message, StringComparison.Ordinal); } [Fact] @@ -2378,7 +2378,7 @@ public void ClaimsPrincipal_AddClaimsWithArray_ThrowsAnExceptionForNullIdentity( var exception = Assert.Throws(() => principal.AddClaims("type", ["value1", "value2"])); Assert.Equal("principal", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message, StringComparison.Ordinal); } [Theory] @@ -2459,7 +2459,7 @@ public void ClaimsIdentity_AddClaimsWithArray_IsCaseInsensitive() identity.AddClaims("TYPE", ["value1", "value2"]); // Assert - Assert.Equal(["value1", "value2"], identity.GetClaims("type")); + Assert.Equal(["value1", "value2"], identity.GetClaims("type"), StringComparer.Ordinal); } [Fact] @@ -2472,7 +2472,7 @@ public void ClaimsPrincipal_AddClaimsWithArray_IsCaseInsensitive() principal.AddClaims("TYPE", ["value1", "value2"]); // Assert - Assert.Equal(["value1", "value2"], principal.GetClaims("type")); + Assert.Equal(["value1", "value2"], principal.GetClaims("type"), StringComparer.Ordinal); } [Fact] @@ -2509,7 +2509,7 @@ public void ClaimsPrincipal_AddClaimsWithJsonElement_ThrowsAnExceptionForNullIde var exception = Assert.Throws(() => principal.AddClaims("type", default(JsonElement))); Assert.Equal("principal", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message, StringComparison.Ordinal); } [Theory] @@ -2551,7 +2551,7 @@ public void ClaimsIdentity_AddClaimsWithJsonElement_ThrowsAnExceptionForIncompat JsonSerializer.Deserialize(@"{""parameter"":""value""}"))); Assert.Equal("value", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0185), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0185), exception.Message, StringComparison.Ordinal); } [Fact] @@ -2565,7 +2565,7 @@ public void ClaimsPrincipal_AddClaimsWithJsonElement_ThrowsAnExceptionForIncompa JsonSerializer.Deserialize(@"{""parameter"":""value""}"))); Assert.Equal("value", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0185), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0185), exception.Message, StringComparison.Ordinal); } [Fact] @@ -2629,7 +2629,7 @@ public void ClaimsIdentity_AddClaimsWithJsonElement_IsCaseInsensitive() identity.AddClaims("TYPE", JsonSerializer.Deserialize(@"[""Fabrikam"",""Contoso""]")); // Assert - Assert.Equal(["Fabrikam", "Contoso"], identity.GetClaims("type")); + Assert.Equal(["Fabrikam", "Contoso"], identity.GetClaims("type"), StringComparer.Ordinal); } [Fact] @@ -2642,7 +2642,7 @@ public void ClaimsPrincipal_AddClaimsWithJsonElement_IsCaseInsensitive() principal.AddClaims("TYPE", JsonSerializer.Deserialize(@"[""Fabrikam"",""Contoso""]")); // Assert - Assert.Equal(["Fabrikam", "Contoso"], principal.GetClaims("type")); + Assert.Equal(["Fabrikam", "Contoso"], principal.GetClaims("type"), StringComparer.Ordinal); } [Fact] @@ -2679,7 +2679,7 @@ public void ClaimsPrincipal_AddClaimsWithJsonArray_ThrowsAnExceptionForNullIdent var exception = Assert.Throws(() => principal.AddClaims("type", (JsonArray) null!)); Assert.Equal("principal", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message, StringComparison.Ordinal); } [Theory] @@ -2795,7 +2795,7 @@ public void ClaimsIdentity_AddClaimsWithJsonArray_IsCaseInsensitive() identity.AddClaims("TYPE", new JsonArray(["Fabrikam", "Contoso"])); // Assert - Assert.Equal(["Fabrikam", "Contoso"], identity.GetClaims("type")); + Assert.Equal(["Fabrikam", "Contoso"], identity.GetClaims("type"), StringComparer.Ordinal); } [Fact] @@ -2808,7 +2808,7 @@ public void ClaimsPrincipal_AddClaimsWithJsonArray_IsCaseInsensitive() principal.AddClaims("TYPE", new JsonArray(["Fabrikam", "Contoso"])); // Assert - Assert.Equal(["Fabrikam", "Contoso"], principal.GetClaims("type")); + Assert.Equal(["Fabrikam", "Contoso"], principal.GetClaims("type"), StringComparer.Ordinal); } [Fact] @@ -3255,7 +3255,7 @@ public void ClaimsPrincipal_SetClaimWithString_ThrowsAnExceptionForNullIdentity( var exception = Assert.Throws(() => principal.SetClaim("type", "value")); Assert.Equal("principal", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message, StringComparison.Ordinal); } [Theory] @@ -3408,7 +3408,7 @@ public void ClaimsPrincipal_SetClaimWithBoolean_ThrowsAnExceptionForNullIdentity var exception = Assert.Throws(() => principal.SetClaim("type", true)); Assert.Equal("principal", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message, StringComparison.Ordinal); } [Theory] @@ -3561,7 +3561,7 @@ public void ClaimsPrincipal_SetClaimWithInteger_ThrowsAnExceptionForNullIdentity var exception = Assert.Throws(() => principal.SetClaim("type", 42L)); Assert.Equal("principal", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message, StringComparison.Ordinal); } [Theory] @@ -3687,7 +3687,7 @@ public void ClaimsIdentity_SetClaimWithDictionary_ThrowsAnExceptionForNullIdenti var identity = (ClaimsIdentity) null!; // Act and assert - var exception = Assert.Throws(() => identity.SetClaim("type", new Dictionary())); + var exception = Assert.Throws(() => identity.SetClaim("type", new Dictionary(StringComparer.Ordinal))); Assert.Equal("identity", exception.ParamName); } @@ -3699,7 +3699,7 @@ public void ClaimsPrincipal_SetClaimWithDictionary_ThrowsAnExceptionForNullPrinc var principal = (ClaimsPrincipal) null!; // Act and assert - var exception = Assert.Throws(() => principal.SetClaim("type", new Dictionary())); + var exception = Assert.Throws(() => principal.SetClaim("type", new Dictionary(StringComparer.Ordinal))); Assert.Equal("principal", exception.ParamName); } @@ -3711,13 +3711,13 @@ public void ClaimsPrincipal_SetClaimWithDictionary_ThrowsAnExceptionForNullIdent var principal = new ClaimsPrincipal(); // Act and assert - var exception = Assert.Throws(() => principal.SetClaim("type", new Dictionary + var exception = Assert.Throws(() => principal.SetClaim("type", new Dictionary(StringComparer.Ordinal) { ["parameter"] = "value" })); Assert.Equal("principal", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message, StringComparison.Ordinal); } [Theory] @@ -3729,7 +3729,7 @@ public void ClaimsIdentity_SetClaimWithDictionary_ThrowsAnExceptionForNullOrEmpt var identity = new ClaimsIdentity(); // Act and assert - var exception = Assert.ThrowsAny(() => identity.SetClaim(type!, new Dictionary())); + var exception = Assert.ThrowsAny(() => identity.SetClaim(type!, new Dictionary(StringComparer.Ordinal))); Assert.Equal("type", exception.ParamName); } @@ -3743,7 +3743,7 @@ public void ClaimsPrincipal_SetClaimWithDictionary_ThrowsAnExceptionForNullOrEmp var principal = new ClaimsPrincipal(new ClaimsIdentity()); // Act and assert - var exception = Assert.ThrowsAny(() => principal.SetClaim(type!, new Dictionary())); + var exception = Assert.ThrowsAny(() => principal.SetClaim(type!, new Dictionary(StringComparer.Ordinal))); Assert.Equal("type", exception.ParamName); } @@ -3756,7 +3756,7 @@ public void ClaimsIdentity_SetClaimWithDictionary_AddsExpectedClaim() identity.AddClaim("type", "value1"); // Act - identity.SetClaim("type", new Dictionary + identity.SetClaim("type", new Dictionary(StringComparer.Ordinal) { ["parameter"] = "value" }, "issuer"); @@ -3776,7 +3776,7 @@ public void ClaimsPrincipal_SetClaimWithDictionary_AddsExpectedClaim() principal.AddClaim("type", "value1"); // Act - principal.SetClaim("type", new Dictionary + principal.SetClaim("type", new Dictionary(StringComparer.Ordinal) { ["parameter"] = "value" }, "issuer"); @@ -3795,7 +3795,7 @@ public void ClaimsIdentity_SetClaimWithDictionary_IsCaseInsensitive() var identity = new ClaimsIdentity(); // Act - identity.SetClaim("TYPE", new Dictionary + identity.SetClaim("TYPE", new Dictionary(StringComparer.Ordinal) { ["parameter"] = "value" }); @@ -3811,7 +3811,7 @@ public void ClaimsPrincipal_SetClaimWithDictionary_IsCaseInsensitive() var principal = new ClaimsPrincipal(new ClaimsIdentity()); // Act - principal.SetClaim("TYPE", new Dictionary + principal.SetClaim("TYPE", new Dictionary(StringComparer.Ordinal) { ["parameter"] = "value" }); @@ -3828,7 +3828,7 @@ public void ClaimsIdentity_SetClaimWithDictionary_RemovesEmptyClaim() identity.AddClaim("type", "value"); // Act - identity.SetClaim("type", new Dictionary()); + identity.SetClaim("type", new Dictionary(StringComparer.Ordinal)); // Assert Assert.Null(identity.GetClaim("type")); @@ -3842,7 +3842,7 @@ public void ClaimsPrincipal_SetClaimWithDictionary_RemovesEmptyClaim() principal.AddClaim("type", "value"); // Act - principal.SetClaim("type", new Dictionary()); + principal.SetClaim("type", new Dictionary(StringComparer.Ordinal)); // Assert Assert.Null(principal.GetClaim("type")); @@ -3883,7 +3883,7 @@ public void ClaimsPrincipal_SetClaimWithJsonElement_ThrowsAnExceptionForNullIden JsonSerializer.Deserialize(@"{""parameter"":""value""}"))); Assert.Equal("principal", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message, StringComparison.Ordinal); } [Theory] @@ -4091,7 +4091,7 @@ public void ClaimsPrincipal_SetClaimWithJsonNode_ThrowsAnExceptionForNullIdentit new JsonObject { ["parameter"] = "value" })); Assert.Equal("principal", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message, StringComparison.Ordinal); } [Theory] @@ -4298,7 +4298,7 @@ public void ClaimsPrincipal_SetClaimsWithArray_ThrowsAnExceptionForNullIdentity( var exception = Assert.Throws(() => principal.SetClaims("type", ["value1", "value2"])); Assert.Equal("principal", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message, StringComparison.Ordinal); } [Theory] @@ -4378,7 +4378,7 @@ public void ClaimsIdentity_SetClaimsWithArray_IsCaseInsensitive() identity.SetClaims("TYPE", ["value1", "value2"]); // Assert - Assert.Equal(["value1", "value2"], identity.GetClaims("type")); + Assert.Equal(["value1", "value2"], identity.GetClaims("type"), StringComparer.Ordinal); } [Fact] @@ -4391,7 +4391,7 @@ public void ClaimsPrincipal_SetClaimsWithArray_IsCaseInsensitive() principal.SetClaims("TYPE", ["value1", "value2"]); // Assert - Assert.Equal(["value1", "value2"], principal.GetClaims("type")); + Assert.Equal(["value1", "value2"], principal.GetClaims("type"), StringComparer.Ordinal); } [Fact] @@ -4457,7 +4457,7 @@ public void ClaimsPrincipal_SetClaimsWithJsonElement_ThrowsAnExceptionForNullIde JsonSerializer.Deserialize(@"[""Fabrikam"",""Contoso""]"))); Assert.Equal("principal", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message, StringComparison.Ordinal); } [Theory] @@ -4537,7 +4537,7 @@ public void ClaimsIdentity_SetClaimsWithJsonElement_IsCaseInsensitive() identity.SetClaims("TYPE", JsonSerializer.Deserialize(@"[""Fabrikam"",""Contoso""]")); // Assert - Assert.Equal(["Fabrikam", "Contoso"], identity.GetClaims("type")); + Assert.Equal(["Fabrikam", "Contoso"], identity.GetClaims("type"), StringComparer.Ordinal); } [Fact] @@ -4550,7 +4550,7 @@ public void ClaimsPrincipal_SetClaimsWithJsonElement_IsCaseInsensitive() principal.SetClaims("TYPE", JsonSerializer.Deserialize(@"[""Fabrikam"",""Contoso""]")); // Assert - Assert.Equal(["Fabrikam", "Contoso"], principal.GetClaims("type")); + Assert.Equal(["Fabrikam", "Contoso"], principal.GetClaims("type"), StringComparer.Ordinal); } [Fact] @@ -4670,7 +4670,7 @@ public void ClaimsPrincipal_SetClaimsWithJsonArray_ThrowsAnExceptionForNullIdent new JsonArray("Fabrikam", "Contoso"))); Assert.Equal("principal", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0286), exception.Message, StringComparison.Ordinal); } [Theory] @@ -4774,7 +4774,7 @@ public void ClaimsIdentity_SetClaimsWithJsonArray_IsCaseInsensitive() identity.SetClaims("TYPE", new JsonArray("Fabrikam", "Contoso")); // Assert - Assert.Equal(["Fabrikam", "Contoso"], identity.GetClaims("type")); + Assert.Equal(["Fabrikam", "Contoso"], identity.GetClaims("type"), StringComparer.Ordinal); } [Fact] @@ -4787,7 +4787,7 @@ public void ClaimsPrincipal_SetClaimsWithJsonArray_IsCaseInsensitive() principal.SetClaims("TYPE", new JsonArray("Fabrikam", "Contoso")); // Assert - Assert.Equal(["Fabrikam", "Contoso"], principal.GetClaims("type")); + Assert.Equal(["Fabrikam", "Contoso"], principal.GetClaims("type"), StringComparer.Ordinal); } [Fact] @@ -4999,7 +4999,7 @@ public void ClaimsIdentity_GetAudiences_ReturnsExpectedAudiences(string[] audien identity.SetClaims(Claims.Private.Audience, audience.ToImmutableArray()); // Act and assert - Assert.Equal(audiences, identity.GetAudiences()); + Assert.Equal(audiences, identity.GetAudiences(), StringComparer.Ordinal); } [Theory] @@ -5015,7 +5015,7 @@ public void ClaimsPrincipal_GetAudiences_ReturnsExpectedAudiences(string[] audie principal.SetClaims(Claims.Private.Audience, audience.ToImmutableArray()); // Act and assert - Assert.Equal(audiences, principal.GetAudiences()); + Assert.Equal(audiences, principal.GetAudiences(), StringComparer.Ordinal); } [Fact] @@ -5055,7 +5055,7 @@ public void ClaimsIdentity_GetPresenters_ReturnsExpectedPresenters(string[] pres identity.SetClaims(Claims.Private.Presenter, presenter.ToImmutableArray()); // Act and assert - Assert.Equal(presenters, identity.GetPresenters()); + Assert.Equal(presenters, identity.GetPresenters(), StringComparer.Ordinal); } [Theory] @@ -5071,7 +5071,7 @@ public void ClaimsPrincipal_GetPresenters_ReturnsExpectedPresenters(string[] pre principal.SetClaims(Claims.Private.Presenter, presenter.ToImmutableArray()); // Act and assert - Assert.Equal(presenters, principal.GetPresenters()); + Assert.Equal(presenters, principal.GetPresenters(), StringComparer.Ordinal); } [Fact] @@ -5111,7 +5111,7 @@ public void ClaimsIdentity_GetResources_ReturnsExpectedResources(string[] resour identity.SetClaims(Claims.Private.Resource, resource.ToImmutableArray()); // Act and assert - Assert.Equal(resources, identity.GetResources()); + Assert.Equal(resources, identity.GetResources(), StringComparer.Ordinal); } [Theory] @@ -5127,7 +5127,7 @@ public void ClaimsPrincipal_GetResources_ReturnsExpectedResources(string[] resou principal.SetClaims(Claims.Private.Resource, resource.ToImmutableArray()); // Act and assert - Assert.Equal(resources, principal.GetResources()); + Assert.Equal(resources, principal.GetResources(), StringComparer.Ordinal); } [Fact] @@ -5167,7 +5167,7 @@ public void ClaimsIdentity_GetScopes_ReturnsExpectedScopes(string[] scope, strin identity.SetClaims(Claims.Private.Scope, scope.ToImmutableArray()); // Act and assert - Assert.Equal(scopes, identity.GetScopes()); + Assert.Equal(scopes, identity.GetScopes(), StringComparer.Ordinal); } [Theory] @@ -5183,7 +5183,7 @@ public void ClaimsPrincipal_GetScopes_ReturnsExpectedScopes(string[] scope, stri principal.SetClaims(Claims.Private.Scope, scope.ToImmutableArray()); // Act and assert - Assert.Equal(scopes, principal.GetScopes()); + Assert.Equal(scopes, principal.GetScopes(), StringComparer.Ordinal); } [Fact] @@ -6430,7 +6430,7 @@ public void ClaimsIdentity_SetAudiences_AddsAudiences(string[]? audiences, strin identity.SetAudiences(audiences); // Assert - Assert.Equal(audience, identity.GetClaims(Claims.Private.Audience)); + Assert.Equal(audience, identity.GetClaims(Claims.Private.Audience), StringComparer.Ordinal); } [Theory] @@ -6449,7 +6449,7 @@ public void ClaimsPrincipal_SetAudiences_AddsAudiences(string[]? audiences, stri principal.SetAudiences(audiences); // Assert - Assert.Equal(audience, principal.GetClaims(Claims.Private.Audience)); + Assert.Equal(audience, principal.GetClaims(Claims.Private.Audience), StringComparer.Ordinal); } [Fact] @@ -6492,7 +6492,7 @@ public void ClaimsIdentity_SetPresenters_AddsPresenters(string[]? presenters, st identity.SetPresenters(presenters); // Assert - Assert.Equal(presenter, identity.GetClaims(Claims.Private.Presenter)); + Assert.Equal(presenter, identity.GetClaims(Claims.Private.Presenter), StringComparer.Ordinal); } [Theory] @@ -6511,7 +6511,7 @@ public void ClaimsPrincipal_SetPresenters_AddsPresenters(string[]? presenters, s principal.SetPresenters(presenters); // Assert - Assert.Equal(presenter, principal.GetClaims(Claims.Private.Presenter)); + Assert.Equal(presenter, principal.GetClaims(Claims.Private.Presenter), StringComparer.Ordinal); } [Fact] @@ -6554,7 +6554,7 @@ public void ClaimsIdentity_SetResources_AddsResources(string[]? resources, strin identity.SetResources(resources); // Assert - Assert.Equal(resource, identity.GetClaims(Claims.Private.Resource)); + Assert.Equal(resource, identity.GetClaims(Claims.Private.Resource), StringComparer.Ordinal); } [Theory] @@ -6573,7 +6573,7 @@ public void ClaimsPrincipal_SetResources_AddsResources(string[]? resources, stri principal.SetResources(resources); // Assert - Assert.Equal(resource, principal.GetClaims(Claims.Private.Resource)); + Assert.Equal(resource, principal.GetClaims(Claims.Private.Resource), StringComparer.Ordinal); } [Fact] @@ -6616,7 +6616,7 @@ public void ClaimsIdentity_SetScopes_AddsScopes(string[]? scopes, string[] scope identity.SetScopes(scopes); // Assert - Assert.Equal(scope, identity.GetClaims(Claims.Private.Scope)); + Assert.Equal(scope, identity.GetClaims(Claims.Private.Scope), StringComparer.Ordinal); } [Theory] @@ -6635,7 +6635,7 @@ public void ClaimsPrincipal_SetScopes_AddsScopes(string[]? scopes, string[] scop principal.SetScopes(scopes); // Assert - Assert.Equal(scope, principal.GetClaims(Claims.Private.Scope)); + Assert.Equal(scope, principal.GetClaims(Claims.Private.Scope), StringComparer.Ordinal); } [Fact] diff --git a/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictMessageTests.cs b/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictMessageTests.cs index 83e5e816f..896e67560 100644 --- a/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictMessageTests.cs +++ b/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictMessageTests.cs @@ -25,7 +25,7 @@ public void Constructor_ThrowsAnExceptionForInvalidJsonElement() }); Assert.Equal("parameters", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0189), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0189), exception.Message, StringComparison.Ordinal); } [Fact] @@ -42,7 +42,7 @@ public void Constructor_ThrowsAnExceptionForDuplicateParameters() }); Assert.Equal("parameters", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0191), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0191), exception.Message, StringComparison.Ordinal); } [Fact] @@ -253,7 +253,7 @@ public void GetParameter_ReturnsNullForUnsetParameter() public void GetParameters_EnumeratesParameters() { // Arrange - var parameters = new Dictionary + var parameters = new Dictionary(StringComparer.Ordinal) { ["int"] = int.MaxValue, ["long"] = long.MaxValue, @@ -483,7 +483,7 @@ public void ToString_ExcludesSensitiveParameters(string parameter) // Act and assert var element = JsonSerializer.Deserialize(message.ToString()); - Assert.DoesNotContain("secret value", message.ToString()); + Assert.DoesNotContain("secret value", message.ToString(), StringComparison.Ordinal); Assert.Equal("[redacted]", element.GetProperty(parameter).GetString()); } diff --git a/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictParameterTests.cs b/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictParameterTests.cs index b45932e42..d5010c863 100644 --- a/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictParameterTests.cs +++ b/test/OpenIddict.Abstractions.Tests/Primitives/OpenIddictParameterTests.cs @@ -316,12 +316,12 @@ public void Equals_UsesDeepEqualsForJsonObjectNodes() ["field"] = new JsonArray(0, 1, 2) }))); - Assert.True(parameter.Equals(new OpenIddictParameter(JsonValue.Create(new Dictionary + Assert.True(parameter.Equals(new OpenIddictParameter(JsonValue.Create(new Dictionary(StringComparer.Ordinal) { ["field"] = new JsonArray(0, 1, 2, 3) })))); - Assert.True(parameter.Equals(new OpenIddictParameter(JsonValue.Create(new Dictionary + Assert.True(parameter.Equals(new OpenIddictParameter(JsonValue.Create(new Dictionary(StringComparer.Ordinal) { ["field"] = new[] { 0, 1, 2, 3 } })))); @@ -445,12 +445,12 @@ public void GetHashCode_ReturnsUnderlyingHashCodeForPrimitiveValues() Assert.Equal(1, new OpenIddictParameter(true).GetHashCode()); Assert.Equal(0, new OpenIddictParameter(false).GetHashCode()); Assert.Equal(42.GetHashCode(), new OpenIddictParameter(42).GetHashCode()); - Assert.Equal("Fabrikam".GetHashCode(), new OpenIddictParameter("Fabrikam").GetHashCode()); + Assert.Equal("Fabrikam".GetHashCode(StringComparison.Ordinal), new OpenIddictParameter("Fabrikam").GetHashCode()); Assert.NotEqual(1, new OpenIddictParameter("true").GetHashCode()); Assert.NotEqual(0, new OpenIddictParameter("false").GetHashCode()); Assert.NotEqual(42.GetHashCode(), new OpenIddictParameter("42").GetHashCode()); - Assert.NotEqual("Fabrikam".GetHashCode(), new OpenIddictParameter(42).GetHashCode()); + Assert.NotEqual("Fabrikam".GetHashCode(StringComparison.Ordinal), new OpenIddictParameter(42).GetHashCode()); } [Fact] @@ -851,7 +851,7 @@ public void GetNamedParameters_ReturnsEmptyDictionaryForJsonArrayNodes() public void GetNamedParameters_ReturnsExpectedParametersForJsonObjectElements() { // Arrange - var parameters = new Dictionary + var parameters = new Dictionary(StringComparer.Ordinal) { ["parameter"] = "value" }; @@ -860,14 +860,14 @@ public void GetNamedParameters_ReturnsExpectedParametersForJsonObjectElements() JsonSerializer.Deserialize(@"{""parameter"":""value""}")); // Act and assert - Assert.Equal(parameters, parameter.GetNamedParameters().ToDictionary(pair => pair.Key, pair => (string?) pair.Value)); + Assert.Equal(parameters, parameter.GetNamedParameters().ToDictionary(pair => pair.Key, pair => (string?) pair.Value, StringComparer.Ordinal)); } [Fact] public void GetNamedParameters_ReturnsExpectedParametersForJsonObjectNodes() { // Arrange - var parameters = new Dictionary + var parameters = new Dictionary(StringComparer.Ordinal) { ["parameter"] = "value" }; @@ -878,7 +878,7 @@ public void GetNamedParameters_ReturnsExpectedParametersForJsonObjectNodes() }); // Act and assert - Assert.Equal(parameters, parameter.GetNamedParameters().ToDictionary(pair => pair.Key, pair => (string?) pair.Value)); + Assert.Equal(parameters, parameter.GetNamedParameters().ToDictionary(pair => pair.Key, pair => (string?) pair.Value, StringComparer.Ordinal)); } [Fact] @@ -926,7 +926,7 @@ public void GetUnnamedParameters_ReturnsExpectedParametersForArrays() // Act and assert Assert.Equal(parameters, from element in parameter.GetUnnamedParameters() - select (string?) element); + select (string?) element, StringComparer.Ordinal); } [Fact] @@ -965,7 +965,7 @@ public void GetUnnamedParameters_ReturnsExpectedParametersForJsonArrayElements() // Act and assert Assert.Equal(parameters, from element in parameter.GetUnnamedParameters() - select (string?) element); + select (string?) element, StringComparer.Ordinal); } [Fact] @@ -982,7 +982,7 @@ public void GetUnnamedParameters_ReturnsExpectedParametersForJsonArrayNodes() // Act and assert Assert.Equal(parameters, from element in parameter.GetUnnamedParameters() - select (string?) element); + select (string?) element, StringComparer.Ordinal); } [Fact] diff --git a/test/OpenIddict.Client.Tests/OpenIddictClientBuilderTests.cs b/test/OpenIddict.Client.Tests/OpenIddictClientBuilderTests.cs index a2337434b..ce9b43c10 100644 --- a/test/OpenIddict.Client.Tests/OpenIddictClientBuilderTests.cs +++ b/test/OpenIddict.Client.Tests/OpenIddictClientBuilderTests.cs @@ -1196,7 +1196,7 @@ public void SetPostLogoutRedirectionEndpointUris_ThrowsExceptionForMalformedUri( // Act and assert var exception = Assert.Throws(() => builder.SetPostLogoutRedirectionEndpointUris(new Uri(uri))); Assert.Equal("uris", exception.ParamName); - Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message); + Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message, StringComparison.Ordinal); } [Theory] @@ -1210,7 +1210,7 @@ public void SetPostLogoutRedirectionEndpointUris_ThrowsExceptionForInvalidRelati // Act and assert var exception = Assert.Throws(() => builder.SetPostLogoutRedirectionEndpointUris(new Uri(uri, UriKind.RelativeOrAbsolute))); Assert.Equal("uris", exception.ParamName); - Assert.Contains(SR.FormatID0081("~"), exception.Message); + Assert.Contains(SR.FormatID0081("~"), exception.Message, StringComparison.Ordinal); } [Fact] @@ -1280,7 +1280,7 @@ public void SetRedirectionEndpointUris_ThrowsExceptionForMalformedUri(string uri // Act and assert var exception = Assert.Throws(() => builder.SetRedirectionEndpointUris(new Uri(uri))); Assert.Equal("uris", exception.ParamName); - Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message); + Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message, StringComparison.Ordinal); } [Theory] @@ -1294,7 +1294,7 @@ public void SetRedirectionEndpointUris_ThrowsExceptionForInvalidRelativeUri(stri // Act and assert var exception = Assert.Throws(() => builder.SetRedirectionEndpointUris(new Uri(uri, UriKind.RelativeOrAbsolute))); Assert.Equal("uris", exception.ParamName); - Assert.Contains(SR.FormatID0081("~"), exception.Message); + Assert.Contains(SR.FormatID0081("~"), exception.Message, StringComparison.Ordinal); } [Fact] diff --git a/test/OpenIddict.Client.Tests/OpenIddictClientConfigurationTests.cs b/test/OpenIddict.Client.Tests/OpenIddictClientConfigurationTests.cs index 8af5e6c45..29d948ddf 100644 --- a/test/OpenIddict.Client.Tests/OpenIddictClientConfigurationTests.cs +++ b/test/OpenIddict.Client.Tests/OpenIddictClientConfigurationTests.cs @@ -175,7 +175,7 @@ public void Validate_ReturnsAnErrorWhenJsonWebTokenHandlerIsMissing() var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0075), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0075), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -196,7 +196,7 @@ public void Validate_ReturnsAnErrorWhenRegistrationIdentifierContainsSeparator() var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0455), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0455), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -216,7 +216,7 @@ public void Validate_ReturnsAnErrorWhenRegistrationIdentifierIsMissing() var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0521), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0521), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -237,7 +237,7 @@ public void Validate_ReturnsAnErrorWhenIssuerIsInvalid() var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0136), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0136), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -258,7 +258,7 @@ public void Validate_ReturnsAnErrorWhenIssuerContainsQueryOrFragment() var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0137), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0137), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -280,7 +280,7 @@ public void Validate_ReturnsAnErrorWhenRegistrationConfigurationIssuerDoesNotMat var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0395), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0395), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -300,7 +300,7 @@ public void Validate_ReturnsAnErrorWhenConfigurationManagerIsMissing() var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0522), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0522), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -321,7 +321,7 @@ public void Validate_ReturnsAnErrorWhenNonStaticConfigurationManagerIsUsedWithou var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0313), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0313), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -335,7 +335,7 @@ public void Validate_ReturnsAnErrorWhenNoFlowIsEnabled() var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0076), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0076), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -353,7 +353,7 @@ public void Validate_ReturnsAnErrorWhenEndpointUrisAreNotUnique() var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0285), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0285), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -368,7 +368,7 @@ public void Validate_ReturnsAnErrorWhenRedirectionEndpointIsMissingForAuthorizat var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0356), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0356), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -384,8 +384,8 @@ public void Validate_ReturnsAnErrorWhenStateTokenCredentialsAreMissing() var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0357), result.Failures!); - Assert.Contains(SR.GetResourceString(SR.ID0358), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0357), result.Failures!, StringComparer.Ordinal); + Assert.Contains(SR.GetResourceString(SR.ID0358), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -400,7 +400,7 @@ public void Validate_ReturnsAnErrorWhenResponseTypeIsInconsistentWithEnabledGran var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.FormatID0281(ResponseTypes.Code), result.Failures!); + Assert.Contains(SR.FormatID0281(ResponseTypes.Code), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -451,7 +451,7 @@ public void Validate_ReturnsAnErrorWhenRegistrationIdentifiersAreDuplicated() var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0347), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0347), result.Failures!, StringComparer.Ordinal); } private static OpenIddictClientOptions CreateBaseOptions() diff --git a/test/OpenIddict.Core.Tests/Managers/OpenIddictApplicationManagerTests.cs b/test/OpenIddict.Core.Tests/Managers/OpenIddictApplicationManagerTests.cs index d31f328e6..045c53b9e 100644 --- a/test/OpenIddict.Core.Tests/Managers/OpenIddictApplicationManagerTests.cs +++ b/test/OpenIddict.Core.Tests/Managers/OpenIddictApplicationManagerTests.cs @@ -895,7 +895,7 @@ public async Task GetLocalizedDisplayNameAsync_ThrowsAnExceptionForNullApplicati // Act and assert var exception = await Assert.ThrowsAsync( - () => manager.GetLocalizedDisplayNameAsync(application: null!).AsTask()); + () => manager.GetLocalizedDisplayNameAsync(application: null!, culture: CultureInfo.InvariantCulture).AsTask()); Assert.Equal("application", exception.ParamName); } @@ -1586,7 +1586,7 @@ public async Task ObfuscateClientSecretAsync_ProducesDifferentHashesForSameSecre var hash1 = await manager.ObfuscateClientSecretAsync("my-secret"); var hash2 = await manager.ObfuscateClientSecretAsync("my-secret"); - Assert.NotEqual(hash1, hash2); + Assert.NotEqual(hash1, hash2, StringComparer.Ordinal); } [Fact] @@ -1756,7 +1756,7 @@ public async Task ValidateAsync_ReturnsErrorWhenClientIdIsEmpty() var results = await manager.ValidateAsync(application).ToListAsync(); // Assert - Assert.Contains(results, result => result.ErrorMessage == SR.GetResourceString(SR.ID2036)); + Assert.Contains(results, result => string.Equals(result.ErrorMessage, SR.GetResourceString(SR.ID2036), StringComparison.Ordinal)); } [Fact] @@ -1801,7 +1801,7 @@ public async Task ValidateAsync_ReturnsErrorWhenClientIdIsAlreadyUsed() var results = await manager.ValidateAsync(application).ToListAsync(); // Assert - Assert.Contains(results, result => result.ErrorMessage == SR.GetResourceString(SR.ID2111)); + Assert.Contains(results, result => string.Equals(result.ErrorMessage, SR.GetResourceString(SR.ID2111), StringComparison.Ordinal)); } [Fact] @@ -1833,7 +1833,7 @@ public async Task ValidateAsync_ReturnsErrorWhenClientTypeIsEmpty() var results = await manager.ValidateAsync(application).ToListAsync(); // Assert - Assert.Contains(results, result => result.ErrorMessage == SR.GetResourceString(SR.ID2050)); + Assert.Contains(results, result => string.Equals(result.ErrorMessage, SR.GetResourceString(SR.ID2050), StringComparison.Ordinal)); } [Fact] @@ -1865,7 +1865,7 @@ public async Task ValidateAsync_ReturnsErrorWhenClientTypeIsNotSupported() var results = await manager.ValidateAsync(application).ToListAsync(); // Assert - Assert.Contains(results, result => result.ErrorMessage == SR.GetResourceString(SR.ID2112)); + Assert.Contains(results, result => string.Equals(result.ErrorMessage, SR.GetResourceString(SR.ID2112), StringComparison.Ordinal)); } [Fact] @@ -1900,7 +1900,7 @@ public async Task ValidateAsync_ReturnsErrorWhenPublicApplicationHasClientSecret var results = await manager.ValidateAsync(application).ToListAsync(); // Assert - Assert.Contains(results, result => result.ErrorMessage == SR.GetResourceString(SR.ID2114)); + Assert.Contains(results, result => string.Equals(result.ErrorMessage, SR.GetResourceString(SR.ID2114), StringComparison.Ordinal)); } [Fact] @@ -1938,7 +1938,7 @@ public async Task ValidateAsync_ReturnsErrorWhenConfidentialApplicationHasNoSecr var results = await manager.ValidateAsync(application).ToListAsync(); // Assert - Assert.Contains(results, result => result.ErrorMessage == SR.GetResourceString(SR.ID2113)); + Assert.Contains(results, result => string.Equals(result.ErrorMessage, SR.GetResourceString(SR.ID2113), StringComparison.Ordinal)); } [Fact] @@ -1979,7 +1979,7 @@ public async Task ValidateAsync_ReturnsErrorWhenConfidentialApplicationHasJwksWi var results = await manager.ValidateAsync(application).ToListAsync(); // Assert - Assert.Contains(results, result => result.ErrorMessage == SR.GetResourceString(SR.ID2113)); + Assert.Contains(results, result => string.Equals(result.ErrorMessage, SR.GetResourceString(SR.ID2113), StringComparison.Ordinal)); } [Fact] @@ -2014,7 +2014,7 @@ public async Task ValidateAsync_ReturnsErrorWhenRedirectUriIsEmpty() var results = await manager.ValidateAsync(application).ToListAsync(); // Assert - Assert.Contains(results, result => result.ErrorMessage == SR.GetResourceString(SR.ID2061)); + Assert.Contains(results, result => string.Equals(result.ErrorMessage, SR.GetResourceString(SR.ID2061), StringComparison.Ordinal)); } [Fact] @@ -2049,7 +2049,7 @@ public async Task ValidateAsync_ReturnsErrorWhenRedirectUriIsNotAbsolute() var results = await manager.ValidateAsync(application).ToListAsync(); // Assert - Assert.Contains(results, result => result.ErrorMessage == SR.GetResourceString(SR.ID2062)); + Assert.Contains(results, result => string.Equals(result.ErrorMessage, SR.GetResourceString(SR.ID2062), StringComparison.Ordinal)); } [Fact] @@ -2084,7 +2084,7 @@ public async Task ValidateAsync_ReturnsErrorWhenRedirectUriContainsFragment() var results = await manager.ValidateAsync(application).ToListAsync(); // Assert - Assert.Contains(results, result => result.ErrorMessage == SR.GetResourceString(SR.ID2115)); + Assert.Contains(results, result => string.Equals(result.ErrorMessage, SR.GetResourceString(SR.ID2115), StringComparison.Ordinal)); } [Fact] @@ -2119,7 +2119,7 @@ public async Task ValidateAsync_ReturnsErrorWhenRedirectUriContainsIssParameter( var results = await manager.ValidateAsync(application).ToListAsync(); // Assert - Assert.Contains(results, result => result.ErrorMessage == SR.FormatID2134(Parameters.Iss)); + Assert.Contains(results, result => string.Equals(result.ErrorMessage, SR.FormatID2134(Parameters.Iss), StringComparison.Ordinal)); } [Fact] @@ -2154,7 +2154,7 @@ public async Task ValidateAsync_ReturnsErrorWhenPostLogoutRedirectUriContainsFra var results = await manager.ValidateAsync(application).ToListAsync(); // Assert - Assert.Contains(results, result => result.ErrorMessage == SR.GetResourceString(SR.ID2115)); + Assert.Contains(results, result => string.Equals(result.ErrorMessage, SR.GetResourceString(SR.ID2115), StringComparison.Ordinal)); } [Fact] diff --git a/test/OpenIddict.Core.Tests/Managers/OpenIddictAuthorizationManagerTests.cs b/test/OpenIddict.Core.Tests/Managers/OpenIddictAuthorizationManagerTests.cs index 9cdfaa929..b089966d8 100644 --- a/test/OpenIddict.Core.Tests/Managers/OpenIddictAuthorizationManagerTests.cs +++ b/test/OpenIddict.Core.Tests/Managers/OpenIddictAuthorizationManagerTests.cs @@ -1132,7 +1132,7 @@ public async Task ValidateAsync_ReturnsErrorWhenTypeIsEmpty() var results = await manager.ValidateAsync(authorization).ToListAsync(); // Assert - Assert.Contains(results, result => result.ErrorMessage == SR.GetResourceString(SR.ID2116)); + Assert.Contains(results, result => string.Equals(result.ErrorMessage, SR.GetResourceString(SR.ID2116), StringComparison.Ordinal)); } [Fact] @@ -1161,7 +1161,7 @@ public async Task ValidateAsync_ReturnsErrorWhenTypeIsNotSupported() var results = await manager.ValidateAsync(authorization).ToListAsync(); // Assert - Assert.Contains(results, result => result.ErrorMessage == SR.GetResourceString(SR.ID2117)); + Assert.Contains(results, result => string.Equals(result.ErrorMessage, SR.GetResourceString(SR.ID2117), StringComparison.Ordinal)); } [Fact] @@ -1190,7 +1190,7 @@ public async Task ValidateAsync_ReturnsErrorWhenStatusIsEmpty() var results = await manager.ValidateAsync(authorization).ToListAsync(); // Assert - Assert.Contains(results, result => result.ErrorMessage == SR.GetResourceString(SR.ID2038)); + Assert.Contains(results, result => string.Equals(result.ErrorMessage, SR.GetResourceString(SR.ID2038), StringComparison.Ordinal)); } [Fact] @@ -1219,7 +1219,7 @@ public async Task ValidateAsync_ReturnsErrorWhenScopeIsEmpty() var results = await manager.ValidateAsync(authorization).ToListAsync(); // Assert - Assert.Contains(results, result => result.ErrorMessage == SR.GetResourceString(SR.ID2039)); + Assert.Contains(results, result => string.Equals(result.ErrorMessage, SR.GetResourceString(SR.ID2039), StringComparison.Ordinal)); } [Fact] @@ -1248,7 +1248,7 @@ public async Task ValidateAsync_ReturnsErrorWhenScopeContainsSpace() var results = await manager.ValidateAsync(authorization).ToListAsync(); // Assert - Assert.Contains(results, result => result.ErrorMessage == SR.GetResourceString(SR.ID2042)); + Assert.Contains(results, result => string.Equals(result.ErrorMessage, SR.GetResourceString(SR.ID2042), StringComparison.Ordinal)); } [Fact] diff --git a/test/OpenIddict.Core.Tests/Managers/OpenIddictResourceManagerTests.cs b/test/OpenIddict.Core.Tests/Managers/OpenIddictResourceManagerTests.cs index 8c9d63ef9..0c40eb874 100644 --- a/test/OpenIddict.Core.Tests/Managers/OpenIddictResourceManagerTests.cs +++ b/test/OpenIddict.Core.Tests/Managers/OpenIddictResourceManagerTests.cs @@ -796,7 +796,7 @@ public async Task ValidateAsync_ReturnsErrorWhenNameIsEmpty() var results = await manager.ValidateAsync(resource).ToListAsync(); // Assert - Assert.Contains(results, result => result.ErrorMessage == SR.GetResourceString(SR.ID2206)); + Assert.Contains(results, result => string.Equals(result.ErrorMessage, SR.GetResourceString(SR.ID2206), StringComparison.Ordinal)); } [Theory] @@ -822,7 +822,7 @@ public async Task ValidateAsync_ReturnsErrorWhenNameIsNotValidUri(string name) var results = await manager.ValidateAsync(resource).ToListAsync(); // Assert - Assert.Contains(results, result => result.ErrorMessage == SR.GetResourceString(SR.ID2207)); + Assert.Contains(results, result => string.Equals(result.ErrorMessage, SR.GetResourceString(SR.ID2207), StringComparison.Ordinal)); } [Fact] @@ -855,7 +855,7 @@ public async Task ValidateAsync_ReturnsErrorWhenNameIsAlreadyUsed() var results = await manager.ValidateAsync(resource).ToListAsync(); // Assert - Assert.Contains(results, result => result.ErrorMessage == SR.GetResourceString(SR.ID2208)); + Assert.Contains(results, result => string.Equals(result.ErrorMessage, SR.GetResourceString(SR.ID2208), StringComparison.Ordinal)); } [Fact] diff --git a/test/OpenIddict.Core.Tests/Managers/OpenIddictScopeManagerTests.cs b/test/OpenIddict.Core.Tests/Managers/OpenIddictScopeManagerTests.cs index 39e584cdb..861528029 100644 --- a/test/OpenIddict.Core.Tests/Managers/OpenIddictScopeManagerTests.cs +++ b/test/OpenIddict.Core.Tests/Managers/OpenIddictScopeManagerTests.cs @@ -768,9 +768,9 @@ public async Task ListResourcesAsync_ReturnsDeduplicatedResourcesFromMatchingSco // Assert Assert.Equal(3, resources.Count); - Assert.Contains("resource1", resources); - Assert.Contains("resource2", resources); - Assert.Contains("resource3", resources); + Assert.Contains("resource1", resources, StringComparer.Ordinal); + Assert.Contains("resource2", resources, StringComparer.Ordinal); + Assert.Contains("resource3", resources, StringComparer.Ordinal); } [Fact] @@ -888,7 +888,7 @@ public async Task ValidateAsync_ReturnsErrorWhenNameIsEmpty() var results = await manager.ValidateAsync(scope).ToListAsync(); // Assert - Assert.Contains(results, result => result.ErrorMessage == SR.GetResourceString(SR.ID2044)); + Assert.Contains(results, result => string.Equals(result.ErrorMessage, SR.GetResourceString(SR.ID2044), StringComparison.Ordinal)); } [Fact] @@ -911,7 +911,7 @@ public async Task ValidateAsync_ReturnsErrorWhenNameContainsSpace() var results = await manager.ValidateAsync(scope).ToListAsync(); // Assert - Assert.Contains(results, result => result.ErrorMessage == SR.GetResourceString(SR.ID2045)); + Assert.Contains(results, result => string.Equals(result.ErrorMessage, SR.GetResourceString(SR.ID2045), StringComparison.Ordinal)); } [Fact] @@ -944,7 +944,7 @@ public async Task ValidateAsync_ReturnsErrorWhenNameIsAlreadyUsed() var results = await manager.ValidateAsync(scope).ToListAsync(); // Assert - Assert.Contains(results, result => result.ErrorMessage == SR.GetResourceString(SR.ID2060)); + Assert.Contains(results, result => string.Equals(result.ErrorMessage, SR.GetResourceString(SR.ID2060), StringComparison.Ordinal)); } [Fact] diff --git a/test/OpenIddict.Core.Tests/Managers/OpenIddictSessionManagerTests.cs b/test/OpenIddict.Core.Tests/Managers/OpenIddictSessionManagerTests.cs index 27b3951ea..b2a6990aa 100644 --- a/test/OpenIddict.Core.Tests/Managers/OpenIddictSessionManagerTests.cs +++ b/test/OpenIddict.Core.Tests/Managers/OpenIddictSessionManagerTests.cs @@ -802,7 +802,7 @@ public async Task ValidateAsync_ReturnsErrorWhenStatusIsEmpty() var results = await manager.ValidateAsync(session).ToListAsync(); // Assert - Assert.Contains(results, result => result.ErrorMessage == SR.GetResourceString(SR.ID2038)); + Assert.Contains(results, result => string.Equals(result.ErrorMessage, SR.GetResourceString(SR.ID2038), StringComparison.Ordinal)); } [Fact] @@ -828,7 +828,7 @@ public async Task ValidateAsync_ReturnsErrorWhenLoginIdIsEmpty() var results = await manager.ValidateAsync(session).ToListAsync(); // Assert - Assert.Contains(results, result => result.ErrorMessage == SR.GetResourceString(SR.ID2209)); + Assert.Contains(results, result => string.Equals(result.ErrorMessage, SR.GetResourceString(SR.ID2209), StringComparison.Ordinal)); } [Fact] diff --git a/test/OpenIddict.Core.Tests/Managers/OpenIddictTokenManagerTests.cs b/test/OpenIddict.Core.Tests/Managers/OpenIddictTokenManagerTests.cs index d9fd1aece..76c01d2e9 100644 --- a/test/OpenIddict.Core.Tests/Managers/OpenIddictTokenManagerTests.cs +++ b/test/OpenIddict.Core.Tests/Managers/OpenIddictTokenManagerTests.cs @@ -1249,7 +1249,7 @@ public async Task ValidateAsync_ReturnsErrorWhenReferenceIdIsAlreadyUsed() var results = await manager.ValidateAsync(token).ToListAsync(); // Assert - Assert.Contains(results, result => result.ErrorMessage == SR.GetResourceString(SR.ID2085)); + Assert.Contains(results, result => string.Equals(result.ErrorMessage, SR.GetResourceString(SR.ID2085), StringComparison.Ordinal)); } [Fact] @@ -1278,7 +1278,7 @@ public async Task ValidateAsync_ReturnsErrorWhenTypeIsEmpty() var results = await manager.ValidateAsync(token).ToListAsync(); // Assert - Assert.Contains(results, result => result.ErrorMessage == SR.GetResourceString(SR.ID2086)); + Assert.Contains(results, result => string.Equals(result.ErrorMessage, SR.GetResourceString(SR.ID2086), StringComparison.Ordinal)); } [Fact] @@ -1307,7 +1307,7 @@ public async Task ValidateAsync_ReturnsErrorWhenStatusIsEmpty() var results = await manager.ValidateAsync(token).ToListAsync(); // Assert - Assert.Contains(results, result => result.ErrorMessage == SR.GetResourceString(SR.ID2038)); + Assert.Contains(results, result => string.Equals(result.ErrorMessage, SR.GetResourceString(SR.ID2038), StringComparison.Ordinal)); } [Fact] diff --git a/test/OpenIddict.Core.Tests/OpenIddictCoreBuilderTests.cs b/test/OpenIddict.Core.Tests/OpenIddictCoreBuilderTests.cs index e2044ee6e..ebdea32ef 100644 --- a/test/OpenIddict.Core.Tests/OpenIddictCoreBuilderTests.cs +++ b/test/OpenIddict.Core.Tests/OpenIddictCoreBuilderTests.cs @@ -36,7 +36,7 @@ public void ReplaceApplicationManager_ThrowsAnExceptionForClosedSourceManager() var exception = Assert.Throws(() => builder.ReplaceApplicationManager(typeof(ClosedGenericApplicationManager))); Assert.Equal("type", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0232), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0232), exception.Message, StringComparison.Ordinal); } [Fact] @@ -50,7 +50,7 @@ public void ReplaceApplicationManager_ThrowsAnExceptionForInvalidManager() var exception = Assert.Throws(() => builder.ReplaceApplicationManager(typeof(object))); Assert.Equal("type", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0232), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0232), exception.Message, StringComparison.Ordinal); } [Fact] @@ -81,7 +81,7 @@ public void ReplaceAuthorizationManager_ThrowsAnExceptionForClosedSourceManager( var exception = Assert.Throws(() => builder.ReplaceAuthorizationManager(typeof(ClosedGenericAuthorizationManager))); Assert.Equal("type", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0232), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0232), exception.Message, StringComparison.Ordinal); } [Fact] @@ -95,7 +95,7 @@ public void ReplaceAuthorizationManager_ThrowsAnExceptionForInvalidManager() var exception = Assert.Throws(() => builder.ReplaceAuthorizationManager(typeof(object))); Assert.Equal("type", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0232), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0232), exception.Message, StringComparison.Ordinal); } [Fact] @@ -126,7 +126,7 @@ public void ReplaceResourceManager_ThrowsAnExceptionForClosedSourceManager() var exception = Assert.Throws(() => builder.ReplaceResourceManager(typeof(ClosedGenericResourceManager))); Assert.Equal("type", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0232), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0232), exception.Message, StringComparison.Ordinal); } [Fact] @@ -140,7 +140,7 @@ public void ReplaceResourceManager_ThrowsAnExceptionForInvalidManager() var exception = Assert.Throws(() => builder.ReplaceResourceManager(typeof(object))); Assert.Equal("type", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0232), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0232), exception.Message, StringComparison.Ordinal); } [Fact] @@ -171,7 +171,7 @@ public void ReplaceScopeManager_ThrowsAnExceptionForClosedSourceManager() var exception = Assert.Throws(() => builder.ReplaceScopeManager(typeof(ClosedGenericScopeManager))); Assert.Equal("type", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0232), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0232), exception.Message, StringComparison.Ordinal); } [Fact] @@ -185,7 +185,7 @@ public void ReplaceScopeManager_ThrowsAnExceptionForInvalidManager() var exception = Assert.Throws(() => builder.ReplaceScopeManager(typeof(object))); Assert.Equal("type", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0232), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0232), exception.Message, StringComparison.Ordinal); } [Fact] @@ -216,7 +216,7 @@ public void ReplaceSessionManager_ThrowsAnExceptionForClosedSourceManager() var exception = Assert.Throws(() => builder.ReplaceSessionManager(typeof(ClosedGenericSessionManager))); Assert.Equal("type", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0232), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0232), exception.Message, StringComparison.Ordinal); } [Fact] @@ -230,7 +230,7 @@ public void ReplaceSessionManager_ThrowsAnExceptionForInvalidManager() var exception = Assert.Throws(() => builder.ReplaceSessionManager(typeof(object))); Assert.Equal("type", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0232), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0232), exception.Message, StringComparison.Ordinal); } [Fact] @@ -261,7 +261,7 @@ public void ReplaceTokenManager_ThrowsAnExceptionForClosedSourceManager() var exception = Assert.Throws(() => builder.ReplaceTokenManager(typeof(ClosedGenericTokenManager))); Assert.Equal("type", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0232), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0232), exception.Message, StringComparison.Ordinal); } [Fact] @@ -275,7 +275,7 @@ public void ReplaceTokenManager_ThrowsAnExceptionForInvalidManager() var exception = Assert.Throws(() => builder.ReplaceTokenManager(typeof(object))); Assert.Equal("type", exception.ParamName); - Assert.StartsWith(SR.GetResourceString(SR.ID0232), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0232), exception.Message, StringComparison.Ordinal); } [Fact] diff --git a/test/OpenIddict.Core.Tests/OpenIddictCoreConfigurationTests.cs b/test/OpenIddict.Core.Tests/OpenIddictCoreConfigurationTests.cs index c5dbdb3e6..1ca78758e 100644 --- a/test/OpenIddict.Core.Tests/OpenIddictCoreConfigurationTests.cs +++ b/test/OpenIddict.Core.Tests/OpenIddictCoreConfigurationTests.cs @@ -163,7 +163,7 @@ public void Validate_FailsForInvalidHashAlgorithm() // Assert Assert.True(result.Failed); - Assert.Contains(SR.FormatID0217("MD5"), result.Failures); + Assert.Contains(SR.FormatID0217("MD5"), result.Failures, StringComparer.Ordinal); } [Theory] @@ -185,7 +185,7 @@ public void Validate_FailsForInvalidIterationCount(int iterations) // Assert Assert.True(result.Failed); - Assert.Contains(SR.FormatID0518(10_000, 10_000_000), result.Failures); + Assert.Contains(SR.FormatID0518(10_000, 10_000_000), result.Failures, StringComparer.Ordinal); } [Theory] @@ -229,7 +229,7 @@ public void Validate_FailsForInvalidSaltLength(int saltLength) // Assert Assert.True(result.Failed); - Assert.Contains(SR.FormatID0519(128, 1024), result.Failures); + Assert.Contains(SR.FormatID0519(128, 1024), result.Failures, StringComparer.Ordinal); } [Theory] @@ -273,7 +273,7 @@ public void Validate_FailsForInvalidOutputLength(int outputLength) // Assert Assert.True(result.Failed); - Assert.Contains(SR.FormatID0520(256, 2048), result.Failures); + Assert.Contains(SR.FormatID0520(256, 2048), result.Failures, StringComparer.Ordinal); } [Theory] diff --git a/test/OpenIddict.Server.AspNetCore.IntegrationTests/OpenIddictServerAspNetCoreIntegrationTests.cs b/test/OpenIddict.Server.AspNetCore.IntegrationTests/OpenIddictServerAspNetCoreIntegrationTests.cs index ab4b5f5ac..35ade840e 100644 --- a/test/OpenIddict.Server.AspNetCore.IntegrationTests/OpenIddictServerAspNetCoreIntegrationTests.cs +++ b/test/OpenIddict.Server.AspNetCore.IntegrationTests/OpenIddictServerAspNetCoreIntegrationTests.cs @@ -159,7 +159,7 @@ public async Task ProcessAuthentication_CreationDateIsMappedToIssuedUtc() // Assert var properties = new AuthenticationProperties(response.GetParameters() - .ToDictionary(parameter => parameter.Key, parameter => (string?) parameter.Value)); + .ToDictionary(parameter => parameter.Key, parameter => (string?) parameter.Value, StringComparer.Ordinal)); Assert.Equal(new DateTimeOffset(2020, 01, 01, 00, 00, 00, TimeSpan.Zero), properties.IssuedUtc); } @@ -209,7 +209,7 @@ public async Task ProcessAuthentication_ExpirationDateIsMappedToIssuedUtc() // Assert var properties = new AuthenticationProperties(response.GetParameters() - .ToDictionary(parameter => parameter.Key, parameter => (string?) parameter.Value)); + .ToDictionary(parameter => parameter.Key, parameter => (string?) parameter.Value, StringComparer.Ordinal)); Assert.Equal(new DateTimeOffset(2120, 01, 01, 00, 00, 00, TimeSpan.Zero), properties.ExpiresUtc); } @@ -257,7 +257,7 @@ public async Task ProcessAuthentication_CustomPropertiesAreAddedForErroredAuthen // Assert var properties = new AuthenticationProperties(response.GetParameters() - .ToDictionary(parameter => parameter.Key, parameter => (string?) parameter.Value)); + .ToDictionary(parameter => parameter.Key, parameter => (string?) parameter.Value, StringComparer.Ordinal)); Assert.Equal("value", properties.Items["custom_property"]); } @@ -714,7 +714,7 @@ void ConfigurePipeline(IApplicationBuilder app) return; } - else if (context.Request.Path == "/signin/custom") + if (context.Request.Path == "/signin/custom") { var identity = new ClaimsIdentity(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme); identity.AddClaim(Claims.Subject, "Bob le Bricoleur"); @@ -722,11 +722,11 @@ void ConfigurePipeline(IApplicationBuilder app) var principal = new ClaimsPrincipal(identity); var properties = new AuthenticationProperties( - items: new Dictionary + items: new Dictionary(StringComparer.Ordinal) { ["custom_property"] = "value" }, - parameters: new Dictionary + parameters: new Dictionary(StringComparer.Ordinal) { ["boolean_parameter"] = true, ["integer_parameter"] = 42, @@ -741,20 +741,20 @@ void ConfigurePipeline(IApplicationBuilder app) return; } - else if (context.Request.Path == "/signout") + if (context.Request.Path == "/signout") { await context.SignOutAsync(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme); return; } - else if (context.Request.Path == "/signout/custom") + if (context.Request.Path == "/signout/custom") { var properties = new AuthenticationProperties( - items: new Dictionary + items: new Dictionary(StringComparer.Ordinal) { ["custom_property"] = "value" }, - parameters: new Dictionary + parameters: new Dictionary(StringComparer.Ordinal) { ["boolean_parameter"] = true, ["integer_parameter"] = 42, @@ -765,16 +765,16 @@ void ConfigurePipeline(IApplicationBuilder app) return; } - else if (context.Request.Path == "/challenge") + if (context.Request.Path == "/challenge") { await context.ChallengeAsync(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme); return; } - else if (context.Request.Path == "/challenge/custom") + if (context.Request.Path == "/challenge/custom") { var properties = new AuthenticationProperties( - items: new Dictionary + items: new Dictionary(StringComparer.Ordinal) { [OpenIddictServerAspNetCoreConstants.Properties.Error] = "custom_error", [OpenIddictServerAspNetCoreConstants.Properties.ErrorDescription] = "custom_error_description", @@ -782,7 +782,7 @@ void ConfigurePipeline(IApplicationBuilder app) ["custom_property"] = "value" }, - parameters: new Dictionary + parameters: new Dictionary(StringComparer.Ordinal) { ["boolean_parameter"] = true, ["integer_parameter"] = 42, @@ -797,7 +797,7 @@ void ConfigurePipeline(IApplicationBuilder app) return; } - else if (context.Request.Path == "/authenticate") + if (context.Request.Path == "/authenticate") { var result = await context.AuthenticateAsync(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme); if (result?.Principal is null) @@ -805,7 +805,7 @@ void ConfigurePipeline(IApplicationBuilder app) return; } - var claims = result.Principal.Claims.GroupBy(claim => claim.Type) + var claims = result.Principal.Claims.GroupBy(claim => claim.Type, StringComparer.Ordinal) .Select(group => KeyValuePair.Create(group.Key, group.Select(claim => claim.Value).ToImmutableArray())); context.Response.ContentType = "application/json"; @@ -813,7 +813,7 @@ void ConfigurePipeline(IApplicationBuilder app) return; } - else if (context.Request.Path == "/authenticate/properties") + if (context.Request.Path == "/authenticate/properties") { var result = await context.AuthenticateAsync(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme); if (result?.Properties is null) diff --git a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTestClient.cs b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTestClient.cs index 01dfc3d05..9a13d0cf3 100644 --- a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTestClient.cs +++ b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTestClient.cs @@ -194,7 +194,7 @@ private HttpRequestMessage CreateRequestMessage(OpenIddictRequest request, HttpM message.RequestUri = OpenIddictHelpers.AddQueryStringParameters(message.RequestUri!, request.GetParameters().ToDictionary( static parameter => parameter.Key, - static parameter => (StringValues) parameter.Value)); + static parameter => (StringValues) parameter.Value, StringComparer.Ordinal)); } if (message.Method != HttpMethod.Get) @@ -320,7 +320,7 @@ private async Task GetResponseAsync(HttpResponseMessage mess return null; } - return Uri.UnescapeDataString(value.Replace("+", "%20")); + return Uri.UnescapeDataString(value.Replace("+", "%20", StringComparison.Ordinal)); } // Note: a dictionary is deliberately not used here to allow multiple parameters with the @@ -359,19 +359,17 @@ private async Task GetResponseAsync(HttpResponseMessage mess parameters.Add(KeyValuePair.Create(name, value)); } - return new OpenIddictResponse( - from parameter in parameters - group parameter by parameter.Key into grouping - let values = grouping.Select(parameter => parameter.Value) - select KeyValuePair.Create(grouping.Key, new StringValues([.. values]))); + return new OpenIddictResponse(parameters + .GroupBy(static parameter => parameter.Key, static parameter => parameter.Value, StringComparer.Ordinal) + .Select(static grouping => KeyValuePair.Create(grouping.Key, new StringValues([.. grouping])))); } - else if (string.Equals(message.Content?.Headers?.ContentType?.MediaType, "application/json", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(message.Content?.Headers?.ContentType?.MediaType, "application/json", StringComparison.OrdinalIgnoreCase)) { return (await message.Content!.ReadFromJsonAsync())!; } - else if (string.Equals(message.Content?.Headers?.ContentType?.MediaType, "text/html", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(message.Content?.Headers?.ContentType?.MediaType, "text/html", StringComparison.OrdinalIgnoreCase)) { // Note: this test client is only used with OpenIddict's ASP.NET Core or OWIN hosts, // that always return their HTTP responses encoded using UTF-8. As such, the stream @@ -402,14 +400,12 @@ group parameter by parameter.Key into grouping parameters.Add(KeyValuePair.Create(name, value)); } - return new OpenIddictResponse( - from parameter in parameters - group parameter by parameter.Key into grouping - let values = grouping.Select(parameter => parameter.Value) - select KeyValuePair.Create(grouping.Key, new StringValues([.. values]))); + return new OpenIddictResponse(parameters + .GroupBy(static parameter => parameter.Key, static parameter => parameter.Value, StringComparer.Ordinal) + .Select(static grouping => KeyValuePair.Create(grouping.Key, new StringValues([.. grouping])))); } - else if (string.Equals(message.Content?.Headers?.ContentType?.MediaType, "text/plain", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(message.Content?.Headers?.ContentType?.MediaType, "text/plain", StringComparison.OrdinalIgnoreCase)) { // Note: this test client is only used with OpenIddict's ASP.NET Core or OWIN hosts, // that always return their HTTP responses encoded using UTF-8. As such, the stream @@ -424,7 +420,7 @@ group parameter by parameter.Key into grouping for (var line = await reader.ReadLineAsync(); line is not null; line = await reader.ReadLineAsync()) { - var index = line.IndexOf(':'); + var index = line.IndexOf(':', StringComparison.Ordinal); if (index is -1) { continue; @@ -441,11 +437,9 @@ group parameter by parameter.Key into grouping parameters.Add(KeyValuePair.Create(name, value)); } - return new OpenIddictResponse( - from parameter in parameters - group parameter by parameter.Key into grouping - let values = grouping.Select(parameter => parameter.Value) - select KeyValuePair.Create(grouping.Key, new StringValues([.. values]))); + return new OpenIddictResponse(parameters + .GroupBy(static parameter => parameter.Key, static parameter => parameter.Value, StringComparer.Ordinal) + .Select(static grouping => KeyValuePair.Create(grouping.Key, new StringValues([.. grouping])))); } return new OpenIddictResponse(); diff --git a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Authentication.cs b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Authentication.cs index 3b2f0eda3..1a890b217 100644 --- a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Authentication.cs +++ b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Authentication.cs @@ -997,7 +997,7 @@ public async Task ValidateAuthorizationRequest_RequestIsValidatedWhenRegisteredS .ReturnsAsync(true); mock.Setup(manager => manager.GetSettingsAsync(application, It.IsAny())) - .ReturnsAsync(ImmutableDictionary.Create()); + .ReturnsAsync(ImmutableDictionary.Create(StringComparer.Ordinal)); })); options.Services.AddSingleton(CreateScopeManager(mock => @@ -1181,7 +1181,7 @@ public async Task ValidateAuthorizationRequest_RequestIsValidatedWhenRegisteredR .ReturnsAsync(true); mock.Setup(manager => manager.GetSettingsAsync(application, It.IsAny())) - .ReturnsAsync(ImmutableDictionary.Create()); + .ReturnsAsync(ImmutableDictionary.Create(StringComparer.Ordinal)); })); options.Services.AddSingleton(CreateResourceManager(mock => @@ -1501,7 +1501,7 @@ public async Task ValidateAuthorizationRequest_PkceRequestWithSensitiveResponseT .ReturnsAsync(true); mock.Setup(manager => manager.GetSettingsAsync(application, It.IsAny())) - .ReturnsAsync(ImmutableDictionary.Create()); + .ReturnsAsync(ImmutableDictionary.Create(StringComparer.Ordinal)); }); await using var server = await CreateServerAsync(options => @@ -1558,7 +1558,7 @@ public async Task ValidateAuthorizationRequest_PkceRequestWithSensitiveResponseT .ReturnsAsync(true); mock.Setup(manager => manager.GetSettingsAsync(application, It.IsAny())) - .ReturnsAsync(ImmutableDictionary.Create()); + .ReturnsAsync(ImmutableDictionary.Create(StringComparer.Ordinal)); }); await using var server = await CreateServerAsync(options => @@ -1853,7 +1853,7 @@ public async Task ValidateAuthorizationRequest_RequestIsValidatedWhenExplicitPer .ReturnsAsync(true); mock.Setup(manager => manager.GetSettingsAsync(application, It.IsAny())) - .ReturnsAsync(ImmutableDictionary.Create()); + .ReturnsAsync(ImmutableDictionary.Create(StringComparer.Ordinal)); }); await using var server = await CreateServerAsync(options => @@ -2111,7 +2111,7 @@ public async Task ValidateAuthorizationRequest_RequestIsValidatedWhenCodeChallen .ReturnsAsync(false); mock.Setup(manager => manager.GetSettingsAsync(application, It.IsAny())) - .ReturnsAsync(ImmutableDictionary.Create()); + .ReturnsAsync(ImmutableDictionary.Create(StringComparer.Ordinal)); }); await using var server = await CreateServerAsync(options => @@ -2174,7 +2174,7 @@ public async Task ValidateAuthorizationRequest_RequestIsValidatedWhenCodeChallen .ReturnsAsync(true); mock.Setup(manager => manager.GetSettingsAsync(application, It.IsAny())) - .ReturnsAsync(ImmutableDictionary.Create()); + .ReturnsAsync(ImmutableDictionary.Create(StringComparer.Ordinal)); }); await using var server = await CreateServerAsync(options => @@ -2237,7 +2237,7 @@ public async Task ValidateAuthorizationRequest_RequestIsValidatedWhenCodeIsNotRe .ReturnsAsync(true); mock.Setup(manager => manager.GetSettingsAsync(application, It.IsAny())) - .ReturnsAsync(ImmutableDictionary.Create()); + .ReturnsAsync(ImmutableDictionary.Create(StringComparer.Ordinal)); }); await using var server = await CreateServerAsync(options => @@ -2418,7 +2418,7 @@ public async Task ValidateAuthorizationRequest_RequestIsValidatedWhenIdentityTok .ReturnsAsync(true); mock.Setup(manager => manager.GetSettingsAsync(application, It.IsAny())) - .ReturnsAsync(ImmutableDictionary.Create()); + .ReturnsAsync(ImmutableDictionary.Create(StringComparer.Ordinal)); }); await using var server = await CreateServerAsync(options => @@ -3920,7 +3920,7 @@ public async Task ValidatePushedAuthorizationRequest_RequestIsValidatedWhenRegis .ReturnsAsync(true); mock.Setup(manager => manager.GetSettingsAsync(application, It.IsAny())) - .ReturnsAsync(ImmutableDictionary.Create()); + .ReturnsAsync(ImmutableDictionary.Create(StringComparer.Ordinal)); })); options.Services.AddSingleton(CreateScopeManager(mock => @@ -4086,7 +4086,7 @@ public async Task ValidatePushedAuthorizationRequest_RequestIsValidatedWhenRegis .ReturnsAsync(true); mock.Setup(manager => manager.GetSettingsAsync(application, It.IsAny())) - .ReturnsAsync(ImmutableDictionary.Create()); + .ReturnsAsync(ImmutableDictionary.Create(StringComparer.Ordinal)); })); options.Services.AddSingleton(CreateResourceManager(mock => @@ -4391,7 +4391,7 @@ public async Task ValidatePushedAuthorizationRequest_PkceRequestWithSensitiveRes .ReturnsAsync(true); mock.Setup(manager => manager.GetSettingsAsync(application, It.IsAny())) - .ReturnsAsync(ImmutableDictionary.Create()); + .ReturnsAsync(ImmutableDictionary.Create(StringComparer.Ordinal)); }); await using var server = await CreateServerAsync(options => options.Services.AddSingleton(manager)); @@ -4438,7 +4438,7 @@ public async Task ValidatePushedAuthorizationRequest_PkceRequestWithSensitiveRes .ReturnsAsync(true); mock.Setup(manager => manager.GetSettingsAsync(application, It.IsAny())) - .ReturnsAsync(ImmutableDictionary.Create()); + .ReturnsAsync(ImmutableDictionary.Create(StringComparer.Ordinal)); }); await using var server = await CreateServerAsync(options => @@ -4740,7 +4740,7 @@ public async Task ValidatePushedAuthorizationRequest_RequestIsValidatedWhenExpli .ReturnsAsync(true); mock.Setup(manager => manager.GetSettingsAsync(application, It.IsAny())) - .ReturnsAsync(ImmutableDictionary.Create()); + .ReturnsAsync(ImmutableDictionary.Create(StringComparer.Ordinal)); }); await using var server = await CreateServerAsync(options => @@ -5059,7 +5059,7 @@ public async Task ValidatePushedAuthorizationRequest_RequestIsValidatedWhenCodeC .ReturnsAsync(false); mock.Setup(manager => manager.GetSettingsAsync(application, It.IsAny())) - .ReturnsAsync(ImmutableDictionary.Create()); + .ReturnsAsync(ImmutableDictionary.Create(StringComparer.Ordinal)); }); await using var server = await CreateServerAsync(options => @@ -5116,7 +5116,7 @@ public async Task ValidatePushedAuthorizationRequest_RequestIsValidatedWhenCodeC .ReturnsAsync(true); mock.Setup(manager => manager.GetSettingsAsync(application, It.IsAny())) - .ReturnsAsync(ImmutableDictionary.Create()); + .ReturnsAsync(ImmutableDictionary.Create(StringComparer.Ordinal)); }); await using var server = await CreateServerAsync(options => @@ -5173,7 +5173,7 @@ public async Task ValidatePushedAuthorizationRequest_RequestIsValidatedWhenCodeI .ReturnsAsync(true); mock.Setup(manager => manager.GetSettingsAsync(application, It.IsAny())) - .ReturnsAsync(ImmutableDictionary.Create()); + .ReturnsAsync(ImmutableDictionary.Create(StringComparer.Ordinal)); }); await using var server = await CreateServerAsync(options => @@ -5345,7 +5345,7 @@ public async Task ValidatePushedAuthorizationRequest_RequestIsValidatedWhenIdent .ReturnsAsync(true); mock.Setup(manager => manager.GetSettingsAsync(application, It.IsAny())) - .ReturnsAsync(ImmutableDictionary.Create()); + .ReturnsAsync(ImmutableDictionary.Create(StringComparer.Ordinal)); }); await using var server = await CreateServerAsync(options => diff --git a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Device.cs b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Device.cs index 2e3bfeef8..e5829a222 100644 --- a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Device.cs +++ b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Device.cs @@ -336,7 +336,7 @@ public async Task ValidateDeviceAuthorizationRequest_RequestIsValidatedWhenScope .ReturnsAsync(true); mock.Setup(manager => manager.GetSettingsAsync(application, It.IsAny())) - .ReturnsAsync(ImmutableDictionary.Create()); + .ReturnsAsync(ImmutableDictionary.Create(StringComparer.Ordinal)); })); options.Services.AddSingleton(CreateTokenManager(mock => @@ -412,7 +412,7 @@ public async Task ValidateDeviceAuthorizationRequest_RequestIsValidatedWhenRegis .ReturnsAsync(true); mock.Setup(manager => manager.GetSettingsAsync(application, It.IsAny())) - .ReturnsAsync(ImmutableDictionary.Create()); + .ReturnsAsync(ImmutableDictionary.Create(StringComparer.Ordinal)); })); options.Services.AddSingleton(CreateTokenManager(mock => diff --git a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Discovery.cs b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Discovery.cs index f0bb1f9ba..ef529ccfd 100644 --- a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Discovery.cs +++ b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Discovery.cs @@ -436,9 +436,9 @@ public async Task HandleConfigurationRequest_SupportedClientAuthenticationMethod // Assert Assert.NotNull(methods); Assert.Equal(3, methods.Value.Length); - Assert.Contains(ClientAuthenticationMethods.ClientSecretPost, methods); - Assert.Contains(ClientAuthenticationMethods.PrivateKeyJwt, methods); - Assert.Contains("custom", methods); + Assert.Contains(ClientAuthenticationMethods.ClientSecretPost, methods, StringComparer.Ordinal); + Assert.Contains(ClientAuthenticationMethods.PrivateKeyJwt, methods, StringComparer.Ordinal); + Assert.Contains("custom", methods, StringComparer.Ordinal); } [Fact] @@ -478,9 +478,9 @@ public async Task HandleConfigurationRequest_SupportedClientAuthenticationMethod // Assert Assert.NotNull(methods); Assert.Equal(3, methods.Value.Length); - Assert.Contains(ClientAuthenticationMethods.ClientSecretPost, methods); - Assert.Contains(ClientAuthenticationMethods.PrivateKeyJwt, methods); - Assert.Contains("custom", methods); + Assert.Contains(ClientAuthenticationMethods.ClientSecretPost, methods, StringComparer.Ordinal); + Assert.Contains(ClientAuthenticationMethods.PrivateKeyJwt, methods, StringComparer.Ordinal); + Assert.Contains("custom", methods, StringComparer.Ordinal); } [Fact] @@ -520,9 +520,9 @@ public async Task HandleConfigurationRequest_SupportedClientAuthenticationMethod // Assert Assert.NotNull(methods); Assert.Equal(3, methods.Value.Length); - Assert.Contains(ClientAuthenticationMethods.ClientSecretPost, methods); - Assert.Contains(ClientAuthenticationMethods.PrivateKeyJwt, methods); - Assert.Contains("custom", methods); + Assert.Contains(ClientAuthenticationMethods.ClientSecretPost, methods, StringComparer.Ordinal); + Assert.Contains(ClientAuthenticationMethods.PrivateKeyJwt, methods, StringComparer.Ordinal); + Assert.Contains("custom", methods, StringComparer.Ordinal); } [Fact] @@ -563,9 +563,9 @@ public async Task HandleConfigurationRequest_SupportedClientAuthenticationMethod // Assert Assert.NotNull(methods); Assert.Equal(3, methods.Value.Length); - Assert.Contains(ClientAuthenticationMethods.ClientSecretPost, methods); - Assert.Contains(ClientAuthenticationMethods.PrivateKeyJwt, methods); - Assert.Contains("custom", methods); + Assert.Contains(ClientAuthenticationMethods.ClientSecretPost, methods, StringComparer.Ordinal); + Assert.Contains(ClientAuthenticationMethods.PrivateKeyJwt, methods, StringComparer.Ordinal); + Assert.Contains("custom", methods, StringComparer.Ordinal); } [Fact] @@ -605,9 +605,9 @@ public async Task HandleConfigurationRequest_SupportedClientAuthenticationMethod // Assert Assert.NotNull(methods); Assert.Equal(3, methods.Value.Length); - Assert.Contains(ClientAuthenticationMethods.ClientSecretPost, methods); - Assert.Contains(ClientAuthenticationMethods.PrivateKeyJwt, methods); - Assert.Contains("custom", methods); + Assert.Contains(ClientAuthenticationMethods.ClientSecretPost, methods, StringComparer.Ordinal); + Assert.Contains(ClientAuthenticationMethods.PrivateKeyJwt, methods, StringComparer.Ordinal); + Assert.Contains("custom", methods, StringComparer.Ordinal); } [Fact] @@ -635,8 +635,8 @@ public async Task HandleConfigurationRequest_ConfiguredGrantTypesAreReturned() // Assert Assert.NotNull(types); Assert.Equal(2, types.Value.Length); - Assert.Contains(GrantTypes.AuthorizationCode, types); - Assert.Contains(GrantTypes.Password, types); + Assert.Contains(GrantTypes.AuthorizationCode, types, StringComparer.Ordinal); + Assert.Contains(GrantTypes.Password, types, StringComparer.Ordinal); } [Fact] @@ -677,8 +677,8 @@ public async Task HandleConfigurationRequest_ConfiguredCodeChallengeMethodsAreRe // Assert Assert.NotNull(methods); Assert.Equal(2, methods.Value.Length); - Assert.Contains(CodeChallengeMethods.Sha256, methods); - Assert.Contains(CodeChallengeMethods.Plain, methods); + Assert.Contains(CodeChallengeMethods.Sha256, methods, StringComparer.Ordinal); + Assert.Contains(CodeChallengeMethods.Plain, methods, StringComparer.Ordinal); } [Fact] @@ -719,8 +719,8 @@ public async Task HandleConfigurationRequest_ConfiguredResponseModesAreReturned( // Assert Assert.NotNull(modes); Assert.Equal(2, modes.Value.Length); - Assert.Contains(ResponseModes.FormPost, modes); - Assert.Contains(ResponseModes.Fragment, modes); + Assert.Contains(ResponseModes.FormPost, modes, StringComparer.Ordinal); + Assert.Contains(ResponseModes.Fragment, modes, StringComparer.Ordinal); } [Fact] @@ -761,8 +761,8 @@ public async Task HandleConfigurationRequest_ConfiguredResponseTypesAreReturned( // Assert Assert.NotNull(types); Assert.Equal(2, types.Value.Length); - Assert.Contains(ResponseTypes.Code, types); - Assert.Contains(ResponseTypes.Code + ' ' + ResponseTypes.IdToken, types); + Assert.Contains(ResponseTypes.Code, types, StringComparer.Ordinal); + Assert.Contains(ResponseTypes.Code + ' ' + ResponseTypes.IdToken, types, StringComparer.Ordinal); } [Fact] @@ -803,8 +803,8 @@ public async Task HandleConfigurationRequest_ConfiguredScopesAreReturned() // Assert Assert.NotNull(scopes); Assert.Equal(2, scopes.Value.Length); - Assert.Contains(Scopes.OpenId, scopes); - Assert.Contains("custom_scope", scopes); + Assert.Contains(Scopes.OpenId, scopes, StringComparer.Ordinal); + Assert.Contains("custom_scope", scopes, StringComparer.Ordinal); } [Fact] @@ -845,8 +845,8 @@ public async Task HandleConfigurationRequest_ConfiguredClaimsAreReturned() // Assert Assert.NotNull(claims); Assert.Equal(2, claims.Value.Length); - Assert.Contains(Claims.Profile, claims); - Assert.Contains("custom_claim", claims); + Assert.Contains(Claims.Profile, claims, StringComparer.Ordinal); + Assert.Contains("custom_claim", claims, StringComparer.Ordinal); } [Fact] @@ -923,7 +923,7 @@ public async Task HandleConfigurationRequest_SigningAlgorithmsAreCorrectlyReturn // Assert Assert.NotNull(algorithms); - Assert.Contains(algorithm, algorithms); + Assert.Contains(algorithm, algorithms, StringComparer.Ordinal); } [Fact] @@ -946,7 +946,7 @@ public async Task HandleConfigurationRequest_SymmetricSigningKeysAreIgnored() // Assert Assert.NotNull(algorithms); Assert.Single(algorithms); - Assert.Contains(Algorithms.RsaSha256, algorithms); + Assert.Contains(Algorithms.RsaSha256, algorithms, StringComparer.Ordinal); } [Fact] diff --git a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Exchange.cs b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Exchange.cs index b75cdb496..327acbbcd 100644 --- a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Exchange.cs +++ b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.Exchange.cs @@ -3032,7 +3032,7 @@ public async Task ValidateTokenRequest_RequestIsValidatedWhenCodeVerifierIsMissi .ReturnsAsync(false); mock.Setup(manager => manager.GetSettingsAsync(application, It.IsAny())) - .ReturnsAsync(ImmutableDictionary.Create()); + .ReturnsAsync(ImmutableDictionary.Create(StringComparer.Ordinal)); }); await using var server = await CreateServerAsync(options => @@ -3103,7 +3103,7 @@ public async Task ValidateTokenRequest_RequestIsValidatedWhenCodeVerifierIsPrese .ReturnsAsync(false); mock.Setup(manager => manager.GetSettingsAsync(application, It.IsAny())) - .ReturnsAsync(ImmutableDictionary.Create()); + .ReturnsAsync(ImmutableDictionary.Create(StringComparer.Ordinal)); }); await using var server = await CreateServerAsync(options => @@ -3309,7 +3309,7 @@ public async Task HandleTokenRequest_AuthorizationCodeRevocationIsIgnoredWhenTok .ReturnsAsync(true); mock.Setup(manager => manager.GetSettingsAsync(application, It.IsAny())) - .ReturnsAsync(ImmutableDictionary.Create()); + .ReturnsAsync(ImmutableDictionary.Create(StringComparer.Ordinal)); })); options.SetDeviceAuthorizationEndpointUris(Array.Empty()); @@ -4809,7 +4809,7 @@ public async Task HandleTokenRequest_AuthorizationAssociatedWithCodeIsIgnoredWhe .ReturnsAsync(true); mock.Setup(manager => manager.GetSettingsAsync(application, It.IsAny())) - .ReturnsAsync(ImmutableDictionary.Create()); + .ReturnsAsync(ImmutableDictionary.Create(StringComparer.Ordinal)); })); options.Services.AddSingleton(CreateTokenManager(mock => @@ -6103,7 +6103,7 @@ public async Task HandleTokenRequest_RequestsAreSuccessfullyHandled(string type) .ReturnsAsync(true); mock.Setup(manager => manager.GetSettingsAsync(application, It.IsAny())) - .ReturnsAsync(ImmutableDictionary.Create()); + .ReturnsAsync(ImmutableDictionary.Create(StringComparer.Ordinal)); })); options.Services.AddSingleton(manager); diff --git a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.cs b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.cs index 46fa1deae..4ade1b675 100644 --- a/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.cs +++ b/test/OpenIddict.Server.IntegrationTests/OpenIddictServerIntegrationTests.cs @@ -4484,7 +4484,7 @@ public async Task ProcessSignIn_AuthorizationCodeIsAutomaticallyRedeemed() .ReturnsAsync(true); mock.Setup(manager => manager.GetSettingsAsync(application, It.IsAny())) - .ReturnsAsync(ImmutableDictionary.Create() + .ReturnsAsync(ImmutableDictionary.Create(StringComparer.Ordinal) .SetItem(Settings.TokenLifetimes.AccessToken, TimeSpan.FromMinutes(5).ToString("c", CultureInfo.InvariantCulture))); })); @@ -4680,7 +4680,7 @@ public async Task ProcessSignIn_AdHocAuthorizationIsAutomaticallyCreated() .ReturnsAsync("3E228451-1555-46F7-A471-951EFBA23A56"); mock.Setup(manager => manager.GetSettingsAsync(application, It.IsAny())) - .ReturnsAsync(ImmutableDictionary.Create()); + .ReturnsAsync(ImmutableDictionary.Create(StringComparer.Ordinal)); })); options.Services.AddSingleton(CreateTokenManager(mock => @@ -4760,7 +4760,7 @@ public async Task ProcessSignIn_AdHocAuthorizationIsNotCreatedWhenAuthorizationS .ReturnsAsync("3E228451-1555-46F7-A471-951EFBA23A56"); mock.Setup(manager => manager.GetSettingsAsync(application, It.IsAny())) - .ReturnsAsync(ImmutableDictionary.Create()); + .ReturnsAsync(ImmutableDictionary.Create(StringComparer.Ordinal)); })); options.Services.AddSingleton(CreateTokenManager(mock => diff --git a/test/OpenIddict.Server.Owin.IntegrationTests/OpenIddictServerOwinIntegrationTests.cs b/test/OpenIddict.Server.Owin.IntegrationTests/OpenIddictServerOwinIntegrationTests.cs index 0c3d36c51..9d5698a4d 100644 --- a/test/OpenIddict.Server.Owin.IntegrationTests/OpenIddictServerOwinIntegrationTests.cs +++ b/test/OpenIddict.Server.Owin.IntegrationTests/OpenIddictServerOwinIntegrationTests.cs @@ -153,7 +153,7 @@ public async Task ProcessAuthentication_CreationDateIsMappedToIssuedUtc() // Assert var properties = new AuthenticationProperties(response.GetParameters() - .ToDictionary(parameter => parameter.Key, parameter => (string?) parameter.Value)); + .ToDictionary(parameter => parameter.Key, parameter => (string?) parameter.Value, StringComparer.Ordinal)); Assert.Equal(new DateTimeOffset(2020, 01, 01, 00, 00, 00, TimeSpan.Zero), properties.IssuedUtc); } @@ -203,7 +203,7 @@ public async Task ProcessAuthentication_ExpirationDateIsMappedToIssuedUtc() // Assert var properties = new AuthenticationProperties(response.GetParameters() - .ToDictionary(parameter => parameter.Key, parameter => (string?) parameter.Value)); + .ToDictionary(parameter => parameter.Key, parameter => (string?) parameter.Value, StringComparer.Ordinal)); Assert.Equal(new DateTimeOffset(2120, 01, 01, 00, 00, 00, TimeSpan.Zero), properties.ExpiresUtc); } @@ -251,7 +251,7 @@ public async Task ProcessAuthentication_CustomPropertiesAreAddedForErroredAuthen // Assert var properties = new AuthenticationProperties(response.GetParameters() - .ToDictionary(parameter => parameter.Key, parameter => (string?) parameter.Value)); + .ToDictionary(parameter => parameter.Key, parameter => (string?) parameter.Value, StringComparer.Ordinal)); Assert.Equal("value", properties.Dictionary["custom_property"]); } @@ -705,7 +705,7 @@ protected override ValueTask CreateServer var principal = new ClaimsPrincipal(identity); - var properties = new AuthenticationProperties(new Dictionary + var properties = new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) { ["custom_property"] = "value", @@ -719,81 +719,87 @@ protected override ValueTask CreateServer return; } - else if (context.Request.Path == new PathString("/signout")) + else + { + if (context.Request.Path == new PathString("/signout")) { context.Authentication.SignOut(OpenIddictServerOwinDefaults.AuthenticationType); return; } - else if (context.Request.Path == new PathString("/signout/custom")) - { - - var properties = new AuthenticationProperties(new Dictionary + if (context.Request.Path == new PathString("/signout/custom")) { - ["custom_property"] = "value", - - ["boolean_parameter#boolean"] = "true", - ["integer_parameter#integer"] = "42", - ["string_parameter#string"] = "Bob l'Eponge" - }); - - context.Authentication.SignOut(properties, OpenIddictServerOwinDefaults.AuthenticationType); - return; - } - - else if (context.Request.Path == new PathString("/challenge")) - { - context.Authentication.Challenge(OpenIddictServerOwinDefaults.AuthenticationType); - return; - } - else if (context.Request.Path == new PathString("/challenge/custom")) - { - var properties = new AuthenticationProperties(new Dictionary - { - [OpenIddictServerOwinConstants.Properties.Error] = "custom_error", - [OpenIddictServerOwinConstants.Properties.ErrorDescription] = "custom_error_description", - [OpenIddictServerOwinConstants.Properties.ErrorUri] = "custom_error_uri", + var properties = new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) + { + ["custom_property"] = "value", - ["custom_property"] = "value", + ["boolean_parameter#boolean"] = "true", + ["integer_parameter#integer"] = "42", + ["string_parameter#string"] = "Bob l'Eponge" + }); - ["boolean_parameter#boolean"] = "true", - ["integer_parameter#integer"] = "42", - ["string_parameter#string"] = "Bob l'Eponge", - ["json_parameter#json"] = @"[""Contoso"",""Fabrikam""]" - }); - - context.Authentication.Challenge(properties, OpenIddictServerOwinDefaults.AuthenticationType); - return; - } - - else if (context.Request.Path == new PathString("/authenticate")) - { - var result = await context.Authentication.AuthenticateAsync(OpenIddictServerOwinDefaults.AuthenticationType); - if (result?.Identity is not { IsAuthenticated: true }) - { + context.Authentication.SignOut(properties, OpenIddictServerOwinDefaults.AuthenticationType); return; } - var claims = result.Identity.Claims.GroupBy(claim => claim.Type) - .Select(group => KeyValuePair.Create(group.Key, group.Select(claim => claim.Value).ToImmutableArray())); - - context.Response.ContentType = "application/json"; - await context.Response.WriteAsync(JsonSerializer.Serialize(new OpenIddictResponse(claims))); - return; - } - - else if (context.Request.Path == new PathString("/authenticate/properties")) - { - var result = await context.Authentication.AuthenticateAsync(OpenIddictServerOwinDefaults.AuthenticationType); - if (result?.Properties is null) + else { - return; + if (context.Request.Path == new PathString("/challenge")) + { + context.Authentication.Challenge(OpenIddictServerOwinDefaults.AuthenticationType); + return; + } + + if (context.Request.Path == new PathString("/challenge/custom")) + { + var properties = new AuthenticationProperties(new Dictionary(StringComparer.Ordinal) + { + [OpenIddictServerOwinConstants.Properties.Error] = "custom_error", + [OpenIddictServerOwinConstants.Properties.ErrorDescription] = "custom_error_description", + [OpenIddictServerOwinConstants.Properties.ErrorUri] = "custom_error_uri", + + ["custom_property"] = "value", + + ["boolean_parameter#boolean"] = "true", + ["integer_parameter#integer"] = "42", + ["string_parameter#string"] = "Bob l'Eponge", + ["json_parameter#json"] = @"[""Contoso"",""Fabrikam""]" + }); + + context.Authentication.Challenge(properties, OpenIddictServerOwinDefaults.AuthenticationType); + return; + } + + if (context.Request.Path == new PathString("/authenticate")) + { + var result = await context.Authentication.AuthenticateAsync(OpenIddictServerOwinDefaults.AuthenticationType); + if (result?.Identity is not { IsAuthenticated: true }) + { + return; + } + + var claims = result.Identity.Claims.GroupBy(claim => claim.Type, StringComparer.Ordinal) + .Select(group => KeyValuePair.Create(group.Key, group.Select(claim => claim.Value).ToImmutableArray())); + + context.Response.ContentType = "application/json"; + await context.Response.WriteAsync(JsonSerializer.Serialize(new OpenIddictResponse(claims))); + return; + } + + else if (context.Request.Path == new PathString("/authenticate/properties")) + { + var result = await context.Authentication.AuthenticateAsync(OpenIddictServerOwinDefaults.AuthenticationType); + if (result?.Properties is null) + { + return; + } + + context.Response.ContentType = "application/json"; + await context.Response.WriteAsync(JsonSerializer.Serialize(new OpenIddictResponse(result.Properties.Dictionary))); + return; + } } - - context.Response.ContentType = "application/json"; - await context.Response.WriteAsync(JsonSerializer.Serialize(new OpenIddictResponse(result.Properties.Dictionary))); - return; } await next(); diff --git a/test/OpenIddict.Server.Tests/OpenIddictServerBuilderTests.cs b/test/OpenIddict.Server.Tests/OpenIddictServerBuilderTests.cs index 8e86ecc52..a4fe86d44 100644 --- a/test/OpenIddict.Server.Tests/OpenIddictServerBuilderTests.cs +++ b/test/OpenIddict.Server.Tests/OpenIddictServerBuilderTests.cs @@ -1100,7 +1100,7 @@ public void AllowCustomFlow_ThrowsAnExceptionForStandardGrantType(string type) var exception = Assert.ThrowsAny(() => builder.AllowCustomFlow(type)); Assert.Equal("type", exception.ParamName); - Assert.StartsWith(SR.FormatID0517(type), exception.Message); + Assert.StartsWith(SR.FormatID0517(type), exception.Message, StringComparison.Ordinal); } [Fact] @@ -1618,7 +1618,7 @@ public void EnablePublicKeyInfrastructureTlsClientAuthentication_PolicyIsCorrect Assert.NotNull(options.PublicKeyInfrastructureTlsClientAuthenticationPolicy); Assert.Equal(X509ChainTrustMode.CustomRootTrust, options.PublicKeyInfrastructureTlsClientAuthenticationPolicy.TrustMode); Assert.Contains(options.PublicKeyInfrastructureTlsClientAuthenticationPolicy.ApplicationPolicy.Cast(), - oid => oid.Value == ObjectIdentifiers.ExtendedKeyUsages.ClientAuthentication); + oid => string.Equals(oid.Value, ObjectIdentifiers.ExtendedKeyUsages.ClientAuthentication, StringComparison.Ordinal)); } [Fact] @@ -1739,7 +1739,7 @@ public void EnableSelfSignedTlsClientAuthentication_PolicyIsCorrectlyConfigured( Assert.Equal(X509ChainTrustMode.CustomRootTrust, options.SelfSignedTlsClientAuthenticationPolicy.TrustMode); Assert.Equal(X509RevocationMode.NoCheck, options.SelfSignedTlsClientAuthenticationPolicy.RevocationMode); Assert.Contains(options.SelfSignedTlsClientAuthenticationPolicy.ApplicationPolicy.Cast(), - oid => oid.Value == ObjectIdentifiers.ExtendedKeyUsages.ClientAuthentication); + oid => string.Equals(oid.Value, ObjectIdentifiers.ExtendedKeyUsages.ClientAuthentication, StringComparison.Ordinal)); } [Fact] @@ -1889,7 +1889,7 @@ public void SetAuthorizationEndpointUris_ThrowsExceptionForMalformedUri(string u // Act and assert var exception = Assert.Throws(() => builder.SetAuthorizationEndpointUris(new Uri(uri))); Assert.Equal("uris", exception.ParamName); - Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message); + Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message, StringComparison.Ordinal); } [Theory] @@ -1903,7 +1903,7 @@ public void SetAuthorizationEndpointUris_ThrowsExceptionForInvalidRelativeUri(st // Act and assert var exception = Assert.Throws(() => builder.SetAuthorizationEndpointUris(new Uri(uri, UriKind.RelativeOrAbsolute))); Assert.Equal("uris", exception.ParamName); - Assert.Contains(SR.FormatID0081("~"), exception.Message); + Assert.Contains(SR.FormatID0081("~"), exception.Message, StringComparison.Ordinal); } [Fact] @@ -1973,7 +1973,7 @@ public void SetConfigurationEndpointUris_ThrowsExceptionForMalformedUri(string u // Act and assert var exception = Assert.Throws(() => builder.SetConfigurationEndpointUris(new Uri(uri))); Assert.Equal("uris", exception.ParamName); - Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message); + Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message, StringComparison.Ordinal); } [Theory] @@ -1987,7 +1987,7 @@ public void SetConfigurationEndpointUris_ThrowsExceptionForInvalidRelativeUri(st // Act and assert var exception = Assert.Throws(() => builder.SetConfigurationEndpointUris(new Uri(uri, UriKind.RelativeOrAbsolute))); Assert.Equal("uris", exception.ParamName); - Assert.Contains(SR.FormatID0081("~"), exception.Message); + Assert.Contains(SR.FormatID0081("~"), exception.Message, StringComparison.Ordinal); } [Fact] @@ -2057,7 +2057,7 @@ public void SetJsonWebKeySetEndpointUris_ThrowsExceptionForMalformedUri(string u // Act and assert var exception = Assert.Throws(() => builder.SetJsonWebKeySetEndpointUris(new Uri(uri))); Assert.Equal("uris", exception.ParamName); - Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message); + Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message, StringComparison.Ordinal); } [Theory] @@ -2071,7 +2071,7 @@ public void SetJsonWebKeySetEndpointUris_ThrowsExceptionForInvalidRelativeUri(st // Act and assert var exception = Assert.Throws(() => builder.SetJsonWebKeySetEndpointUris(new Uri(uri, UriKind.RelativeOrAbsolute))); Assert.Equal("uris", exception.ParamName); - Assert.Contains(SR.FormatID0081("~"), exception.Message); + Assert.Contains(SR.FormatID0081("~"), exception.Message, StringComparison.Ordinal); } [Fact] @@ -2141,7 +2141,7 @@ public void SetDeviceAuthorizationEndpointUris_ThrowsExceptionForMalformedUri(st // Act and assert var exception = Assert.Throws(() => builder.SetDeviceAuthorizationEndpointUris(new Uri(uri))); Assert.Equal("uris", exception.ParamName); - Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message); + Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message, StringComparison.Ordinal); } [Theory] @@ -2155,7 +2155,7 @@ public void SetDeviceAuthorizationEndpointUris_ThrowsExceptionForInvalidRelative // Act and assert var exception = Assert.Throws(() => builder.SetDeviceAuthorizationEndpointUris(new Uri(uri, UriKind.RelativeOrAbsolute))); Assert.Equal("uris", exception.ParamName); - Assert.Contains(SR.FormatID0081("~"), exception.Message); + Assert.Contains(SR.FormatID0081("~"), exception.Message, StringComparison.Ordinal); } [Fact] @@ -2225,7 +2225,7 @@ public void SetEndSessionEndpointUris_ThrowsExceptionForMalformedUri(string uri) // Act and assert var exception = Assert.Throws(() => builder.SetEndSessionEndpointUris(new Uri(uri))); Assert.Equal("uris", exception.ParamName); - Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message); + Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message, StringComparison.Ordinal); } [Theory] @@ -2239,7 +2239,7 @@ public void SetEndSessionEndpointUris_ThrowsExceptionForInvalidRelativeUri(strin // Act and assert var exception = Assert.Throws(() => builder.SetEndSessionEndpointUris(new Uri(uri, UriKind.RelativeOrAbsolute))); Assert.Equal("uris", exception.ParamName); - Assert.Contains(SR.FormatID0081("~"), exception.Message); + Assert.Contains(SR.FormatID0081("~"), exception.Message, StringComparison.Ordinal); } [Fact] @@ -2309,7 +2309,7 @@ public void SetMtlsDeviceAuthorizationEndpointAliasUri_ThrowsExceptionForMalform // Act and assert var exception = Assert.Throws(() => builder.SetMtlsDeviceAuthorizationEndpointAliasUri(new Uri(uri))); Assert.Equal("uri", exception.ParamName); - Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message); + Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message, StringComparison.Ordinal); } [Theory] @@ -2323,7 +2323,7 @@ public void SetMtlsDeviceAuthorizationEndpointAliasUri_ThrowsExceptionForInvalid // Act and assert var exception = Assert.Throws(() => builder.SetMtlsDeviceAuthorizationEndpointAliasUri(new Uri(uri, UriKind.RelativeOrAbsolute))); Assert.Equal("uri", exception.ParamName); - Assert.Contains(SR.FormatID0081("~"), exception.Message); + Assert.Contains(SR.FormatID0081("~"), exception.Message, StringComparison.Ordinal); } [Fact] @@ -2377,7 +2377,7 @@ public void SetMtlsIntrospectionEndpointAliasUri_ThrowsExceptionForMalformedUri( // Act and assert var exception = Assert.Throws(() => builder.SetMtlsIntrospectionEndpointAliasUri(new Uri(uri))); Assert.Equal("uri", exception.ParamName); - Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message); + Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message, StringComparison.Ordinal); } [Theory] @@ -2391,7 +2391,7 @@ public void SetMtlsIntrospectionEndpointAliasUri_ThrowsExceptionForInvalidRelati // Act and assert var exception = Assert.Throws(() => builder.SetMtlsIntrospectionEndpointAliasUri(new Uri(uri, UriKind.RelativeOrAbsolute))); Assert.Equal("uri", exception.ParamName); - Assert.Contains(SR.FormatID0081("~"), exception.Message); + Assert.Contains(SR.FormatID0081("~"), exception.Message, StringComparison.Ordinal); } [Fact] @@ -2445,7 +2445,7 @@ public void SetMtlsPushedAuthorizationEndpointAliasUri_ThrowsExceptionForMalform // Act and assert var exception = Assert.Throws(() => builder.SetMtlsPushedAuthorizationEndpointAliasUri(new Uri(uri))); Assert.Equal("uri", exception.ParamName); - Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message); + Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message, StringComparison.Ordinal); } [Theory] @@ -2459,7 +2459,7 @@ public void SetMtlsPushedAuthorizationEndpointAliasUri_ThrowsExceptionForInvalid // Act and assert var exception = Assert.Throws(() => builder.SetMtlsPushedAuthorizationEndpointAliasUri(new Uri(uri, UriKind.RelativeOrAbsolute))); Assert.Equal("uri", exception.ParamName); - Assert.Contains(SR.FormatID0081("~"), exception.Message); + Assert.Contains(SR.FormatID0081("~"), exception.Message, StringComparison.Ordinal); } [Fact] @@ -2513,7 +2513,7 @@ public void SetMtlsRevocationEndpointAliasUri_ThrowsExceptionForMalformedUri(str // Act and assert var exception = Assert.Throws(() => builder.SetMtlsRevocationEndpointAliasUri(new Uri(uri))); Assert.Equal("uri", exception.ParamName); - Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message); + Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message, StringComparison.Ordinal); } [Theory] @@ -2527,7 +2527,7 @@ public void SetMtlsRevocationEndpointAliasUri_ThrowsExceptionForInvalidRelativeU // Act and assert var exception = Assert.Throws(() => builder.SetMtlsRevocationEndpointAliasUri(new Uri(uri, UriKind.RelativeOrAbsolute))); Assert.Equal("uri", exception.ParamName); - Assert.Contains(SR.FormatID0081("~"), exception.Message); + Assert.Contains(SR.FormatID0081("~"), exception.Message, StringComparison.Ordinal); } [Fact] @@ -2581,7 +2581,7 @@ public void SetMtlsTokenEndpointAliasUri_ThrowsExceptionForMalformedUri(string u // Act and assert var exception = Assert.Throws(() => builder.SetMtlsTokenEndpointAliasUri(new Uri(uri))); Assert.Equal("uri", exception.ParamName); - Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message); + Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message, StringComparison.Ordinal); } [Theory] @@ -2595,7 +2595,7 @@ public void SetMtlsTokenEndpointAliasUri_ThrowsExceptionForInvalidRelativeUri(st // Act and assert var exception = Assert.Throws(() => builder.SetMtlsTokenEndpointAliasUri(new Uri(uri, UriKind.RelativeOrAbsolute))); Assert.Equal("uri", exception.ParamName); - Assert.Contains(SR.FormatID0081("~"), exception.Message); + Assert.Contains(SR.FormatID0081("~"), exception.Message, StringComparison.Ordinal); } [Fact] @@ -2625,7 +2625,7 @@ public void SetMtlsUserInfoEndpointAliasUri_ThrowsExceptionForInvalidRelativeUri // Act and assert var exception = Assert.Throws(() => builder.SetMtlsUserInfoEndpointAliasUri(new Uri(uri, UriKind.RelativeOrAbsolute))); Assert.Equal("uri", exception.ParamName); - Assert.Contains(SR.FormatID0081("~"), exception.Message); + Assert.Contains(SR.FormatID0081("~"), exception.Message, StringComparison.Ordinal); } [Fact] @@ -2679,7 +2679,7 @@ public void SetIntrospectionEndpointUris_ThrowsExceptionForMalformedUri(string u // Act and assert var exception = Assert.Throws(() => builder.SetIntrospectionEndpointUris(new Uri(uri))); Assert.Equal("uris", exception.ParamName); - Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message); + Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message, StringComparison.Ordinal); } [Theory] @@ -2693,7 +2693,7 @@ public void SetIntrospectionEndpointUris_ThrowsExceptionForInvalidRelativeUri(st // Act and assert var exception = Assert.Throws(() => builder.SetIntrospectionEndpointUris(new Uri(uri, UriKind.RelativeOrAbsolute))); Assert.Equal("uris", exception.ParamName); - Assert.Contains(SR.FormatID0081("~"), exception.Message); + Assert.Contains(SR.FormatID0081("~"), exception.Message, StringComparison.Ordinal); } [Fact] @@ -2763,7 +2763,7 @@ public void SetRevocationEndpointUris_ThrowsExceptionForMalformedUri(string uri) // Act and assert var exception = Assert.Throws(() => builder.SetRevocationEndpointUris(new Uri(uri))); Assert.Equal("uris", exception.ParamName); - Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message); + Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message, StringComparison.Ordinal); } [Theory] @@ -2777,7 +2777,7 @@ public void SetRevocationEndpointUris_ThrowsExceptionForInvalidRelativeUri(strin // Act and assert var exception = Assert.Throws(() => builder.SetRevocationEndpointUris(new Uri(uri, UriKind.RelativeOrAbsolute))); Assert.Equal("uris", exception.ParamName); - Assert.Contains(SR.FormatID0081("~"), exception.Message); + Assert.Contains(SR.FormatID0081("~"), exception.Message, StringComparison.Ordinal); } [Fact] @@ -2847,7 +2847,7 @@ public void SetTokenEndpointUris_ThrowsExceptionForMalformedUri(string uri) // Act and assert var exception = Assert.Throws(() => builder.SetTokenEndpointUris(new Uri(uri))); Assert.Equal("uris", exception.ParamName); - Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message); + Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message, StringComparison.Ordinal); } [Theory] @@ -2861,7 +2861,7 @@ public void SetTokenEndpointUris_ThrowsExceptionForInvalidRelativeUri(string uri // Act and assert var exception = Assert.Throws(() => builder.SetTokenEndpointUris(new Uri(uri, UriKind.RelativeOrAbsolute))); Assert.Equal("uris", exception.ParamName); - Assert.Contains(SR.FormatID0081("~"), exception.Message); + Assert.Contains(SR.FormatID0081("~"), exception.Message, StringComparison.Ordinal); } [Fact] @@ -2931,7 +2931,7 @@ public void SetUserInfoEndpointUris_ThrowsExceptionForMalformedUri(string uri) // Act and assert var exception = Assert.Throws(() => builder.SetUserInfoEndpointUris(new Uri(uri))); Assert.Equal("uris", exception.ParamName); - Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message); + Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message, StringComparison.Ordinal); } [Theory] @@ -2945,7 +2945,7 @@ public void SetUserInfoEndpointUris_ThrowsExceptionForInvalidRelativeUri(string // Act and assert var exception = Assert.Throws(() => builder.SetUserInfoEndpointUris(new Uri(uri, UriKind.RelativeOrAbsolute))); Assert.Equal("uris", exception.ParamName); - Assert.Contains(SR.FormatID0081("~"), exception.Message); + Assert.Contains(SR.FormatID0081("~"), exception.Message, StringComparison.Ordinal); } [Fact] @@ -3015,7 +3015,7 @@ public void SetEndUserVerificationEndpointUris_ThrowsExceptionForMalformedUri(st // Act and assert var exception = Assert.Throws(() => builder.SetEndUserVerificationEndpointUris(new Uri(uri))); Assert.Equal("uris", exception.ParamName); - Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message); + Assert.Contains(SR.GetResourceString(SR.ID0072), exception.Message, StringComparison.Ordinal); } [Theory] @@ -3029,7 +3029,7 @@ public void SetEndUserVerificationEndpointUris_ThrowsExceptionForInvalidRelative // Act and assert var exception = Assert.Throws(() => builder.SetEndUserVerificationEndpointUris(new Uri(uri, UriKind.RelativeOrAbsolute))); Assert.Equal("uris", exception.ParamName); - Assert.Contains(SR.FormatID0081("~"), exception.Message); + Assert.Contains(SR.FormatID0081("~"), exception.Message, StringComparison.Ordinal); } [Fact] @@ -3277,7 +3277,7 @@ public void SetUserCodeCharset_ThrowsAnExceptionForCharsetWithDuplicatedCharacte var exception = Assert.Throws(() => builder.SetUserCodeCharset( ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "9"])); - Assert.StartsWith(SR.GetResourceString(SR.ID0436), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0436), exception.Message, StringComparison.Ordinal); Assert.Equal("charset", exception.ParamName); } @@ -3295,7 +3295,7 @@ public void SetUserCodeCharset_ThrowsAnExceptionForCharsetWithInvalidCharacter(s var exception = Assert.Throws(() => builder.SetUserCodeCharset( ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", character])); - Assert.StartsWith(SR.GetResourceString(SR.ID0437), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0437), exception.Message, StringComparison.Ordinal); Assert.Equal("charset", exception.ParamName); } #else @@ -3310,7 +3310,7 @@ public void SetUserCodeCharset_ThrowsAnExceptionForCharsetWithNonAsciiCharacter( var exception = Assert.Throws(() => builder.SetUserCodeCharset( ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "\uD83D\uDE42"])); - Assert.StartsWith(SR.GetResourceString(SR.ID0438), exception.Message); + Assert.StartsWith(SR.GetResourceString(SR.ID0438), exception.Message, StringComparison.Ordinal); Assert.Equal("charset", exception.ParamName); } #endif @@ -3529,7 +3529,7 @@ public void RegisterAudiences_ThrowsAnExceptionForNullOrEmptyAudience(string? au var exception = Assert.Throws(() => builder.RegisterAudiences([audience!])); Assert.Equal("audiences", exception.ParamName); - Assert.Contains(SR.FormatID0457("audiences"), exception.Message); + Assert.Contains(SR.FormatID0457("audiences"), exception.Message, StringComparison.Ordinal); } [Fact] @@ -3574,7 +3574,7 @@ public void RegisterClaims_ThrowsAnExceptionForNullOrEmptyClaim(string? claim) var exception = Assert.Throws(() => builder.RegisterClaims([claim!])); Assert.Equal("claims", exception.ParamName); - Assert.Contains(SR.FormatID0457("claims"), exception.Message); + Assert.Contains(SR.FormatID0457("claims"), exception.Message, StringComparison.Ordinal); } [Fact] @@ -3619,7 +3619,7 @@ public void RegisterPromptValues_ThrowsAnExceptionForNullOrEmptyValue(string? va var exception = Assert.Throws(() => builder.RegisterPromptValues([value!])); Assert.Equal("values", exception.ParamName); - Assert.Contains(SR.FormatID0457("values"), exception.Message); + Assert.Contains(SR.FormatID0457("values"), exception.Message, StringComparison.Ordinal); } [Fact] @@ -3665,7 +3665,7 @@ public void RegisterResources_ThrowsAnExceptionForInvalidResources(string? resou var exception = Assert.Throws(() => builder.RegisterResources([resource!])); Assert.Equal("resources", exception.ParamName); - Assert.Contains(SR.FormatID0495("resources"), exception.Message); + Assert.Contains(SR.FormatID0495("resources"), exception.Message, StringComparison.Ordinal); } [Fact] @@ -3710,7 +3710,7 @@ public void RegisterScopes_ThrowsAnExceptionForNullOrEmptyScope(string? scope) var exception = Assert.Throws(() => builder.RegisterScopes([scope!])); Assert.Equal("scopes", exception.ParamName); - Assert.Contains(SR.FormatID0457("scopes"), exception.Message); + Assert.Contains(SR.FormatID0457("scopes"), exception.Message, StringComparison.Ordinal); } [Fact] diff --git a/test/OpenIddict.Server.Tests/OpenIddictServerConfigurationTests.cs b/test/OpenIddict.Server.Tests/OpenIddictServerConfigurationTests.cs index 45e394f62..76de2895a 100644 --- a/test/OpenIddict.Server.Tests/OpenIddictServerConfigurationTests.cs +++ b/test/OpenIddict.Server.Tests/OpenIddictServerConfigurationTests.cs @@ -154,7 +154,7 @@ public void Validate_ReturnsAnErrorWhenJsonWebTokenHandlerIsMissing() var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0075), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0075), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -168,7 +168,7 @@ public void Validate_ReturnsAnErrorWhenNoFlowIsEnabled() var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0076), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0076), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -186,7 +186,7 @@ public void Validate_ReturnsAnErrorWhenEndpointUrisAreNotUnique() var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0285), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0285), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -201,7 +201,7 @@ public void Validate_ReturnsAnErrorWhenAuthorizationEndpointIsMissingForAuthoriz var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0077), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0077), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -216,7 +216,7 @@ public void Validate_ReturnsAnErrorWhenTokenEndpointIsMissingForPasswordGrant() var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0079), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0079), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -231,7 +231,7 @@ public void Validate_ReturnsAnErrorWhenDeviceVerificationEndpointIsMissingForDev var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0080), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0080), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -246,7 +246,7 @@ public void Validate_ReturnsAnErrorWhenDeviceEndpointIsEnabledWithoutDeviceGrant var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0084), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0084), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -263,7 +263,7 @@ public void Validate_ReturnsAnErrorWhenNoClientAuthenticationMethodIsEnabledForN var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0419), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0419), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -281,7 +281,7 @@ public void Validate_ReturnsAnErrorWhenPrivateKeyJwtIsEnabledWithoutJwtBearerAss var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.FormatID0420(ClientAssertionTypes.JwtBearer, ClientAuthenticationMethods.PrivateKeyJwt), result.Failures!); + Assert.Contains(SR.FormatID0420(ClientAssertionTypes.JwtBearer, ClientAuthenticationMethods.PrivateKeyJwt), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -296,7 +296,7 @@ public void Validate_ReturnsAnErrorWhenTlsClientAuthMethodIsEnabledWithoutPolicy var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0505), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0505), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -311,7 +311,7 @@ public void Validate_ReturnsAnErrorWhenSelfSignedTlsClientAuthMethodIsEnabledWit var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0506), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0506), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -326,7 +326,7 @@ public void Validate_ReturnsAnErrorWhenSubjectTypesAreMissing() var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0421), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0421), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -343,7 +343,7 @@ public void Validate_ReturnsAnErrorWhenReferenceTokensAreEnabledWithDisabledToke var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0083), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0083), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -360,7 +360,7 @@ public void Validate_ReturnsAnErrorWhenRequestCachingIsEnabledWithDisabledTokenS var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0465), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0465), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -378,7 +378,7 @@ public void Validate_ReturnsAnErrorWhenDeviceGrantIsEnabledWithDisabledTokenStor var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0367), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0367), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -394,7 +394,7 @@ public void Validate_ReturnsAnErrorWhenTokenExchangeGrantIsEnabledWithoutSubject var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0486), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0486), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -409,7 +409,7 @@ public void Validate_ReturnsAnErrorWhenDefaultRequestedTokenTypeIsMissing() var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0490), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0490), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -425,7 +425,7 @@ public void Validate_ReturnsAnErrorWhenDefaultRequestedTokenTypeIsNotAllowed() var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0492), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0492), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -439,7 +439,7 @@ public void Validate_ReturnsAnErrorWhenEncryptionCredentialsAreMissing() var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0085), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0085), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -462,7 +462,7 @@ public void Validate_ReturnsAnErrorWhenNoAsymmetricSigningCredentialIsRegistered var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0086), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0086), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -478,7 +478,7 @@ public void Validate_ReturnsAnErrorWhenMtlsEndpointAliasIsInvalid() var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0499), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0499), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -494,7 +494,7 @@ public void Validate_ReturnsAnErrorWhenMtlsEndpointAliasIsConfiguredWithoutEndpo var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0510), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0510), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -511,7 +511,7 @@ public void Validate_ReturnsAnErrorWhenMtlsEndpointAliasIsConfiguredWithoutIssue var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0500), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0500), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -527,7 +527,7 @@ public void Validate_ReturnsAnErrorWhenDegradedModeIsEnabledAndCustomTokenEndpoi var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0094), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0094), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -542,7 +542,7 @@ public void Validate_ReturnsAnErrorWhenUserCodeLengthIsTooShort() var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.FormatID0439(6), result.Failures!); + Assert.Contains(SR.FormatID0439(6), result.Failures!, StringComparer.Ordinal); } private static OpenIddictServerOptions CreateBaseOptions() diff --git a/test/OpenIddict.Validation.AspNetCore.IntegrationTests/OpenIddictValidationAspNetCoreIntegrationTests.cs b/test/OpenIddict.Validation.AspNetCore.IntegrationTests/OpenIddictValidationAspNetCoreIntegrationTests.cs index 27bf54e45..2746f8cd2 100644 --- a/test/OpenIddict.Validation.AspNetCore.IntegrationTests/OpenIddictValidationAspNetCoreIntegrationTests.cs +++ b/test/OpenIddict.Validation.AspNetCore.IntegrationTests/OpenIddictValidationAspNetCoreIntegrationTests.cs @@ -23,7 +23,7 @@ namespace OpenIddict.Validation.AspNetCore.IntegrationTests; -public partial class OpenIddictValidationAspNetCoreIntegrationTests : OpenIddictValidationIntegrationTests +public class OpenIddictValidationAspNetCoreIntegrationTests : OpenIddictValidationIntegrationTests { public OpenIddictValidationAspNetCoreIntegrationTests(ITestOutputHelper outputHelper) : base(outputHelper) @@ -65,7 +65,7 @@ public async Task ProcessAuthentication_CreationDateIsMappedToIssuedUtc() // Assert var properties = new AuthenticationProperties(response.GetParameters() - .ToDictionary(parameter => parameter.Key, parameter => (string?) parameter.Value)); + .ToDictionary(parameter => parameter.Key, parameter => (string?) parameter.Value, StringComparer.Ordinal)); Assert.Equal(new DateTimeOffset(2020, 01, 01, 00, 00, 00, TimeSpan.Zero), properties.IssuedUtc); } @@ -104,7 +104,7 @@ public async Task ProcessAuthentication_ExpirationDateIsMappedToIssuedUtc() // Assert var properties = new AuthenticationProperties(response.GetParameters() - .ToDictionary(parameter => parameter.Key, parameter => (string?) parameter.Value)); + .ToDictionary(parameter => parameter.Key, parameter => (string?) parameter.Value, StringComparer.Ordinal)); Assert.Equal(new DateTimeOffset(2120, 01, 01, 00, 00, 00, TimeSpan.Zero), properties.ExpiresUtc); } @@ -167,7 +167,7 @@ void ConfigurePipeline(IApplicationBuilder app) return; } - var claims = result.Principal.Claims.GroupBy(claim => claim.Type) + var claims = result.Principal.Claims.GroupBy(claim => claim.Type, StringComparer.Ordinal) .Select(group => KeyValuePair.Create(group.Key, group.Select(claim => claim.Value).ToImmutableArray())); context.Response.ContentType = "application/json"; @@ -175,7 +175,9 @@ void ConfigurePipeline(IApplicationBuilder app) return; } - else if (context.Request.Path == "/authenticate/properties") + else + { + if (context.Request.Path == "/authenticate/properties") { var result = await context.AuthenticateAsync(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme); if (result?.Properties is null) @@ -188,10 +190,11 @@ void ConfigurePipeline(IApplicationBuilder app) return; } - else if (context.Request.Path == "/challenge") - { - await context.ChallengeAsync(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme); - return; + if (context.Request.Path == "/challenge") + { + await context.ChallengeAsync(OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme); + return; + } } await next(context); diff --git a/test/OpenIddict.Validation.IntegrationTests/OpenIddictValidationIntegrationTestClient.cs b/test/OpenIddict.Validation.IntegrationTests/OpenIddictValidationIntegrationTestClient.cs index 305b3cdad..7105fb751 100644 --- a/test/OpenIddict.Validation.IntegrationTests/OpenIddictValidationIntegrationTestClient.cs +++ b/test/OpenIddict.Validation.IntegrationTests/OpenIddictValidationIntegrationTestClient.cs @@ -194,7 +194,7 @@ private HttpRequestMessage CreateRequestMessage(OpenIddictRequest request, HttpM message.RequestUri = OpenIddictHelpers.AddQueryStringParameters(message.RequestUri!, request.GetParameters().ToDictionary( static parameter => parameter.Key, - static parameter => (StringValues) parameter.Value)); + static parameter => (StringValues) parameter.Value, StringComparer.Ordinal)); } if (message.Method != HttpMethod.Get) @@ -320,7 +320,7 @@ private async Task GetResponseAsync(HttpResponseMessage mess return null; } - return Uri.UnescapeDataString(value.Replace("+", "%20")); + return Uri.UnescapeDataString(value.Replace("+", "%20", StringComparison.Ordinal)); } // Note: a dictionary is deliberately not used here to allow multiple parameters with the @@ -359,19 +359,17 @@ private async Task GetResponseAsync(HttpResponseMessage mess parameters.Add(KeyValuePair.Create(name, value)); } - return new OpenIddictResponse( - from parameter in parameters - group parameter by parameter.Key into grouping - let values = grouping.Select(parameter => parameter.Value) - select KeyValuePair.Create(grouping.Key, new StringValues([.. values]))); + return new OpenIddictResponse(parameters + .GroupBy(static parameter => parameter.Key, static parameter => parameter.Value, StringComparer.Ordinal) + .Select(static grouping => KeyValuePair.Create(grouping.Key, new StringValues([.. grouping])))); } - else if (string.Equals(message.Content?.Headers?.ContentType?.MediaType, "application/json", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(message.Content?.Headers?.ContentType?.MediaType, "application/json", StringComparison.OrdinalIgnoreCase)) { return (await message.Content!.ReadFromJsonAsync())!; } - else if (string.Equals(message.Content?.Headers?.ContentType?.MediaType, "text/html", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(message.Content?.Headers?.ContentType?.MediaType, "text/html", StringComparison.OrdinalIgnoreCase)) { // Note: this test client is only used with OpenIddict's ASP.NET Core or OWIN hosts, // that always return their HTTP responses encoded using UTF-8. As such, the stream @@ -402,14 +400,12 @@ group parameter by parameter.Key into grouping parameters.Add(KeyValuePair.Create(name, value)); } - return new OpenIddictResponse( - from parameter in parameters - group parameter by parameter.Key into grouping - let values = grouping.Select(parameter => parameter.Value) - select KeyValuePair.Create(grouping.Key, new StringValues([.. values]))); + return new OpenIddictResponse(parameters + .GroupBy(static parameter => parameter.Key, static parameter => parameter.Value, StringComparer.Ordinal) + .Select(static grouping => KeyValuePair.Create(grouping.Key, new StringValues([.. grouping])))); } - else if (string.Equals(message.Content?.Headers?.ContentType?.MediaType, "text/plain", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(message.Content?.Headers?.ContentType?.MediaType, "text/plain", StringComparison.OrdinalIgnoreCase)) { // Note: this test client is only used with OpenIddict's ASP.NET Core or OWIN hosts, // that always return their HTTP responses encoded using UTF-8. As such, the stream @@ -424,7 +420,7 @@ group parameter by parameter.Key into grouping for (var line = await reader.ReadLineAsync(); line is not null; line = await reader.ReadLineAsync()) { - var index = line.IndexOf(':'); + var index = line.IndexOf(':', StringComparison.Ordinal); if (index is -1) { continue; @@ -441,11 +437,9 @@ group parameter by parameter.Key into grouping parameters.Add(KeyValuePair.Create(name, value)); } - return new OpenIddictResponse( - from parameter in parameters - group parameter by parameter.Key into grouping - let values = grouping.Select(parameter => parameter.Value) - select KeyValuePair.Create(grouping.Key, new StringValues([.. values]))); + return new OpenIddictResponse(parameters + .GroupBy(static parameter => parameter.Key, static parameter => parameter.Value, StringComparer.Ordinal) + .Select(static grouping => KeyValuePair.Create(grouping.Key, new StringValues([.. grouping])))); } return new OpenIddictResponse(); diff --git a/test/OpenIddict.Validation.IntegrationTests/OpenIddictValidationIntegrationTests.cs b/test/OpenIddict.Validation.IntegrationTests/OpenIddictValidationIntegrationTests.cs index 2812011f4..5ef0cafdb 100644 --- a/test/OpenIddict.Validation.IntegrationTests/OpenIddictValidationIntegrationTests.cs +++ b/test/OpenIddict.Validation.IntegrationTests/OpenIddictValidationIntegrationTests.cs @@ -24,7 +24,7 @@ namespace OpenIddict.Validation.IntegrationTests; -public abstract partial class OpenIddictValidationIntegrationTests +public abstract class OpenIddictValidationIntegrationTests { protected OpenIddictValidationIntegrationTests(ITestOutputHelper outputHelper) { diff --git a/test/OpenIddict.Validation.Owin.IntegrationTests/OpenIddictValidationOwinIntegrationTests.cs b/test/OpenIddict.Validation.Owin.IntegrationTests/OpenIddictValidationOwinIntegrationTests.cs index a7dc3951e..d546aba1c 100644 --- a/test/OpenIddict.Validation.Owin.IntegrationTests/OpenIddictValidationOwinIntegrationTests.cs +++ b/test/OpenIddict.Validation.Owin.IntegrationTests/OpenIddictValidationOwinIntegrationTests.cs @@ -21,7 +21,7 @@ namespace OpenIddict.Validation.Owin.IntegrationTests; -public partial class OpenIddictValidationOwinIntegrationTests : OpenIddictValidationIntegrationTests +public class OpenIddictValidationOwinIntegrationTests : OpenIddictValidationIntegrationTests { public OpenIddictValidationOwinIntegrationTests(ITestOutputHelper outputHelper) : base(outputHelper) @@ -63,7 +63,7 @@ public async Task ProcessAuthentication_CreationDateIsMappedToIssuedUtc() // Assert var properties = new AuthenticationProperties(response.GetParameters() - .ToDictionary(parameter => parameter.Key, parameter => (string?) parameter.Value)); + .ToDictionary(parameter => parameter.Key, parameter => (string?) parameter.Value, StringComparer.Ordinal)); Assert.Equal(new DateTimeOffset(2020, 01, 01, 00, 00, 00, TimeSpan.Zero), properties.IssuedUtc); } @@ -102,7 +102,7 @@ public async Task ProcessAuthentication_ExpirationDateIsMappedToIssuedUtc() // Assert var properties = new AuthenticationProperties(response.GetParameters() - .ToDictionary(parameter => parameter.Key, parameter => (string?) parameter.Value)); + .ToDictionary(parameter => parameter.Key, parameter => (string?) parameter.Value, StringComparer.Ordinal)); Assert.Equal(new DateTimeOffset(2120, 01, 01, 00, 00, 00, TimeSpan.Zero), properties.ExpiresUtc); } @@ -169,7 +169,7 @@ protected override ValueTask CreateSe return; } - var claims = result.Identity.Claims.GroupBy(claim => claim.Type) + var claims = result.Identity.Claims.GroupBy(claim => claim.Type, StringComparer.Ordinal) .Select(group => KeyValuePair.Create(group.Key, group.Select(claim => claim.Value).ToImmutableArray())); context.Response.ContentType = "application/json"; @@ -177,7 +177,7 @@ protected override ValueTask CreateSe return; } - else if (context.Request.Path == new PathString("/authenticate/properties")) + if (context.Request.Path == new PathString("/authenticate/properties")) { var result = await context.Authentication.AuthenticateAsync(OpenIddictValidationOwinDefaults.AuthenticationType); if (result?.Properties is null) @@ -190,7 +190,7 @@ protected override ValueTask CreateSe return; } - else if (context.Request.Path == new PathString("/challenge")) + if (context.Request.Path == new PathString("/challenge")) { context.Authentication.Challenge(OpenIddictValidationOwinDefaults.AuthenticationType); return; diff --git a/test/OpenIddict.Validation.Tests/OpenIddictValidationConfigurationTests.cs b/test/OpenIddict.Validation.Tests/OpenIddictValidationConfigurationTests.cs index e6ac42355..22c80c828 100644 --- a/test/OpenIddict.Validation.Tests/OpenIddictValidationConfigurationTests.cs +++ b/test/OpenIddict.Validation.Tests/OpenIddictValidationConfigurationTests.cs @@ -145,7 +145,7 @@ public void Validate_ReturnsAnErrorWhenJsonWebTokenHandlerIsMissing() var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0075), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0075), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -159,7 +159,7 @@ public void Validate_ReturnsAnErrorWhenNoIssuerOrConfigurationInformationIsProvi var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0128), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0128), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -175,7 +175,7 @@ public void Validate_ReturnsAnErrorWhenIssuerIsInvalid() var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0136), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0136), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -190,7 +190,7 @@ public void Validate_ReturnsAnErrorWhenIssuerContainsQueryOrFragment() var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0137), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0137), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -210,7 +210,7 @@ public void Validate_ReturnsAnErrorWhenConfigurationIssuerDoesNotMatchOptionsIss var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0394), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0394), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -225,7 +225,7 @@ public void Validate_ReturnsAnErrorWhenConfigurationManagerIsMissing() var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0523), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0523), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -242,7 +242,7 @@ public void Validate_ReturnsAnErrorWhenNonStaticConfigurationManagerIsUsedWithou var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0135), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0135), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -263,7 +263,7 @@ public void Validate_ReturnsAnErrorWhenIntrospectionHandlersAreMissing() var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0129), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0129), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -284,7 +284,7 @@ public void Validate_ReturnsAnErrorWhenIntrospectionIssuerAndConfigurationEndpoi var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0130), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0130), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -303,8 +303,8 @@ public void Validate_ReturnsAnErrorWhenIntrospectionClientCredentialsAreMissing( var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0131), result.Failures!); - Assert.Contains(SR.GetResourceString(SR.ID0132), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0131), result.Failures!, StringComparer.Ordinal); + Assert.Contains(SR.GetResourceString(SR.ID0132), result.Failures!, StringComparer.Ordinal); } [Fact] @@ -327,8 +327,8 @@ public void Validate_ReturnsAnErrorWhenAuthorizationOrTokenEntryValidationIsEnab var result = configuration.Validate(name: null, options); // Assert - Assert.Contains(SR.GetResourceString(SR.ID0133), result.Failures!); - Assert.Contains(SR.GetResourceString(SR.ID0134), result.Failures!); + Assert.Contains(SR.GetResourceString(SR.ID0133), result.Failures!, StringComparer.Ordinal); + Assert.Contains(SR.GetResourceString(SR.ID0134), result.Failures!, StringComparer.Ordinal); } [Fact]