From e36a80bc145d0c2d1bd7f9d5ec07386bb1a3cd7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Tue, 14 Feb 2017 10:08:03 +0100 Subject: [PATCH] Adhere to the ASP.NET team coding style guidelines --- README.md | 54 +-- .../Controllers/AuthenticationController.cs | 15 +- .../Mvc.Client/Controllers/HomeController.cs | 18 +- samples/Mvc.Client/Program.cs | 9 +- samples/Mvc.Client/Startup.cs | 21 +- samples/Mvc.Client/web.config | 4 +- .../Controllers/AccountController.cs | 192 +++++++---- .../Controllers/AuthorizationController.cs | 114 ++++-- .../Mvc.Server/Controllers/ErrorController.cs | 15 +- .../Mvc.Server/Controllers/HomeController.cs | 18 +- .../Controllers/ManageController.cs | 132 ++++--- .../Controllers/ResourceController.cs | 15 +- .../Controllers/UserinfoController.cs | 27 +- .../Extensions/AppBuilderExtensions.cs | 27 +- .../Helpers/FormValueRequiredAttribute.cs | 21 +- .../Mvc.Server/Models/ApplicationDbContext.cs | 9 +- samples/Mvc.Server/Models/ApplicationUser.cs | 3 +- samples/Mvc.Server/Program.cs | 9 +- samples/Mvc.Server/Services/IEmailSender.cs | 6 +- samples/Mvc.Server/Services/ISmsSender.cs | 6 +- .../Mvc.Server/Services/MessageServices.cs | 12 +- samples/Mvc.Server/Startup.cs | 50 ++- .../ExternalLoginConfirmationViewModel.cs | 3 +- .../Account/ForgotPasswordViewModel.cs | 6 +- .../ViewModels/Account/LoginViewModel.cs | 6 +- .../ViewModels/Account/RegisterViewModel.cs | 6 +- .../Account/ResetPasswordViewModel.cs | 6 +- .../ViewModels/Account/SendCodeViewModel.cs | 6 +- .../ViewModels/Account/VerifyCodeViewModel.cs | 6 +- .../Authorization/AuthorizeViewModel.cs | 6 +- .../Authorization/LogoutViewModel.cs | 6 +- .../Manage/AddPhoneNumberViewModel.cs | 6 +- .../Manage/ChangePasswordViewModel.cs | 6 +- .../Manage/ConfigureTwoFactorViewModel.cs | 6 +- .../ViewModels/Manage/FactorViewModel.cs | 6 +- .../ViewModels/Manage/IndexViewModel.cs | 6 +- .../Manage/ManageLoginsViewModel.cs | 3 +- .../ViewModels/Manage/RemoveLoginViewModel.cs | 6 +- .../ViewModels/Manage/SetPasswordViewModel.cs | 6 +- .../Manage/VerifyPhoneNumberViewModel.cs | 6 +- .../ViewModels/Shared/ErrorViewModel.cs | 6 +- samples/Mvc.Server/web.config | 4 +- .../Managers/OpenIddictApplicationManager.cs | 183 ++++++---- .../OpenIddictAuthorizationManager.cs | 36 +- .../Managers/OpenIddictScopeManager.cs | 9 +- .../Managers/OpenIddictTokenManager.cs | 78 +++-- src/OpenIddict.Core/OpenIddictBuilder.cs | 84 +++-- src/OpenIddict.Core/OpenIddictConstants.cs | 24 +- src/OpenIddict.Core/OpenIddictExtensions.cs | 36 +- .../Stores/IOpenIddictApplicationStore.cs | 6 +- .../Stores/IOpenIddictAuthorizationStore.cs | 6 +- .../Stores/IOpenIddictScopeStore.cs | 3 +- .../Stores/IOpenIddictTokenStore.cs | 6 +- .../OpenIddictCustomizer.cs | 15 +- .../OpenIddictExtension.cs | 12 +- .../OpenIddictExtensions.cs | 78 +++-- .../Stores/OpenIddictApplicationStore.cs | 132 ++++--- .../Stores/OpenIddictAuthorizationStore.cs | 54 ++- .../Stores/OpenIddictScopeStore.cs | 30 +- .../Stores/OpenIddictTokenStore.cs | 120 ++++--- .../OpenIddictApplication.cs | 15 +- .../OpenIddictAuthorization.cs | 15 +- src/OpenIddict.Models/OpenIddictScope.cs | 12 +- src/OpenIddict.Models/OpenIddictToken.cs | 15 +- src/OpenIddict.Mvc/OpenIddictExtensions.cs | 21 +- src/OpenIddict.Mvc/OpenIddictModelBinder.cs | 39 ++- src/OpenIddict/OpenIddictExtensions.cs | 326 ++++++++++++------ src/OpenIddict/OpenIddictOptions.cs | 9 +- .../OpenIddictProvider.Authentication.cs | 105 ++++-- .../OpenIddictProvider.Discovery.cs | 13 +- src/OpenIddict/OpenIddictProvider.Exchange.cs | 66 ++-- .../OpenIddictProvider.Introspection.cs | 39 ++- .../OpenIddictProvider.Revocation.cs | 42 ++- .../OpenIddictProvider.Serialization.cs | 51 ++- src/OpenIddict/OpenIddictProvider.Session.cs | 60 ++-- src/OpenIddict/OpenIddictProvider.Userinfo.cs | 9 +- src/OpenIddict/OpenIddictProvider.cs | 6 +- .../OpenIddict.Core.Tests.xproj | 5 +- .../OpenIddictBuilderTests.cs | 54 ++- .../OpenIddictExtensionsTests.cs | 15 +- ...OpenIddict.EntityFrameworkCore.Tests.xproj | 5 +- .../OpenIddictExtensionsTests.cs | 45 ++- .../OpenIddict.Mvc.Tests.xproj | 7 +- .../OpenIddictExtensionsTests.cs | 9 +- .../OpenIddictModelBinderTests.cs | 66 ++-- test/OpenIddict.Tests/OpenIddict.Tests.xproj | 7 +- .../OpenIddictExtensionsTests.cs | 120 ++++--- .../OpenIddictProviderTests.Authentication.cs | 192 +++++++---- .../OpenIddictProviderTests.Discovery.cs | 36 +- .../OpenIddictProviderTests.Exchange.cs | 204 +++++++---- .../OpenIddictProviderTests.Introspection.cs | 120 ++++--- .../OpenIddictProviderTests.Revocation.cs | 108 ++++-- .../OpenIddictProviderTests.Serialization.cs | 117 ++++--- .../OpenIddictProviderTests.Session.cs | 69 ++-- .../OpenIddictProviderTests.Userinfo.cs | 12 +- .../OpenIddictProviderTests.cs | 57 ++- 96 files changed, 2589 insertions(+), 1303 deletions(-) diff --git a/README.md b/README.md index b7fea284..b4f3b507 100644 --- a/README.md +++ b/README.md @@ -69,10 +69,12 @@ To use OpenIddict, you need to: - **Configure the OpenIddict services** in `Startup.ConfigureServices`: ```csharp -public void ConfigureServices(IServiceCollection services) { +public void ConfigureServices(IServiceCollection services) +{ services.AddMvc(); - services.AddDbContext(options => { + services.AddDbContext(options => + { // Configure the context to use Microsoft SQL Server. options.UseSqlServer(configuration["Data:DefaultConnection:ConnectionString"]); @@ -90,23 +92,25 @@ public void ConfigureServices(IServiceCollection services) { // Register the OpenIddict services. // Note: use the generic overload if you need // to replace the default OpenIddict entities. - services.AddOpenIddict() + services.AddOpenIddict(options => + { // Register the Entity Framework stores. - .AddEntityFrameworkCoreStores() + options.AddEntityFrameworkCoreStores(); // Register the ASP.NET Core MVC binder used by OpenIddict. // Note: if you don't call this method, you won't be able to // bind OpenIdConnectRequest or OpenIdConnectResponse parameters. - .AddMvcBinders() + options.AddMvcBinders(); // Enable the token endpoint (required to use the password flow). - .EnableTokenEndpoint("/connect/token") + options.EnableTokenEndpoint("/connect/token"); // Allow client applications to use the grant_type=password flow. - .AllowPasswordFlow() + options.AllowPasswordFlow(); // During development, you can disable the HTTPS requirement. - .DisableHttpsRequirement(); + options.DisableHttpsRequirement(); + }); } ``` @@ -133,7 +137,8 @@ public void Configure(IApplicationBuilder app) { - **Update your Entity Framework context registration to register the OpenIddict entities**: ```csharp -services.AddDbContext(options => { +services.AddDbContext(options => +{ // Configure the context to use Microsoft SQL Server. options.UseSqlServer(configuration["Data:DefaultConnection:ConnectionString"]); @@ -151,7 +156,8 @@ services.AddDbContext(options => { services.AddOpenIddict() .AddEntityFrameworkCoreStores() -services.AddDbContext(options => { +services.AddDbContext(options => +{ // Configure the context to use Microsoft SQL Server. options.UseSqlServer(configuration["Data:DefaultConnection:ConnectionString"]); @@ -169,28 +175,31 @@ The **Mvc.Server sample comes with an [`AuthorizationController` that supports b - **Enable the corresponding flows in the OpenIddict options**: ```csharp -public void ConfigureServices(IServiceCollection services) { +public void ConfigureServices(IServiceCollection services) +{ // Register the OpenIddict services. // Note: use the generic overload if you need // to replace the default OpenIddict entities. - services.AddOpenIddict() + services.AddOpenIddict(options => + { // Register the Entity Framework stores. - .AddEntityFrameworkCoreStores() + options.AddEntityFrameworkCoreStores(); // Register the ASP.NET Core MVC binder used by OpenIddict. // Note: if you don't call this method, you won't be able to // bind OpenIdConnectRequest or OpenIdConnectResponse parameters. - .AddMvcBinders() + options.AddMvcBinders(); // Enable the authorization and token endpoints (required to use the code flow). - .EnableAuthorizationEndpoint("/connect/authorize") - .EnableTokenEndpoint("/connect/token") + options.EnableAuthorizationEndpoint("/connect/authorize") + .EnableTokenEndpoint("/connect/token"); // Allow client applications to use the code flow. - .AllowAuthorizationCodeFlow() + options.AllowAuthorizationCodeFlow(); // During development, you can disable the HTTPS requirement. - .DisableHttpsRequirement(); + options.DisableHttpsRequirement(); + }); } ``` @@ -198,15 +207,18 @@ public void ConfigureServices(IServiceCollection services) { ```csharp // Create a new service scope to ensure the database context is correctly disposed when this methods returns. -using (var scope = app.ApplicationServices.GetRequiredService().CreateScope()) { +using (var scope = app.ApplicationServices.GetRequiredService().CreateScope()) +{ var context = scope.ServiceProvider.GetRequiredService(); await context.Database.EnsureCreatedAsync(); // Note: when using a custom entity or a custom key type, replace OpenIddictApplication by the appropriate type. var manager = scope.ServiceProvider.GetRequiredService>(); - if (await manager.FindByClientIdAsync("[client identifier]", cancellationToken) == null) { - var application = new OpenIddictApplication { + if (await manager.FindByClientIdAsync("[client identifier]", cancellationToken) == null) + { + var application = new OpenIddictApplication + { ClientId = "[client identifier]", RedirectUri = "[redirect uri]" }; diff --git a/samples/Mvc.Client/Controllers/AuthenticationController.cs b/samples/Mvc.Client/Controllers/AuthenticationController.cs index 8b71306d..da8b2cd7 100644 --- a/samples/Mvc.Client/Controllers/AuthenticationController.cs +++ b/samples/Mvc.Client/Controllers/AuthenticationController.cs @@ -4,19 +4,24 @@ using Microsoft.AspNetCore.Authentication.OpenIdConnect; using Microsoft.AspNetCore.Http.Authentication; using Microsoft.AspNetCore.Mvc; -namespace Mvc.Client.Controllers { - public class AuthenticationController : Controller { +namespace Mvc.Client.Controllers +{ + public class AuthenticationController : Controller + { [HttpGet("~/signin")] - public ActionResult SignIn() { + public ActionResult SignIn() + { // Instruct the OIDC client middleware to redirect the user agent to the identity provider. // Note: the authenticationType parameter must match the value configured in Startup.cs - return new ChallengeResult(OpenIdConnectDefaults.AuthenticationScheme, new AuthenticationProperties { + return new ChallengeResult(OpenIdConnectDefaults.AuthenticationScheme, new AuthenticationProperties + { RedirectUri = "/" }); } [HttpGet("~/signout"), HttpPost("~/signout")] - public async Task SignOut() { + public async Task SignOut() + { // Instruct the cookies middleware to delete the local cookie created when the user agent // is redirected from the identity provider after a successful authorization flow. await HttpContext.Authentication.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); diff --git a/samples/Mvc.Client/Controllers/HomeController.cs b/samples/Mvc.Client/Controllers/HomeController.cs index 4c9b616c..25ee9450 100644 --- a/samples/Mvc.Client/Controllers/HomeController.cs +++ b/samples/Mvc.Client/Controllers/HomeController.cs @@ -8,23 +8,29 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.IdentityModel.Protocols.OpenIdConnect; -namespace Mvc.Client.Controllers { - public class HomeController : Controller { +namespace Mvc.Client.Controllers +{ + public class HomeController : Controller + { private readonly HttpClient _client; - public HomeController(HttpClient client) { + public HomeController(HttpClient client) + { _client = client; } [HttpGet("~/")] - public ActionResult Index() { + public ActionResult Index() + { return View("Home"); } [Authorize, HttpPost("~/")] - public async Task Index(CancellationToken cancellationToken) { + public async Task Index(CancellationToken cancellationToken) + { var token = await HttpContext.Authentication.GetTokenAsync(OpenIdConnectParameterNames.AccessToken); - if (string.IsNullOrEmpty(token)) { + if (string.IsNullOrEmpty(token)) + { throw new InvalidOperationException("The access token cannot be found in the authentication ticket. " + "Make sure that SaveTokens is set to true in the OIDC options."); } diff --git a/samples/Mvc.Client/Program.cs b/samples/Mvc.Client/Program.cs index 84b28c53..3c4e0ad3 100644 --- a/samples/Mvc.Client/Program.cs +++ b/samples/Mvc.Client/Program.cs @@ -2,9 +2,12 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; -namespace Mvc.Client { - public static class Program { - public static void Main(string[] args) { +namespace Mvc.Client +{ + public static class Program + { + public static void Main(string[] args) + { var configuration = new ConfigurationBuilder() .AddEnvironmentVariables() .AddCommandLine(args) diff --git a/samples/Mvc.Client/Startup.cs b/samples/Mvc.Client/Startup.cs index 71c46d00..9ae46b44 100644 --- a/samples/Mvc.Client/Startup.cs +++ b/samples/Mvc.Client/Startup.cs @@ -6,10 +6,14 @@ using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.IdentityModel.Protocols.OpenIdConnect; -namespace Mvc.Client { - public class Startup { - public void ConfigureServices(IServiceCollection services) { - services.AddAuthentication(options => { +namespace Mvc.Client +{ + public class Startup + { + public void ConfigureServices(IServiceCollection services) + { + services.AddAuthentication(options => + { options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; }); @@ -18,20 +22,23 @@ namespace Mvc.Client { services.AddSingleton(); } - public void Configure(IApplicationBuilder app) { + public void Configure(IApplicationBuilder app) + { app.UseDeveloperExceptionPage(); app.UseStaticFiles(); // Insert a new cookies middleware in the pipeline to store the user // identity after he has been redirected from the identity provider. - app.UseCookieAuthentication(new CookieAuthenticationOptions { + app.UseCookieAuthentication(new CookieAuthenticationOptions + { AutomaticAuthenticate = true, AutomaticChallenge = true, LoginPath = new PathString("/signin") }); - app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions { + app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions + { // Note: these settings must match the application details // inserted in the database at the server level. ClientId = "mvc", diff --git a/samples/Mvc.Client/web.config b/samples/Mvc.Client/web.config index f7ac6793..3fd33e55 100644 --- a/samples/Mvc.Client/web.config +++ b/samples/Mvc.Client/web.config @@ -2,8 +2,8 @@ - + - + \ No newline at end of file diff --git a/samples/Mvc.Server/Controllers/AccountController.cs b/samples/Mvc.Server/Controllers/AccountController.cs index 5186942c..d140ad68 100644 --- a/samples/Mvc.Server/Controllers/AccountController.cs +++ b/samples/Mvc.Server/Controllers/AccountController.cs @@ -9,9 +9,11 @@ using Mvc.Server.Models; using Mvc.Server.Services; using Mvc.Server.ViewModels.Account; -namespace Mvc.Server.Controllers { +namespace Mvc.Server.Controllers +{ [Authorize] - public class AccountController : Controller { + public class AccountController : Controller + { private readonly UserManager _userManager; private readonly SignInManager _signInManager; private readonly IEmailSender _emailSender; @@ -24,7 +26,8 @@ namespace Mvc.Server.Controllers { SignInManager signInManager, IEmailSender emailSender, ISmsSender smsSender, - ApplicationDbContext applicationDbContext) { + ApplicationDbContext applicationDbContext) + { _userManager = userManager; _signInManager = signInManager; _emailSender = emailSender; @@ -36,7 +39,8 @@ namespace Mvc.Server.Controllers { // GET: /Account/Login [HttpGet] [AllowAnonymous] - public IActionResult Login(string returnUrl = null) { + public IActionResult Login(string returnUrl = null) + { ViewData["ReturnUrl"] = returnUrl; return View(); } @@ -46,23 +50,29 @@ namespace Mvc.Server.Controllers { [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] - public async Task Login(LoginViewModel model, string returnUrl = null) { + public async Task Login(LoginViewModel model, string returnUrl = null) + { EnsureDatabaseCreated(_applicationDbContext); ViewData["ReturnUrl"] = returnUrl; - if (ModelState.IsValid) { + if (ModelState.IsValid) + { // This doesn't count login failures towards account lockout // To enable password failures to trigger account lockout, set lockoutOnFailure: true var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false); - if (result.Succeeded) { + if (result.Succeeded) + { return RedirectToLocal(returnUrl); } - if (result.RequiresTwoFactor) { + if (result.RequiresTwoFactor) + { return RedirectToAction(nameof(SendCode), new { ReturnUrl = returnUrl, RememberMe = model.RememberMe }); } - if (result.IsLockedOut) { + if (result.IsLockedOut) + { return View("Lockout"); } - else { + else + { ModelState.AddModelError(string.Empty, "Invalid login attempt."); return View(model); } @@ -76,7 +86,8 @@ namespace Mvc.Server.Controllers { // GET: /Account/Register [HttpGet] [AllowAnonymous] - public IActionResult Register(string returnUrl = null) { + public IActionResult Register(string returnUrl = null) + { ViewData["ReturnUrl"] = returnUrl; return View(); } @@ -86,13 +97,16 @@ namespace Mvc.Server.Controllers { [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] - public async Task Register(RegisterViewModel model, string returnUrl = null) { + public async Task Register(RegisterViewModel model, string returnUrl = null) + { EnsureDatabaseCreated(_applicationDbContext); ViewData["ReturnUrl"] = returnUrl; - if (ModelState.IsValid) { + if (ModelState.IsValid) + { var user = new ApplicationUser { UserName = model.Email, Email = model.Email }; var result = await _userManager.CreateAsync(user, model.Password); - if (result.Succeeded) { + if (result.Succeeded) + { // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=532713 // Send an email with this link //var code = await _userManager.GenerateEmailConfirmationTokenAsync(user); @@ -113,7 +127,8 @@ namespace Mvc.Server.Controllers { // POST: /Account/LogOff [HttpPost] [ValidateAntiForgeryToken] - public async Task LogOff() { + public async Task LogOff() + { await _signInManager.SignOutAsync(); return RedirectToAction(nameof(HomeController.Index), "Home"); } @@ -123,7 +138,8 @@ namespace Mvc.Server.Controllers { [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] - public IActionResult ExternalLogin(string provider, string returnUrl = null) { + public IActionResult ExternalLogin(string provider, string returnUrl = null) + { EnsureDatabaseCreated(_applicationDbContext); // Request a redirect to the external login provider. var redirectUrl = Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl }); @@ -135,24 +151,30 @@ namespace Mvc.Server.Controllers { // GET: /Account/ExternalLoginCallback [HttpGet] [AllowAnonymous] - public async Task ExternalLoginCallback(string returnUrl = null) { + public async Task ExternalLoginCallback(string returnUrl = null) + { var info = await _signInManager.GetExternalLoginInfoAsync(); - if (info == null) { + if (info == null) + { return RedirectToAction(nameof(Login)); } // Sign in the user with this external login provider if the user already has a login. var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false); - if (result.Succeeded) { + if (result.Succeeded) + { return RedirectToLocal(returnUrl); } - if (result.RequiresTwoFactor) { + if (result.RequiresTwoFactor) + { return RedirectToAction(nameof(SendCode), new { ReturnUrl = returnUrl }); } - if (result.IsLockedOut) { + if (result.IsLockedOut) + { return View("Lockout"); } - else { + else + { // If the user does not have an account, then ask the user to create an account. ViewData["ReturnUrl"] = returnUrl; ViewData["LoginProvider"] = info.LoginProvider; @@ -166,18 +188,23 @@ namespace Mvc.Server.Controllers { [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] - public async Task ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model, string returnUrl = null) { - if (ModelState.IsValid) { + public async Task ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model, string returnUrl = null) + { + if (ModelState.IsValid) + { // Get the information about the user from the external login provider var info = await _signInManager.GetExternalLoginInfoAsync(); - if (info == null) { + if (info == null) + { return View("ExternalLoginFailure"); } var user = new ApplicationUser { UserName = model.Email, Email = model.Email }; var result = await _userManager.CreateAsync(user); - if (result.Succeeded) { + if (result.Succeeded) + { result = await _userManager.AddLoginAsync(user, info); - if (result.Succeeded) { + if (result.Succeeded) + { await _signInManager.SignInAsync(user, isPersistent: false); return RedirectToLocal(returnUrl); } @@ -192,12 +219,15 @@ namespace Mvc.Server.Controllers { // GET: /Account/ConfirmEmail [HttpGet] [AllowAnonymous] - public async Task ConfirmEmail(string userId, string code) { - if (userId == null || code == null) { + public async Task ConfirmEmail(string userId, string code) + { + if (userId == null || code == null) + { return View("Error"); } var user = await _userManager.FindByIdAsync(userId); - if (user == null) { + if (user == null) + { return View("Error"); } var result = await _userManager.ConfirmEmailAsync(user, code); @@ -208,7 +238,8 @@ namespace Mvc.Server.Controllers { // GET: /Account/ForgotPassword [HttpGet] [AllowAnonymous] - public IActionResult ForgotPassword() { + public IActionResult ForgotPassword() + { return View(); } @@ -217,10 +248,13 @@ namespace Mvc.Server.Controllers { [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] - public async Task ForgotPassword(ForgotPasswordViewModel model) { - if (ModelState.IsValid) { + public async Task ForgotPassword(ForgotPasswordViewModel model) + { + if (ModelState.IsValid) + { var user = await _userManager.FindByNameAsync(model.Email); - if (user == null || !(await _userManager.IsEmailConfirmedAsync(user))) { + if (user == null || !(await _userManager.IsEmailConfirmedAsync(user))) + { // Don't reveal that the user does not exist or is not confirmed return View("ForgotPasswordConfirmation"); } @@ -242,7 +276,8 @@ namespace Mvc.Server.Controllers { // GET: /Account/ForgotPasswordConfirmation [HttpGet] [AllowAnonymous] - public IActionResult ForgotPasswordConfirmation() { + public IActionResult ForgotPasswordConfirmation() + { return View(); } @@ -250,7 +285,8 @@ namespace Mvc.Server.Controllers { // GET: /Account/ResetPassword [HttpGet] [AllowAnonymous] - public IActionResult ResetPassword(string code = null) { + public IActionResult ResetPassword(string code = null) + { return code == null ? View("Error") : View(); } @@ -259,17 +295,21 @@ namespace Mvc.Server.Controllers { [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] - public async Task ResetPassword(ResetPasswordViewModel model) { - if (!ModelState.IsValid) { + public async Task ResetPassword(ResetPasswordViewModel model) + { + if (!ModelState.IsValid) + { return View(model); } var user = await _userManager.FindByNameAsync(model.Email); - if (user == null) { + if (user == null) + { // Don't reveal that the user does not exist return RedirectToAction(nameof(AccountController.ResetPasswordConfirmation), "Account"); } var result = await _userManager.ResetPasswordAsync(user, model.Code, model.Password); - if (result.Succeeded) { + if (result.Succeeded) + { return RedirectToAction(nameof(AccountController.ResetPasswordConfirmation), "Account"); } AddErrors(result); @@ -280,7 +320,8 @@ namespace Mvc.Server.Controllers { // GET: /Account/ResetPasswordConfirmation [HttpGet] [AllowAnonymous] - public IActionResult ResetPasswordConfirmation() { + public IActionResult ResetPasswordConfirmation() + { return View(); } @@ -288,9 +329,11 @@ namespace Mvc.Server.Controllers { // GET: /Account/SendCode [HttpGet] [AllowAnonymous] - public async Task SendCode(string returnUrl = null, bool rememberMe = false) { + public async Task SendCode(string returnUrl = null, bool rememberMe = false) + { var user = await _signInManager.GetTwoFactorAuthenticationUserAsync(); - if (user == null) { + if (user == null) + { return View("Error"); } var userFactors = await _userManager.GetValidTwoFactorProvidersAsync(user); @@ -303,27 +346,33 @@ namespace Mvc.Server.Controllers { [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] - public async Task SendCode(SendCodeViewModel model) { - if (!ModelState.IsValid) { + public async Task SendCode(SendCodeViewModel model) + { + if (!ModelState.IsValid) + { return View(); } var user = await _signInManager.GetTwoFactorAuthenticationUserAsync(); - if (user == null) { + if (user == null) + { return View("Error"); } // Generate the token and send it var code = await _userManager.GenerateTwoFactorTokenAsync(user, model.SelectedProvider); - if (string.IsNullOrWhiteSpace(code)) { + if (string.IsNullOrWhiteSpace(code)) + { return View("Error"); } var message = "Your security code is: " + code; - if (model.SelectedProvider == "Email") { + if (model.SelectedProvider == "Email") + { await _emailSender.SendEmailAsync(await _userManager.GetEmailAsync(user), "Security Code", message); } - else if (model.SelectedProvider == "Phone") { + else if (model.SelectedProvider == "Phone") + { await _smsSender.SendSmsAsync(await _userManager.GetPhoneNumberAsync(user), message); } @@ -334,10 +383,12 @@ namespace Mvc.Server.Controllers { // GET: /Account/VerifyCode [HttpGet] [AllowAnonymous] - public async Task VerifyCode(string provider, bool rememberMe, string returnUrl = null) { + public async Task VerifyCode(string provider, bool rememberMe, string returnUrl = null) + { // Require that the user has already logged in via username/password or external login var user = await _signInManager.GetTwoFactorAuthenticationUserAsync(); - if (user == null) { + if (user == null) + { return View("Error"); } return View(new VerifyCodeViewModel { Provider = provider, ReturnUrl = returnUrl, RememberMe = rememberMe }); @@ -348,8 +399,10 @@ namespace Mvc.Server.Controllers { [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] - public async Task VerifyCode(VerifyCodeViewModel model) { - if (!ModelState.IsValid) { + public async Task VerifyCode(VerifyCodeViewModel model) + { + if (!ModelState.IsValid) + { return View(model); } @@ -357,13 +410,16 @@ namespace Mvc.Server.Controllers { // If a user enters incorrect codes for a specified amount of time then the user account // will be locked out for a specified amount of time. var result = await _signInManager.TwoFactorSignInAsync(model.Provider, model.Code, model.RememberMe, model.RememberBrowser); - if (result.Succeeded) { + if (result.Succeeded) + { return RedirectToLocal(model.ReturnUrl); } - if (result.IsLockedOut) { + if (result.IsLockedOut) + { return View("Lockout"); } - else { + else + { ModelState.AddModelError("", "Invalid code."); return View(model); } @@ -376,28 +432,36 @@ namespace Mvc.Server.Controllers { // not yet supported in this release. // Please see this http://go.microsoft.com/fwlink/?LinkID=615859 for more information on how to do deploy the database // when publishing your application. - private static void EnsureDatabaseCreated(ApplicationDbContext context) { - if (!_databaseChecked) { + private static void EnsureDatabaseCreated(ApplicationDbContext context) + { + if (!_databaseChecked) + { _databaseChecked = true; context.Database.EnsureCreated(); } } - private void AddErrors(IdentityResult result) { - foreach (var error in result.Errors) { + private void AddErrors(IdentityResult result) + { + foreach (var error in result.Errors) + { ModelState.AddModelError(string.Empty, error.Description); } } - private async Task GetCurrentUserAsync() { + private async Task GetCurrentUserAsync() + { return await _userManager.GetUserAsync(User); } - private IActionResult RedirectToLocal(string returnUrl) { - if (Url.IsLocalUrl(returnUrl)) { + private IActionResult RedirectToLocal(string returnUrl) + { + if (Url.IsLocalUrl(returnUrl)) + { return Redirect(returnUrl); } - else { + else + { return RedirectToAction(nameof(HomeController.Index), "Home"); } } diff --git a/samples/Mvc.Server/Controllers/AuthorizationController.cs b/samples/Mvc.Server/Controllers/AuthorizationController.cs index 12d98ce0..e300969d 100644 --- a/samples/Mvc.Server/Controllers/AuthorizationController.cs +++ b/samples/Mvc.Server/Controllers/AuthorizationController.cs @@ -22,8 +22,10 @@ using Mvc.Server.ViewModels.Shared; using OpenIddict.Core; using OpenIddict.Models; -namespace Mvc.Server { - public class AuthorizationController : Controller { +namespace Mvc.Server +{ + public class AuthorizationController : Controller + { private readonly OpenIddictApplicationManager _applicationManager; private readonly SignInManager _signInManager; private readonly UserManager _userManager; @@ -31,7 +33,8 @@ namespace Mvc.Server { public AuthorizationController( OpenIddictApplicationManager applicationManager, SignInManager signInManager, - UserManager userManager) { + UserManager userManager) + { _applicationManager = applicationManager; _signInManager = signInManager; _userManager = userManager; @@ -42,15 +45,18 @@ namespace Mvc.Server { // you must provide your own authorization endpoint action: [Authorize, HttpGet("~/connect/authorize")] - public async Task Authorize(OpenIdConnectRequest request) { + public async Task Authorize(OpenIdConnectRequest request) + { Debug.Assert(request.IsAuthorizationRequest(), "The OpenIddict binder for ASP.NET Core MVC is not registered. " + "Make sure services.AddOpenIddict().AddMvcBinders() is correctly called."); // Retrieve the application details from the database. var application = await _applicationManager.FindByClientIdAsync(request.ClientId, HttpContext.RequestAborted); - if (application == null) { - return View("Error", new ErrorViewModel { + if (application == null) + { + return View("Error", new ErrorViewModel + { Error = OpenIdConnectConstants.Errors.InvalidClient, ErrorDescription = "Details concerning the calling client application cannot be found in the database" }); @@ -58,7 +64,8 @@ namespace Mvc.Server { // Flow the request_id to allow OpenIddict to restore // the original authorization request from the cache. - return View(new AuthorizeViewModel { + return View(new AuthorizeViewModel + { ApplicationName = application.DisplayName, RequestId = request.RequestId, Scope = request.Scope @@ -67,15 +74,18 @@ namespace Mvc.Server { [Authorize, FormValueRequired("submit.Accept")] [HttpPost("~/connect/authorize"), ValidateAntiForgeryToken] - public async Task Accept(OpenIdConnectRequest request) { + public async Task Accept(OpenIdConnectRequest request) + { Debug.Assert(request.IsAuthorizationRequest(), "The OpenIddict binder for ASP.NET Core MVC is not registered. " + "Make sure services.AddOpenIddict().AddMvcBinders() is correctly called."); // Retrieve the profile of the logged in user. var user = await _userManager.GetUserAsync(User); - if (user == null) { - return View("Error", new ErrorViewModel { + if (user == null) + { + return View("Error", new ErrorViewModel + { Error = OpenIdConnectConstants.Errors.ServerError, ErrorDescription = "An internal error has occurred" }); @@ -90,7 +100,8 @@ namespace Mvc.Server { [Authorize, FormValueRequired("submit.Deny")] [HttpPost("~/connect/authorize"), ValidateAntiForgeryToken] - public IActionResult Deny() { + public IActionResult Deny() + { // Notify OpenIddict that the authorization grant has been denied by the resource owner // to redirect the user agent to the client application using the appropriate response_mode. return Forbid(OpenIdConnectServerDefaults.AuthenticationScheme); @@ -100,20 +111,23 @@ namespace Mvc.Server { // flows like the authorization code flow or the implicit flow. [HttpGet("~/connect/logout")] - public IActionResult Logout(OpenIdConnectRequest request) { + public IActionResult Logout(OpenIdConnectRequest request) + { Debug.Assert(request.IsLogoutRequest(), "The OpenIddict binder for ASP.NET Core MVC is not registered. " + "Make sure services.AddOpenIddict().AddMvcBinders() is correctly called."); // Flow the request_id to allow OpenIddict to restore // the original logout request from the distributed cache. - return View(new LogoutViewModel { + return View(new LogoutViewModel + { RequestId = request.RequestId }); } [HttpPost("~/connect/logout"), ValidateAntiForgeryToken] - public async Task Logout() { + public async Task Logout() + { // Ask ASP.NET Core Identity to delete the local and external cookies created // when the user agent is redirected from the external identity provider // after a successful authentication flow (e.g Google or Facebook). @@ -130,57 +144,71 @@ namespace Mvc.Server { // you must provide your own token endpoint action: [HttpPost("~/connect/token"), Produces("application/json")] - public async Task Exchange(OpenIdConnectRequest request) { + public async Task Exchange(OpenIdConnectRequest request) + { Debug.Assert(request.IsTokenRequest(), "The OpenIddict binder for ASP.NET Core MVC is not registered. " + "Make sure services.AddOpenIddict().AddMvcBinders() is correctly called."); - if (request.IsPasswordGrantType()) { + if (request.IsPasswordGrantType()) + { var user = await _userManager.FindByNameAsync(request.Username); - if (user == null) { - return BadRequest(new OpenIdConnectResponse { + if (user == null) + { + return BadRequest(new OpenIdConnectResponse + { Error = OpenIdConnectConstants.Errors.InvalidGrant, ErrorDescription = "The username/password couple is invalid." }); } // Ensure the user is allowed to sign in. - if (!await _signInManager.CanSignInAsync(user)) { - return BadRequest(new OpenIdConnectResponse { + if (!await _signInManager.CanSignInAsync(user)) + { + return BadRequest(new OpenIdConnectResponse + { Error = OpenIdConnectConstants.Errors.InvalidGrant, ErrorDescription = "The specified user is not allowed to sign in." }); } // Reject the token request if two-factor authentication has been enabled by the user. - if (_userManager.SupportsUserTwoFactor && await _userManager.GetTwoFactorEnabledAsync(user)) { - return BadRequest(new OpenIdConnectResponse { + if (_userManager.SupportsUserTwoFactor && await _userManager.GetTwoFactorEnabledAsync(user)) + { + return BadRequest(new OpenIdConnectResponse + { Error = OpenIdConnectConstants.Errors.InvalidGrant, ErrorDescription = "The specified user is not allowed to sign in." }); } // Ensure the user is not already locked out. - if (_userManager.SupportsUserLockout && await _userManager.IsLockedOutAsync(user)) { - return BadRequest(new OpenIdConnectResponse { + if (_userManager.SupportsUserLockout && await _userManager.IsLockedOutAsync(user)) + { + return BadRequest(new OpenIdConnectResponse + { Error = OpenIdConnectConstants.Errors.InvalidGrant, ErrorDescription = "The username/password couple is invalid." }); } // Ensure the password is valid. - if (!await _userManager.CheckPasswordAsync(user, request.Password)) { - if (_userManager.SupportsUserLockout) { + if (!await _userManager.CheckPasswordAsync(user, request.Password)) + { + if (_userManager.SupportsUserLockout) + { await _userManager.AccessFailedAsync(user); } - return BadRequest(new OpenIdConnectResponse { + return BadRequest(new OpenIdConnectResponse + { Error = OpenIdConnectConstants.Errors.InvalidGrant, ErrorDescription = "The username/password couple is invalid." }); } - if (_userManager.SupportsUserLockout) { + if (_userManager.SupportsUserLockout) + { await _userManager.ResetAccessFailedCountAsync(user); } @@ -190,23 +218,28 @@ namespace Mvc.Server { return SignIn(ticket.Principal, ticket.Properties, ticket.AuthenticationScheme); } - else if (request.IsAuthorizationCodeGrantType() || request.IsRefreshTokenGrantType()) { + else if (request.IsAuthorizationCodeGrantType() || request.IsRefreshTokenGrantType()) + { // Retrieve the claims principal stored in the authorization code/refresh token. var info = await HttpContext.Authentication.GetAuthenticateInfoAsync( OpenIdConnectServerDefaults.AuthenticationScheme); // Retrieve the user profile corresponding to the authorization code/refresh token. var user = await _userManager.GetUserAsync(info.Principal); - if (user == null) { - return BadRequest(new OpenIdConnectResponse { + if (user == null) + { + return BadRequest(new OpenIdConnectResponse + { Error = OpenIdConnectConstants.Errors.InvalidGrant, ErrorDescription = "The token is no longer valid." }); } // Ensure the user is still allowed to sign in. - if (!await _signInManager.CanSignInAsync(user)) { - return BadRequest(new OpenIdConnectResponse { + if (!await _signInManager.CanSignInAsync(user)) + { + return BadRequest(new OpenIdConnectResponse + { Error = OpenIdConnectConstants.Errors.InvalidGrant, ErrorDescription = "The user is no longer allowed to sign in." }); @@ -219,7 +252,8 @@ namespace Mvc.Server { return SignIn(ticket.Principal, ticket.Properties, ticket.AuthenticationScheme); } - return BadRequest(new OpenIdConnectResponse { + return BadRequest(new OpenIdConnectResponse + { Error = OpenIdConnectConstants.Errors.UnsupportedGrantType, ErrorDescription = "The specified grant type is not supported." }); @@ -228,7 +262,8 @@ namespace Mvc.Server { private async Task CreateTicketAsync( OpenIdConnectRequest request, ApplicationUser user, - AuthenticationProperties properties = null) { + AuthenticationProperties properties = null) + { // Create a new ClaimsPrincipal containing the claims that // will be used to create an id_token, a token or a code. var principal = await _signInManager.CreateUserPrincipalAsync(user); @@ -237,7 +272,8 @@ namespace Mvc.Server { // To allow OpenIddict to serialize them, you must attach them a destination, that specifies // whether they should be included in access tokens, in identity tokens or in both. - foreach (var claim in principal.Claims) { + foreach (var claim in principal.Claims) + { // In this sample, every claim is serialized in both the access and the identity tokens. // In a real world application, you'd probably want to exclude confidential claims // or apply a claims policy based on the scopes requested by the client application. @@ -249,11 +285,13 @@ namespace Mvc.Server { var ticket = new AuthenticationTicket(principal, properties, OpenIdConnectServerDefaults.AuthenticationScheme); - if (!request.IsAuthorizationCodeGrantType() && !request.IsRefreshTokenGrantType()) { + if (!request.IsAuthorizationCodeGrantType() && !request.IsRefreshTokenGrantType()) + { // Set the list of scopes granted to the client application. // Note: the offline_access scope must be granted // to allow OpenIddict to return a refresh token. - ticket.SetScopes(new[] { + ticket.SetScopes(new[] + { OpenIdConnectConstants.Scopes.OpenId, OpenIdConnectConstants.Scopes.Email, OpenIdConnectConstants.Scopes.Profile, diff --git a/samples/Mvc.Server/Controllers/ErrorController.cs b/samples/Mvc.Server/Controllers/ErrorController.cs index 7e80ecca..8c24da99 100644 --- a/samples/Mvc.Server/Controllers/ErrorController.cs +++ b/samples/Mvc.Server/Controllers/ErrorController.cs @@ -8,17 +8,22 @@ using AspNet.Security.OpenIdConnect.Primitives; using Microsoft.AspNetCore.Mvc; using Mvc.Server.ViewModels.Shared; -namespace Mvc.Server { - public class ErrorController : Controller { +namespace Mvc.Server +{ + public class ErrorController : Controller + { [HttpGet, HttpPost, Route("~/error")] - public IActionResult Error(OpenIdConnectResponse response) { + public IActionResult Error(OpenIdConnectResponse response) + { // If the error was not caused by an invalid // OIDC request, display a generic error page. - if (response == null) { + if (response == null) + { return View(new ErrorViewModel()); } - return View(new ErrorViewModel { + return View(new ErrorViewModel + { Error = response.Error, ErrorDescription = response.ErrorDescription }); diff --git a/samples/Mvc.Server/Controllers/HomeController.cs b/samples/Mvc.Server/Controllers/HomeController.cs index cb57012f..f8a8902d 100644 --- a/samples/Mvc.Server/Controllers/HomeController.cs +++ b/samples/Mvc.Server/Controllers/HomeController.cs @@ -1,24 +1,30 @@ using Microsoft.AspNetCore.Mvc; -namespace Mvc.Server.Controllers { - public class HomeController : Controller { - public IActionResult Index() { +namespace Mvc.Server.Controllers +{ + public class HomeController : Controller + { + public IActionResult Index() + { return View(); } - public IActionResult About() { + public IActionResult About() + { ViewData["Message"] = "Your application description page."; return View(); } - public IActionResult Contact() { + public IActionResult Contact() + { ViewData["Message"] = "Your contact page."; return View(); } - public IActionResult Error() { + public IActionResult Error() + { return View("~/Views/Shared/Error.cshtml"); } } diff --git a/samples/Mvc.Server/Controllers/ManageController.cs b/samples/Mvc.Server/Controllers/ManageController.cs index 466df9a9..31e22adf 100644 --- a/samples/Mvc.Server/Controllers/ManageController.cs +++ b/samples/Mvc.Server/Controllers/ManageController.cs @@ -8,9 +8,11 @@ using Mvc.Server.Models; using Mvc.Server.Services; using Mvc.Server.ViewModels.Manage; -namespace Mvc.Server.Controllers { +namespace Mvc.Server.Controllers +{ [Authorize] - public class ManageController : Controller { + public class ManageController : Controller + { private readonly UserManager _userManager; private readonly SignInManager _signInManager; private readonly IEmailSender _emailSender; @@ -22,7 +24,8 @@ namespace Mvc.Server.Controllers { SignInManager signInManager, IEmailSender emailSender, ISmsSender smsSender, - ILoggerFactory loggerFactory) { + ILoggerFactory loggerFactory) + { _userManager = userManager; _signInManager = signInManager; _emailSender = emailSender; @@ -33,7 +36,8 @@ namespace Mvc.Server.Controllers { // // GET: /Manage/Index [HttpGet] - public async Task Index(ManageMessageId? message = null) { + public async Task Index(ManageMessageId? message = null) + { ViewData["StatusMessage"] = message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed." : message == ManageMessageId.SetPasswordSuccess ? "Your password has been set." @@ -44,7 +48,8 @@ namespace Mvc.Server.Controllers { : ""; var user = await GetCurrentUserAsync(); - var model = new IndexViewModel { + var model = new IndexViewModel + { HasPassword = await _userManager.HasPasswordAsync(user), PhoneNumber = await _userManager.GetPhoneNumberAsync(user), TwoFactor = await _userManager.GetTwoFactorEnabledAsync(user), @@ -58,12 +63,15 @@ namespace Mvc.Server.Controllers { // POST: /Manage/RemoveLogin [HttpPost] [ValidateAntiForgeryToken] - public async Task RemoveLogin(RemoveLoginViewModel account) { + public async Task RemoveLogin(RemoveLoginViewModel account) + { ManageMessageId? message = ManageMessageId.Error; var user = await GetCurrentUserAsync(); - if (user != null) { + if (user != null) + { var result = await _userManager.RemoveLoginAsync(user, account.LoginProvider, account.ProviderKey); - if (result.Succeeded) { + if (result.Succeeded) + { await _signInManager.SignInAsync(user, isPersistent: false); message = ManageMessageId.RemoveLoginSuccess; } @@ -73,7 +81,8 @@ namespace Mvc.Server.Controllers { // // GET: /Manage/AddPhoneNumber - public IActionResult AddPhoneNumber() { + public IActionResult AddPhoneNumber() + { return View(); } @@ -81,8 +90,10 @@ namespace Mvc.Server.Controllers { // POST: /Manage/AddPhoneNumber [HttpPost] [ValidateAntiForgeryToken] - public async Task AddPhoneNumber(AddPhoneNumberViewModel model) { - if (!ModelState.IsValid) { + public async Task AddPhoneNumber(AddPhoneNumberViewModel model) + { + if (!ModelState.IsValid) + { return View(model); } // Generate the token and send it @@ -96,9 +107,11 @@ namespace Mvc.Server.Controllers { // POST: /Manage/EnableTwoFactorAuthentication [HttpPost] [ValidateAntiForgeryToken] - public async Task EnableTwoFactorAuthentication() { + public async Task EnableTwoFactorAuthentication() + { var user = await GetCurrentUserAsync(); - if (user != null) { + if (user != null) + { await _userManager.SetTwoFactorEnabledAsync(user, true); await _signInManager.SignInAsync(user, isPersistent: false); _logger.LogInformation(1, "User enabled two-factor authentication."); @@ -110,9 +123,11 @@ namespace Mvc.Server.Controllers { // POST: /Manage/DisableTwoFactorAuthentication [HttpPost] [ValidateAntiForgeryToken] - public async Task DisableTwoFactorAuthentication() { + public async Task DisableTwoFactorAuthentication() + { var user = await GetCurrentUserAsync(); - if (user != null) { + if (user != null) + { await _userManager.SetTwoFactorEnabledAsync(user, false); await _signInManager.SignInAsync(user, isPersistent: false); _logger.LogInformation(2, "User disabled two-factor authentication."); @@ -123,7 +138,8 @@ namespace Mvc.Server.Controllers { // // GET: /Manage/VerifyPhoneNumber [HttpGet] - public async Task VerifyPhoneNumber(string phoneNumber) { + public async Task VerifyPhoneNumber(string phoneNumber) + { var code = await _userManager.GenerateChangePhoneNumberTokenAsync(await GetCurrentUserAsync(), phoneNumber); // Send an SMS to verify the phone number return phoneNumber == null ? View("Error") : View(new VerifyPhoneNumberViewModel { PhoneNumber = phoneNumber }); @@ -133,14 +149,18 @@ namespace Mvc.Server.Controllers { // POST: /Manage/VerifyPhoneNumber [HttpPost] [ValidateAntiForgeryToken] - public async Task VerifyPhoneNumber(VerifyPhoneNumberViewModel model) { - if (!ModelState.IsValid) { + public async Task VerifyPhoneNumber(VerifyPhoneNumberViewModel model) + { + if (!ModelState.IsValid) + { return View(model); } var user = await GetCurrentUserAsync(); - if (user != null) { + if (user != null) + { var result = await _userManager.ChangePhoneNumberAsync(user, model.PhoneNumber, model.Code); - if (result.Succeeded) { + if (result.Succeeded) + { await _signInManager.SignInAsync(user, isPersistent: false); return RedirectToAction(nameof(Index), new { Message = ManageMessageId.AddPhoneSuccess }); } @@ -154,11 +174,14 @@ namespace Mvc.Server.Controllers { // GET: /Manage/RemovePhoneNumber [HttpPost] [ValidateAntiForgeryToken] - public async Task RemovePhoneNumber() { + public async Task RemovePhoneNumber() + { var user = await GetCurrentUserAsync(); - if (user != null) { + if (user != null) + { var result = await _userManager.SetPhoneNumberAsync(user, null); - if (result.Succeeded) { + if (result.Succeeded) + { await _signInManager.SignInAsync(user, isPersistent: false); return RedirectToAction(nameof(Index), new { Message = ManageMessageId.RemovePhoneSuccess }); } @@ -169,7 +192,8 @@ namespace Mvc.Server.Controllers { // // GET: /Manage/ChangePassword [HttpGet] - public IActionResult ChangePassword() { + public IActionResult ChangePassword() + { return View(); } @@ -177,14 +201,18 @@ namespace Mvc.Server.Controllers { // POST: /Manage/ChangePassword [HttpPost] [ValidateAntiForgeryToken] - public async Task ChangePassword(ChangePasswordViewModel model) { - if (!ModelState.IsValid) { + public async Task ChangePassword(ChangePasswordViewModel model) + { + if (!ModelState.IsValid) + { return View(model); } var user = await GetCurrentUserAsync(); - if (user != null) { + if (user != null) + { var result = await _userManager.ChangePasswordAsync(user, model.OldPassword, model.NewPassword); - if (result.Succeeded) { + if (result.Succeeded) + { await _signInManager.SignInAsync(user, isPersistent: false); _logger.LogInformation(3, "User changed their password successfully."); return RedirectToAction(nameof(Index), new { Message = ManageMessageId.ChangePasswordSuccess }); @@ -198,7 +226,8 @@ namespace Mvc.Server.Controllers { // // GET: /Manage/SetPassword [HttpGet] - public IActionResult SetPassword() { + public IActionResult SetPassword() + { return View(); } @@ -206,15 +235,19 @@ namespace Mvc.Server.Controllers { // POST: /Manage/SetPassword [HttpPost] [ValidateAntiForgeryToken] - public async Task SetPassword(SetPasswordViewModel model) { - if (!ModelState.IsValid) { + public async Task SetPassword(SetPasswordViewModel model) + { + if (!ModelState.IsValid) + { return View(model); } var user = await GetCurrentUserAsync(); - if (user != null) { + if (user != null) + { var result = await _userManager.AddPasswordAsync(user, model.NewPassword); - if (result.Succeeded) { + if (result.Succeeded) + { await _signInManager.SignInAsync(user, isPersistent: false); return RedirectToAction(nameof(Index), new { Message = ManageMessageId.SetPasswordSuccess }); } @@ -226,20 +259,23 @@ namespace Mvc.Server.Controllers { //GET: /Manage/ManageLogins [HttpGet] - public async Task ManageLogins(ManageMessageId? message = null) { + public async Task ManageLogins(ManageMessageId? message = null) + { ViewData["StatusMessage"] = message == ManageMessageId.RemoveLoginSuccess ? "The external login was removed." : message == ManageMessageId.AddLoginSuccess ? "The external login was added." : message == ManageMessageId.Error ? "An error has occurred." : ""; var user = await GetCurrentUserAsync(); - if (user == null) { + if (user == null) + { return View("Error"); } var userLogins = await _userManager.GetLoginsAsync(user); var otherLogins = _signInManager.GetExternalAuthenticationSchemes().Where(auth => userLogins.All(ul => auth.AuthenticationScheme != ul.LoginProvider)).ToList(); ViewData["ShowRemoveButton"] = user.PasswordHash != null || userLogins.Count > 1; - return View(new ManageLoginsViewModel { + return View(new ManageLoginsViewModel + { CurrentLogins = userLogins, OtherLogins = otherLogins }); @@ -249,7 +285,8 @@ namespace Mvc.Server.Controllers { // POST: /Manage/LinkLogin [HttpPost] [ValidateAntiForgeryToken] - public IActionResult LinkLogin(string provider) { + public IActionResult LinkLogin(string provider) + { // Request a redirect to the external login provider to link a login for the current user var redirectUrl = Url.Action("LinkLoginCallback", "Manage"); var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl, _userManager.GetUserId(User)); @@ -259,13 +296,16 @@ namespace Mvc.Server.Controllers { // // GET: /Manage/LinkLoginCallback [HttpGet] - public async Task LinkLoginCallback() { + public async Task LinkLoginCallback() + { var user = await GetCurrentUserAsync(); - if (user == null) { + if (user == null) + { return View("Error"); } var info = await _signInManager.GetExternalLoginInfoAsync(await _userManager.GetUserIdAsync(user)); - if (info == null) { + if (info == null) + { return RedirectToAction(nameof(ManageLogins), new { Message = ManageMessageId.Error }); } var result = await _userManager.AddLoginAsync(user, info); @@ -275,13 +315,16 @@ namespace Mvc.Server.Controllers { #region Helpers - private void AddErrors(IdentityResult result) { - foreach (var error in result.Errors) { + private void AddErrors(IdentityResult result) + { + foreach (var error in result.Errors) + { ModelState.AddModelError(string.Empty, error.Description); } } - public enum ManageMessageId { + public enum ManageMessageId + { AddPhoneSuccess, AddLoginSuccess, ChangePasswordSuccess, @@ -292,7 +335,8 @@ namespace Mvc.Server.Controllers { Error } - private Task GetCurrentUserAsync() { + private Task GetCurrentUserAsync() + { return _userManager.GetUserAsync(User); } diff --git a/samples/Mvc.Server/Controllers/ResourceController.cs b/samples/Mvc.Server/Controllers/ResourceController.cs index 1f8cc3d5..94642400 100644 --- a/samples/Mvc.Server/Controllers/ResourceController.cs +++ b/samples/Mvc.Server/Controllers/ResourceController.cs @@ -5,20 +5,25 @@ using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Mvc.Server.Models; -namespace Mvc.Server.Controllers { +namespace Mvc.Server.Controllers +{ [Route("api")] - public class ResourceController : Controller { + public class ResourceController : Controller + { private readonly UserManager _userManager; - public ResourceController(UserManager userManager) { + public ResourceController(UserManager userManager) + { _userManager = userManager; } [Authorize(ActiveAuthenticationSchemes = OAuthValidationDefaults.AuthenticationScheme)] [HttpGet("message")] - public async Task GetMessage() { + public async Task GetMessage() + { var user = await _userManager.GetUserAsync(User); - if (user == null) { + if (user == null) + { return BadRequest(); } diff --git a/samples/Mvc.Server/Controllers/UserinfoController.cs b/samples/Mvc.Server/Controllers/UserinfoController.cs index cb7d41ac..129711b6 100644 --- a/samples/Mvc.Server/Controllers/UserinfoController.cs +++ b/samples/Mvc.Server/Controllers/UserinfoController.cs @@ -8,12 +8,15 @@ using Mvc.Server.Models; using Newtonsoft.Json.Linq; using OpenIddict.Core; -namespace Mvc.Server.Controllers { +namespace Mvc.Server.Controllers +{ [Route("api")] - public class UserinfoController : Controller { + public class UserinfoController : Controller + { private readonly UserManager _userManager; - public UserinfoController(UserManager userManager) { + public UserinfoController(UserManager userManager) + { _userManager = userManager; } @@ -21,10 +24,13 @@ namespace Mvc.Server.Controllers { // GET: /api/userinfo [Authorize(ActiveAuthenticationSchemes = OAuthValidationDefaults.AuthenticationScheme)] [HttpGet("userinfo"), Produces("application/json")] - public async Task Userinfo() { + public async Task Userinfo() + { var user = await _userManager.GetUserAsync(User); - if (user == null) { - return BadRequest(new OpenIdConnectResponse { + if (user == null) + { + return BadRequest(new OpenIdConnectResponse + { Error = OpenIdConnectConstants.Errors.InvalidGrant, ErrorDescription = "The user profile is no longer available." }); @@ -35,17 +41,20 @@ namespace Mvc.Server.Controllers { // Note: the "sub" claim is a mandatory claim and must be included in the JSON response. claims[OpenIdConnectConstants.Claims.Subject] = await _userManager.GetUserIdAsync(user); - if (User.HasClaim(OpenIdConnectConstants.Claims.Scope, OpenIdConnectConstants.Scopes.Email)) { + if (User.HasClaim(OpenIdConnectConstants.Claims.Scope, OpenIdConnectConstants.Scopes.Email)) + { claims[OpenIdConnectConstants.Claims.Email] = await _userManager.GetEmailAsync(user); claims[OpenIdConnectConstants.Claims.EmailVerified] = await _userManager.IsEmailConfirmedAsync(user); } - if (User.HasClaim(OpenIdConnectConstants.Claims.Scope, OpenIdConnectConstants.Scopes.Phone)) { + if (User.HasClaim(OpenIdConnectConstants.Claims.Scope, OpenIdConnectConstants.Scopes.Phone)) + { claims[OpenIdConnectConstants.Claims.PhoneNumber] = await _userManager.GetPhoneNumberAsync(user); claims[OpenIdConnectConstants.Claims.PhoneNumberVerified] = await _userManager.IsPhoneNumberConfirmedAsync(user); } - if (User.HasClaim(OpenIdConnectConstants.Claims.Scope, OpenIddictConstants.Scopes.Roles)) { + if (User.HasClaim(OpenIdConnectConstants.Claims.Scope, OpenIddictConstants.Scopes.Roles)) + { claims[OpenIddictConstants.Claims.Roles] = JArray.FromObject(await _userManager.GetRolesAsync(user)); } diff --git a/samples/Mvc.Server/Extensions/AppBuilderExtensions.cs b/samples/Mvc.Server/Extensions/AppBuilderExtensions.cs index 36bbca3d..58f91546 100644 --- a/samples/Mvc.Server/Extensions/AppBuilderExtensions.cs +++ b/samples/Mvc.Server/Extensions/AppBuilderExtensions.cs @@ -3,32 +3,41 @@ using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; -namespace Mvc.Server.Extensions { - public static class AppBuilderExtensions { +namespace Mvc.Server.Extensions +{ + public static class AppBuilderExtensions + { public static IApplicationBuilder UseWhen(this IApplicationBuilder app, - Func condition, Action configuration) { - if (app == null) { + Func condition, Action configuration) + { + if (app == null) + { throw new ArgumentNullException(nameof(app)); } - if (condition == null) { + if (condition == null) + { throw new ArgumentNullException(nameof(condition)); } - if (configuration == null) { + if (configuration == null) + { throw new ArgumentNullException(nameof(configuration)); } var builder = app.New(); configuration(builder); - return app.Use(next => { + return app.Use(next => + { builder.Run(next); var branch = builder.Build(); - return context => { - if (condition(context)) { + return context => + { + if (condition(context)) + { return branch(context); } diff --git a/samples/Mvc.Server/Helpers/FormValueRequiredAttribute.cs b/samples/Mvc.Server/Helpers/FormValueRequiredAttribute.cs index 872f5964..f97cfee5 100644 --- a/samples/Mvc.Server/Helpers/FormValueRequiredAttribute.cs +++ b/samples/Mvc.Server/Helpers/FormValueRequiredAttribute.cs @@ -3,27 +3,34 @@ using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.ActionConstraints; using Microsoft.AspNetCore.Routing; -namespace Mvc.Server.Helpers { - public sealed class FormValueRequiredAttribute : ActionMethodSelectorAttribute { +namespace Mvc.Server.Helpers +{ + public sealed class FormValueRequiredAttribute : ActionMethodSelectorAttribute + { private readonly string _name; - public FormValueRequiredAttribute(string name) { + public FormValueRequiredAttribute(string name) + { _name = name; } - public override bool IsValidForRequest(RouteContext context, ActionDescriptor action) { + public override bool IsValidForRequest(RouteContext context, ActionDescriptor action) + { if (string.Equals(context.HttpContext.Request.Method, "GET", StringComparison.OrdinalIgnoreCase) || string.Equals(context.HttpContext.Request.Method, "HEAD", StringComparison.OrdinalIgnoreCase) || string.Equals(context.HttpContext.Request.Method, "DELETE", StringComparison.OrdinalIgnoreCase) || - string.Equals(context.HttpContext.Request.Method, "TRACE", StringComparison.OrdinalIgnoreCase)) { + string.Equals(context.HttpContext.Request.Method, "TRACE", StringComparison.OrdinalIgnoreCase)) + { return false; } - if (string.IsNullOrEmpty(context.HttpContext.Request.ContentType)) { + if (string.IsNullOrEmpty(context.HttpContext.Request.ContentType)) + { return false; } - if (!context.HttpContext.Request.ContentType.StartsWith("application/x-www-form-urlencoded", StringComparison.OrdinalIgnoreCase)) { + if (!context.HttpContext.Request.ContentType.StartsWith("application/x-www-form-urlencoded", StringComparison.OrdinalIgnoreCase)) + { return false; } diff --git a/samples/Mvc.Server/Models/ApplicationDbContext.cs b/samples/Mvc.Server/Models/ApplicationDbContext.cs index 27cc8e52..9234da9e 100644 --- a/samples/Mvc.Server/Models/ApplicationDbContext.cs +++ b/samples/Mvc.Server/Models/ApplicationDbContext.cs @@ -1,12 +1,15 @@ using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; -namespace Mvc.Server.Models { - public class ApplicationDbContext : IdentityDbContext { +namespace Mvc.Server.Models +{ + public class ApplicationDbContext : IdentityDbContext + { public ApplicationDbContext(DbContextOptions options) : base(options) { } - protected override void OnModelCreating(ModelBuilder builder) { + protected override void OnModelCreating(ModelBuilder builder) + { base.OnModelCreating(builder); // Customize the ASP.NET Identity model and override the defaults if needed. diff --git a/samples/Mvc.Server/Models/ApplicationUser.cs b/samples/Mvc.Server/Models/ApplicationUser.cs index 7a885488..905c7c47 100644 --- a/samples/Mvc.Server/Models/ApplicationUser.cs +++ b/samples/Mvc.Server/Models/ApplicationUser.cs @@ -1,6 +1,7 @@ using Microsoft.AspNetCore.Identity.EntityFrameworkCore; -namespace Mvc.Server.Models { +namespace Mvc.Server.Models +{ // Add profile data for application users by adding properties to the ApplicationUser class public class ApplicationUser : IdentityUser { } } diff --git a/samples/Mvc.Server/Program.cs b/samples/Mvc.Server/Program.cs index 7966c65e..b1c8ae68 100644 --- a/samples/Mvc.Server/Program.cs +++ b/samples/Mvc.Server/Program.cs @@ -2,9 +2,12 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; -namespace Mvc.Server { - public static class Program { - public static void Main(string[] args) { +namespace Mvc.Server +{ + public static class Program + { + public static void Main(string[] args) + { var configuration = new ConfigurationBuilder() .AddEnvironmentVariables() .AddCommandLine(args) diff --git a/samples/Mvc.Server/Services/IEmailSender.cs b/samples/Mvc.Server/Services/IEmailSender.cs index 579efa01..d4c4f1af 100644 --- a/samples/Mvc.Server/Services/IEmailSender.cs +++ b/samples/Mvc.Server/Services/IEmailSender.cs @@ -1,7 +1,9 @@ using System.Threading.Tasks; -namespace Mvc.Server.Services { - public interface IEmailSender { +namespace Mvc.Server.Services +{ + public interface IEmailSender + { Task SendEmailAsync(string email, string subject, string message); } } diff --git a/samples/Mvc.Server/Services/ISmsSender.cs b/samples/Mvc.Server/Services/ISmsSender.cs index b45bc85f..80e505df 100644 --- a/samples/Mvc.Server/Services/ISmsSender.cs +++ b/samples/Mvc.Server/Services/ISmsSender.cs @@ -1,7 +1,9 @@ using System.Threading.Tasks; -namespace Mvc.Server.Services { - public interface ISmsSender { +namespace Mvc.Server.Services +{ + public interface ISmsSender + { Task SendSmsAsync(string number, string message); } } diff --git a/samples/Mvc.Server/Services/MessageServices.cs b/samples/Mvc.Server/Services/MessageServices.cs index 6a8f850b..a0794786 100644 --- a/samples/Mvc.Server/Services/MessageServices.cs +++ b/samples/Mvc.Server/Services/MessageServices.cs @@ -1,16 +1,20 @@ using System.Threading.Tasks; -namespace Mvc.Server.Services { +namespace Mvc.Server.Services +{ // This class is used by the application to send Email and SMS // when you turn on two-factor authentication in ASP.NET Identity. // For more details see this link http://go.microsoft.com/fwlink/?LinkID=532713 - public class AuthMessageSender : IEmailSender, ISmsSender { - public Task SendEmailAsync(string email, string subject, string message) { + public class AuthMessageSender : IEmailSender, ISmsSender + { + public Task SendEmailAsync(string email, string subject, string message) + { // Plug in your email service here to send an email. return Task.FromResult(0); } - public Task SendSmsAsync(string number, string message) { + public Task SendSmsAsync(string number, string message) + { // Plug in your SMS service here to send a text message. return Task.FromResult(0); } diff --git a/samples/Mvc.Server/Startup.cs b/samples/Mvc.Server/Startup.cs index 509d35e0..dd79e165 100644 --- a/samples/Mvc.Server/Startup.cs +++ b/samples/Mvc.Server/Startup.cs @@ -12,9 +12,12 @@ using Mvc.Server.Services; using OpenIddict.Core; using OpenIddict.Models; -namespace Mvc.Server { - public class Startup { - public void ConfigureServices(IServiceCollection services) { +namespace Mvc.Server +{ + public class Startup + { + public void ConfigureServices(IServiceCollection services) + { var configuration = new ConfigurationBuilder() .AddJsonFile("config.json") .AddEnvironmentVariables() @@ -22,7 +25,8 @@ namespace Mvc.Server { services.AddMvc(); - services.AddDbContext(options => { + services.AddDbContext(options => + { // Configure the context to use Microsoft SQL Server. options.UseSqlServer(configuration["Data:DefaultConnection:ConnectionString"]); @@ -65,6 +69,8 @@ namespace Mvc.Server { // During development, you can disable the HTTPS requirement. .DisableHttpsRequirement() + .SetAccessTokenLifetime(TimeSpan.FromSeconds(15)) + // When request caching is enabled, authorization and logout requests // are stored in the distributed cache by OpenIddict and the user agent // is redirected to the same page with a single parameter (request_id). @@ -76,12 +82,14 @@ namespace Mvc.Server { services.AddTransient(); } - public void Configure(IApplicationBuilder app) { + public void Configure(IApplicationBuilder app) + { app.UseDeveloperExceptionPage(); app.UseStaticFiles(); - app.UseWhen(context => context.Request.Path.StartsWithSegments("/api"), branch => { + app.UseWhen(context => context.Request.Path.StartsWithSegments("/api"), branch => + { // Add a middleware used to validate access // tokens and protect the API endpoints. branch.UseOAuthValidation(); @@ -90,7 +98,8 @@ namespace Mvc.Server { // Using it is recommended if your resource server is in a // different application/separated from the authorization server. // - // branch.UseOAuthIntrospection(options => { + // branch.UseOAuthIntrospection(options => + // { // options.AutomaticAuthenticate = true; // options.AutomaticChallenge = true; // options.Authority = "http://localhost:54540/"; @@ -100,17 +109,20 @@ namespace Mvc.Server { // }); }); - app.UseWhen(context => !context.Request.Path.StartsWithSegments("/api"), branch => { + app.UseWhen(context => !context.Request.Path.StartsWithSegments("/api"), branch => + { branch.UseStatusCodePagesWithReExecute("/error"); branch.UseIdentity(); - branch.UseGoogleAuthentication(new GoogleOptions { + branch.UseGoogleAuthentication(new GoogleOptions + { ClientId = "560027070069-37ldt4kfuohhu3m495hk2j4pjp92d382.apps.googleusercontent.com", ClientSecret = "n2Q-GEw9RQjzcRbU3qhfTj8f" }); - branch.UseTwitterAuthentication(new TwitterOptions { + branch.UseTwitterAuthentication(new TwitterOptions + { ConsumerKey = "6XaCTaLbMqfj6ww3zvZ5g", ConsumerSecret = "Il2eFzGIrYhz6BWjYhVXBPQSfZuS4xoHpSSyD9PI" }); @@ -125,16 +137,20 @@ namespace Mvc.Server { InitializeAsync(app.ApplicationServices, CancellationToken.None).GetAwaiter().GetResult(); } - private async Task InitializeAsync(IServiceProvider services, CancellationToken cancellationToken) { + private async Task InitializeAsync(IServiceProvider services, CancellationToken cancellationToken) + { // Create a new service scope to ensure the database context is correctly disposed when this methods returns. - using (var scope = services.GetRequiredService().CreateScope()) { + using (var scope = services.GetRequiredService().CreateScope()) + { var context = scope.ServiceProvider.GetRequiredService(); await context.Database.EnsureCreatedAsync(); var manager = scope.ServiceProvider.GetRequiredService>(); - if (await manager.FindByClientIdAsync("mvc", cancellationToken) == null) { - var application = new OpenIddictApplication { + if (await manager.FindByClientIdAsync("mvc", cancellationToken) == null) + { + var application = new OpenIddictApplication + { ClientId = "mvc", DisplayName = "MVC client application", LogoutRedirectUri = "http://localhost:53507/", @@ -153,8 +169,10 @@ namespace Mvc.Server { // * Scope: openid email profile roles // * Grant type: authorization code // * Request access token locally: yes - if (await manager.FindByClientIdAsync("postman", cancellationToken) == null) { - var application = new OpenIddictApplication { + if (await manager.FindByClientIdAsync("postman", cancellationToken) == null) + { + var application = new OpenIddictApplication + { ClientId = "postman", DisplayName = "Postman", RedirectUri = "https://www.getpostman.com/oauth2/callback" diff --git a/samples/Mvc.Server/ViewModels/Account/ExternalLoginConfirmationViewModel.cs b/samples/Mvc.Server/ViewModels/Account/ExternalLoginConfirmationViewModel.cs index 19f60055..72715e94 100644 --- a/samples/Mvc.Server/ViewModels/Account/ExternalLoginConfirmationViewModel.cs +++ b/samples/Mvc.Server/ViewModels/Account/ExternalLoginConfirmationViewModel.cs @@ -1,6 +1,7 @@ using System.ComponentModel.DataAnnotations; -namespace Mvc.Server.ViewModels.Account { +namespace Mvc.Server.ViewModels.Account +{ public class ExternalLoginConfirmationViewModel { [Required] diff --git a/samples/Mvc.Server/ViewModels/Account/ForgotPasswordViewModel.cs b/samples/Mvc.Server/ViewModels/Account/ForgotPasswordViewModel.cs index 06c8abd3..c6b5c091 100644 --- a/samples/Mvc.Server/ViewModels/Account/ForgotPasswordViewModel.cs +++ b/samples/Mvc.Server/ViewModels/Account/ForgotPasswordViewModel.cs @@ -1,7 +1,9 @@ using System.ComponentModel.DataAnnotations; -namespace Mvc.Server.ViewModels.Account { - public class ForgotPasswordViewModel { +namespace Mvc.Server.ViewModels.Account +{ + public class ForgotPasswordViewModel + { [Required] [EmailAddress] public string Email { get; set; } diff --git a/samples/Mvc.Server/ViewModels/Account/LoginViewModel.cs b/samples/Mvc.Server/ViewModels/Account/LoginViewModel.cs index 17decf30..18dcd38a 100644 --- a/samples/Mvc.Server/ViewModels/Account/LoginViewModel.cs +++ b/samples/Mvc.Server/ViewModels/Account/LoginViewModel.cs @@ -1,7 +1,9 @@ using System.ComponentModel.DataAnnotations; -namespace Mvc.Server.ViewModels.Account { - public class LoginViewModel { +namespace Mvc.Server.ViewModels.Account +{ + public class LoginViewModel + { [Required] [EmailAddress] public string Email { get; set; } diff --git a/samples/Mvc.Server/ViewModels/Account/RegisterViewModel.cs b/samples/Mvc.Server/ViewModels/Account/RegisterViewModel.cs index cbdad769..9f98dd77 100644 --- a/samples/Mvc.Server/ViewModels/Account/RegisterViewModel.cs +++ b/samples/Mvc.Server/ViewModels/Account/RegisterViewModel.cs @@ -1,7 +1,9 @@ using System.ComponentModel.DataAnnotations; -namespace Mvc.Server.ViewModels.Account { - public class RegisterViewModel { +namespace Mvc.Server.ViewModels.Account +{ + public class RegisterViewModel + { [Required] [EmailAddress] [Display(Name = "Email")] diff --git a/samples/Mvc.Server/ViewModels/Account/ResetPasswordViewModel.cs b/samples/Mvc.Server/ViewModels/Account/ResetPasswordViewModel.cs index 076b0c2b..863649a0 100644 --- a/samples/Mvc.Server/ViewModels/Account/ResetPasswordViewModel.cs +++ b/samples/Mvc.Server/ViewModels/Account/ResetPasswordViewModel.cs @@ -1,7 +1,9 @@ using System.ComponentModel.DataAnnotations; -namespace Mvc.Server.ViewModels.Account { - public class ResetPasswordViewModel { +namespace Mvc.Server.ViewModels.Account +{ + public class ResetPasswordViewModel + { [Required] [EmailAddress] public string Email { get; set; } diff --git a/samples/Mvc.Server/ViewModels/Account/SendCodeViewModel.cs b/samples/Mvc.Server/ViewModels/Account/SendCodeViewModel.cs index b4507a04..5419eea7 100644 --- a/samples/Mvc.Server/ViewModels/Account/SendCodeViewModel.cs +++ b/samples/Mvc.Server/ViewModels/Account/SendCodeViewModel.cs @@ -1,8 +1,10 @@ using System.Collections.Generic; using Microsoft.AspNetCore.Mvc.Rendering; -namespace Mvc.Server.ViewModels.Account { - public class SendCodeViewModel { +namespace Mvc.Server.ViewModels.Account +{ + public class SendCodeViewModel + { public string SelectedProvider { get; set; } public ICollection Providers { get; set; } diff --git a/samples/Mvc.Server/ViewModels/Account/VerifyCodeViewModel.cs b/samples/Mvc.Server/ViewModels/Account/VerifyCodeViewModel.cs index e0af06b6..b12eb9b2 100644 --- a/samples/Mvc.Server/ViewModels/Account/VerifyCodeViewModel.cs +++ b/samples/Mvc.Server/ViewModels/Account/VerifyCodeViewModel.cs @@ -1,7 +1,9 @@ using System.ComponentModel.DataAnnotations; -namespace Mvc.Server.ViewModels.Account { - public class VerifyCodeViewModel { +namespace Mvc.Server.ViewModels.Account +{ + public class VerifyCodeViewModel + { [Required] public string Provider { get; set; } diff --git a/samples/Mvc.Server/ViewModels/Authorization/AuthorizeViewModel.cs b/samples/Mvc.Server/ViewModels/Authorization/AuthorizeViewModel.cs index 95400f84..35561ed7 100644 --- a/samples/Mvc.Server/ViewModels/Authorization/AuthorizeViewModel.cs +++ b/samples/Mvc.Server/ViewModels/Authorization/AuthorizeViewModel.cs @@ -1,8 +1,10 @@ using System.ComponentModel.DataAnnotations; using Microsoft.AspNetCore.Mvc.ModelBinding; -namespace Mvc.Server.ViewModels.Authorization { - public class AuthorizeViewModel { +namespace Mvc.Server.ViewModels.Authorization +{ + public class AuthorizeViewModel + { [Display(Name = "Application")] public string ApplicationName { get; set; } diff --git a/samples/Mvc.Server/ViewModels/Authorization/LogoutViewModel.cs b/samples/Mvc.Server/ViewModels/Authorization/LogoutViewModel.cs index 4e8cfa71..3a9a9661 100644 --- a/samples/Mvc.Server/ViewModels/Authorization/LogoutViewModel.cs +++ b/samples/Mvc.Server/ViewModels/Authorization/LogoutViewModel.cs @@ -1,7 +1,9 @@ using Microsoft.AspNetCore.Mvc.ModelBinding; -namespace Mvc.Server.ViewModels.Authorization { - public class LogoutViewModel { +namespace Mvc.Server.ViewModels.Authorization +{ + public class LogoutViewModel + { [BindNever] public string RequestId { get; set; } } diff --git a/samples/Mvc.Server/ViewModels/Manage/AddPhoneNumberViewModel.cs b/samples/Mvc.Server/ViewModels/Manage/AddPhoneNumberViewModel.cs index b394d67e..d1c70f2c 100644 --- a/samples/Mvc.Server/ViewModels/Manage/AddPhoneNumberViewModel.cs +++ b/samples/Mvc.Server/ViewModels/Manage/AddPhoneNumberViewModel.cs @@ -1,7 +1,9 @@ using System.ComponentModel.DataAnnotations; -namespace Mvc.Server.ViewModels.Manage { - public class AddPhoneNumberViewModel { +namespace Mvc.Server.ViewModels.Manage +{ + public class AddPhoneNumberViewModel + { [Required] [Phone] [Display(Name = "Phone number")] diff --git a/samples/Mvc.Server/ViewModels/Manage/ChangePasswordViewModel.cs b/samples/Mvc.Server/ViewModels/Manage/ChangePasswordViewModel.cs index 45a72c2a..83d56483 100644 --- a/samples/Mvc.Server/ViewModels/Manage/ChangePasswordViewModel.cs +++ b/samples/Mvc.Server/ViewModels/Manage/ChangePasswordViewModel.cs @@ -1,7 +1,9 @@ using System.ComponentModel.DataAnnotations; -namespace Mvc.Server.ViewModels.Manage { - public class ChangePasswordViewModel { +namespace Mvc.Server.ViewModels.Manage +{ + public class ChangePasswordViewModel + { [Required] [DataType(DataType.Password)] [Display(Name = "Current password")] diff --git a/samples/Mvc.Server/ViewModels/Manage/ConfigureTwoFactorViewModel.cs b/samples/Mvc.Server/ViewModels/Manage/ConfigureTwoFactorViewModel.cs index 48f8fad6..d5f57116 100644 --- a/samples/Mvc.Server/ViewModels/Manage/ConfigureTwoFactorViewModel.cs +++ b/samples/Mvc.Server/ViewModels/Manage/ConfigureTwoFactorViewModel.cs @@ -1,8 +1,10 @@ using System.Collections.Generic; using Microsoft.AspNetCore.Mvc.Rendering; -namespace Mvc.Server.ViewModels.Manage { - public class ConfigureTwoFactorViewModel { +namespace Mvc.Server.ViewModels.Manage +{ + public class ConfigureTwoFactorViewModel + { public string SelectedProvider { get; set; } public ICollection Providers { get; set; } diff --git a/samples/Mvc.Server/ViewModels/Manage/FactorViewModel.cs b/samples/Mvc.Server/ViewModels/Manage/FactorViewModel.cs index db18cfae..38e4fe73 100644 --- a/samples/Mvc.Server/ViewModels/Manage/FactorViewModel.cs +++ b/samples/Mvc.Server/ViewModels/Manage/FactorViewModel.cs @@ -1,5 +1,7 @@ -namespace Mvc.Server.ViewModels.Manage { - public class FactorViewModel { +namespace Mvc.Server.ViewModels.Manage +{ + public class FactorViewModel + { public string Purpose { get; set; } } } diff --git a/samples/Mvc.Server/ViewModels/Manage/IndexViewModel.cs b/samples/Mvc.Server/ViewModels/Manage/IndexViewModel.cs index 1056f572..f9ad95ca 100644 --- a/samples/Mvc.Server/ViewModels/Manage/IndexViewModel.cs +++ b/samples/Mvc.Server/ViewModels/Manage/IndexViewModel.cs @@ -1,8 +1,10 @@ using System.Collections.Generic; using Microsoft.AspNetCore.Identity; -namespace Mvc.Server.ViewModels.Manage { - public class IndexViewModel { +namespace Mvc.Server.ViewModels.Manage +{ + public class IndexViewModel + { public bool HasPassword { get; set; } public IList Logins { get; set; } diff --git a/samples/Mvc.Server/ViewModels/Manage/ManageLoginsViewModel.cs b/samples/Mvc.Server/ViewModels/Manage/ManageLoginsViewModel.cs index 23070b10..8f063701 100644 --- a/samples/Mvc.Server/ViewModels/Manage/ManageLoginsViewModel.cs +++ b/samples/Mvc.Server/ViewModels/Manage/ManageLoginsViewModel.cs @@ -2,7 +2,8 @@ using Microsoft.AspNetCore.Http.Authentication; using Microsoft.AspNetCore.Identity; -namespace Mvc.Server.ViewModels.Manage { +namespace Mvc.Server.ViewModels.Manage +{ public class ManageLoginsViewModel { public IList CurrentLogins { get; set; } diff --git a/samples/Mvc.Server/ViewModels/Manage/RemoveLoginViewModel.cs b/samples/Mvc.Server/ViewModels/Manage/RemoveLoginViewModel.cs index 7e8c5838..78f03085 100644 --- a/samples/Mvc.Server/ViewModels/Manage/RemoveLoginViewModel.cs +++ b/samples/Mvc.Server/ViewModels/Manage/RemoveLoginViewModel.cs @@ -1,5 +1,7 @@ -namespace Mvc.Server.ViewModels.Manage { - public class RemoveLoginViewModel { +namespace Mvc.Server.ViewModels.Manage +{ + public class RemoveLoginViewModel + { public string LoginProvider { get; set; } public string ProviderKey { get; set; } } diff --git a/samples/Mvc.Server/ViewModels/Manage/SetPasswordViewModel.cs b/samples/Mvc.Server/ViewModels/Manage/SetPasswordViewModel.cs index d06242f5..944eed46 100644 --- a/samples/Mvc.Server/ViewModels/Manage/SetPasswordViewModel.cs +++ b/samples/Mvc.Server/ViewModels/Manage/SetPasswordViewModel.cs @@ -1,7 +1,9 @@ using System.ComponentModel.DataAnnotations; -namespace Mvc.Server.ViewModels.Manage { - public class SetPasswordViewModel { +namespace Mvc.Server.ViewModels.Manage +{ + public class SetPasswordViewModel + { [Required] [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] [DataType(DataType.Password)] diff --git a/samples/Mvc.Server/ViewModels/Manage/VerifyPhoneNumberViewModel.cs b/samples/Mvc.Server/ViewModels/Manage/VerifyPhoneNumberViewModel.cs index 13da757c..dea0eb17 100644 --- a/samples/Mvc.Server/ViewModels/Manage/VerifyPhoneNumberViewModel.cs +++ b/samples/Mvc.Server/ViewModels/Manage/VerifyPhoneNumberViewModel.cs @@ -1,7 +1,9 @@ using System.ComponentModel.DataAnnotations; -namespace Mvc.Server.ViewModels.Manage { - public class VerifyPhoneNumberViewModel { +namespace Mvc.Server.ViewModels.Manage +{ + public class VerifyPhoneNumberViewModel + { [Required] public string Code { get; set; } diff --git a/samples/Mvc.Server/ViewModels/Shared/ErrorViewModel.cs b/samples/Mvc.Server/ViewModels/Shared/ErrorViewModel.cs index aebc2452..ad317594 100644 --- a/samples/Mvc.Server/ViewModels/Shared/ErrorViewModel.cs +++ b/samples/Mvc.Server/ViewModels/Shared/ErrorViewModel.cs @@ -1,7 +1,9 @@ using System.ComponentModel.DataAnnotations; -namespace Mvc.Server.ViewModels.Shared { - public class ErrorViewModel { +namespace Mvc.Server.ViewModels.Shared +{ + public class ErrorViewModel + { [Display(Name = "Error")] public string Error { get; set; } diff --git a/samples/Mvc.Server/web.config b/samples/Mvc.Server/web.config index f7ac6793..3fd33e55 100644 --- a/samples/Mvc.Server/web.config +++ b/samples/Mvc.Server/web.config @@ -2,8 +2,8 @@ - + - + \ No newline at end of file diff --git a/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs b/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs index 824e07e8..1c6340fb 100644 --- a/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs +++ b/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs @@ -12,15 +12,18 @@ using CryptoHelper; using JetBrains.Annotations; using Microsoft.Extensions.Logging; -namespace OpenIddict.Core { +namespace OpenIddict.Core +{ /// /// Provides methods allowing to manage the applications stored in the store. /// /// The type of the Application entity. - public class OpenIddictApplicationManager where TApplication : class { + public class OpenIddictApplicationManager where TApplication : class + { public OpenIddictApplicationManager( [NotNull] IOpenIddictApplicationStore store, - [NotNull] ILogger> logger) { + [NotNull] ILogger> logger) + { Store = store; Logger = logger; } @@ -44,18 +47,22 @@ namespace OpenIddict.Core { /// A that can be used to monitor the asynchronous operation, /// whose result returns the unique identifier associated with the application. /// - public virtual async Task CreateAsync([NotNull] TApplication application, CancellationToken cancellationToken) { - if (application == null) { + public virtual async Task CreateAsync([NotNull] TApplication application, CancellationToken cancellationToken) + { + if (application == null) + { throw new ArgumentNullException(nameof(application)); } - if (!string.IsNullOrEmpty(await Store.GetHashedSecretAsync(application, cancellationToken))) { + if (!string.IsNullOrEmpty(await Store.GetHashedSecretAsync(application, cancellationToken))) + { throw new ArgumentException("The client secret hash cannot be directly set on the application entity. " + "To create a confidential application, use the CreateAsync() overload accepting a secret parameter."); } // If no client type was specified, assume it's a public application. - if (string.IsNullOrEmpty(await Store.GetClientTypeAsync(application, cancellationToken))) { + if (string.IsNullOrEmpty(await Store.GetClientTypeAsync(application, cancellationToken))) + { await Store.SetClientTypeAsync(application, OpenIddictConstants.ClientTypes.Public, cancellationToken); } @@ -75,18 +82,22 @@ namespace OpenIddict.Core { /// public virtual async Task CreateAsync( [NotNull] TApplication application, - [NotNull] string secret, CancellationToken cancellationToken) { - if (application == null) { + [NotNull] string secret, CancellationToken cancellationToken) + { + if (application == null) + { throw new ArgumentNullException(nameof(application)); } - if (!string.IsNullOrEmpty(await Store.GetHashedSecretAsync(application, cancellationToken))) { + if (!string.IsNullOrEmpty(await Store.GetHashedSecretAsync(application, cancellationToken))) + { throw new ArgumentException("The client secret hash cannot be directly set on the application entity."); } var type = await Store.GetClientTypeAsync(application, cancellationToken); if (!string.IsNullOrEmpty(type) && - !string.Equals(type, OpenIddictConstants.ClientTypes.Confidential, StringComparison.OrdinalIgnoreCase)) { + !string.Equals(type, OpenIddictConstants.ClientTypes.Confidential, StringComparison.OrdinalIgnoreCase)) + { throw new InvalidOperationException("The client type must be set to 'confidential' when creating an application with a client secret." + "To create a public application, use the CreateAsync() overload that doesn't take a secret parameter."); } @@ -106,8 +117,10 @@ namespace OpenIddict.Core { /// /// A that can be used to monitor the asynchronous operation. /// - public virtual Task DeleteAsync([NotNull] TApplication application, CancellationToken cancellationToken) { - if (application == null) { + public virtual Task DeleteAsync([NotNull] TApplication application, CancellationToken cancellationToken) + { + if (application == null) + { throw new ArgumentNullException(nameof(application)); } @@ -123,7 +136,8 @@ namespace OpenIddict.Core { /// A that can be used to monitor the asynchronous operation, /// whose result returns the client application corresponding to the identifier. /// - public virtual Task FindByIdAsync(string identifier, CancellationToken cancellationToken) { + public virtual Task FindByIdAsync(string identifier, CancellationToken cancellationToken) + { return Store.FindByIdAsync(identifier, cancellationToken); } @@ -136,7 +150,8 @@ namespace OpenIddict.Core { /// A that can be used to monitor the asynchronous operation, /// whose result returns the client application corresponding to the identifier. /// - public virtual Task FindByClientIdAsync(string identifier, CancellationToken cancellationToken) { + public virtual Task FindByClientIdAsync(string identifier, CancellationToken cancellationToken) + { return Store.FindByClientIdAsync(identifier, cancellationToken); } @@ -149,7 +164,8 @@ namespace OpenIddict.Core { /// A that can be used to monitor the asynchronous operation, whose result /// returns the client application corresponding to the post_logout_redirect_uri. /// - public virtual Task FindByLogoutRedirectUri(string url, CancellationToken cancellationToken) { + public virtual Task FindByLogoutRedirectUri(string url, CancellationToken cancellationToken) + { return Store.FindByLogoutRedirectUri(url, cancellationToken); } @@ -162,8 +178,10 @@ namespace OpenIddict.Core { /// A that can be used to monitor the asynchronous operation, /// whose result returns the client type of the application (by default, "public"). /// - public virtual async Task GetClientTypeAsync([NotNull] TApplication application, CancellationToken cancellationToken) { - if (application == null) { + public virtual async Task GetClientTypeAsync([NotNull] TApplication application, CancellationToken cancellationToken) + { + if (application == null) + { throw new ArgumentNullException(nameof(application)); } @@ -171,7 +189,8 @@ namespace OpenIddict.Core { // Ensure the application type returned by the store is supported by the manager. if (!string.Equals(type, OpenIddictConstants.ClientTypes.Confidential, StringComparison.OrdinalIgnoreCase) && - !string.Equals(type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase)) { + !string.Equals(type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase)) + { throw new InvalidOperationException("Only 'confidential' or 'public' applications are " + "supported by the default application manager."); } @@ -188,8 +207,10 @@ namespace OpenIddict.Core { /// A that can be used to monitor the asynchronous operation, /// whose result returns the display name associated with the application. /// - public virtual Task GetDisplayNameAsync([NotNull] TApplication application, CancellationToken cancellationToken) { - if (application == null) { + public virtual Task GetDisplayNameAsync([NotNull] TApplication application, CancellationToken cancellationToken) + { + if (application == null) + { throw new ArgumentNullException(nameof(application)); } @@ -205,8 +226,10 @@ namespace OpenIddict.Core { /// A that can be used to monitor the asynchronous operation, /// whose result returns the unique identifier associated with the application. /// - public virtual Task GetIdAsync([NotNull] TApplication application, CancellationToken cancellationToken) { - if (application == null) { + public virtual Task GetIdAsync([NotNull] TApplication application, CancellationToken cancellationToken) + { + if (application == null) + { throw new ArgumentNullException(nameof(application)); } @@ -222,8 +245,10 @@ namespace OpenIddict.Core { /// A that can be used to monitor the asynchronous operation, /// whose result returns the tokens associated with the application. /// - public virtual Task> GetTokensAsync([NotNull] TApplication application, CancellationToken cancellationToken) { - if (application == null) { + public virtual Task> GetTokensAsync([NotNull] TApplication application, CancellationToken cancellationToken) + { + if (application == null) + { throw new ArgumentNullException(nameof(application)); } @@ -239,8 +264,10 @@ namespace OpenIddict.Core { /// A that can be used to monitor the asynchronous operation, /// whose result returns a boolean indicating whether a redirect_uri is registered. /// - public virtual async Task HasRedirectUriAsync([NotNull] TApplication application, CancellationToken cancellationToken) { - if (application == null) { + public virtual async Task HasRedirectUriAsync([NotNull] TApplication application, CancellationToken cancellationToken) + { + if (application == null) + { throw new ArgumentNullException(nameof(application)); } @@ -256,8 +283,10 @@ namespace OpenIddict.Core { /// A that can be used to monitor the asynchronous operation, /// whose result returns a boolean indicating whether a client secret is registered. /// - public virtual async Task HasClientSecretAsync([NotNull] TApplication application, CancellationToken cancellationToken) { - if (application == null) { + public virtual async Task HasClientSecretAsync([NotNull] TApplication application, CancellationToken cancellationToken) + { + if (application == null) + { throw new ArgumentNullException(nameof(application)); } @@ -270,13 +299,16 @@ namespace OpenIddict.Core { /// The application. /// The that can be used to abort the operation. /// true if the application is a confidential client, false otherwise. - public async Task IsConfidentialAsync([NotNull] TApplication application, CancellationToken cancellationToken) { - if (application == null) { + public async Task IsConfidentialAsync([NotNull] TApplication application, CancellationToken cancellationToken) + { + if (application == null) + { throw new ArgumentNullException(nameof(application)); } var type = await GetClientTypeAsync(application, cancellationToken); - if (string.IsNullOrEmpty(type)) { + if (string.IsNullOrEmpty(type)) + { return false; } @@ -289,14 +321,17 @@ namespace OpenIddict.Core { /// The application. /// The that can be used to abort the operation. /// true if the application is a public client, false otherwise. - public async Task IsPublicAsync([NotNull] TApplication application, CancellationToken cancellationToken) { - if (application == null) { + public async Task IsPublicAsync([NotNull] TApplication application, CancellationToken cancellationToken) + { + if (application == null) + { throw new ArgumentNullException(nameof(application)); } // Assume client applications are public if their type is not explicitly set. var type = await GetClientTypeAsync(application, cancellationToken); - if (string.IsNullOrEmpty(type)) { + if (string.IsNullOrEmpty(type)) + { return true; } @@ -312,12 +347,15 @@ namespace OpenIddict.Core { /// /// A that can be used to monitor the asynchronous operation. /// - public virtual async Task SetClientSecretAsync([NotNull] TApplication application, [NotNull] string secret, CancellationToken cancellationToken) { - if (application == null) { + public virtual async Task SetClientSecretAsync([NotNull] TApplication application, [NotNull] string secret, CancellationToken cancellationToken) + { + if (application == null) + { throw new ArgumentNullException(nameof(application)); } - if (string.IsNullOrEmpty(secret)) { + if (string.IsNullOrEmpty(secret)) + { throw new ArgumentException("The client secret cannot be null or empty.", nameof(secret)); } @@ -333,8 +371,10 @@ namespace OpenIddict.Core { /// /// A that can be used to monitor the asynchronous operation. /// - public virtual async Task UpdateAsync([NotNull] TApplication application, CancellationToken cancellationToken) { - if (application == null) { + public virtual async Task UpdateAsync([NotNull] TApplication application, CancellationToken cancellationToken) + { + if (application == null) + { throw new ArgumentNullException(nameof(application)); } @@ -350,23 +390,28 @@ namespace OpenIddict.Core { /// /// A that can be used to monitor the asynchronous operation. /// - protected virtual async Task ValidateAsync([NotNull] TApplication application, CancellationToken cancellationToken) { - if (application == null) { + protected virtual async Task ValidateAsync([NotNull] TApplication application, CancellationToken cancellationToken) + { + if (application == null) + { throw new ArgumentNullException(nameof(application)); } - if (string.IsNullOrEmpty(await Store.GetClientIdAsync(application, cancellationToken))) { + if (string.IsNullOrEmpty(await Store.GetClientIdAsync(application, cancellationToken))) + { throw new ArgumentException("The client identifier cannot be null or empty.", nameof(application)); } var type = await Store.GetClientTypeAsync(application, cancellationToken); - if (string.IsNullOrEmpty(type)) { + if (string.IsNullOrEmpty(type)) + { throw new ArgumentException("The client type cannot be null or empty.", nameof(application)); } // Ensure the application type is supported by the manager. if (!string.Equals(type, OpenIddictConstants.ClientTypes.Confidential, StringComparison.OrdinalIgnoreCase) && - !string.Equals(type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase)) { + !string.Equals(type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase)) + { throw new ArgumentException("Only 'confidential' or 'public' applications are " + "supported by the default application manager.", nameof(application)); } @@ -375,43 +420,51 @@ namespace OpenIddict.Core { // Ensure a client secret was specified if the client is a confidential application. if (string.IsNullOrEmpty(hash) && - string.Equals(type, OpenIddictConstants.ClientTypes.Confidential, StringComparison.OrdinalIgnoreCase)) { + string.Equals(type, OpenIddictConstants.ClientTypes.Confidential, StringComparison.OrdinalIgnoreCase)) + { throw new ArgumentException("The client secret cannot be null or empty for a confidential application.", nameof(application)); } // Ensure no client secret was specified if the client is a public application. else if (!string.IsNullOrEmpty(hash) && - string.Equals(type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase)) { + string.Equals(type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase)) + { throw new ArgumentException("A client secret cannot be associated with a public application.", nameof(application)); } // When a redirect_uri is specified, ensure it is valid and spec-compliant. // See https://tools.ietf.org/html/rfc6749#section-3.1 for more information. var address = await Store.GetRedirectUriAsync(application, cancellationToken); - if (!string.IsNullOrEmpty(address)) { + if (!string.IsNullOrEmpty(address)) + { Uri uri; // Ensure the redirect_uri is a valid and absolute URL. - if (!Uri.TryCreate(address, UriKind.Absolute, out uri)) { + if (!Uri.TryCreate(address, UriKind.Absolute, out uri)) + { throw new ArgumentException("The redirect_uri must be an absolute URL."); } // Ensure the redirect_uri doesn't contain a fragment. - if (!string.IsNullOrEmpty(uri.Fragment)) { + if (!string.IsNullOrEmpty(uri.Fragment)) + { throw new ArgumentException("The redirect_uri cannot contain a fragment."); } } // When a post_logout_redirect_uri is specified, ensure it is valid. address = await Store.GetLogoutRedirectUriAsync(application, cancellationToken); - if (!string.IsNullOrEmpty(address)) { + if (!string.IsNullOrEmpty(address)) + { Uri uri; // Ensure the post_logout_redirect_uri is a valid and absolute URL. - if (!Uri.TryCreate(address, UriKind.Absolute, out uri)) { + if (!Uri.TryCreate(address, UriKind.Absolute, out uri)) + { throw new ArgumentException("The post_logout_redirect_uri must be an absolute URL."); } // Ensure the post_logout_redirect_uri doesn't contain a fragment. - if (!string.IsNullOrEmpty(uri.Fragment)) { + if (!string.IsNullOrEmpty(uri.Fragment)) + { throw new ArgumentException("The post_logout_redirect_uri cannot contain a fragment."); } } @@ -427,12 +480,15 @@ namespace OpenIddict.Core { /// A that can be used to monitor the asynchronous operation, /// whose result returns a boolean indicating whether the redirect_uri was valid. /// - public virtual async Task ValidateRedirectUriAsync([NotNull] TApplication application, string address, CancellationToken cancellationToken) { - if (application == null) { + public virtual async Task ValidateRedirectUriAsync([NotNull] TApplication application, string address, CancellationToken cancellationToken) + { + if (application == null) + { throw new ArgumentNullException(nameof(application)); } - if (!string.Equals(address, await Store.GetRedirectUriAsync(application, cancellationToken), StringComparison.Ordinal)) { + if (!string.Equals(address, await Store.GetRedirectUriAsync(application, cancellationToken), StringComparison.Ordinal)) + { Logger.LogWarning("Client validation failed because {RedirectUri} was not a valid redirect_uri " + "for {Client}", address, await GetDisplayNameAsync(application, cancellationToken)); @@ -453,26 +509,31 @@ namespace OpenIddict.Core { /// A that can be used to monitor the asynchronous operation, /// whose result returns a boolean indicating whether the client secret was valid. /// - public virtual async Task ValidateClientSecretAsync([NotNull] TApplication application, string secret, CancellationToken cancellationToken) { - if (application == null) { + public virtual async Task ValidateClientSecretAsync([NotNull] TApplication application, string secret, CancellationToken cancellationToken) + { + if (application == null) + { throw new ArgumentNullException(nameof(application)); } - if (!await IsConfidentialAsync(application, cancellationToken)) { + if (!await IsConfidentialAsync(application, cancellationToken)) + { Logger.LogWarning("Client authentication cannot be enforced for non-confidential applications."); return false; } var hash = await Store.GetHashedSecretAsync(application, cancellationToken); - if (string.IsNullOrEmpty(hash)) { + if (string.IsNullOrEmpty(hash)) + { Logger.LogError("Client authentication failed for {Client} because " + "no client secret was associated with the application."); return false; } - if (!Crypto.VerifyHashedPassword(hash, secret)) { + if (!Crypto.VerifyHashedPassword(hash, secret)) + { Logger.LogWarning("Client authentication failed for {Client}.", await GetDisplayNameAsync(application, cancellationToken)); diff --git a/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs b/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs index c377075c..19d62ec8 100644 --- a/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs +++ b/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs @@ -10,15 +10,18 @@ using System.Threading.Tasks; using JetBrains.Annotations; using Microsoft.Extensions.Logging; -namespace OpenIddict.Core { +namespace OpenIddict.Core +{ /// /// Provides methods allowing to manage the authorizations stored in the store. /// /// The type of the Authorization entity. - public class OpenIddictAuthorizationManager where TAuthorization : class { + public class OpenIddictAuthorizationManager where TAuthorization : class + { public OpenIddictAuthorizationManager( [NotNull] IOpenIddictAuthorizationStore store, - [NotNull] ILogger> logger) { + [NotNull] ILogger> logger) + { Logger = logger; Store = store; } @@ -41,8 +44,10 @@ namespace OpenIddict.Core { /// /// A that can be used to monitor the asynchronous operation. /// - public virtual Task CreateAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken) { - if (authorization == null) { + public virtual Task CreateAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken) + { + if (authorization == null) + { throw new ArgumentNullException(nameof(authorization)); } @@ -59,7 +64,8 @@ namespace OpenIddict.Core { /// A that can be used to monitor the asynchronous operation, /// whose result returns the authorization corresponding to the subject/client. /// - public virtual Task FindAsync(string subject, string client, CancellationToken cancellationToken) { + public virtual Task FindAsync(string subject, string client, CancellationToken cancellationToken) + { return Store.FindAsync(subject, client, cancellationToken); } @@ -72,7 +78,8 @@ namespace OpenIddict.Core { /// A that can be used to monitor the asynchronous operation, /// whose result returns the authorization corresponding to the identifier. /// - public virtual Task FindByIdAsync(string identifier, CancellationToken cancellationToken) { + public virtual Task FindByIdAsync(string identifier, CancellationToken cancellationToken) + { return Store.FindByIdAsync(identifier, cancellationToken); } @@ -85,8 +92,10 @@ namespace OpenIddict.Core { /// A that can be used to monitor the asynchronous operation, /// whose result returns the unique identifier associated with the authorization. /// - public virtual Task GetIdAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken) { - if (authorization == null) { + public virtual Task GetIdAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken) + { + if (authorization == null) + { throw new ArgumentNullException(nameof(authorization)); } @@ -101,12 +110,15 @@ namespace OpenIddict.Core { /// /// A that can be used to monitor the asynchronous operation. /// - protected virtual async Task ValidateAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken) { - if (authorization == null) { + protected virtual async Task ValidateAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken) + { + if (authorization == null) + { throw new ArgumentNullException(nameof(authorization)); } - if (string.IsNullOrEmpty(await Store.GetSubjectAsync(authorization, cancellationToken))) { + if (string.IsNullOrEmpty(await Store.GetSubjectAsync(authorization, cancellationToken))) + { throw new ArgumentException("The subject cannot be null or empty."); } } diff --git a/src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs b/src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs index 87bfb1fe..b981ec42 100644 --- a/src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs +++ b/src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs @@ -7,15 +7,18 @@ using JetBrains.Annotations; using Microsoft.Extensions.Logging; -namespace OpenIddict.Core { +namespace OpenIddict.Core +{ /// /// Provides methods allowing to manage the scopes stored in the store. /// /// The type of the Scope entity. - public class OpenIddictScopeManager where TScope : class { + public class OpenIddictScopeManager where TScope : class + { public OpenIddictScopeManager( [NotNull] IOpenIddictScopeStore store, - [NotNull] ILogger> logger) { + [NotNull] ILogger> logger) + { Logger = logger; Store = store; } diff --git a/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs b/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs index 95ef036a..b1b95d1d 100644 --- a/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs +++ b/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs @@ -11,15 +11,18 @@ using AspNet.Security.OpenIdConnect.Primitives; using JetBrains.Annotations; using Microsoft.Extensions.Logging; -namespace OpenIddict.Core { +namespace OpenIddict.Core +{ /// /// Provides methods allowing to manage the tokens stored in the store. /// /// The type of the Token entity. - public class OpenIddictTokenManager where TToken : class { + public class OpenIddictTokenManager where TToken : class + { public OpenIddictTokenManager( [NotNull] IOpenIddictTokenStore store, - [NotNull] ILogger> logger) { + [NotNull] ILogger> logger) + { Logger = logger; Store = store; } @@ -42,8 +45,10 @@ namespace OpenIddict.Core { /// /// A that can be used to monitor the asynchronous operation, whose result returns the token. /// - public virtual async Task CreateAsync([NotNull] TToken token, CancellationToken cancellationToken) { - if (token == null) { + public virtual async Task CreateAsync([NotNull] TToken token, CancellationToken cancellationToken) + { + if (token == null) + { throw new ArgumentNullException(nameof(token)); } @@ -60,17 +65,21 @@ namespace OpenIddict.Core { /// /// A that can be used to monitor the asynchronous operation, whose result returns the token. /// - public virtual async Task CreateAsync([NotNull] string type, [NotNull] string subject, CancellationToken cancellationToken) { - if (string.IsNullOrEmpty(type)) { + public virtual async Task CreateAsync([NotNull] string type, [NotNull] string subject, CancellationToken cancellationToken) + { + if (string.IsNullOrEmpty(type)) + { throw new ArgumentException("The token type cannot be null or empty.", nameof(type)); } if (!string.Equals(type, OpenIdConnectConstants.TokenTypeHints.AuthorizationCode, StringComparison.OrdinalIgnoreCase) && - !string.Equals(type, OpenIdConnectConstants.TokenTypeHints.RefreshToken, StringComparison.OrdinalIgnoreCase)) { + !string.Equals(type, OpenIdConnectConstants.TokenTypeHints.RefreshToken, StringComparison.OrdinalIgnoreCase)) + { throw new ArgumentException("The specified token type is not supported by the default token manager."); } - if (string.IsNullOrEmpty(subject)) { + if (string.IsNullOrEmpty(subject)) + { throw new ArgumentException("The subject cannot be null or empty."); } @@ -86,7 +95,8 @@ namespace OpenIddict.Core { /// A that can be used to monitor the asynchronous operation, /// whose result returns the token corresponding to the unique identifier. /// - public virtual Task FindByIdAsync(string identifier, CancellationToken cancellationToken) { + public virtual Task FindByIdAsync(string identifier, CancellationToken cancellationToken) + { return Store.FindByIdAsync(identifier, cancellationToken); } @@ -99,7 +109,8 @@ namespace OpenIddict.Core { /// A that can be used to monitor the asynchronous operation, /// whose result returns the tokens corresponding to the specified subject. /// - public virtual Task FindBySubjectAsync(string subject, CancellationToken cancellationToken) { + public virtual Task FindBySubjectAsync(string subject, CancellationToken cancellationToken) + { return Store.FindBySubjectAsync(subject, cancellationToken); } @@ -112,8 +123,10 @@ namespace OpenIddict.Core { /// A that can be used to monitor the asynchronous operation, /// whose result returns the unique identifier associated with the token. /// - public virtual Task GetIdAsync([NotNull] TToken token, CancellationToken cancellationToken) { - if (token == null) { + public virtual Task GetIdAsync([NotNull] TToken token, CancellationToken cancellationToken) + { + if (token == null) + { throw new ArgumentNullException(nameof(token)); } @@ -126,8 +139,10 @@ namespace OpenIddict.Core { /// The token to revoke. /// The that can be used to abort the operation. /// A that can be used to monitor the asynchronous operation. - public virtual Task RevokeAsync([NotNull] TToken token, CancellationToken cancellationToken) { - if (token == null) { + public virtual Task RevokeAsync([NotNull] TToken token, CancellationToken cancellationToken) + { + if (token == null) + { throw new ArgumentNullException(nameof(token)); } @@ -143,8 +158,10 @@ namespace OpenIddict.Core { /// /// A that can be used to monitor the asynchronous operation. /// - public virtual async Task SetAuthorizationAsync([NotNull] TToken token, [CanBeNull] string identifier, CancellationToken cancellationToken) { - if (token == null) { + public virtual async Task SetAuthorizationAsync([NotNull] TToken token, [CanBeNull] string identifier, CancellationToken cancellationToken) + { + if (token == null) + { throw new ArgumentNullException(nameof(token)); } @@ -161,8 +178,10 @@ namespace OpenIddict.Core { /// /// A that can be used to monitor the asynchronous operation. /// - public virtual async Task SetClientAsync([NotNull] TToken token, [CanBeNull] string identifier, CancellationToken cancellationToken) { - if (token == null) { + public virtual async Task SetClientAsync([NotNull] TToken token, [CanBeNull] string identifier, CancellationToken cancellationToken) + { + if (token == null) + { throw new ArgumentNullException(nameof(token)); } @@ -178,8 +197,10 @@ namespace OpenIddict.Core { /// /// A that can be used to monitor the asynchronous operation. /// - public virtual Task UpdateAsync([NotNull] TToken token, CancellationToken cancellationToken) { - if (token == null) { + public virtual Task UpdateAsync([NotNull] TToken token, CancellationToken cancellationToken) + { + if (token == null) + { throw new ArgumentNullException(nameof(token)); } @@ -194,22 +215,27 @@ namespace OpenIddict.Core { /// /// A that can be used to monitor the asynchronous operation. /// - protected virtual async Task ValidateAsync([NotNull] TToken token, CancellationToken cancellationToken) { - if (token == null) { + protected virtual async Task ValidateAsync([NotNull] TToken token, CancellationToken cancellationToken) + { + if (token == null) + { throw new ArgumentNullException(nameof(token)); } var type = await Store.GetTokenTypeAsync(token, cancellationToken); - if (string.IsNullOrEmpty(type)) { + if (string.IsNullOrEmpty(type)) + { throw new ArgumentException("The token type cannot be null or empty.", nameof(token)); } if (!string.Equals(type, OpenIdConnectConstants.TokenTypeHints.AuthorizationCode, StringComparison.OrdinalIgnoreCase) && - !string.Equals(type, OpenIdConnectConstants.TokenTypeHints.RefreshToken, StringComparison.OrdinalIgnoreCase)) { + !string.Equals(type, OpenIdConnectConstants.TokenTypeHints.RefreshToken, StringComparison.OrdinalIgnoreCase)) + { throw new ArgumentException("The specified token type is not supported by the default token manager."); } - if (string.IsNullOrEmpty(await Store.GetSubjectAsync(token, cancellationToken))) { + if (string.IsNullOrEmpty(await Store.GetSubjectAsync(token, cancellationToken))) + { throw new ArgumentException("The subject cannot be null or empty."); } } diff --git a/src/OpenIddict.Core/OpenIddictBuilder.cs b/src/OpenIddict.Core/OpenIddictBuilder.cs index ebb1ec31..47b549a9 100644 --- a/src/OpenIddict.Core/OpenIddictBuilder.cs +++ b/src/OpenIddict.Core/OpenIddictBuilder.cs @@ -14,17 +14,21 @@ using OpenIddict.Models; using System.Reflection; #endif -namespace Microsoft.Extensions.DependencyInjection { +namespace Microsoft.Extensions.DependencyInjection +{ /// /// Exposes the necessary methods required to configure OpenIddict. /// - public class OpenIddictBuilder { + public class OpenIddictBuilder + { /// /// Initializes a new instance of . /// /// The services collection. - public OpenIddictBuilder([NotNull] IServiceCollection services) { - if (services == null) { + public OpenIddictBuilder([NotNull] IServiceCollection services) + { + if (services == null) + { throw new ArgumentNullException(nameof(services)); } @@ -74,13 +78,16 @@ namespace Microsoft.Extensions.DependencyInjection { /// /// The type of the custom manager. /// The . - public virtual OpenIddictBuilder AddApplicationManager([NotNull] Type type) { - if (type == null) { + public virtual OpenIddictBuilder AddApplicationManager([NotNull] Type type) + { + if (type == null) + { throw new ArgumentNullException(nameof(type)); } var contract = typeof(OpenIddictApplicationManager<>).MakeGenericType(ApplicationType); - if (!contract.IsAssignableFrom(type)) { + if (!contract.IsAssignableFrom(type)) + { throw new InvalidOperationException("Custom managers must be derived from OpenIddictApplicationManager."); } @@ -102,13 +109,16 @@ namespace Microsoft.Extensions.DependencyInjection { /// /// The type of the custom store. /// The . - public virtual OpenIddictBuilder AddApplicationStore([NotNull] Type type) { - if (type == null) { + public virtual OpenIddictBuilder AddApplicationStore([NotNull] Type type) + { + if (type == null) + { throw new ArgumentNullException(nameof(type)); } var contract = typeof(IOpenIddictApplicationStore<>).MakeGenericType(ApplicationType); - if (!contract.IsAssignableFrom(type)) { + if (!contract.IsAssignableFrom(type)) + { throw new InvalidOperationException("Custom stores must implement IOpenIddictApplicationStore."); } @@ -130,13 +140,16 @@ namespace Microsoft.Extensions.DependencyInjection { /// /// The type of the custom manager. /// The . - public virtual OpenIddictBuilder AddAuthorizationManager([NotNull] Type type) { - if (type == null) { + public virtual OpenIddictBuilder AddAuthorizationManager([NotNull] Type type) + { + if (type == null) + { throw new ArgumentNullException(nameof(type)); } var contract = typeof(OpenIddictAuthorizationManager<>).MakeGenericType(AuthorizationType); - if (!contract.IsAssignableFrom(type)) { + if (!contract.IsAssignableFrom(type)) + { throw new InvalidOperationException("Custom managers must be derived from OpenIddictAuthorizationManager."); } @@ -158,13 +171,16 @@ namespace Microsoft.Extensions.DependencyInjection { /// /// The type of the custom store. /// The . - public virtual OpenIddictBuilder AddAuthorizationStore([NotNull] Type type) { - if (type == null) { + public virtual OpenIddictBuilder AddAuthorizationStore([NotNull] Type type) + { + if (type == null) + { throw new ArgumentNullException(nameof(type)); } var contract = typeof(IOpenIddictAuthorizationStore<>).MakeGenericType(AuthorizationType); - if (!contract.IsAssignableFrom(type)) { + if (!contract.IsAssignableFrom(type)) + { throw new InvalidOperationException("Custom stores must implement IOpenIddictAuthorizationStore."); } @@ -186,13 +202,16 @@ namespace Microsoft.Extensions.DependencyInjection { /// /// The type of the custom manager. /// The . - public virtual OpenIddictBuilder AddScopeManager([NotNull] Type type) { - if (type == null) { + public virtual OpenIddictBuilder AddScopeManager([NotNull] Type type) + { + if (type == null) + { throw new ArgumentNullException(nameof(type)); } var contract = typeof(OpenIddictScopeManager<>).MakeGenericType(ScopeType); - if (!contract.IsAssignableFrom(type)) { + if (!contract.IsAssignableFrom(type)) + { throw new InvalidOperationException("Custom managers must be derived from OpenIddictScopeManager."); } @@ -214,13 +233,16 @@ namespace Microsoft.Extensions.DependencyInjection { /// /// The type of the custom store. /// The . - public virtual OpenIddictBuilder AddScopeStore([NotNull] Type type) { - if (type == null) { + public virtual OpenIddictBuilder AddScopeStore([NotNull] Type type) + { + if (type == null) + { throw new ArgumentNullException(nameof(type)); } var contract = typeof(IOpenIddictScopeStore<>).MakeGenericType(ScopeType); - if (!contract.IsAssignableFrom(type)) { + if (!contract.IsAssignableFrom(type)) + { throw new InvalidOperationException("Custom stores must implement IOpenIddictScopeStore."); } @@ -242,13 +264,16 @@ namespace Microsoft.Extensions.DependencyInjection { /// /// The type of the custom manager. /// The . - public virtual OpenIddictBuilder AddTokenManager([NotNull] Type type) { - if (type == null) { + public virtual OpenIddictBuilder AddTokenManager([NotNull] Type type) + { + if (type == null) + { throw new ArgumentNullException(nameof(type)); } var contract = typeof(OpenIddictTokenManager<>).MakeGenericType(TokenType); - if (!contract.IsAssignableFrom(type)) { + if (!contract.IsAssignableFrom(type)) + { throw new InvalidOperationException("Custom managers must be derived from OpenIddictTokenManager."); } @@ -270,13 +295,16 @@ namespace Microsoft.Extensions.DependencyInjection { /// /// The type of the custom store. /// The . - public virtual OpenIddictBuilder AddTokenStore([NotNull] Type type) { - if (type == null) { + public virtual OpenIddictBuilder AddTokenStore([NotNull] Type type) + { + if (type == null) + { throw new ArgumentNullException(nameof(type)); } var contract = typeof(IOpenIddictTokenStore<>).MakeGenericType(TokenType); - if (!contract.IsAssignableFrom(type)) { + if (!contract.IsAssignableFrom(type)) + { throw new InvalidOperationException("Custom stores must implement IOpenIddictTokenStore."); } diff --git a/src/OpenIddict.Core/OpenIddictConstants.cs b/src/OpenIddict.Core/OpenIddictConstants.cs index f8ca9d9d..ec3f7d4c 100644 --- a/src/OpenIddict.Core/OpenIddictConstants.cs +++ b/src/OpenIddict.Core/OpenIddictConstants.cs @@ -4,31 +4,39 @@ * the license and the contributors participating to this project. */ -namespace OpenIddict.Core { - public static class OpenIddictConstants { - public static class Claims { +namespace OpenIddict.Core +{ + public static class OpenIddictConstants + { + public static class Claims + { public const string Roles = "roles"; } - public static class ClientTypes { + public static class ClientTypes + { public const string Confidential = "confidential"; public const string Public = "public"; } - public static class Environment { + public static class Environment + { public const string AuthorizationRequest = "openiddict-authorization-request:"; public const string LogoutRequest = "openiddict-logout-request:"; } - public static class Metadata { + public static class Metadata + { public const string ExternalProvidersSupported = "external_providers_supported"; } - public static class Properties { + public static class Properties + { public const string AuthorizationId = ".authorization_id"; } - public static class Scopes { + public static class Scopes + { public const string Roles = "roles"; } } diff --git a/src/OpenIddict.Core/OpenIddictExtensions.cs b/src/OpenIddict.Core/OpenIddictExtensions.cs index 70c9b6e4..3ed52d03 100644 --- a/src/OpenIddict.Core/OpenIddictExtensions.cs +++ b/src/OpenIddict.Core/OpenIddictExtensions.cs @@ -10,15 +10,18 @@ using Microsoft.Extensions.DependencyInjection.Extensions; using OpenIddict.Core; using OpenIddict.Models; -namespace Microsoft.Extensions.DependencyInjection { - public static class OpenIddictExtensions { +namespace Microsoft.Extensions.DependencyInjection +{ + public static class OpenIddictExtensions + { /// /// Registers the default OpenIddict services in the DI container, /// using the default entities and the default entity key type. /// /// The services collection. /// The . - public static OpenIddictBuilder AddOpenIddict([NotNull] this IServiceCollection services) { + public static OpenIddictBuilder AddOpenIddict([NotNull] this IServiceCollection services) + { return services.AddOpenIddictThe services collection. /// The . public static OpenIddictBuilder AddOpenIddict([NotNull] this IServiceCollection services) - where TKey : IEquatable { + where TKey : IEquatable + { return services.AddOpenIddict, OpenIddictAuthorization, OpenIddictScope, @@ -53,14 +57,17 @@ namespace Microsoft.Extensions.DependencyInjection { where TApplication : class where TAuthorization : class where TScope : class - where TToken : class { - if (services == null) { + where TToken : class + { + if (services == null) + { throw new ArgumentNullException(nameof(services)); } services.AddOptions(); - var builder = new OpenIddictBuilder(services) { + var builder = new OpenIddictBuilder(services) + { ApplicationType = typeof(TApplication), AuthorizationType = typeof(TAuthorization), ScopeType = typeof(TScope), @@ -86,7 +93,8 @@ namespace Microsoft.Extensions.DependencyInjection { /// The . public static IServiceCollection AddOpenIddict( [NotNull] this IServiceCollection services, - [NotNull] Action configuration) { + [NotNull] Action configuration) + { return services.AddOpenIddict( [NotNull] this IServiceCollection services, [NotNull] Action configuration) - where TKey : IEquatable { + where TKey : IEquatable + { return services.AddOpenIddict, OpenIddictAuthorization, OpenIddictScope, @@ -127,12 +136,15 @@ namespace Microsoft.Extensions.DependencyInjection { where TApplication : class where TAuthorization : class where TScope : class - where TToken : class { - if (services == null) { + where TToken : class + { + if (services == null) + { throw new ArgumentNullException(nameof(services)); } - if (configuration == null) { + if (configuration == null) + { throw new ArgumentNullException(nameof(configuration)); } diff --git a/src/OpenIddict.Core/Stores/IOpenIddictApplicationStore.cs b/src/OpenIddict.Core/Stores/IOpenIddictApplicationStore.cs index a6954e8f..c0e77d39 100644 --- a/src/OpenIddict.Core/Stores/IOpenIddictApplicationStore.cs +++ b/src/OpenIddict.Core/Stores/IOpenIddictApplicationStore.cs @@ -9,12 +9,14 @@ using System.Threading; using System.Threading.Tasks; using JetBrains.Annotations; -namespace OpenIddict.Core { +namespace OpenIddict.Core +{ /// /// Provides methods allowing to manage the applications stored in a database. /// /// The type of the Application entity. - public interface IOpenIddictApplicationStore where TApplication : class { + public interface IOpenIddictApplicationStore where TApplication : class + { /// /// Creates a new application. /// diff --git a/src/OpenIddict.Core/Stores/IOpenIddictAuthorizationStore.cs b/src/OpenIddict.Core/Stores/IOpenIddictAuthorizationStore.cs index 2bb1b3a8..5035e1a5 100644 --- a/src/OpenIddict.Core/Stores/IOpenIddictAuthorizationStore.cs +++ b/src/OpenIddict.Core/Stores/IOpenIddictAuthorizationStore.cs @@ -8,12 +8,14 @@ using System.Threading; using System.Threading.Tasks; using JetBrains.Annotations; -namespace OpenIddict.Core { +namespace OpenIddict.Core +{ /// /// Provides methods allowing to manage the authorizations stored in a database. /// /// The type of the Authorization entity. - public interface IOpenIddictAuthorizationStore where TAuthorization : class { + public interface IOpenIddictAuthorizationStore where TAuthorization : class + { /// /// Creates a new authorization. /// diff --git a/src/OpenIddict.Core/Stores/IOpenIddictScopeStore.cs b/src/OpenIddict.Core/Stores/IOpenIddictScopeStore.cs index ccb06a79..e72b14d9 100644 --- a/src/OpenIddict.Core/Stores/IOpenIddictScopeStore.cs +++ b/src/OpenIddict.Core/Stores/IOpenIddictScopeStore.cs @@ -4,7 +4,8 @@ * the license and the contributors participating to this project. */ -namespace OpenIddict.Core { +namespace OpenIddict.Core +{ /// /// Provides methods allowing to manage the scopes stored in a database. /// diff --git a/src/OpenIddict.Core/Stores/IOpenIddictTokenStore.cs b/src/OpenIddict.Core/Stores/IOpenIddictTokenStore.cs index c2f92973..4456f5bc 100644 --- a/src/OpenIddict.Core/Stores/IOpenIddictTokenStore.cs +++ b/src/OpenIddict.Core/Stores/IOpenIddictTokenStore.cs @@ -8,12 +8,14 @@ using System.Threading; using System.Threading.Tasks; using JetBrains.Annotations; -namespace OpenIddict.Core { +namespace OpenIddict.Core +{ /// /// Provides methods allowing to manage the tokens stored in a database. /// /// The type of the Token entity. - public interface IOpenIddictTokenStore where TToken : class { + public interface IOpenIddictTokenStore where TToken : class + { /// /// Creates a new token. /// diff --git a/src/OpenIddict.EntityFrameworkCore/OpenIddictCustomizer.cs b/src/OpenIddict.EntityFrameworkCore/OpenIddictCustomizer.cs index 46f86ec5..861c845e 100644 --- a/src/OpenIddict.EntityFrameworkCore/OpenIddictCustomizer.cs +++ b/src/OpenIddict.EntityFrameworkCore/OpenIddictCustomizer.cs @@ -11,7 +11,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.Extensions.DependencyInjection; using OpenIddict.Models; -namespace OpenIddict.EntityFrameworkCore { +namespace OpenIddict.EntityFrameworkCore +{ /// /// Represents a model customizer able to register the entity sets /// required by the OpenIddict stack in an Entity Framework context. @@ -21,13 +22,17 @@ namespace OpenIddict.EntityFrameworkCore { where TAuthorization : OpenIddictAuthorization, new() where TScope : OpenIddictScope, new() where TToken : OpenIddictToken, new() - where TKey : IEquatable { - public override void Customize([NotNull] ModelBuilder builder, [NotNull] DbContext context) { - if (builder == null) { + where TKey : IEquatable + { + public override void Customize([NotNull] ModelBuilder builder, [NotNull] DbContext context) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } - if (context == null) { + if (context == null) + { throw new ArgumentNullException(nameof(context)); } diff --git a/src/OpenIddict.EntityFrameworkCore/OpenIddictExtension.cs b/src/OpenIddict.EntityFrameworkCore/OpenIddictExtension.cs index a698efd0..ad20237b 100644 --- a/src/OpenIddict.EntityFrameworkCore/OpenIddictExtension.cs +++ b/src/OpenIddict.EntityFrameworkCore/OpenIddictExtension.cs @@ -10,15 +10,19 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.Extensions.DependencyInjection; using OpenIddict.Models; -namespace OpenIddict.EntityFrameworkCore { +namespace OpenIddict.EntityFrameworkCore +{ public class OpenIddictExtension : IDbContextOptionsExtension where TApplication : OpenIddictApplication, new() where TAuthorization : OpenIddictAuthorization, new() where TScope : OpenIddictScope, new() where TToken : OpenIddictToken, new() - where TKey : IEquatable { - public void ApplyServices([NotNull] IServiceCollection services) { - if (services == null) { + where TKey : IEquatable + { + public void ApplyServices([NotNull] IServiceCollection services) + { + if (services == null) + { throw new ArgumentNullException(nameof(services)); } diff --git a/src/OpenIddict.EntityFrameworkCore/OpenIddictExtensions.cs b/src/OpenIddict.EntityFrameworkCore/OpenIddictExtensions.cs index 593f7835..93674ea1 100644 --- a/src/OpenIddict.EntityFrameworkCore/OpenIddictExtensions.cs +++ b/src/OpenIddict.EntityFrameworkCore/OpenIddictExtensions.cs @@ -16,8 +16,10 @@ using OpenIddict.Core; using OpenIddict.EntityFrameworkCore; using OpenIddict.Models; -namespace Microsoft.Extensions.DependencyInjection { - public static class OpenIddictExtensions { +namespace Microsoft.Extensions.DependencyInjection +{ + public static class OpenIddictExtensions + { /// /// Registers the Entity Framework Core stores. Note: when using the Entity Framework Core stores, /// the entities MUST be derived from the models contained in the OpenIddict.Models package. @@ -25,8 +27,10 @@ namespace Microsoft.Extensions.DependencyInjection { /// The services builder used by OpenIddict to register new services. /// The . public static OpenIddictBuilder AddEntityFrameworkCoreStores([NotNull] this OpenIddictBuilder builder) - where TContext : DbContext { - if (builder == null) { + where TContext : DbContext + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } @@ -36,32 +40,37 @@ namespace Microsoft.Extensions.DependencyInjection { builder.TokenType != null, "The entity types exposed by OpenIddictBuilder shouldn't be null."); var application = FindGenericBaseType(builder.ApplicationType, typeof(OpenIddictApplication<,,>)); - if (application == null) { + if (application == null) + { throw new InvalidOperationException("The Entity Framework Core stores can only be used " + "with the built-in OpenIddictApplication entity."); } var authorization = FindGenericBaseType(builder.AuthorizationType, typeof(OpenIddictAuthorization<,,>)); - if (authorization == null) { + if (authorization == null) + { throw new InvalidOperationException("The Entity Framework Core stores can only be used " + "with the built-in OpenIddictAuthorization entity."); } var scope = FindGenericBaseType(builder.ScopeType, typeof(OpenIddictScope<>)); - if (scope == null) { + if (scope == null) + { throw new InvalidOperationException("The Entity Framework Core stores can only be used " + "with the built-in OpenIddictScope entity."); } var token = FindGenericBaseType(builder.TokenType, typeof(OpenIddictToken<,,>)); - if (token == null) { + if (token == null) + { throw new InvalidOperationException("The Entity Framework Core stores can only be used " + "with the built-in OpenIddictToken entity."); } var converter = TypeDescriptor.GetConverter(application.GenericTypeArguments[0]); if (converter == null || !converter.CanConvertFrom(typeof(string)) || - !converter.CanConvertTo(typeof(string))) { + !converter.CanConvertTo(typeof(string))) + { throw new InvalidOperationException("The specified entity key type is not supported."); } @@ -112,7 +121,8 @@ namespace Microsoft.Extensions.DependencyInjection { /// /// The builder used to configure the Entity Framework context. /// The Entity Framework context builder. - public static DbContextOptionsBuilder UseOpenIddict([NotNull] this DbContextOptionsBuilder builder) { + public static DbContextOptionsBuilder UseOpenIddict([NotNull] this DbContextOptionsBuilder builder) + { return builder.UseOpenIddict /// The builder used to configure the Entity Framework context. /// The Entity Framework context builder. - public static DbContextOptionsBuilder UseOpenIddict([NotNull] this DbContextOptionsBuilder builder) where TKey : IEquatable { + public static DbContextOptionsBuilder UseOpenIddict([NotNull] this DbContextOptionsBuilder builder) where TKey : IEquatable + { return builder.UseOpenIddict, OpenIddictAuthorization, OpenIddictScope, @@ -143,8 +154,10 @@ namespace Microsoft.Extensions.DependencyInjection { where TAuthorization : OpenIddictAuthorization, new() where TScope : OpenIddictScope, new() where TToken : OpenIddictToken, new() - where TKey : IEquatable { - if (builder == null) { + where TKey : IEquatable + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } @@ -160,7 +173,8 @@ namespace Microsoft.Extensions.DependencyInjection { /// /// The builder used to configure the Entity Framework context. /// The Entity Framework context builder. - public static ModelBuilder UseOpenIddict([NotNull] this ModelBuilder builder) { + public static ModelBuilder UseOpenIddict([NotNull] this ModelBuilder builder) + { return builder.UseOpenIddict /// The builder used to configure the Entity Framework context. /// The Entity Framework context builder. - public static ModelBuilder UseOpenIddict([NotNull] this ModelBuilder builder) where TKey : IEquatable { + public static ModelBuilder UseOpenIddict([NotNull] this ModelBuilder builder) where TKey : IEquatable + { return builder.UseOpenIddict, OpenIddictAuthorization, OpenIddictScope, @@ -191,8 +206,10 @@ namespace Microsoft.Extensions.DependencyInjection { where TAuthorization : OpenIddictAuthorization, new() where TScope : OpenIddictScope, new() where TToken : OpenIddictToken, new() - where TKey : IEquatable { - if (builder == null) { + where TKey : IEquatable + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } @@ -201,7 +218,8 @@ namespace Microsoft.Extensions.DependencyInjection { // being non-nullable when using value types like short, int, long or Guid. // Configure the TApplication entity. - builder.Entity(entity => { + builder.Entity(entity => + { entity.HasKey(application => application.Id); entity.HasIndex(application => application.ClientId) @@ -221,7 +239,8 @@ namespace Microsoft.Extensions.DependencyInjection { }); // Configure the TAuthorization entity. - builder.Entity(entity => { + builder.Entity(entity => + { entity.HasKey(authorization => authorization.Id); entity.HasMany(application => application.Tokens) @@ -233,14 +252,16 @@ namespace Microsoft.Extensions.DependencyInjection { }); // Configure the TScope entity. - builder.Entity(entity => { + builder.Entity(entity => + { entity.HasKey(scope => scope.Id); entity.ToTable("OpenIddictScopes"); }); // Configure the TToken entity. - builder.Entity(entity => { + builder.Entity(entity => + { entity.HasKey(token => token.Id); entity.ToTable("OpenIddictTokens"); @@ -249,17 +270,22 @@ namespace Microsoft.Extensions.DependencyInjection { return builder; } - private static TypeInfo FindGenericBaseType(Type type, Type definition) { - if (type == null) { + private static TypeInfo FindGenericBaseType(Type type, Type definition) + { + if (type == null) + { throw new ArgumentNullException(nameof(type)); } - if (definition == null) { + if (definition == null) + { throw new ArgumentNullException(nameof(definition)); } - for (var candidate = type.GetTypeInfo(); candidate != null; candidate = candidate.BaseType?.GetTypeInfo()) { - if (candidate.IsGenericType && candidate.GetGenericTypeDefinition() == definition) { + for (var candidate = type.GetTypeInfo(); candidate != null; candidate = candidate.BaseType?.GetTypeInfo()) + { + if (candidate.IsGenericType && candidate.GetGenericTypeDefinition() == definition) + { return candidate; } } diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs index 35f7fb56..78e34f7d 100644 --- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs +++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs @@ -15,7 +15,8 @@ using Microsoft.EntityFrameworkCore; using OpenIddict.Core; using OpenIddict.Models; -namespace OpenIddict.EntityFrameworkCore { +namespace OpenIddict.EntityFrameworkCore +{ /// /// Provides methods allowing to manage the applications stored in a database. /// @@ -23,7 +24,8 @@ namespace OpenIddict.EntityFrameworkCore { public class OpenIddictApplicationStore : OpenIddictApplicationStore - where TContext : DbContext { + where TContext : DbContext + { public OpenIddictApplicationStore([NotNull] TContext context) : base(context) { } } @@ -36,7 +38,8 @@ namespace OpenIddict.EntityFrameworkCore { OpenIddictAuthorization, OpenIddictToken, TContext, TKey> where TContext : DbContext - where TKey : IEquatable { + where TKey : IEquatable + { public OpenIddictApplicationStore([NotNull] TContext context) : base(context) { } } @@ -53,9 +56,12 @@ namespace OpenIddict.EntityFrameworkCore { where TAuthorization : OpenIddictAuthorization, new() where TToken : OpenIddictToken, new() where TContext : DbContext - where TKey : IEquatable { - public OpenIddictApplicationStore([NotNull] TContext context) { - if (context == null) { + where TKey : IEquatable + { + public OpenIddictApplicationStore([NotNull] TContext context) + { + if (context == null) + { throw new ArgumentNullException(nameof(context)); } @@ -80,8 +86,10 @@ namespace OpenIddict.EntityFrameworkCore { /// /// A that can be used to monitor the asynchronous operation, whose result returns the application. /// - public virtual async Task CreateAsync([NotNull] TApplication application, CancellationToken cancellationToken) { - if (application == null) { + public virtual async Task CreateAsync([NotNull] TApplication application, CancellationToken cancellationToken) + { + if (application == null) + { throw new ArgumentNullException(nameof(application)); } @@ -100,14 +108,17 @@ namespace OpenIddict.EntityFrameworkCore { /// /// A that can be used to monitor the asynchronous operation. /// - public virtual async Task DeleteAsync([NotNull] TApplication application, CancellationToken cancellationToken) { - if (application == null) { + public virtual async Task DeleteAsync([NotNull] TApplication application, CancellationToken cancellationToken) + { + if (application == null) + { throw new ArgumentNullException(nameof(application)); } Context.Remove(application); - try { + try + { await Context.SaveChangesAsync(cancellationToken); } @@ -123,7 +134,8 @@ namespace OpenIddict.EntityFrameworkCore { /// A that can be used to monitor the asynchronous operation, /// whose result returns the client application corresponding to the identifier. /// - public virtual Task FindByIdAsync(string identifier, CancellationToken cancellationToken) { + public virtual Task FindByIdAsync(string identifier, CancellationToken cancellationToken) + { var key = ConvertIdentifierFromString(identifier); return Applications.SingleOrDefaultAsync(application => application.Id.Equals(key), cancellationToken); @@ -138,7 +150,8 @@ namespace OpenIddict.EntityFrameworkCore { /// A that can be used to monitor the asynchronous operation, /// whose result returns the client application corresponding to the identifier. /// - public virtual Task FindByClientIdAsync(string identifier, CancellationToken cancellationToken) { + public virtual Task FindByClientIdAsync(string identifier, CancellationToken cancellationToken) + { return Applications.SingleOrDefaultAsync(application => application.ClientId.Equals(identifier), cancellationToken); } @@ -151,7 +164,8 @@ namespace OpenIddict.EntityFrameworkCore { /// A that can be used to monitor the asynchronous operation, whose result /// returns the client application corresponding to the post_logout_redirect_uri. /// - public virtual Task FindByLogoutRedirectUri(string url, CancellationToken cancellationToken) { + public virtual Task FindByLogoutRedirectUri(string url, CancellationToken cancellationToken) + { return Applications.SingleOrDefaultAsync(application => application.LogoutRedirectUri == url, cancellationToken); } @@ -164,8 +178,10 @@ namespace OpenIddict.EntityFrameworkCore { /// A that can be used to monitor the asynchronous operation, /// whose result returns the client identifier associated with the application. /// - public virtual Task GetClientIdAsync([NotNull] TApplication application, CancellationToken cancellationToken) { - if (application == null) { + public virtual Task GetClientIdAsync([NotNull] TApplication application, CancellationToken cancellationToken) + { + if (application == null) + { throw new ArgumentNullException(nameof(application)); } @@ -181,8 +197,10 @@ namespace OpenIddict.EntityFrameworkCore { /// A that can be used to monitor the asynchronous operation, /// whose result returns the client type of the application (by default, "public"). /// - public virtual Task GetClientTypeAsync([NotNull] TApplication application, CancellationToken cancellationToken) { - if (application == null) { + public virtual Task GetClientTypeAsync([NotNull] TApplication application, CancellationToken cancellationToken) + { + if (application == null) + { throw new ArgumentNullException(nameof(application)); } @@ -198,8 +216,10 @@ namespace OpenIddict.EntityFrameworkCore { /// A that can be used to monitor the asynchronous operation, /// whose result returns the display name associated with the application. /// - public virtual Task GetDisplayNameAsync([NotNull] TApplication application, CancellationToken cancellationToken) { - if (application == null) { + public virtual Task GetDisplayNameAsync([NotNull] TApplication application, CancellationToken cancellationToken) + { + if (application == null) + { throw new ArgumentNullException(nameof(application)); } @@ -215,8 +235,10 @@ namespace OpenIddict.EntityFrameworkCore { /// A that can be used to monitor the asynchronous operation, /// whose result returns the hashed secret associated with the application. /// - public virtual Task GetHashedSecretAsync([NotNull] TApplication application, CancellationToken cancellationToken) { - if (application == null) { + public virtual Task GetHashedSecretAsync([NotNull] TApplication application, CancellationToken cancellationToken) + { + if (application == null) + { throw new ArgumentNullException(nameof(application)); } @@ -232,8 +254,10 @@ namespace OpenIddict.EntityFrameworkCore { /// A that can be used to monitor the asynchronous operation, /// whose result returns the unique identifier associated with the application. /// - public virtual Task GetIdAsync([NotNull] TApplication application, CancellationToken cancellationToken) { - if (application == null) { + public virtual Task GetIdAsync([NotNull] TApplication application, CancellationToken cancellationToken) + { + if (application == null) + { throw new ArgumentNullException(nameof(application)); } @@ -249,8 +273,10 @@ namespace OpenIddict.EntityFrameworkCore { /// A that can be used to monitor the asynchronous operation, /// whose result returns the post_logout_redirect_uri associated with the application. /// - public virtual Task GetLogoutRedirectUriAsync([NotNull] TApplication application, CancellationToken cancellationToken) { - if (application == null) { + public virtual Task GetLogoutRedirectUriAsync([NotNull] TApplication application, CancellationToken cancellationToken) + { + if (application == null) + { throw new ArgumentNullException(nameof(application)); } @@ -266,8 +292,10 @@ namespace OpenIddict.EntityFrameworkCore { /// A that can be used to monitor the asynchronous operation, /// whose result returns the redirect_uri associated with the application. /// - public virtual Task GetRedirectUriAsync([NotNull] TApplication application, CancellationToken cancellationToken) { - if (application == null) { + public virtual Task GetRedirectUriAsync([NotNull] TApplication application, CancellationToken cancellationToken) + { + if (application == null) + { throw new ArgumentNullException(nameof(application)); } @@ -283,8 +311,10 @@ namespace OpenIddict.EntityFrameworkCore { /// A that can be used to monitor the asynchronous operation, /// whose result returns the tokens associated with the application. /// - public virtual async Task> GetTokensAsync([NotNull] TApplication application, CancellationToken cancellationToken) { - if (application == null) { + public virtual async Task> GetTokensAsync([NotNull] TApplication application, CancellationToken cancellationToken) + { + if (application == null) + { throw new ArgumentNullException(nameof(application)); } @@ -295,7 +325,8 @@ namespace OpenIddict.EntityFrameworkCore { var tokens = new List(); - foreach (var identifier in await query.ToArrayAsync()) { + foreach (var identifier in await query.ToArrayAsync()) + { tokens.Add(ConvertIdentifierToString(identifier)); } @@ -311,12 +342,15 @@ namespace OpenIddict.EntityFrameworkCore { /// /// A that can be used to monitor the asynchronous operation. /// - public virtual Task SetClientTypeAsync([NotNull] TApplication application, [NotNull] string type, CancellationToken cancellationToken) { - if (application == null) { + public virtual Task SetClientTypeAsync([NotNull] TApplication application, [NotNull] string type, CancellationToken cancellationToken) + { + if (application == null) + { throw new ArgumentNullException(nameof(application)); } - if (string.IsNullOrEmpty(type)) { + if (string.IsNullOrEmpty(type)) + { throw new ArgumentException("The client type cannot be null or empty.", nameof(type)); } @@ -334,12 +368,15 @@ namespace OpenIddict.EntityFrameworkCore { /// /// A that can be used to monitor the asynchronous operation. /// - public virtual Task SetHashedSecretAsync([NotNull] TApplication application, [NotNull] string hash, CancellationToken cancellationToken) { - if (application == null) { + public virtual Task SetHashedSecretAsync([NotNull] TApplication application, [NotNull] string hash, CancellationToken cancellationToken) + { + if (application == null) + { throw new ArgumentNullException(nameof(application)); } - if (string.IsNullOrEmpty(hash)) { + if (string.IsNullOrEmpty(hash)) + { throw new ArgumentException("The client secret hash cannot be null or empty.", nameof(hash)); } @@ -356,15 +393,18 @@ namespace OpenIddict.EntityFrameworkCore { /// /// A that can be used to monitor the asynchronous operation. /// - public virtual async Task UpdateAsync([NotNull] TApplication application, CancellationToken cancellationToken) { - if (application == null) { + public virtual async Task UpdateAsync([NotNull] TApplication application, CancellationToken cancellationToken) + { + if (application == null) + { throw new ArgumentNullException(nameof(application)); } Context.Attach(application); Context.Update(application); - try { + try + { await Context.SaveChangesAsync(cancellationToken); } @@ -376,8 +416,10 @@ namespace OpenIddict.EntityFrameworkCore { /// /// The identifier to convert. /// An instance of representing the provided identifier. - public virtual TKey ConvertIdentifierFromString([CanBeNull] string identifier) { - if (string.IsNullOrEmpty(identifier)) { + public virtual TKey ConvertIdentifierFromString([CanBeNull] string identifier) + { + if (string.IsNullOrEmpty(identifier)) + { return default(TKey); } @@ -390,8 +432,10 @@ namespace OpenIddict.EntityFrameworkCore { /// /// The identifier to convert. /// A representation of the provided identifier. - public virtual string ConvertIdentifierToString([CanBeNull] TKey identifier) { - if (Equals(identifier, default(TKey))) { + public virtual string ConvertIdentifierToString([CanBeNull] TKey identifier) + { + if (Equals(identifier, default(TKey))) + { return null; } diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs index 26a36030..dd2da734 100644 --- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs +++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs @@ -14,7 +14,8 @@ using Microsoft.EntityFrameworkCore; using OpenIddict.Core; using OpenIddict.Models; -namespace OpenIddict.EntityFrameworkCore { +namespace OpenIddict.EntityFrameworkCore +{ /// /// Provides methods allowing to manage the authorizations stored in a database. /// @@ -22,7 +23,8 @@ namespace OpenIddict.EntityFrameworkCore { public class OpenIddictAuthorizationStore : OpenIddictAuthorizationStore - where TContext : DbContext { + where TContext : DbContext + { public OpenIddictAuthorizationStore([NotNull] TContext context) : base(context) { } } @@ -35,7 +37,8 @@ namespace OpenIddict.EntityFrameworkCore { OpenIddictApplication, OpenIddictToken, TContext, TKey> where TContext : DbContext - where TKey : IEquatable { + where TKey : IEquatable + { public OpenIddictAuthorizationStore([NotNull] TContext context) : base(context) { } } @@ -52,9 +55,12 @@ namespace OpenIddict.EntityFrameworkCore { where TApplication : OpenIddictApplication, new() where TToken : OpenIddictToken, new() where TContext : DbContext - where TKey : IEquatable { - public OpenIddictAuthorizationStore([NotNull] TContext context) { - if (context == null) { + where TKey : IEquatable + { + public OpenIddictAuthorizationStore([NotNull] TContext context) + { + if (context == null) + { throw new ArgumentNullException(nameof(context)); } @@ -84,8 +90,10 @@ namespace OpenIddict.EntityFrameworkCore { /// /// A that can be used to monitor the asynchronous operation, whose result returns the authorization. /// - public virtual async Task CreateAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken) { - if (authorization == null) { + public virtual async Task CreateAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken) + { + if (authorization == null) + { throw new ArgumentNullException(nameof(authorization)); } @@ -106,7 +114,8 @@ namespace OpenIddict.EntityFrameworkCore { /// A that can be used to monitor the asynchronous operation, /// whose result returns the authorization corresponding to the subject/client. /// - public virtual Task FindAsync(string subject, string client, CancellationToken cancellationToken) { + public virtual Task FindAsync(string subject, string client, CancellationToken cancellationToken) + { var key = ConvertIdentifierFromString(client); return (from application in Applications @@ -125,7 +134,8 @@ namespace OpenIddict.EntityFrameworkCore { /// A that can be used to monitor the asynchronous operation, /// whose result returns the authorization corresponding to the identifier. /// - public virtual Task FindByIdAsync(string identifier, CancellationToken cancellationToken) { + public virtual Task FindByIdAsync(string identifier, CancellationToken cancellationToken) + { var key = ConvertIdentifierFromString(identifier); return Authorizations.SingleOrDefaultAsync(authorization => authorization.Id.Equals(key), cancellationToken); @@ -140,8 +150,10 @@ namespace OpenIddict.EntityFrameworkCore { /// A that can be used to monitor the asynchronous operation, /// whose result returns the unique identifier associated with the authorization. /// - public virtual Task GetIdAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken) { - if (authorization == null) { + public virtual Task GetIdAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken) + { + if (authorization == null) + { throw new ArgumentNullException(nameof(authorization)); } @@ -157,8 +169,10 @@ namespace OpenIddict.EntityFrameworkCore { /// A that can be used to monitor the asynchronous operation, /// whose result returns the subject associated with the specified authorization. /// - public virtual Task GetSubjectAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken) { - if (authorization == null) { + public virtual Task GetSubjectAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken) + { + if (authorization == null) + { throw new ArgumentNullException(nameof(authorization)); } @@ -170,8 +184,10 @@ namespace OpenIddict.EntityFrameworkCore { /// /// The identifier to convert. /// An instance of representing the provided identifier. - public virtual TKey ConvertIdentifierFromString([CanBeNull] string identifier) { - if (string.IsNullOrEmpty(identifier)) { + public virtual TKey ConvertIdentifierFromString([CanBeNull] string identifier) + { + if (string.IsNullOrEmpty(identifier)) + { return default(TKey); } @@ -184,8 +200,10 @@ namespace OpenIddict.EntityFrameworkCore { /// /// The identifier to convert. /// A representation of the provided identifier. - public virtual string ConvertIdentifierToString([CanBeNull] TKey identifier) { - if (Equals(identifier, default(TKey))) { + public virtual string ConvertIdentifierToString([CanBeNull] TKey identifier) + { + if (Equals(identifier, default(TKey))) + { return null; } diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs index d2ed90b6..c67239e4 100644 --- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs +++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs @@ -11,13 +11,15 @@ using Microsoft.EntityFrameworkCore; using OpenIddict.Core; using OpenIddict.Models; -namespace OpenIddict.EntityFrameworkCore { +namespace OpenIddict.EntityFrameworkCore +{ /// /// Provides methods allowing to manage the scopes stored in a database. /// /// The type of the Entity Framework database context. public class OpenIddictScopeStore : OpenIddictScopeStore - where TContext : DbContext { + where TContext : DbContext + { public OpenIddictScopeStore([NotNull] TContext context) : base(context) { } } @@ -28,7 +30,8 @@ namespace OpenIddict.EntityFrameworkCore { /// The type of the entity primary keys. public class OpenIddictScopeStore : OpenIddictScopeStore, TContext, TKey> where TContext : DbContext - where TKey : IEquatable { + where TKey : IEquatable + { public OpenIddictScopeStore([NotNull] TContext context) : base(context) { } } @@ -41,9 +44,12 @@ namespace OpenIddict.EntityFrameworkCore { public class OpenIddictScopeStore : IOpenIddictScopeStore where TScope : OpenIddictScope, new() where TContext : DbContext - where TKey : IEquatable { - public OpenIddictScopeStore([NotNull] TContext context) { - if (context == null) { + where TKey : IEquatable + { + public OpenIddictScopeStore([NotNull] TContext context) + { + if (context == null) + { throw new ArgumentNullException(nameof(context)); } @@ -65,8 +71,10 @@ namespace OpenIddict.EntityFrameworkCore { /// /// The identifier to convert. /// An instance of representing the provided identifier. - public virtual TKey ConvertIdentifierFromString([CanBeNull] string identifier) { - if (string.IsNullOrEmpty(identifier)) { + public virtual TKey ConvertIdentifierFromString([CanBeNull] string identifier) + { + if (string.IsNullOrEmpty(identifier)) + { return default(TKey); } @@ -79,8 +87,10 @@ namespace OpenIddict.EntityFrameworkCore { /// /// The identifier to convert. /// A representation of the provided identifier. - public virtual string ConvertIdentifierToString([CanBeNull] TKey identifier) { - if (Equals(identifier, default(TKey))) { + public virtual string ConvertIdentifierToString([CanBeNull] TKey identifier) + { + if (Equals(identifier, default(TKey))) + { return null; } diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs index 5621c005..b6b45092 100644 --- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs +++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs @@ -14,7 +14,8 @@ using Microsoft.EntityFrameworkCore; using OpenIddict.Core; using OpenIddict.Models; -namespace OpenIddict.EntityFrameworkCore { +namespace OpenIddict.EntityFrameworkCore +{ /// /// Provides methods allowing to manage the tokens stored in a database. /// @@ -22,7 +23,8 @@ namespace OpenIddict.EntityFrameworkCore { public class OpenIddictTokenStore : OpenIddictTokenStore - where TContext : DbContext { + where TContext : DbContext + { public OpenIddictTokenStore([NotNull] TContext context) : base(context) { } } @@ -35,7 +37,8 @@ namespace OpenIddict.EntityFrameworkCore { OpenIddictApplication, OpenIddictAuthorization, TContext, TKey> where TContext : DbContext - where TKey : IEquatable { + where TKey : IEquatable + { public OpenIddictTokenStore([NotNull] TContext context) : base(context) { } } @@ -52,9 +55,12 @@ namespace OpenIddict.EntityFrameworkCore { where TApplication : OpenIddictApplication, new() where TAuthorization : OpenIddictAuthorization, new() where TContext : DbContext - where TKey : IEquatable { - public OpenIddictTokenStore([NotNull] TContext context) { - if (context == null) { + where TKey : IEquatable + { + public OpenIddictTokenStore([NotNull] TContext context) + { + if (context == null) + { throw new ArgumentNullException(nameof(context)); } @@ -89,8 +95,10 @@ namespace OpenIddict.EntityFrameworkCore { /// /// A that can be used to monitor the asynchronous operation, whose result returns the token. /// - public virtual async Task CreateAsync([NotNull] TToken token, CancellationToken cancellationToken) { - if (token == null) { + public virtual async Task CreateAsync([NotNull] TToken token, CancellationToken cancellationToken) + { + if (token == null) + { throw new ArgumentNullException(nameof(token)); } @@ -110,8 +118,10 @@ namespace OpenIddict.EntityFrameworkCore { /// /// A that can be used to monitor the asynchronous operation, whose result returns the token. /// - public virtual Task CreateAsync([NotNull] string type, [NotNull] string subject, CancellationToken cancellationToken) { - if (string.IsNullOrEmpty(type)) { + public virtual Task CreateAsync([NotNull] string type, [NotNull] string subject, CancellationToken cancellationToken) + { + if (string.IsNullOrEmpty(type)) + { throw new ArgumentException("The token type cannot be null or empty."); } @@ -127,7 +137,8 @@ namespace OpenIddict.EntityFrameworkCore { /// A that can be used to monitor the asynchronous operation, /// whose result returns the token corresponding to the unique identifier. /// - public virtual Task FindByIdAsync(string identifier, CancellationToken cancellationToken) { + public virtual Task FindByIdAsync(string identifier, CancellationToken cancellationToken) + { var key = ConvertIdentifierFromString(identifier); return Tokens.SingleOrDefaultAsync(token => token.Id.Equals(key), cancellationToken); @@ -142,7 +153,8 @@ namespace OpenIddict.EntityFrameworkCore { /// A that can be used to monitor the asynchronous operation, /// whose result returns the tokens corresponding to the specified subject. /// - public virtual Task FindBySubjectAsync(string subject, CancellationToken cancellationToken) { + public virtual Task FindBySubjectAsync(string subject, CancellationToken cancellationToken) + { return Tokens.Where(token => token.Subject == subject).ToArrayAsync(); } @@ -155,8 +167,10 @@ namespace OpenIddict.EntityFrameworkCore { /// A that can be used to monitor the asynchronous operation, /// whose result returns the unique identifier associated with the token. /// - public virtual Task GetIdAsync([NotNull] TToken token, CancellationToken cancellationToken) { - if (token == null) { + public virtual Task GetIdAsync([NotNull] TToken token, CancellationToken cancellationToken) + { + if (token == null) + { throw new ArgumentNullException(nameof(token)); } @@ -172,8 +186,10 @@ namespace OpenIddict.EntityFrameworkCore { /// A that can be used to monitor the asynchronous operation, /// whose result returns the token type associated with the specified token. /// - public virtual Task GetTokenTypeAsync([NotNull] TToken token, CancellationToken cancellationToken) { - if (token == null) { + public virtual Task GetTokenTypeAsync([NotNull] TToken token, CancellationToken cancellationToken) + { + if (token == null) + { throw new ArgumentNullException(nameof(token)); } @@ -189,8 +205,10 @@ namespace OpenIddict.EntityFrameworkCore { /// A that can be used to monitor the asynchronous operation, /// whose result returns the subject associated with the specified token. /// - public virtual Task GetSubjectAsync([NotNull] TToken token, CancellationToken cancellationToken) { - if (token == null) { + public virtual Task GetSubjectAsync([NotNull] TToken token, CancellationToken cancellationToken) + { + if (token == null) + { throw new ArgumentNullException(nameof(token)); } @@ -203,14 +221,17 @@ namespace OpenIddict.EntityFrameworkCore { /// The token to revoke. /// The that can be used to abort the operation. /// A that can be used to monitor the asynchronous operation. - public virtual async Task RevokeAsync([NotNull] TToken token, CancellationToken cancellationToken) { - if (token == null) { + public virtual async Task RevokeAsync([NotNull] TToken token, CancellationToken cancellationToken) + { + if (token == null) + { throw new ArgumentNullException(nameof(token)); } Context.Remove(token); - try { + try + { await Context.SaveChangesAsync(cancellationToken); } @@ -226,29 +247,35 @@ namespace OpenIddict.EntityFrameworkCore { /// /// A that can be used to monitor the asynchronous operation. /// - public virtual async Task SetAuthorizationAsync([NotNull] TToken token, [CanBeNull] string identifier, CancellationToken cancellationToken) { - if (token == null) { + public virtual async Task SetAuthorizationAsync([NotNull] TToken token, [CanBeNull] string identifier, CancellationToken cancellationToken) + { + if (token == null) + { throw new ArgumentNullException(nameof(token)); } - if (!string.IsNullOrEmpty(identifier)) { + if (!string.IsNullOrEmpty(identifier)) + { var key = ConvertIdentifierFromString(identifier); var authorization = await Authorizations.SingleOrDefaultAsync(element => element.Id.Equals(key)); - if (authorization == null) { + if (authorization == null) + { throw new InvalidOperationException("The authorization associated with the token cannot be found."); } authorization.Tokens.Add(token); } - else { + else + { var key = await GetIdAsync(token, cancellationToken); // Try to retrieve the authorization associated with the token. // If none can be found, assume that no authorization is attached. var authorization = await Authorizations.SingleOrDefaultAsync(element => element.Tokens.Any(t => t.Id.Equals(key))); - if (authorization != null) { + if (authorization != null) + { authorization.Tokens.Remove(token); } } @@ -263,29 +290,35 @@ namespace OpenIddict.EntityFrameworkCore { /// /// A that can be used to monitor the asynchronous operation. /// - public virtual async Task SetClientAsync([NotNull] TToken token, [CanBeNull] string identifier, CancellationToken cancellationToken) { - if (token == null) { + public virtual async Task SetClientAsync([NotNull] TToken token, [CanBeNull] string identifier, CancellationToken cancellationToken) + { + if (token == null) + { throw new ArgumentNullException(nameof(token)); } - if (!string.IsNullOrEmpty(identifier)) { + if (!string.IsNullOrEmpty(identifier)) + { var key = ConvertIdentifierFromString(identifier); var application = await Applications.SingleOrDefaultAsync(element => element.Id.Equals(key)); - if (application == null) { + if (application == null) + { throw new InvalidOperationException("The application associated with the token cannot be found."); } application.Tokens.Add(token); } - else { + else + { var key = await GetIdAsync(token, cancellationToken); // Try to retrieve the application associated with the token. // If none can be found, assume that no application is attached. var application = await Applications.SingleOrDefaultAsync(element => element.Tokens.Any(t => t.Id.Equals(key))); - if (application != null) { + if (application != null) + { application.Tokens.Remove(token); } } @@ -299,15 +332,18 @@ namespace OpenIddict.EntityFrameworkCore { /// /// A that can be used to monitor the asynchronous operation. /// - public virtual async Task UpdateAsync([NotNull] TToken token, CancellationToken cancellationToken) { - if (token == null) { + public virtual async Task UpdateAsync([NotNull] TToken token, CancellationToken cancellationToken) + { + if (token == null) + { throw new ArgumentNullException(nameof(token)); } Context.Attach(token); Context.Update(token); - try { + try + { await Context.SaveChangesAsync(cancellationToken); } @@ -319,8 +355,10 @@ namespace OpenIddict.EntityFrameworkCore { /// /// The identifier to convert. /// An instance of representing the provided identifier. - public virtual TKey ConvertIdentifierFromString([CanBeNull] string identifier) { - if (string.IsNullOrEmpty(identifier)) { + public virtual TKey ConvertIdentifierFromString([CanBeNull] string identifier) + { + if (string.IsNullOrEmpty(identifier)) + { return default(TKey); } @@ -333,8 +371,10 @@ namespace OpenIddict.EntityFrameworkCore { /// /// The identifier to convert. /// A representation of the provided identifier. - public virtual string ConvertIdentifierToString([CanBeNull] TKey identifier) { - if (Equals(identifier, default(TKey))) { + public virtual string ConvertIdentifierToString([CanBeNull] TKey identifier) + { + if (Equals(identifier, default(TKey))) + { return null; } diff --git a/src/OpenIddict.Models/OpenIddictApplication.cs b/src/OpenIddict.Models/OpenIddictApplication.cs index dc9b98df..140421d4 100644 --- a/src/OpenIddict.Models/OpenIddictApplication.cs +++ b/src/OpenIddict.Models/OpenIddictApplication.cs @@ -7,12 +7,15 @@ using System; using System.Collections.Generic; -namespace OpenIddict.Models { +namespace OpenIddict.Models +{ /// /// Represents an OpenIddict application. /// - public class OpenIddictApplication : OpenIddictApplication { - public OpenIddictApplication() { + public class OpenIddictApplication : OpenIddictApplication + { + public OpenIddictApplication() + { // Generate a new string identifier. Id = Guid.NewGuid().ToString(); } @@ -22,12 +25,14 @@ namespace OpenIddict.Models { /// Represents an OpenIddict application. /// public class OpenIddictApplication : OpenIddictApplication, OpenIddictToken> - where TKey : IEquatable { } + where TKey : IEquatable + { } /// /// Represents an OpenIddict application. /// - public class OpenIddictApplication where TKey : IEquatable { + public class OpenIddictApplication where TKey : IEquatable + { /// /// Gets the list of the authorizations associated with this application. /// diff --git a/src/OpenIddict.Models/OpenIddictAuthorization.cs b/src/OpenIddict.Models/OpenIddictAuthorization.cs index 13ad15b5..34a4be67 100644 --- a/src/OpenIddict.Models/OpenIddictAuthorization.cs +++ b/src/OpenIddict.Models/OpenIddictAuthorization.cs @@ -7,12 +7,15 @@ using System; using System.Collections.Generic; -namespace OpenIddict.Models { +namespace OpenIddict.Models +{ /// /// Represents an OpenIddict authorization. /// - public class OpenIddictAuthorization : OpenIddictAuthorization { - public OpenIddictAuthorization() { + public class OpenIddictAuthorization : OpenIddictAuthorization + { + public OpenIddictAuthorization() + { // Generate a new string identifier. Id = Guid.NewGuid().ToString(); } @@ -22,12 +25,14 @@ namespace OpenIddict.Models { /// Represents an OpenIddict authorization. /// public class OpenIddictAuthorization : OpenIddictAuthorization, OpenIddictToken> - where TKey : IEquatable { } + where TKey : IEquatable + { } /// /// Represents an OpenIddict authorization. /// - public class OpenIddictAuthorization where TKey : IEquatable { + public class OpenIddictAuthorization where TKey : IEquatable + { /// /// Gets or sets the application associated with the current authorization. /// diff --git a/src/OpenIddict.Models/OpenIddictScope.cs b/src/OpenIddict.Models/OpenIddictScope.cs index dfa46cd2..10c9c6c4 100644 --- a/src/OpenIddict.Models/OpenIddictScope.cs +++ b/src/OpenIddict.Models/OpenIddictScope.cs @@ -6,12 +6,15 @@ using System; -namespace OpenIddict.Models { +namespace OpenIddict.Models +{ /// /// Represents an OpenIddict scope. /// - public class OpenIddictScope : OpenIddictScope { - public OpenIddictScope() { + public class OpenIddictScope : OpenIddictScope + { + public OpenIddictScope() + { // Generate a new string identifier. Id = Guid.NewGuid().ToString(); } @@ -20,7 +23,8 @@ namespace OpenIddict.Models { /// /// Represents an OpenIddict scope. /// - public class OpenIddictScope where TKey : IEquatable { + public class OpenIddictScope where TKey : IEquatable + { /// /// Gets or sets the public description /// associated with the current scope. diff --git a/src/OpenIddict.Models/OpenIddictToken.cs b/src/OpenIddict.Models/OpenIddictToken.cs index d9574e3d..d4801084 100644 --- a/src/OpenIddict.Models/OpenIddictToken.cs +++ b/src/OpenIddict.Models/OpenIddictToken.cs @@ -6,12 +6,15 @@ using System; -namespace OpenIddict.Models { +namespace OpenIddict.Models +{ /// /// Represents an OpenIddict token. /// - public class OpenIddictToken : OpenIddictToken { - public OpenIddictToken() { + public class OpenIddictToken : OpenIddictToken + { + public OpenIddictToken() + { // Generate a new string identifier. Id = Guid.NewGuid().ToString(); } @@ -21,13 +24,15 @@ namespace OpenIddict.Models { /// Represents an OpenIddict token. /// public class OpenIddictToken : OpenIddictToken, OpenIddictAuthorization> - where TKey : IEquatable { + where TKey : IEquatable + { } /// /// Represents an OpenIddict token. /// - public class OpenIddictToken where TKey : IEquatable { + public class OpenIddictToken where TKey : IEquatable + { /// /// Gets or sets the application associated with the current token. /// diff --git a/src/OpenIddict.Mvc/OpenIddictExtensions.cs b/src/OpenIddict.Mvc/OpenIddictExtensions.cs index 7787d437..ca0a44fc 100644 --- a/src/OpenIddict.Mvc/OpenIddictExtensions.cs +++ b/src/OpenIddict.Mvc/OpenIddictExtensions.cs @@ -9,23 +9,30 @@ using JetBrains.Annotations; using Microsoft.AspNetCore.Mvc; using OpenIddict.Mvc; -namespace Microsoft.Extensions.DependencyInjection { - public static class OpenIddictExtensions { +namespace Microsoft.Extensions.DependencyInjection +{ + public static class OpenIddictExtensions + { /// /// Registers the ASP.NET Core MVC model binders used by OpenIddict. /// /// The services builder used by OpenIddict to register new services. /// The . - public static OpenIddictBuilder AddMvcBinders([NotNull] this OpenIddictBuilder builder) { - if (builder == null) { + public static OpenIddictBuilder AddMvcBinders([NotNull] this OpenIddictBuilder builder) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } - builder.Services.Configure(options => { + builder.Services.Configure(options => + { // Skip the binder registration if it was already added to the providers collection. - for (var index = 0; index < options.ModelBinderProviders.Count; index++) { + for (var index = 0; index < options.ModelBinderProviders.Count; index++) + { var provider = options.ModelBinderProviders[index]; - if (provider is OpenIddictModelBinder) { + if (provider is OpenIddictModelBinder) + { return; } } diff --git a/src/OpenIddict.Mvc/OpenIddictModelBinder.cs b/src/OpenIddict.Mvc/OpenIddictModelBinder.cs index df34f900..9a716717 100644 --- a/src/OpenIddict.Mvc/OpenIddictModelBinder.cs +++ b/src/OpenIddict.Mvc/OpenIddictModelBinder.cs @@ -6,26 +6,32 @@ using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; -namespace OpenIddict.Mvc { +namespace OpenIddict.Mvc +{ /// /// Represents an ASP.NET Core MVC model binder that is able to bind /// and /// instances. /// - public class OpenIddictModelBinder : IModelBinder, IModelBinderProvider { + public class OpenIddictModelBinder : IModelBinder, IModelBinderProvider + { /// /// Tries to bind a model from the request. /// /// The model binding context. /// A representing the asynchronous operation. - public Task BindModelAsync([NotNull] ModelBindingContext context) { - if (context == null) { + public Task BindModelAsync([NotNull] ModelBindingContext context) + { + if (context == null) + { throw new ArgumentNullException(nameof(context)); } - if (context.ModelType == typeof(OpenIdConnectRequest)) { + if (context.ModelType == typeof(OpenIdConnectRequest)) + { var request = context.HttpContext.GetOpenIdConnectRequest(); - if (request == null) { + if (request == null) + { throw new InvalidOperationException("The OpenID Connect request cannot be retrieved from the ASP.NET context. " + "Make sure that 'app.UseOpenIddict()' is called before 'app.UseMvc()' and " + "that the action route corresponds to the endpoint path registered via " + @@ -34,7 +40,8 @@ namespace OpenIddict.Mvc { // Add a new validation state entry to prevent the built-in // model validators from validating the OpenID Connect request. - context.ValidationState.Add(request, new ValidationStateEntry { + context.ValidationState.Add(request, new ValidationStateEntry + { SuppressValidation = true }); @@ -43,12 +50,15 @@ namespace OpenIddict.Mvc { return Task.FromResult(0); } - else if (context.ModelType == typeof(OpenIdConnectResponse)) { + else if (context.ModelType == typeof(OpenIdConnectResponse)) + { var response = context.HttpContext.GetOpenIdConnectResponse(); - if (response != null) { + if (response != null) + { // Add a new validation state entry to prevent the built-in // model validators from validating the OpenID Connect response. - context.ValidationState.Add(response, new ValidationStateEntry { + context.ValidationState.Add(response, new ValidationStateEntry + { SuppressValidation = true }); } @@ -66,13 +76,16 @@ namespace OpenIddict.Mvc { /// /// The model binding context. /// The current instance or null if the model is not supported. - public IModelBinder GetBinder([NotNull] ModelBinderProviderContext context) { - if (context == null) { + public IModelBinder GetBinder([NotNull] ModelBinderProviderContext context) + { + if (context == null) + { throw new ArgumentNullException(nameof(context)); } if (context.Metadata.ModelType == typeof(OpenIdConnectRequest) || - context.Metadata.ModelType == typeof(OpenIdConnectResponse)) { + context.Metadata.ModelType == typeof(OpenIdConnectResponse)) + { return this; } diff --git a/src/OpenIddict/OpenIddictExtensions.cs b/src/OpenIddict/OpenIddictExtensions.cs index 9111a8dc..075ab60d 100644 --- a/src/OpenIddict/OpenIddictExtensions.cs +++ b/src/OpenIddict/OpenIddictExtensions.cs @@ -21,22 +21,27 @@ using Microsoft.Extensions.Options; using Microsoft.IdentityModel.Tokens; using OpenIddict; -namespace Microsoft.AspNetCore.Builder { - public static class OpenIddictExtensions { +namespace Microsoft.AspNetCore.Builder +{ + public static class OpenIddictExtensions + { /// /// Registers OpenIddict in the ASP.NET Core pipeline. /// /// The application builder used to register middleware instances. /// The . - public static IApplicationBuilder UseOpenIddict([NotNull] this IApplicationBuilder app) { - if (app == null) { + public static IApplicationBuilder UseOpenIddict([NotNull] this IApplicationBuilder app) + { + if (app == null) + { throw new ArgumentNullException(nameof(app)); } // Resolve the OpenIddict builder from the DI container. // If it cannot be found, throw an invalid operation exception. var builder = app.ApplicationServices.GetService(); - if (builder == null) { + if (builder == null) + { throw new InvalidOperationException("The OpenIddict services cannot be resolved from the dependency injection container. " + "Make sure 'services.AddOpenIddict()' is correctly called from 'ConfigureServices()'."); } @@ -46,7 +51,8 @@ namespace Microsoft.AspNetCore.Builder { // When no authorization provider has been registered in the options, // create a new OpenIddictProvider instance using the specified entities. - if (options.Provider == null) { + if (options.Provider == null) + { options.Provider = (OpenIdConnectServerProvider) Activator.CreateInstance( typeof(OpenIddictProvider<,,,>).MakeGenericType( /* TApplication: */ builder.ApplicationType, @@ -57,24 +63,28 @@ namespace Microsoft.AspNetCore.Builder { // When no distributed cache has been registered in the options, // try to resolve it from the dependency injection container. - if (options.Cache == null) { + if (options.Cache == null) + { options.Cache = app.ApplicationServices.GetService(); - if (options.EnableRequestCaching && options.Cache == null) { + if (options.EnableRequestCaching && options.Cache == null) + { throw new InvalidOperationException("A distributed cache implementation must be registered in the OpenIddict options " + "or in the dependency injection container when enabling request caching support."); } } // Ensure at least one flow has been enabled. - if (options.GrantTypes.Count == 0) { + if (options.GrantTypes.Count == 0) + { throw new InvalidOperationException("At least one OAuth2/OpenID Connect flow must be enabled."); } // Ensure the authorization endpoint has been enabled when // the authorization code or implicit grants are supported. if (!options.AuthorizationEndpointPath.HasValue && (options.GrantTypes.Contains(OpenIdConnectConstants.GrantTypes.AuthorizationCode) || - options.GrantTypes.Contains(OpenIdConnectConstants.GrantTypes.Implicit))) { + options.GrantTypes.Contains(OpenIdConnectConstants.GrantTypes.Implicit))) + { throw new InvalidOperationException("The authorization endpoint must be enabled to use " + "the authorization code and implicit flows."); } @@ -84,19 +94,22 @@ namespace Microsoft.AspNetCore.Builder { if (!options.TokenEndpointPath.HasValue && (options.GrantTypes.Contains(OpenIdConnectConstants.GrantTypes.AuthorizationCode) || options.GrantTypes.Contains(OpenIdConnectConstants.GrantTypes.ClientCredentials) || options.GrantTypes.Contains(OpenIdConnectConstants.GrantTypes.Password) || - options.GrantTypes.Contains(OpenIdConnectConstants.GrantTypes.RefreshToken))) { + options.GrantTypes.Contains(OpenIdConnectConstants.GrantTypes.RefreshToken))) + { throw new InvalidOperationException("The token endpoint must be enabled to use the authorization code, " + "client credentials, password and refresh token flows."); } - if (options.RevocationEndpointPath.HasValue && options.DisableTokenRevocation) { + if (options.RevocationEndpointPath.HasValue && options.DisableTokenRevocation) + { throw new InvalidOperationException("The revocation endpoint cannot be enabled when token revocation is disabled."); } // Ensure at least one asymmetric signing certificate/key was registered if the implicit flow was enabled. if (!options.SigningCredentials.Any(credentials => credentials.Key is AsymmetricSecurityKey) && - options.GrantTypes.Contains(OpenIdConnectConstants.GrantTypes.Implicit)) { - throw new InvalidOperationException("At least one asymmetric signing key must be registered when enabling the implicit flow. "+ + options.GrantTypes.Contains(OpenIdConnectConstants.GrantTypes.Implicit)) + { + throw new InvalidOperationException("At least one asymmetric signing key must be registered when enabling the implicit flow. " + "Consider registering a X.509 certificate using 'services.AddOpenIddict().AddSigningCertificate()' " + "or call 'services.AddOpenIddict().AddEphemeralSigningKey()' to use an ephemeral key."); } @@ -113,12 +126,15 @@ namespace Microsoft.AspNetCore.Builder { /// The . public static OpenIddictBuilder Configure( [NotNull] this OpenIddictBuilder builder, - [NotNull] Action configuration) { - if (builder == null) { + [NotNull] Action configuration) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } - if (configuration == null) { + if (configuration == null) + { throw new ArgumentNullException(nameof(configuration)); } @@ -135,8 +151,10 @@ namespace Microsoft.AspNetCore.Builder { /// /// The services builder used by OpenIddict to register new services. /// The . - public static OpenIddictBuilder AddEphemeralSigningKey([NotNull] this OpenIddictBuilder builder) { - if (builder == null) { + public static OpenIddictBuilder AddEphemeralSigningKey([NotNull] this OpenIddictBuilder builder) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } @@ -153,12 +171,15 @@ namespace Microsoft.AspNetCore.Builder { /// The algorithm associated with the signing key. /// The . public static OpenIddictBuilder AddEphemeralSigningKey( - [NotNull] this OpenIddictBuilder builder, [NotNull] string algorithm) { - if (builder == null) { + [NotNull] this OpenIddictBuilder builder, [NotNull] string algorithm) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } - if (string.IsNullOrEmpty(algorithm)) { + if (string.IsNullOrEmpty(algorithm)) + { throw new ArgumentException("The algorithm cannot be null or empty.", nameof(algorithm)); } @@ -173,16 +194,20 @@ namespace Microsoft.AspNetCore.Builder { /// The . public static OpenIddictBuilder AddSigningCertificate( [NotNull] this OpenIddictBuilder builder, - [NotNull] X509Certificate2 certificate) { - if (builder == null) { + [NotNull] X509Certificate2 certificate) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } - if (certificate == null) { + if (certificate == null) + { throw new ArgumentNullException(nameof(certificate)); } - if (!certificate.HasPrivateKey) { + if (!certificate.HasPrivateKey) + { throw new InvalidOperationException("The certificate doesn't contain the required private key."); } @@ -200,20 +225,25 @@ namespace Microsoft.AspNetCore.Builder { /// The . public static OpenIddictBuilder AddSigningCertificate( [NotNull] this OpenIddictBuilder builder, [NotNull] Assembly assembly, - [NotNull] string resource, [NotNull] string password) { - if (builder == null) { + [NotNull] string resource, [NotNull] string password) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } - if (assembly == null) { + if (assembly == null) + { throw new ArgumentNullException(nameof(assembly)); } - if (string.IsNullOrEmpty(resource)) { + if (string.IsNullOrEmpty(resource)) + { throw new ArgumentNullException(nameof(resource)); } - if (string.IsNullOrEmpty(password)) { + if (string.IsNullOrEmpty(password)) + { throw new ArgumentNullException(nameof(password)); } @@ -230,16 +260,20 @@ namespace Microsoft.AspNetCore.Builder { /// The . public static OpenIddictBuilder AddSigningCertificate( [NotNull] this OpenIddictBuilder builder, - [NotNull] Stream stream, [NotNull] string password) { - if (builder == null) { + [NotNull] Stream stream, [NotNull] string password) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } - if (stream == null) { + if (stream == null) + { throw new ArgumentNullException(nameof(stream)); } - if (string.IsNullOrEmpty(password)) { + if (string.IsNullOrEmpty(password)) + { throw new ArgumentNullException(nameof(password)); } @@ -260,16 +294,20 @@ namespace Microsoft.AspNetCore.Builder { /// The . public static OpenIddictBuilder AddSigningCertificate( [NotNull] this OpenIddictBuilder builder, [NotNull] Stream stream, - [NotNull] string password, X509KeyStorageFlags flags) { - if (builder == null) { + [NotNull] string password, X509KeyStorageFlags flags) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } - if (stream == null) { + if (stream == null) + { throw new ArgumentNullException(nameof(stream)); } - if (string.IsNullOrEmpty(password)) { + if (string.IsNullOrEmpty(password)) + { throw new ArgumentNullException(nameof(password)); } @@ -284,12 +322,15 @@ namespace Microsoft.AspNetCore.Builder { /// The thumbprint of the certificate used to identify it in the X.509 store. /// The . public static OpenIddictBuilder AddSigningCertificate( - [NotNull] this OpenIddictBuilder builder, [NotNull] string thumbprint) { - if (builder == null) { + [NotNull] this OpenIddictBuilder builder, [NotNull] string thumbprint) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } - if (string.IsNullOrEmpty(thumbprint)) { + if (string.IsNullOrEmpty(thumbprint)) + { throw new ArgumentNullException(nameof(thumbprint)); } @@ -307,12 +348,15 @@ namespace Microsoft.AspNetCore.Builder { /// The . public static OpenIddictBuilder AddSigningCertificate( [NotNull] this OpenIddictBuilder builder, - [NotNull] string thumbprint, StoreName name, StoreLocation location) { - if (builder == null) { + [NotNull] string thumbprint, StoreName name, StoreLocation location) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } - if (string.IsNullOrEmpty(thumbprint)) { + if (string.IsNullOrEmpty(thumbprint)) + { throw new ArgumentNullException(nameof(thumbprint)); } @@ -327,12 +371,15 @@ namespace Microsoft.AspNetCore.Builder { /// The security key. /// The . public static OpenIddictBuilder AddSigningKey( - [NotNull] this OpenIddictBuilder builder, [NotNull] SecurityKey key) { - if (builder == null) { + [NotNull] this OpenIddictBuilder builder, [NotNull] SecurityKey key) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } - if (key == null) { + if (key == null) + { throw new ArgumentNullException(nameof(key)); } @@ -347,8 +394,10 @@ namespace Microsoft.AspNetCore.Builder { /// /// The services builder used by OpenIddict to register new services. /// The . - public static OpenIddictBuilder AllowAuthorizationCodeFlow([NotNull] this OpenIddictBuilder builder) { - if (builder == null) { + public static OpenIddictBuilder AllowAuthorizationCodeFlow([NotNull] this OpenIddictBuilder builder) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } @@ -361,8 +410,10 @@ namespace Microsoft.AspNetCore.Builder { /// /// The services builder used by OpenIddict to register new services. /// The . - public static OpenIddictBuilder AllowClientCredentialsFlow([NotNull] this OpenIddictBuilder builder) { - if (builder == null) { + public static OpenIddictBuilder AllowClientCredentialsFlow([NotNull] this OpenIddictBuilder builder) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } @@ -376,12 +427,15 @@ namespace Microsoft.AspNetCore.Builder { /// The grant type associated with the flow. /// The . public static OpenIddictBuilder AllowCustomFlow( - [NotNull] this OpenIddictBuilder builder, [NotNull] string type) { - if (builder == null) { + [NotNull] this OpenIddictBuilder builder, [NotNull] string type) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } - if (string.IsNullOrEmpty(type)) { + if (string.IsNullOrEmpty(type)) + { throw new ArgumentException("The grant type cannot be null or empty.", nameof(type)); } @@ -396,8 +450,10 @@ namespace Microsoft.AspNetCore.Builder { /// /// The services builder used by OpenIddict to register new services. /// The . - public static OpenIddictBuilder AllowImplicitFlow([NotNull] this OpenIddictBuilder builder) { - if (builder == null) { + public static OpenIddictBuilder AllowImplicitFlow([NotNull] this OpenIddictBuilder builder) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } @@ -410,8 +466,10 @@ namespace Microsoft.AspNetCore.Builder { /// /// The services builder used by OpenIddict to register new services. /// The . - public static OpenIddictBuilder AllowPasswordFlow([NotNull] this OpenIddictBuilder builder) { - if (builder == null) { + public static OpenIddictBuilder AllowPasswordFlow([NotNull] this OpenIddictBuilder builder) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } @@ -424,8 +482,10 @@ namespace Microsoft.AspNetCore.Builder { /// /// The services builder used by OpenIddict to register new services. /// The . - public static OpenIddictBuilder AllowRefreshTokenFlow([NotNull] this OpenIddictBuilder builder) { - if (builder == null) { + public static OpenIddictBuilder AllowRefreshTokenFlow([NotNull] this OpenIddictBuilder builder) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } @@ -437,8 +497,10 @@ namespace Microsoft.AspNetCore.Builder { /// /// The services builder used by OpenIddict to register new services. /// The . - public static OpenIddictBuilder DisableConfigurationEndpoint([NotNull] this OpenIddictBuilder builder) { - if (builder == null) { + public static OpenIddictBuilder DisableConfigurationEndpoint([NotNull] this OpenIddictBuilder builder) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } @@ -450,8 +512,10 @@ namespace Microsoft.AspNetCore.Builder { /// /// The services builder used by OpenIddict to register new services. /// The . - public static OpenIddictBuilder DisableCryptographyEndpoint([NotNull] this OpenIddictBuilder builder) { - if (builder == null) { + public static OpenIddictBuilder DisableCryptographyEndpoint([NotNull] this OpenIddictBuilder builder) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } @@ -463,8 +527,10 @@ namespace Microsoft.AspNetCore.Builder { /// /// The services builder used by OpenIddict to register new services. /// The . - public static OpenIddictBuilder DisableHttpsRequirement([NotNull] this OpenIddictBuilder builder) { - if (builder == null) { + public static OpenIddictBuilder DisableHttpsRequirement([NotNull] this OpenIddictBuilder builder) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } @@ -477,8 +543,10 @@ namespace Microsoft.AspNetCore.Builder { /// /// The services builder used by OpenIddict to register new services. /// The . - public static OpenIddictBuilder DisableSlidingExpiration([NotNull] this OpenIddictBuilder builder) { - if (builder == null) { + public static OpenIddictBuilder DisableSlidingExpiration([NotNull] this OpenIddictBuilder builder) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } @@ -492,8 +560,10 @@ namespace Microsoft.AspNetCore.Builder { /// /// The services builder used by OpenIddict to register new services. /// The . - public static OpenIddictBuilder DisableTokenRevocation([NotNull] this OpenIddictBuilder builder) { - if (builder == null) { + public static OpenIddictBuilder DisableTokenRevocation([NotNull] this OpenIddictBuilder builder) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } @@ -507,12 +577,15 @@ namespace Microsoft.AspNetCore.Builder { /// The relative path of the authorization endpoint. /// The . public static OpenIddictBuilder EnableAuthorizationEndpoint( - [NotNull] this OpenIddictBuilder builder, PathString path) { - if (builder == null) { + [NotNull] this OpenIddictBuilder builder, PathString path) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } - if (!path.HasValue) { + if (!path.HasValue) + { throw new ArgumentException("The path cannot be empty.", nameof(path)); } @@ -526,12 +599,15 @@ namespace Microsoft.AspNetCore.Builder { /// The relative path of the logout endpoint. /// The . public static OpenIddictBuilder EnableIntrospectionEndpoint( - [NotNull] this OpenIddictBuilder builder, PathString path) { - if (builder == null) { + [NotNull] this OpenIddictBuilder builder, PathString path) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } - if (!path.HasValue) { + if (!path.HasValue) + { throw new ArgumentException("The path cannot be empty.", nameof(path)); } @@ -545,12 +621,15 @@ namespace Microsoft.AspNetCore.Builder { /// The relative path of the logout endpoint. /// The . public static OpenIddictBuilder EnableLogoutEndpoint( - [NotNull] this OpenIddictBuilder builder, PathString path) { - if (builder == null) { + [NotNull] this OpenIddictBuilder builder, PathString path) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } - if (!path.HasValue) { + if (!path.HasValue) + { throw new ArgumentException("The path cannot be empty.", nameof(path)); } @@ -566,8 +645,10 @@ namespace Microsoft.AspNetCore.Builder { /// /// The services builder used by OpenIddict to register new services. /// The . - public static OpenIddictBuilder EnableRequestCaching([NotNull] this OpenIddictBuilder builder) { - if (builder == null) { + public static OpenIddictBuilder EnableRequestCaching([NotNull] this OpenIddictBuilder builder) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } @@ -581,12 +662,15 @@ namespace Microsoft.AspNetCore.Builder { /// The relative path of the revocation endpoint. /// The . public static OpenIddictBuilder EnableRevocationEndpoint( - [NotNull] this OpenIddictBuilder builder, PathString path) { - if (builder == null) { + [NotNull] this OpenIddictBuilder builder, PathString path) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } - if (!path.HasValue) { + if (!path.HasValue) + { throw new ArgumentException("The path cannot be empty.", nameof(path)); } @@ -600,12 +684,15 @@ namespace Microsoft.AspNetCore.Builder { /// The relative path of the token endpoint. /// The . public static OpenIddictBuilder EnableTokenEndpoint( - [NotNull] this OpenIddictBuilder builder, PathString path) { - if (builder == null) { + [NotNull] this OpenIddictBuilder builder, PathString path) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } - if (!path.HasValue) { + if (!path.HasValue) + { throw new ArgumentException("The path cannot be empty.", nameof(path)); } @@ -619,12 +706,15 @@ namespace Microsoft.AspNetCore.Builder { /// The relative path of the userinfo endpoint. /// The . public static OpenIddictBuilder EnableUserinfoEndpoint( - [NotNull] this OpenIddictBuilder builder, PathString path) { - if (builder == null) { + [NotNull] this OpenIddictBuilder builder, PathString path) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } - if (!path.HasValue) { + if (!path.HasValue) + { throw new ArgumentException("The path cannot be empty.", nameof(path)); } @@ -638,8 +728,10 @@ namespace Microsoft.AspNetCore.Builder { /// the token and revocation endpoints, but specifying a client_id is required. /// /// The services builder used by OpenIddict to register new services. - public static OpenIddictBuilder RequireClientIdentification([NotNull] this OpenIddictBuilder builder) { - if (builder == null) { + public static OpenIddictBuilder RequireClientIdentification([NotNull] this OpenIddictBuilder builder) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } @@ -656,8 +748,10 @@ namespace Microsoft.AspNetCore.Builder { /// The access token lifetime. /// The . public static OpenIddictBuilder SetAccessTokenLifetime( - [NotNull] this OpenIddictBuilder builder, TimeSpan lifetime) { - if (builder == null) { + [NotNull] this OpenIddictBuilder builder, TimeSpan lifetime) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } @@ -673,8 +767,10 @@ namespace Microsoft.AspNetCore.Builder { /// The authorization code lifetime. /// The . public static OpenIddictBuilder SetAuthorizationCodeLifetime( - [NotNull] this OpenIddictBuilder builder, TimeSpan lifetime) { - if (builder == null) { + [NotNull] this OpenIddictBuilder builder, TimeSpan lifetime) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } @@ -689,8 +785,10 @@ namespace Microsoft.AspNetCore.Builder { /// The identity token lifetime. /// The . public static OpenIddictBuilder SetIdentityTokenLifetime( - [NotNull] this OpenIddictBuilder builder, TimeSpan lifetime) { - if (builder == null) { + [NotNull] this OpenIddictBuilder builder, TimeSpan lifetime) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } @@ -707,8 +805,10 @@ namespace Microsoft.AspNetCore.Builder { /// The refresh token lifetime. /// The . public static OpenIddictBuilder SetRefreshTokenLifetime( - [NotNull] this OpenIddictBuilder builder, TimeSpan lifetime) { - if (builder == null) { + [NotNull] this OpenIddictBuilder builder, TimeSpan lifetime) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } @@ -723,12 +823,15 @@ namespace Microsoft.AspNetCore.Builder { /// The issuer address. /// The . public static OpenIddictBuilder SetIssuer( - [NotNull] this OpenIddictBuilder builder, [NotNull] Uri address) { - if (builder == null) { + [NotNull] this OpenIddictBuilder builder, [NotNull] Uri address) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } - if (address == null) { + if (address == null) + { throw new ArgumentNullException(nameof(address)); } @@ -743,12 +846,15 @@ namespace Microsoft.AspNetCore.Builder { /// The data protection provider used to create token protectors. /// The . public static OpenIddictBuilder UseDataProtectionProvider( - [NotNull] this OpenIddictBuilder builder, [NotNull] IDataProtectionProvider provider) { - if (builder == null) { + [NotNull] this OpenIddictBuilder builder, [NotNull] IDataProtectionProvider provider) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } - if (provider == null) { + if (provider == null) + { throw new ArgumentNullException(nameof(provider)); } @@ -760,8 +866,10 @@ namespace Microsoft.AspNetCore.Builder { /// /// The services builder used by OpenIddict to register new services. /// The . - public static OpenIddictBuilder UseJsonWebTokens([NotNull] this OpenIddictBuilder builder) { - if (builder == null) { + public static OpenIddictBuilder UseJsonWebTokens([NotNull] this OpenIddictBuilder builder) + { + if (builder == null) + { throw new ArgumentNullException(nameof(builder)); } diff --git a/src/OpenIddict/OpenIddictOptions.cs b/src/OpenIddict/OpenIddictOptions.cs index 1fb050db..0960ae63 100644 --- a/src/OpenIddict/OpenIddictOptions.cs +++ b/src/OpenIddict/OpenIddictOptions.cs @@ -9,12 +9,15 @@ using System.Collections.Generic; using AspNet.Security.OpenIdConnect.Server; using Microsoft.Extensions.Caching.Distributed; -namespace OpenIddict { +namespace OpenIddict +{ /// /// Provides various settings needed to configure OpenIddict. /// - public class OpenIddictOptions : OpenIdConnectServerOptions { - public OpenIddictOptions() { + public class OpenIddictOptions : OpenIdConnectServerOptions + { + public OpenIddictOptions() + { Provider = null; } diff --git a/src/OpenIddict/OpenIddictProvider.Authentication.cs b/src/OpenIddict/OpenIddictProvider.Authentication.cs index 94a3a5a1..a54f3d92 100644 --- a/src/OpenIddict/OpenIddictProvider.Authentication.cs +++ b/src/OpenIddict/OpenIddictProvider.Authentication.cs @@ -22,15 +22,19 @@ using Newtonsoft.Json.Bson; using Newtonsoft.Json.Linq; using OpenIddict.Core; -namespace OpenIddict { +namespace OpenIddict +{ public partial class OpenIddictProvider : OpenIdConnectServerProvider - where TApplication : class where TAuthorization : class where TScope : class where TToken : class { - public override async Task ExtractAuthorizationRequest([NotNull] ExtractAuthorizationRequestContext context) { + where TApplication : class where TAuthorization : class where TScope : class where TToken : class + { + public override async Task ExtractAuthorizationRequest([NotNull] ExtractAuthorizationRequestContext context) + { var logger = context.HttpContext.RequestServices.GetRequiredService>>(); var options = context.HttpContext.RequestServices.GetRequiredService>(); // Reject requests using the unsupported request parameter. - if (!string.IsNullOrEmpty(context.Request.Request)) { + if (!string.IsNullOrEmpty(context.Request.Request)) + { logger.LogError("The authorization request was rejected because it contained " + "an unsupported parameter: {Parameter}.", "request"); @@ -42,7 +46,8 @@ namespace OpenIddict { } // Reject requests using the unsupported request_uri parameter. - if (!string.IsNullOrEmpty(context.Request.RequestUri)) { + if (!string.IsNullOrEmpty(context.Request.RequestUri)) + { logger.LogError("The authorization request was rejected because it contained " + "an unsupported parameter: {Parameter}.", "request_uri"); @@ -55,9 +60,11 @@ namespace OpenIddict { // If a request_id parameter can be found in the authorization request, // restore the complete authorization request from the distributed cache. - if (!string.IsNullOrEmpty(context.Request.RequestId)) { + if (!string.IsNullOrEmpty(context.Request.RequestId)) + { // Return an error if request caching support was not enabled. - if (!options.Value.EnableRequestCaching) { + if (!options.Value.EnableRequestCaching) + { logger.LogError("The authorization request was rejected because " + "request caching support was not enabled."); @@ -73,7 +80,8 @@ namespace OpenIddict { var key = OpenIddictConstants.Environment.AuthorizationRequest + context.Request.RequestId; var payload = await options.Value.Cache.GetAsync(key); - if (payload == null) { + if (payload == null) + { logger.LogError("The authorization request was rejected because an unknown " + "or invalid request_id parameter was specified."); @@ -85,10 +93,13 @@ namespace OpenIddict { } // Restore the authorization request parameters from the serialized payload. - using (var reader = new BsonReader(new MemoryStream(payload))) { - foreach (var parameter in JObject.Load(reader)) { + using (var reader = new BsonReader(new MemoryStream(payload))) + { + foreach (var parameter in JObject.Load(reader)) + { // Avoid overriding the current request parameters. - if (context.Request.HasParameter(parameter.Key)) { + if (context.Request.HasParameter(parameter.Key)) + { continue; } @@ -98,7 +109,8 @@ namespace OpenIddict { } } - public override async Task ValidateAuthorizationRequest([NotNull] ValidateAuthorizationRequestContext context) { + public override async Task ValidateAuthorizationRequest([NotNull] ValidateAuthorizationRequestContext context) + { var applications = context.HttpContext.RequestServices.GetRequiredService>(); var logger = context.HttpContext.RequestServices.GetRequiredService>>(); var options = context.HttpContext.RequestServices.GetRequiredService>(); @@ -106,7 +118,8 @@ namespace OpenIddict { // Note: the OpenID Connect server middleware supports authorization code, implicit, hybrid, // none and custom flows but OpenIddict uses a stricter policy rejecting unknown flows. if (!context.Request.IsAuthorizationCodeFlow() && !context.Request.IsHybridFlow() && - !context.Request.IsImplicitFlow() && !context.Request.IsNoneFlow()) { + !context.Request.IsImplicitFlow() && !context.Request.IsNoneFlow()) + { logger.LogError("The authorization request was rejected because the '{ResponseType}' " + "response type is not supported.", context.Request.ResponseType); @@ -119,7 +132,8 @@ namespace OpenIddict { // Reject code flow authorization requests if the authorization code flow is not enabled. if (context.Request.IsAuthorizationCodeFlow() && - !options.Value.GrantTypes.Contains(OpenIdConnectConstants.GrantTypes.AuthorizationCode)) { + !options.Value.GrantTypes.Contains(OpenIdConnectConstants.GrantTypes.AuthorizationCode)) + { logger.LogError("The authorization request was rejected because " + "the authorization code flow was not enabled."); @@ -131,7 +145,8 @@ namespace OpenIddict { } // Reject implicit flow authorization requests if the implicit flow is not enabled. - if (context.Request.IsImplicitFlow() && !options.Value.GrantTypes.Contains(OpenIdConnectConstants.GrantTypes.Implicit)) { + if (context.Request.IsImplicitFlow() && !options.Value.GrantTypes.Contains(OpenIdConnectConstants.GrantTypes.Implicit)) + { logger.LogError("The authorization request was rejected because the implicit flow was not enabled."); context.Reject( @@ -143,7 +158,8 @@ namespace OpenIddict { // Reject hybrid flow authorization requests if the authorization code or the implicit flows are not enabled. if (context.Request.IsHybridFlow() && (!options.Value.GrantTypes.Contains(OpenIdConnectConstants.GrantTypes.AuthorizationCode) || - !options.Value.GrantTypes.Contains(OpenIdConnectConstants.GrantTypes.Implicit))) { + !options.Value.GrantTypes.Contains(OpenIdConnectConstants.GrantTypes.Implicit))) + { logger.LogError("The authorization request was rejected because the " + "authorization code flow or the implicit flow was not enabled."); @@ -156,7 +172,8 @@ namespace OpenIddict { // Reject authorization requests that specify scope=offline_access if the refresh token flow is not enabled. if (context.Request.HasScope(OpenIdConnectConstants.Scopes.OfflineAccess) && - !options.Value.GrantTypes.Contains(OpenIdConnectConstants.GrantTypes.RefreshToken)) { + !options.Value.GrantTypes.Contains(OpenIdConnectConstants.GrantTypes.RefreshToken)) + { context.Reject( error: OpenIdConnectConstants.Errors.InvalidRequest, description: "The 'offline_access' scope is not allowed."); @@ -169,7 +186,8 @@ namespace OpenIddict { // To ensure authorization requests are rejected early enough, an additional check is made by OpenIddict. if (!string.IsNullOrEmpty(context.Request.ResponseMode) && !context.Request.IsFormPostResponseMode() && !context.Request.IsFragmentResponseMode() && - !context.Request.IsQueryResponseMode()) { + !context.Request.IsQueryResponseMode()) + { logger.LogError("The authorization request was rejected because the '{ResponseMode}' " + "response mode is not supported.", context.Request.ResponseMode); @@ -184,7 +202,8 @@ namespace OpenIddict { // but this provider uses a stricter policy making it mandatory, // as required by the OpenID Connect core specification. // See http://openid.net/specs/openid-connect-core-1_0.html#AuthRequest. - if (string.IsNullOrEmpty(context.RedirectUri)) { + if (string.IsNullOrEmpty(context.RedirectUri)) + { context.Reject( error: OpenIdConnectConstants.Errors.InvalidRequest, description: "The required redirect_uri parameter was missing."); @@ -194,10 +213,12 @@ namespace OpenIddict { // Note: the OpenID Connect server middleware always ensures a // code_challenge_method can't be specified without code_challenge. - if (!string.IsNullOrEmpty(context.Request.CodeChallenge)) { + if (!string.IsNullOrEmpty(context.Request.CodeChallenge)) + { // Since the default challenge method (plain) is explicitly disallowed, // reject the authorization request if the code_challenge_method is missing. - if (string.IsNullOrEmpty(context.Request.CodeChallengeMethod)) { + if (string.IsNullOrEmpty(context.Request.CodeChallengeMethod)) + { logger.LogError("The authorization request was rejected because the " + "required 'code_challenge_method' parameter was missing."); @@ -210,7 +231,8 @@ namespace OpenIddict { // Disallow the use of the unsecure code_challenge_method=plain method. // See https://tools.ietf.org/html/rfc7636#section-7.2 for more information. - if (string.Equals(context.Request.CodeChallengeMethod, OpenIdConnectConstants.CodeChallengeMethods.Plain)) { + if (string.Equals(context.Request.CodeChallengeMethod, OpenIdConnectConstants.CodeChallengeMethods.Plain)) + { logger.LogError("The authorization request was rejected because the " + "'code_challenge_method' parameter was set to 'plain'."); @@ -222,7 +244,8 @@ namespace OpenIddict { } // Reject authorization requests that contain response_type=token when a code_challenge is specified. - if (context.Request.HasResponseType(OpenIdConnectConstants.ResponseTypes.Token)) { + if (context.Request.HasResponseType(OpenIdConnectConstants.ResponseTypes.Token)) + { logger.LogError("The authorization request was rejected because the " + "specified response type was not compatible with PKCE."); @@ -236,7 +259,8 @@ namespace OpenIddict { // Retrieve the application details corresponding to the requested client_id. var application = await applications.FindByClientIdAsync(context.ClientId, context.HttpContext.RequestAborted); - if (application == null) { + if (application == null) + { logger.LogError("The authorization request was rejected because the client " + "application was not found: '{ClientId}'.", context.ClientId); @@ -248,7 +272,8 @@ namespace OpenIddict { } // Ensure a redirect_uri was associated with the application. - if (!await applications.HasRedirectUriAsync(application, context.HttpContext.RequestAborted)) { + if (!await applications.HasRedirectUriAsync(application, context.HttpContext.RequestAborted)) + { logger.LogError("The authorization request was rejected because no redirect_uri " + "was registered with the application '{ClientId}'.", context.ClientId); @@ -260,7 +285,8 @@ namespace OpenIddict { } // Ensure the redirect_uri is valid. - if (!await applications.ValidateRedirectUriAsync(application, context.RedirectUri, context.HttpContext.RequestAborted)) { + if (!await applications.ValidateRedirectUriAsync(application, context.RedirectUri, context.HttpContext.RequestAborted)) + { logger.LogError("The authorization request was rejected because the redirect_uri " + "was invalid: '{RedirectUri}'.", context.RedirectUri); @@ -276,7 +302,8 @@ namespace OpenIddict { // Note: when using the authorization code grant, ValidateTokenRequest is responsible of rejecting // the token request if the client_id corresponds to an unauthenticated confidential client. if (await applications.IsConfidentialAsync(application, context.HttpContext.RequestAborted) && - context.Request.HasResponseType(OpenIdConnectConstants.ResponseTypes.Token)) { + context.Request.HasResponseType(OpenIdConnectConstants.ResponseTypes.Token)) + { context.Reject( error: OpenIdConnectConstants.Errors.InvalidRequest, description: "Confidential clients are not allowed to retrieve " + @@ -288,20 +315,23 @@ namespace OpenIddict { context.Validate(); } - public override async Task HandleAuthorizationRequest([NotNull] HandleAuthorizationRequestContext context) { + public override async Task HandleAuthorizationRequest([NotNull] HandleAuthorizationRequestContext context) + { var options = context.HttpContext.RequestServices.GetRequiredService>(); // If no request_id parameter can be found in the current request, assume the OpenID Connect request // was not serialized yet and store the entire payload in the distributed cache to make it easier // to flow across requests and internal/external authentication/registration workflows. - if (options.Value.EnableRequestCaching && string.IsNullOrEmpty(context.Request.RequestId)) { + if (options.Value.EnableRequestCaching && string.IsNullOrEmpty(context.Request.RequestId)) + { // Generate a request identifier. Note: using a crypto-secure // random number generator is not necessary in this case. context.Request.RequestId = Guid.NewGuid().ToString(); // Store the serialized authorization request parameters in the distributed cache. var stream = new MemoryStream(); - using (var writer = new BsonWriter(stream)) { + using (var writer = new BsonWriter(stream)) + { writer.CloseOutput = false; var serializer = JsonSerializer.CreateDefault(); @@ -312,7 +342,8 @@ namespace OpenIddict { // to avoid collisions with the other types of cached requests. var key = OpenIddictConstants.Environment.AuthorizationRequest + context.Request.RequestId; - await options.Value.Cache.SetAsync(key, stream.ToArray(), new DistributedCacheEntryOptions { + await options.Value.Cache.SetAsync(key, stream.ToArray(), new DistributedCacheEntryOptions + { AbsoluteExpiration = context.Options.SystemClock.UtcNow + TimeSpan.FromMinutes(30), SlidingExpiration = TimeSpan.FromMinutes(10) }); @@ -335,11 +366,13 @@ namespace OpenIddict { context.SkipToNextMiddleware(); } - public override async Task ApplyAuthorizationResponse([NotNull] ApplyAuthorizationResponseContext context) { + public override async Task ApplyAuthorizationResponse([NotNull] ApplyAuthorizationResponseContext context) + { var options = context.HttpContext.RequestServices.GetRequiredService>(); // Remove the authorization request from the distributed cache. - if (options.Value.EnableRequestCaching && !string.IsNullOrEmpty(context.Request.RequestId)) { + if (options.Value.EnableRequestCaching && !string.IsNullOrEmpty(context.Request.RequestId)) + { // Note: the cache key is always prefixed with a specific marker // to avoid collisions with the other types of cached requests. var key = OpenIddictConstants.Environment.AuthorizationRequest + context.Request.RequestId; @@ -351,12 +384,14 @@ namespace OpenIddict { } if (!options.Value.ApplicationCanDisplayErrors && !string.IsNullOrEmpty(context.Response.Error) && - string.IsNullOrEmpty(context.Response.RedirectUri)) { + string.IsNullOrEmpty(context.Response.RedirectUri)) + { // Determine if the status code pages middleware has been enabled for this request. // If it was not registered or enabled, let the OpenID Connect server middleware render // a default error page instead of delegating the rendering to the status code middleware. var feature = context.HttpContext.Features.Get(); - if (feature != null && feature.Enabled) { + if (feature != null && feature.Enabled) + { // Replace the default status code to return a 400 response. context.HttpContext.Response.StatusCode = 400; diff --git a/src/OpenIddict/OpenIddictProvider.Discovery.cs b/src/OpenIddict/OpenIddictProvider.Discovery.cs index 9bbc1f7f..7e04869c 100644 --- a/src/OpenIddict/OpenIddictProvider.Discovery.cs +++ b/src/OpenIddict/OpenIddictProvider.Discovery.cs @@ -9,16 +9,18 @@ using System.Threading.Tasks; using AspNet.Security.OpenIdConnect.Primitives; using AspNet.Security.OpenIdConnect.Server; using JetBrains.Annotations; -using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Newtonsoft.Json.Linq; using OpenIddict.Core; -namespace OpenIddict { +namespace OpenIddict +{ public partial class OpenIddictProvider : OpenIdConnectServerProvider - where TApplication : class where TAuthorization : class where TScope : class where TToken : class { - public override Task HandleConfigurationRequest([NotNull] HandleConfigurationRequestContext context) { + where TApplication : class where TAuthorization : class where TScope : class where TToken : class + { + public override Task HandleConfigurationRequest([NotNull] HandleConfigurationRequestContext context) + { var options = context.HttpContext.RequestServices.GetRequiredService>(); // Note: though it's natively supported by the OpenID Connect server middleware, @@ -40,7 +42,8 @@ namespace OpenIddict { context.Scopes.Add(OpenIddictConstants.Scopes.Roles); // Only add the "offline_access" scope if the refresh token grant is enabled. - if (context.GrantTypes.Contains(OpenIdConnectConstants.GrantTypes.RefreshToken)) { + if (context.GrantTypes.Contains(OpenIdConnectConstants.GrantTypes.RefreshToken)) + { context.Scopes.Add(OpenIdConnectConstants.Scopes.OfflineAccess); } diff --git a/src/OpenIddict/OpenIddictProvider.Exchange.cs b/src/OpenIddict/OpenIddictProvider.Exchange.cs index fa057b74..56c9471d 100644 --- a/src/OpenIddict/OpenIddictProvider.Exchange.cs +++ b/src/OpenIddict/OpenIddictProvider.Exchange.cs @@ -15,16 +15,20 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using OpenIddict.Core; -namespace OpenIddict { +namespace OpenIddict +{ public partial class OpenIddictProvider : OpenIdConnectServerProvider - where TApplication : class where TAuthorization : class where TScope : class where TToken : class { - public override async Task ValidateTokenRequest([NotNull] ValidateTokenRequestContext context) { + where TApplication : class where TAuthorization : class where TScope : class where TToken : class + { + public override async Task ValidateTokenRequest([NotNull] ValidateTokenRequestContext context) + { var applications = context.HttpContext.RequestServices.GetRequiredService>(); var logger = context.HttpContext.RequestServices.GetRequiredService>>(); var options = context.HttpContext.RequestServices.GetRequiredService>(); // Reject token requests that don't specify a supported grant type. - if (!options.Value.GrantTypes.Contains(context.Request.GrantType)) { + if (!options.Value.GrantTypes.Contains(context.Request.GrantType)) + { logger.LogError("The token request was rejected because the '{Grant}' " + "grant is not supported.", context.Request.GrantType); @@ -37,7 +41,8 @@ namespace OpenIddict { // Reject token requests that specify scope=offline_access if the refresh token flow is not enabled. if (context.Request.HasScope(OpenIdConnectConstants.Scopes.OfflineAccess) && - !options.Value.GrantTypes.Contains(OpenIdConnectConstants.GrantTypes.RefreshToken)) { + !options.Value.GrantTypes.Contains(OpenIdConnectConstants.GrantTypes.RefreshToken)) + { context.Reject( error: OpenIdConnectConstants.Errors.InvalidRequest, description: "The 'offline_access' scope is not allowed."); @@ -51,7 +56,8 @@ namespace OpenIddict { // that rejects grant_type=client_credentials requests containing the 'offline_access' scope. // See https://tools.ietf.org/html/rfc6749#section-4.4.3 for more information. if (context.Request.IsClientCredentialsGrantType() && - context.Request.HasScope(OpenIdConnectConstants.Scopes.OfflineAccess)) { + context.Request.HasScope(OpenIdConnectConstants.Scopes.OfflineAccess)) + { context.Reject( error: OpenIdConnectConstants.Errors.InvalidRequest, description: "The 'offline_access' scope is not allowed when using grant_type=client_credentials."); @@ -63,7 +69,8 @@ namespace OpenIddict { // when validation is skipped but an early check is made here to avoid making unnecessary // database roundtrips to retrieve the client application corresponding to the client_id. if (context.Request.IsClientCredentialsGrantType() && (string.IsNullOrEmpty(context.Request.ClientId) || - string.IsNullOrEmpty(context.Request.ClientSecret))) { + string.IsNullOrEmpty(context.Request.ClientSecret))) + { logger.LogError("The token request was rejected because the client credentials were missing."); context.Reject( @@ -85,9 +92,11 @@ namespace OpenIddict { // Note: the OpenID Connect server middleware will automatically ensure that // the calling application cannot use an authorization code or a refresh token // if it's not the intended audience, even if client authentication was skipped. - if (string.IsNullOrEmpty(context.ClientId)) { + if (string.IsNullOrEmpty(context.ClientId)) + { // Reject the request if client identification is mandatory. - if (options.Value.RequireClientIdentification) { + if (options.Value.RequireClientIdentification) + { logger.LogError("The token request was rejected becaused the " + "mandatory client_id parameter was missing or empty."); @@ -108,7 +117,8 @@ namespace OpenIddict { // Retrieve the application details corresponding to the requested client_id. var application = await applications.FindByClientIdAsync(context.ClientId, context.HttpContext.RequestAborted); - if (application == null) { + if (application == null) + { logger.LogError("The token request was rejected because the client " + "application was not found: '{ClientId}'.", context.ClientId); @@ -119,9 +129,11 @@ namespace OpenIddict { return; } - if (await applications.IsPublicAsync(application, context.HttpContext.RequestAborted)) { + if (await applications.IsPublicAsync(application, context.HttpContext.RequestAborted)) + { // Note: public applications are not allowed to use the client credentials grant. - if (context.Request.IsClientCredentialsGrantType()) { + if (context.Request.IsClientCredentialsGrantType()) + { logger.LogError("The token request was rejected because the public client application '{ClientId}' " + "was not allowed to use the client credentials grant.", context.Request.ClientId); @@ -133,7 +145,8 @@ namespace OpenIddict { } // Reject tokens requests containing a client_secret when the client is a public application. - if (!string.IsNullOrEmpty(context.ClientSecret)) { + if (!string.IsNullOrEmpty(context.ClientSecret)) + { logger.LogError("The token request was rejected because the public application '{ClientId}' " + "was not allowed to send a client secret.", context.ClientId); @@ -156,7 +169,8 @@ namespace OpenIddict { // Confidential applications MUST authenticate // to protect them from impersonation attacks. - if (string.IsNullOrEmpty(context.ClientSecret)) { + if (string.IsNullOrEmpty(context.ClientSecret)) + { logger.LogError("The token request was rejected because the confidential application " + "'{ClientId}' didn't specify a client secret.", context.ClientId); @@ -167,7 +181,8 @@ namespace OpenIddict { return; } - if (!await applications.ValidateClientSecretAsync(application, context.ClientSecret, context.HttpContext.RequestAborted)) { + if (!await applications.ValidateClientSecretAsync(application, context.ClientSecret, context.HttpContext.RequestAborted)) + { logger.LogError("The token request was rejected because the confidential application " + "'{ClientId}' didn't specify valid client credentials.", context.ClientId); @@ -181,13 +196,15 @@ namespace OpenIddict { context.Validate(); } - public override async Task HandleTokenRequest([NotNull] HandleTokenRequestContext context) { + public override async Task HandleTokenRequest([NotNull] HandleTokenRequestContext context) + { var options = context.HttpContext.RequestServices.GetRequiredService>(); var logger = context.HttpContext.RequestServices.GetRequiredService>>(); var tokens = context.HttpContext.RequestServices.GetRequiredService>(); if (!options.Value.DisableTokenRevocation && (context.Request.IsAuthorizationCodeGrantType() || - context.Request.IsRefreshTokenGrantType())) { + context.Request.IsRefreshTokenGrantType())) + { Debug.Assert(context.Ticket != null, "The authentication ticket shouldn't be null."); // Extract the token identifier from the authentication ticket. @@ -195,10 +212,12 @@ namespace OpenIddict { Debug.Assert(!string.IsNullOrEmpty(identifier), "The authentication ticket should contain a ticket identifier."); - if (context.Request.IsAuthorizationCodeGrantType()) { + if (context.Request.IsAuthorizationCodeGrantType()) + { // Retrieve the token from the database and ensure it is still valid. var token = await tokens.FindByIdAsync(identifier, context.HttpContext.RequestAborted); - if (token == null) { + if (token == null) + { logger.LogError("The token request was rejected because the authorization code was revoked."); context.Reject( @@ -212,10 +231,12 @@ namespace OpenIddict { await tokens.RevokeAsync(token, context.HttpContext.RequestAborted); } - else if (context.Request.IsRefreshTokenGrantType()) { + else if (context.Request.IsRefreshTokenGrantType()) + { // Retrieve the token from the database and ensure it is still valid. var token = await tokens.FindByIdAsync(identifier, context.HttpContext.RequestAborted); - if (token == null) { + if (token == null) + { logger.LogError("The token request was rejected because the refresh token was revoked."); context.Reject( @@ -228,7 +249,8 @@ namespace OpenIddict { // When sliding expiration is enabled, immediately // revoke the refresh token to prevent future reuse. // See https://tools.ietf.org/html/rfc6749#section-6. - if (context.Options.UseSlidingExpiration) { + if (context.Options.UseSlidingExpiration) + { await tokens.RevokeAsync(token, context.HttpContext.RequestAborted); } } diff --git a/src/OpenIddict/OpenIddictProvider.Introspection.cs b/src/OpenIddict/OpenIddictProvider.Introspection.cs index 9925df9b..868373e3 100644 --- a/src/OpenIddict/OpenIddictProvider.Introspection.cs +++ b/src/OpenIddict/OpenIddictProvider.Introspection.cs @@ -16,13 +16,17 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using OpenIddict.Core; -namespace OpenIddict { +namespace OpenIddict +{ public partial class OpenIddictProvider : OpenIdConnectServerProvider - where TApplication : class where TAuthorization : class where TScope : class where TToken : class { - public override Task ExtractIntrospectionRequest([NotNull] ExtractIntrospectionRequestContext context) { + where TApplication : class where TAuthorization : class where TScope : class where TToken : class + { + public override Task ExtractIntrospectionRequest([NotNull] ExtractIntrospectionRequestContext context) + { // Note: the OpenID Connect server middleware supports both GET and POST // introspection requests but OpenIddict only accepts POST requests. - if (!string.Equals(context.HttpContext.Request.Method, "POST", StringComparison.OrdinalIgnoreCase)) { + if (!string.Equals(context.HttpContext.Request.Method, "POST", StringComparison.OrdinalIgnoreCase)) + { context.Reject( error: OpenIdConnectConstants.Errors.InvalidRequest, description: "Introspection requests must use HTTP POST."); @@ -33,7 +37,8 @@ namespace OpenIddict { return Task.FromResult(0); } - public override async Task ValidateIntrospectionRequest([NotNull] ValidateIntrospectionRequestContext context) { + public override async Task ValidateIntrospectionRequest([NotNull] ValidateIntrospectionRequestContext context) + { var applications = context.HttpContext.RequestServices.GetRequiredService>(); var logger = context.HttpContext.RequestServices.GetRequiredService>>(); @@ -41,7 +46,8 @@ namespace OpenIddict { // but OpenIddict uses a stricter policy preventing unauthenticated/public applications // from using the introspection endpoint, as required by the specifications. // See https://tools.ietf.org/html/rfc7662#section-2.1 for more information. - if (string.IsNullOrEmpty(context.ClientId) || string.IsNullOrEmpty(context.ClientSecret)) { + if (string.IsNullOrEmpty(context.ClientId) || string.IsNullOrEmpty(context.ClientSecret)) + { context.Reject( error: OpenIdConnectConstants.Errors.InvalidRequest, description: "Clients must be authenticated to use the introspection endpoint."); @@ -51,7 +57,8 @@ namespace OpenIddict { // Retrieve the application details corresponding to the requested client_id. var application = await applications.FindByClientIdAsync(context.ClientId, context.HttpContext.RequestAborted); - if (application == null) { + if (application == null) + { logger.LogError("The introspection request was rejected because the client " + "application was not found: '{ClientId}'.", context.ClientId); @@ -63,7 +70,8 @@ namespace OpenIddict { } // Reject non-confidential applications. - if (!await applications.IsConfidentialAsync(application, context.HttpContext.RequestAborted)) { + if (!await applications.IsConfidentialAsync(application, context.HttpContext.RequestAborted)) + { logger.LogError("The introspection request was rejected because the public application " + "'{ClientId}' was not allowed to use this endpoint.", context.ClientId); @@ -75,7 +83,8 @@ namespace OpenIddict { } // Validate the client credentials. - if (!await applications.ValidateClientSecretAsync(application, context.ClientSecret, context.HttpContext.RequestAborted)) { + if (!await applications.ValidateClientSecretAsync(application, context.ClientSecret, context.HttpContext.RequestAborted)) + { logger.LogError("The introspection request was rejected because the confidential application " + "'{ClientId}' didn't specify valid client credentials.", context.ClientId); @@ -89,7 +98,8 @@ namespace OpenIddict { context.Validate(); } - public override async Task HandleIntrospectionRequest([NotNull] HandleIntrospectionRequestContext context) { + public override async Task HandleIntrospectionRequest([NotNull] HandleIntrospectionRequestContext context) + { var options = context.HttpContext.RequestServices.GetRequiredService>(); var logger = context.HttpContext.RequestServices.GetRequiredService>>(); var tokens = context.HttpContext.RequestServices.GetRequiredService>(); @@ -100,7 +110,8 @@ namespace OpenIddict { // Note: the OpenID Connect server middleware allows authorized presenters (e.g relying parties) to introspect access tokens // but OpenIddict uses a stricter policy that only allows resource servers to use the introspection endpoint, unless the ticket // doesn't have any audience: in this case, the caller is allowed to introspect the token even if it's not listed as a valid audience. - if (context.Ticket.IsAccessToken() && context.Ticket.HasAudience() && !context.Ticket.HasAudience(context.Request.ClientId)) { + if (context.Ticket.IsAccessToken() && context.Ticket.HasAudience() && !context.Ticket.HasAudience(context.Request.ClientId)) + { logger.LogWarning("The client application '{ClientId}' is not allowed to introspect the access " + "token '{Identifier}' because it's not listed as a valid audience.", context.Request.ClientId, context.Ticket.GetTicketId()); @@ -111,11 +122,13 @@ namespace OpenIddict { } // When the received ticket is revocable, ensure it is still valid. - if (!options.Value.DisableTokenRevocation && (context.Ticket.IsAuthorizationCode() || context.Ticket.IsRefreshToken())) { + if (!options.Value.DisableTokenRevocation && (context.Ticket.IsAuthorizationCode() || context.Ticket.IsRefreshToken())) + { // Retrieve the token from the database using the unique identifier stored in the authentication ticket: // if the corresponding entry cannot be found, return Active = false to indicate that is is no longer valid. var token = await tokens.FindByIdAsync(context.Ticket.GetTicketId(), context.HttpContext.RequestAborted); - if (token == null) { + if (token == null) + { logger.LogInformation("The token {Identifier} was declared as inactive because " + "it was revoked.", context.Ticket.GetTicketId()); diff --git a/src/OpenIddict/OpenIddictProvider.Revocation.cs b/src/OpenIddict/OpenIddictProvider.Revocation.cs index 2ef8bdf3..eefa3fb1 100644 --- a/src/OpenIddict/OpenIddictProvider.Revocation.cs +++ b/src/OpenIddict/OpenIddictProvider.Revocation.cs @@ -15,10 +15,13 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using OpenIddict.Core; -namespace OpenIddict { +namespace OpenIddict +{ public partial class OpenIddictProvider : OpenIdConnectServerProvider - where TApplication : class where TAuthorization : class where TScope : class where TToken : class { - public override async Task ValidateRevocationRequest([NotNull] ValidateRevocationRequestContext context) { + where TApplication : class where TAuthorization : class where TScope : class where TToken : class + { + public override async Task ValidateRevocationRequest([NotNull] ValidateRevocationRequestContext context) + { var applications = context.HttpContext.RequestServices.GetRequiredService>(); var logger = context.HttpContext.RequestServices.GetRequiredService>>(); var options = context.HttpContext.RequestServices.GetRequiredService>(); @@ -28,7 +31,8 @@ namespace OpenIddict { // When token_type_hint is specified, reject the request if it doesn't correspond to a revocable token. if (!string.IsNullOrEmpty(context.Request.TokenTypeHint) && !string.Equals(context.Request.TokenTypeHint, OpenIdConnectConstants.TokenTypeHints.AuthorizationCode) && - !string.Equals(context.Request.TokenTypeHint, OpenIdConnectConstants.TokenTypeHints.RefreshToken)) { + !string.Equals(context.Request.TokenTypeHint, OpenIdConnectConstants.TokenTypeHints.RefreshToken)) + { context.Reject( error: OpenIdConnectConstants.Errors.UnsupportedTokenType, description: "Only authorization codes and refresh tokens can be revoked. When specifying a token_type_hint " + @@ -42,9 +46,11 @@ namespace OpenIddict { // Note: the OpenID Connect server middleware will automatically ensure that // the calling application cannot revoke a refresh token if it's not // the intended audience, even if client authentication was skipped. - if (string.IsNullOrEmpty(context.ClientId)) { + if (string.IsNullOrEmpty(context.ClientId)) + { // Reject the request if client identification is mandatory. - if (options.Value.RequireClientIdentification) { + if (options.Value.RequireClientIdentification) + { logger.LogError("The revocation request was rejected becaused the " + "mandatory client_id parameter was missing or empty."); @@ -65,7 +71,8 @@ namespace OpenIddict { // Retrieve the application details corresponding to the requested client_id. var application = await applications.FindByClientIdAsync(context.ClientId, context.HttpContext.RequestAborted); - if (application == null) { + if (application == null) + { context.Reject( error: OpenIdConnectConstants.Errors.InvalidClient, description: "Application not found in the database: ensure that your client_id is correct."); @@ -74,9 +81,11 @@ namespace OpenIddict { } // Reject revocation requests containing a client_secret if the client application is not confidential. - if (await applications.IsPublicAsync(application, context.HttpContext.RequestAborted)) { + if (await applications.IsPublicAsync(application, context.HttpContext.RequestAborted)) + { // Reject tokens requests containing a client_secret when the client is a public application. - if (!string.IsNullOrEmpty(context.ClientSecret)) { + if (!string.IsNullOrEmpty(context.ClientSecret)) + { context.Reject( error: OpenIdConnectConstants.Errors.InvalidRequest, description: "Public clients are not allowed to send a client_secret."); @@ -96,7 +105,8 @@ namespace OpenIddict { // Confidential applications MUST authenticate // to protect them from impersonation attacks. - if (string.IsNullOrEmpty(context.ClientSecret)) { + if (string.IsNullOrEmpty(context.ClientSecret)) + { context.Reject( error: OpenIdConnectConstants.Errors.InvalidClient, description: "Missing credentials: ensure that you specified a client_secret."); @@ -104,7 +114,8 @@ namespace OpenIddict { return; } - if (!await applications.ValidateClientSecretAsync(application, context.ClientSecret, context.HttpContext.RequestAborted)) { + if (!await applications.ValidateClientSecretAsync(application, context.ClientSecret, context.HttpContext.RequestAborted)) + { context.Reject( error: OpenIdConnectConstants.Errors.InvalidClient, description: "Invalid credentials: ensure that you specified a correct client_secret."); @@ -115,7 +126,8 @@ namespace OpenIddict { context.Validate(); } - public override async Task HandleRevocationRequest([NotNull] HandleRevocationRequestContext context) { + public override async Task HandleRevocationRequest([NotNull] HandleRevocationRequestContext context) + { var logger = context.HttpContext.RequestServices.GetRequiredService>>(); var tokens = context.HttpContext.RequestServices.GetRequiredService>(); @@ -123,7 +135,8 @@ namespace OpenIddict { // If the received token is not an authorization code or a refresh token, // return an error to indicate that the token cannot be revoked. - if (!context.Ticket.IsAuthorizationCode() && !context.Ticket.IsRefreshToken()) { + if (!context.Ticket.IsAuthorizationCode() && !context.Ticket.IsRefreshToken()) + { logger.LogError("The revocation request was rejected because the token was not revocable."); context.Reject( @@ -140,7 +153,8 @@ namespace OpenIddict { // Retrieve the token from the database. If the token cannot be found, // assume it is invalid and consider the revocation as successful. var token = await tokens.FindByIdAsync(identifier, context.HttpContext.RequestAborted); - if (token == null) { + if (token == null) + { logger.LogInformation("The token '{Identifier}' was already revoked.", identifier); context.Revoked = true; diff --git a/src/OpenIddict/OpenIddictProvider.Serialization.cs b/src/OpenIddict/OpenIddictProvider.Serialization.cs index 022a4b07..eff2d5df 100644 --- a/src/OpenIddict/OpenIddictProvider.Serialization.cs +++ b/src/OpenIddict/OpenIddictProvider.Serialization.cs @@ -16,35 +16,42 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using OpenIddict.Core; -namespace OpenIddict { +namespace OpenIddict +{ public partial class OpenIddictProvider : OpenIdConnectServerProvider - where TApplication : class where TAuthorization : class where TScope : class where TToken : class { - public override async Task SerializeAuthorizationCode([NotNull] SerializeAuthorizationCodeContext context) { + where TApplication : class where TAuthorization : class where TScope : class where TToken : class + { + public override async Task SerializeAuthorizationCode([NotNull] SerializeAuthorizationCodeContext context) + { var applications = context.HttpContext.RequestServices.GetRequiredService>(); var options = context.HttpContext.RequestServices.GetRequiredService>(); var tokens = context.HttpContext.RequestServices.GetRequiredService>(); Debug.Assert(!string.IsNullOrEmpty(context.Request.ClientId), "The client identifier shouldn't be null or empty."); - if (!options.Value.DisableTokenRevocation) { + if (!options.Value.DisableTokenRevocation) + { // Resolve the subject from the authentication ticket. If it cannot be found, throw an exception. var subject = context.Ticket.Principal.GetClaim(OpenIdConnectConstants.Claims.Subject) ?? context.Ticket.Principal.GetClaim(ClaimTypes.NameIdentifier) ?? context.Ticket.Principal.GetClaim(ClaimTypes.Upn); - if (string.IsNullOrEmpty(subject)) { + if (string.IsNullOrEmpty(subject)) + { throw new InvalidOperationException("The subject associated with the authentication ticket cannot be retrieved."); } // If a null value was returned by CreateAsync, return immediately. var token = await tokens.CreateAsync(OpenIdConnectConstants.TokenTypeHints.AuthorizationCode, subject, context.HttpContext.RequestAborted); - if (token == null) { + if (token == null) + { return; } // Throw an exception if the token identifier can't be resolved. var identifier = await tokens.GetIdAsync(token, context.HttpContext.RequestAborted); - if (string.IsNullOrEmpty(identifier)) { + if (string.IsNullOrEmpty(identifier)) + { throw new InvalidOperationException("The unique key associated with an authorization code cannot be null or empty."); } @@ -54,7 +61,8 @@ namespace OpenIddict { context.Ticket.SetTicketId(identifier); var application = await applications.FindByClientIdAsync(context.Request.ClientId, context.HttpContext.RequestAborted); - if (application == null) { + if (application == null) + { throw new InvalidOperationException("The client application cannot be retrieved from the database."); } @@ -62,36 +70,42 @@ namespace OpenIddict { // If an authorization identifier was specified, bind it to the token. var authorization = context.Ticket.GetProperty(OpenIddictConstants.Properties.AuthorizationId); - if (!string.IsNullOrEmpty(authorization)) { + if (!string.IsNullOrEmpty(authorization)) + { await tokens.SetAuthorizationAsync(token, authorization, context.HttpContext.RequestAborted); } } } - public override async Task SerializeRefreshToken([NotNull] SerializeRefreshTokenContext context) { + public override async Task SerializeRefreshToken([NotNull] SerializeRefreshTokenContext context) + { var applications = context.HttpContext.RequestServices.GetRequiredService>(); var options = context.HttpContext.RequestServices.GetRequiredService>(); var tokens = context.HttpContext.RequestServices.GetRequiredService>(); - if (!options.Value.DisableTokenRevocation) { + if (!options.Value.DisableTokenRevocation) + { // Resolve the subject from the authentication ticket. If it cannot be found, throw an exception. var subject = context.Ticket.Principal.GetClaim(OpenIdConnectConstants.Claims.Subject) ?? context.Ticket.Principal.GetClaim(ClaimTypes.NameIdentifier) ?? context.Ticket.Principal.GetClaim(ClaimTypes.Upn); - if (string.IsNullOrEmpty(subject)) { + if (string.IsNullOrEmpty(subject)) + { throw new InvalidOperationException("The subject associated with the authentication ticket cannot be retrieved."); } // If a null value was returned by CreateAsync, return immediately. var token = await tokens.CreateAsync(OpenIdConnectConstants.TokenTypeHints.RefreshToken, subject, context.HttpContext.RequestAborted); - if (token == null) { + if (token == null) + { return; } // Throw an exception if the token identifier can't be resolved. var identifier = await tokens.GetIdAsync(token, context.HttpContext.RequestAborted); - if (string.IsNullOrEmpty(identifier)) { + if (string.IsNullOrEmpty(identifier)) + { throw new InvalidOperationException("The unique key associated with a refresh token cannot be null or empty."); } @@ -101,9 +115,11 @@ namespace OpenIddict { context.Ticket.SetTicketId(identifier); // If the client application is known, associate it with the token. - if (!string.IsNullOrEmpty(context.Request.ClientId)) { + if (!string.IsNullOrEmpty(context.Request.ClientId)) + { var application = await applications.FindByClientIdAsync(context.Request.ClientId, context.HttpContext.RequestAborted); - if (application == null) { + if (application == null) + { throw new InvalidOperationException("The client application cannot be retrieved from the database."); } @@ -112,7 +128,8 @@ namespace OpenIddict { // If an authorization identifier was specified, bind it to the token. var authorization = context.Ticket.GetProperty(OpenIddictConstants.Properties.AuthorizationId); - if (!string.IsNullOrEmpty(authorization)) { + if (!string.IsNullOrEmpty(authorization)) + { await tokens.SetAuthorizationAsync(token, authorization, context.HttpContext.RequestAborted); } } diff --git a/src/OpenIddict/OpenIddictProvider.Session.cs b/src/OpenIddict/OpenIddictProvider.Session.cs index 497254d7..29b2a8f3 100644 --- a/src/OpenIddict/OpenIddictProvider.Session.cs +++ b/src/OpenIddict/OpenIddictProvider.Session.cs @@ -21,18 +21,23 @@ using Newtonsoft.Json.Bson; using Newtonsoft.Json.Linq; using OpenIddict.Core; -namespace OpenIddict { +namespace OpenIddict +{ public partial class OpenIddictProvider : OpenIdConnectServerProvider - where TApplication : class where TAuthorization : class where TScope : class where TToken : class { - public override async Task ExtractLogoutRequest([NotNull] ExtractLogoutRequestContext context) { + where TApplication : class where TAuthorization : class where TScope : class where TToken : class + { + public override async Task ExtractLogoutRequest([NotNull] ExtractLogoutRequestContext context) + { var logger = context.HttpContext.RequestServices.GetRequiredService>>(); var options = context.HttpContext.RequestServices.GetRequiredService>(); // If a request_id parameter can be found in the logout request, // restore the complete logout request from the distributed cache. - if (!string.IsNullOrEmpty(context.Request.RequestId)) { + if (!string.IsNullOrEmpty(context.Request.RequestId)) + { // Return an error if request caching support was not enabled. - if (!options.Value.EnableRequestCaching) { + if (!options.Value.EnableRequestCaching) + { logger.LogError("The logout request was rejected because " + "request caching support was not enabled."); @@ -48,7 +53,8 @@ namespace OpenIddict { var key = OpenIddictConstants.Environment.LogoutRequest + context.Request.RequestId; var payload = await options.Value.Cache.GetAsync(key); - if (payload == null) { + if (payload == null) + { logger.LogError("The logout request was rejected because an unknown " + "or invalid request_id parameter was specified."); @@ -60,10 +66,13 @@ namespace OpenIddict { } // Restore the logout request parameters from the serialized payload. - using (var reader = new BsonReader(new MemoryStream(payload))) { - foreach (var parameter in JObject.Load(reader)) { + using (var reader = new BsonReader(new MemoryStream(payload))) + { + foreach (var parameter in JObject.Load(reader)) + { // Avoid overriding the current request parameters. - if (context.Request.HasParameter(parameter.Key)) { + if (context.Request.HasParameter(parameter.Key)) + { continue; } @@ -73,13 +82,15 @@ namespace OpenIddict { } } - public override async Task ValidateLogoutRequest([NotNull] ValidateLogoutRequestContext context) { + public override async Task ValidateLogoutRequest([NotNull] ValidateLogoutRequestContext context) + { var applications = context.HttpContext.RequestServices.GetRequiredService>(); var logger = context.HttpContext.RequestServices.GetRequiredService>>(); // Skip validation if the optional post_logout_redirect_uri // parameter was missing from the logout request. - if (string.IsNullOrEmpty(context.PostLogoutRedirectUri)) { + if (string.IsNullOrEmpty(context.PostLogoutRedirectUri)) + { logger.LogInformation("The logout request validation process was skipped because " + "the post_logout_redirect_uri parameter was missing."); @@ -89,7 +100,8 @@ namespace OpenIddict { } var application = await applications.FindByLogoutRedirectUri(context.PostLogoutRedirectUri, context.HttpContext.RequestAborted); - if (application == null) { + if (application == null) + { logger.LogError("The logout request was rejected because the client application corresponding " + "to the specified post_logout_redirect_uri was not found in the database: " + "'{PostLogoutRedirectUri}'.", context.PostLogoutRedirectUri); @@ -104,20 +116,23 @@ namespace OpenIddict { context.Validate(); } - public override async Task HandleLogoutRequest([NotNull] HandleLogoutRequestContext context) { + public override async Task HandleLogoutRequest([NotNull] HandleLogoutRequestContext context) + { var options = context.HttpContext.RequestServices.GetRequiredService>(); // If no request_id parameter can be found in the current request, assume the OpenID Connect // request was not serialized yet and store the entire payload in the distributed cache // to make it easier to flow across requests and internal/external logout workflows. - if (options.Value.EnableRequestCaching && string.IsNullOrEmpty(context.Request.RequestId)) { + if (options.Value.EnableRequestCaching && string.IsNullOrEmpty(context.Request.RequestId)) + { // Generate a request identifier. Note: using a crypto-secure // random number generator is not necessary in this case. context.Request.RequestId = Guid.NewGuid().ToString(); // Store the serialized logout request parameters in the distributed cache. var stream = new MemoryStream(); - using (var writer = new BsonWriter(stream)) { + using (var writer = new BsonWriter(stream)) + { writer.CloseOutput = false; var serializer = JsonSerializer.CreateDefault(); @@ -128,7 +143,8 @@ namespace OpenIddict { // to avoid collisions with the other types of cached requests. var key = OpenIddictConstants.Environment.LogoutRequest + context.Request.RequestId; - await options.Value.Cache.SetAsync(key, stream.ToArray(), new DistributedCacheEntryOptions { + await options.Value.Cache.SetAsync(key, stream.ToArray(), new DistributedCacheEntryOptions + { AbsoluteExpiration = context.Options.SystemClock.UtcNow + TimeSpan.FromMinutes(30), SlidingExpiration = TimeSpan.FromMinutes(10) }); @@ -149,11 +165,13 @@ namespace OpenIddict { } } - public override async Task ApplyLogoutResponse([NotNull] ApplyLogoutResponseContext context) { + public override async Task ApplyLogoutResponse([NotNull] ApplyLogoutResponseContext context) + { var options = context.HttpContext.RequestServices.GetRequiredService>(); // Remove the logout request from the distributed cache. - if (options.Value.EnableRequestCaching && !string.IsNullOrEmpty(context.Request.RequestId)) { + if (options.Value.EnableRequestCaching && !string.IsNullOrEmpty(context.Request.RequestId)) + { // Note: the cache key is always prefixed with a specific marker // to avoid collisions with the other types of cached requests. var key = OpenIddictConstants.Environment.LogoutRequest + context.Request.RequestId; @@ -165,12 +183,14 @@ namespace OpenIddict { } if (!options.Value.ApplicationCanDisplayErrors && !string.IsNullOrEmpty(context.Response.Error) && - string.IsNullOrEmpty(context.Response.PostLogoutRedirectUri)) { + string.IsNullOrEmpty(context.Response.PostLogoutRedirectUri)) + { // Determine if the status code pages middleware has been enabled for this request. // If it was not registered or enabled, let the OpenID Connect server middleware render // a default error page instead of delegating the rendering to the status code middleware. var feature = context.HttpContext.Features.Get(); - if (feature != null && feature.Enabled) { + if (feature != null && feature.Enabled) + { // Replace the default status code by a 400 response. context.HttpContext.Response.StatusCode = 400; diff --git a/src/OpenIddict/OpenIddictProvider.Userinfo.cs b/src/OpenIddict/OpenIddictProvider.Userinfo.cs index 2f9d7369..214cf1b7 100644 --- a/src/OpenIddict/OpenIddictProvider.Userinfo.cs +++ b/src/OpenIddict/OpenIddictProvider.Userinfo.cs @@ -8,10 +8,13 @@ using System.Threading.Tasks; using AspNet.Security.OpenIdConnect.Server; using JetBrains.Annotations; -namespace OpenIddict { +namespace OpenIddict +{ public partial class OpenIddictProvider : OpenIdConnectServerProvider - where TApplication : class where TAuthorization : class where TScope : class where TToken : class { - public override Task ExtractUserinfoRequest([NotNull] ExtractUserinfoRequestContext context) { + where TApplication : class where TAuthorization : class where TScope : class where TToken : class + { + public override Task ExtractUserinfoRequest([NotNull] ExtractUserinfoRequestContext context) + { // Note: when enabling the userinfo endpoint, OpenIddict users are intended // to handle the userinfo requests in their own code (e.g in a MVC controller). // To avoid validating the access token twice, the default logic enforced by diff --git a/src/OpenIddict/OpenIddictProvider.cs b/src/OpenIddict/OpenIddictProvider.cs index 16f7de39..c6b3a336 100644 --- a/src/OpenIddict/OpenIddictProvider.cs +++ b/src/OpenIddict/OpenIddictProvider.cs @@ -7,10 +7,12 @@ using System.ComponentModel; using AspNet.Security.OpenIdConnect.Server; -namespace OpenIddict { +namespace OpenIddict +{ [EditorBrowsable(EditorBrowsableState.Never)] public partial class OpenIddictProvider : OpenIdConnectServerProvider - where TApplication : class where TAuthorization : class where TScope : class where TToken : class { + where TApplication : class where TAuthorization : class where TScope : class where TToken : class + { // Note: this class is split into specialized partial classes. } } \ No newline at end of file diff --git a/test/OpenIddict.Core.Tests/OpenIddict.Core.Tests.xproj b/test/OpenIddict.Core.Tests/OpenIddict.Core.Tests.xproj index fa2dafca..a5d1a1f9 100644 --- a/test/OpenIddict.Core.Tests/OpenIddict.Core.Tests.xproj +++ b/test/OpenIddict.Core.Tests/OpenIddict.Core.Tests.xproj @@ -14,5 +14,8 @@ 2.0 + + + - + \ No newline at end of file diff --git a/test/OpenIddict.Core.Tests/OpenIddictBuilderTests.cs b/test/OpenIddict.Core.Tests/OpenIddictBuilderTests.cs index 94ba7f7a..fd9fd1cb 100644 --- a/test/OpenIddict.Core.Tests/OpenIddictBuilderTests.cs +++ b/test/OpenIddict.Core.Tests/OpenIddictBuilderTests.cs @@ -4,10 +4,13 @@ using Microsoft.Extensions.Logging; using Moq; using Xunit; -namespace OpenIddict.Core.Tests { - public class OpenIddictBuilderTests { +namespace OpenIddict.Core.Tests +{ + public class OpenIddictBuilderTests + { [Fact] - public void AddApplicationManager_ThrowsAnExceptionForInvalidManager() { + public void AddApplicationManager_ThrowsAnExceptionForInvalidManager() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -22,7 +25,8 @@ namespace OpenIddict.Core.Tests { } [Fact] - public void AddApplicationManager_OverridesDefaultManager() { + public void AddApplicationManager_OverridesDefaultManager() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -45,7 +49,8 @@ namespace OpenIddict.Core.Tests { } [Fact] - public void AddApplicationStore_ThrowsAnExceptionForInvalidStore() { + public void AddApplicationStore_ThrowsAnExceptionForInvalidStore() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -60,7 +65,8 @@ namespace OpenIddict.Core.Tests { } [Fact] - public void AddApplicationStore_OverridesDefaultManager() { + public void AddApplicationStore_OverridesDefaultManager() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -81,7 +87,8 @@ namespace OpenIddict.Core.Tests { } [Fact] - public void AddAuthorizationManager_ThrowsAnExceptionForInvalidManager() { + public void AddAuthorizationManager_ThrowsAnExceptionForInvalidManager() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -96,7 +103,8 @@ namespace OpenIddict.Core.Tests { } [Fact] - public void AddAuthorizationManager_OverridesDefaultManager() { + public void AddAuthorizationManager_OverridesDefaultManager() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -119,7 +127,8 @@ namespace OpenIddict.Core.Tests { } [Fact] - public void AddAuthorizationStore_ThrowsAnExceptionForInvalidStore() { + public void AddAuthorizationStore_ThrowsAnExceptionForInvalidStore() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -134,7 +143,8 @@ namespace OpenIddict.Core.Tests { } [Fact] - public void AddAuthorizationStore_OverridesDefaultManager() { + public void AddAuthorizationStore_OverridesDefaultManager() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -155,7 +165,8 @@ namespace OpenIddict.Core.Tests { } [Fact] - public void AddScopeManager_ThrowsAnExceptionForInvalidManager() { + public void AddScopeManager_ThrowsAnExceptionForInvalidManager() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -170,7 +181,8 @@ namespace OpenIddict.Core.Tests { } [Fact] - public void AddScopeManager_OverridesDefaultManager() { + public void AddScopeManager_OverridesDefaultManager() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -193,7 +205,8 @@ namespace OpenIddict.Core.Tests { } [Fact] - public void AddScopeStore_ThrowsAnExceptionForInvalidStore() { + public void AddScopeStore_ThrowsAnExceptionForInvalidStore() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -208,7 +221,8 @@ namespace OpenIddict.Core.Tests { } [Fact] - public void AddScopeStore_OverridesDefaultManager() { + public void AddScopeStore_OverridesDefaultManager() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -229,7 +243,8 @@ namespace OpenIddict.Core.Tests { } [Fact] - public void AddTokenManager_ThrowsAnExceptionForInvalidManager() { + public void AddTokenManager_ThrowsAnExceptionForInvalidManager() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -244,7 +259,8 @@ namespace OpenIddict.Core.Tests { } [Fact] - public void AddTokenManager_OverridesDefaultManager() { + public void AddTokenManager_OverridesDefaultManager() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -267,7 +283,8 @@ namespace OpenIddict.Core.Tests { } [Fact] - public void AddTokenStore_ThrowsAnExceptionForInvalidStore() { + public void AddTokenStore_ThrowsAnExceptionForInvalidStore() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -282,7 +299,8 @@ namespace OpenIddict.Core.Tests { } [Fact] - public void AddTokenStore_OverridesDefaultManager() { + public void AddTokenStore_OverridesDefaultManager() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); diff --git a/test/OpenIddict.Core.Tests/OpenIddictExtensionsTests.cs b/test/OpenIddict.Core.Tests/OpenIddictExtensionsTests.cs index 5f8eed6d..b740f2ff 100644 --- a/test/OpenIddict.Core.Tests/OpenIddictExtensionsTests.cs +++ b/test/OpenIddict.Core.Tests/OpenIddictExtensionsTests.cs @@ -3,14 +3,17 @@ using Microsoft.Extensions.DependencyInjection; using OpenIddict.Models; using Xunit; -namespace OpenIddict.Core.Tests { - public class OpenIddictExtensionsTests { +namespace OpenIddict.Core.Tests +{ + public class OpenIddictExtensionsTests + { [Theory] [InlineData(typeof(OpenIddictApplicationManager))] [InlineData(typeof(OpenIddictAuthorizationManager))] [InlineData(typeof(OpenIddictScopeManager))] [InlineData(typeof(OpenIddictTokenManager))] - public void AddOpenIddict_KeyTypeDefaultsToString(Type type) { + public void AddOpenIddict_KeyTypeDefaultsToString(Type type) + { // Arrange var services = new ServiceCollection(); @@ -26,7 +29,8 @@ namespace OpenIddict.Core.Tests { [InlineData(typeof(OpenIddictAuthorizationManager>))] [InlineData(typeof(OpenIddictScopeManager>))] [InlineData(typeof(OpenIddictTokenManager>))] - public void AddOpenIddict_KeyTypeCanBeOverriden(Type type) { + public void AddOpenIddict_KeyTypeCanBeOverriden(Type type) + { // Arrange var services = new ServiceCollection(); @@ -42,7 +46,8 @@ namespace OpenIddict.Core.Tests { [InlineData(typeof(OpenIddictAuthorizationManager))] [InlineData(typeof(OpenIddictScopeManager))] [InlineData(typeof(OpenIddictTokenManager))] - public void AddOpenIddict_DefaultEntitiesCanBeReplaced(Type type) { + public void AddOpenIddict_DefaultEntitiesCanBeReplaced(Type type) + { // Arrange var services = new ServiceCollection(); diff --git a/test/OpenIddict.EntityFrameworkCore.Tests/OpenIddict.EntityFrameworkCore.Tests.xproj b/test/OpenIddict.EntityFrameworkCore.Tests/OpenIddict.EntityFrameworkCore.Tests.xproj index 1a2290d6..90d57844 100644 --- a/test/OpenIddict.EntityFrameworkCore.Tests/OpenIddict.EntityFrameworkCore.Tests.xproj +++ b/test/OpenIddict.EntityFrameworkCore.Tests/OpenIddict.EntityFrameworkCore.Tests.xproj @@ -4,7 +4,6 @@ 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - 7831f17a-df0b-42ec-841b-065a9b5bd786 @@ -13,9 +12,11 @@ .\bin\ v4.6.1 - 2.0 + + + \ No newline at end of file diff --git a/test/OpenIddict.EntityFrameworkCore.Tests/OpenIddictExtensionsTests.cs b/test/OpenIddict.EntityFrameworkCore.Tests/OpenIddictExtensionsTests.cs index 2d5f0356..afc77758 100644 --- a/test/OpenIddict.EntityFrameworkCore.Tests/OpenIddictExtensionsTests.cs +++ b/test/OpenIddict.EntityFrameworkCore.Tests/OpenIddictExtensionsTests.cs @@ -4,16 +4,20 @@ using Microsoft.Extensions.DependencyInjection; using OpenIddict.Models; using Xunit; -namespace OpenIddict.EntityFrameworkCore.Tests { - public class OpenIddictExtensionsTests { +namespace OpenIddict.EntityFrameworkCore.Tests +{ + public class OpenIddictExtensionsTests + { [Fact] - public void AddEntityFrameworkCoreStores_ThrowsAnExceptionForInvalidApplicationEntity() { + public void AddEntityFrameworkCoreStores_ThrowsAnExceptionForInvalidApplicationEntity() + { // Arrange var builder = new OpenIddictBuilder(new ServiceCollection()); builder.ApplicationType = typeof(object); // Act and assert - var exception = Assert.Throws(delegate { + var exception = Assert.Throws(delegate + { builder.AddEntityFrameworkCoreStores(); }); @@ -22,13 +26,15 @@ namespace OpenIddict.EntityFrameworkCore.Tests { } [Fact] - public void AddEntityFrameworkCoreStores_ThrowsAnExceptionForInvalidAuthorizationEntity() { + public void AddEntityFrameworkCoreStores_ThrowsAnExceptionForInvalidAuthorizationEntity() + { // Arrange var builder = new OpenIddictBuilder(new ServiceCollection()); builder.AuthorizationType = typeof(object); // Act and assert - var exception = Assert.Throws(delegate { + var exception = Assert.Throws(delegate + { builder.AddEntityFrameworkCoreStores(); }); @@ -37,13 +43,15 @@ namespace OpenIddict.EntityFrameworkCore.Tests { } [Fact] - public void AddEntityFrameworkCoreStores_ThrowsAnExceptionForInvalidScopeEntity() { + public void AddEntityFrameworkCoreStores_ThrowsAnExceptionForInvalidScopeEntity() + { // Arrange var builder = new OpenIddictBuilder(new ServiceCollection()); builder.ScopeType = typeof(object); // Act and assert - var exception = Assert.Throws(delegate { + var exception = Assert.Throws(delegate + { builder.AddEntityFrameworkCoreStores(); }); @@ -52,13 +60,15 @@ namespace OpenIddict.EntityFrameworkCore.Tests { } [Fact] - public void AddEntityFrameworkCoreStores_ThrowsAnExceptionForInvalidTokenEntity() { + public void AddEntityFrameworkCoreStores_ThrowsAnExceptionForInvalidTokenEntity() + { // Arrange var builder = new OpenIddictBuilder(new ServiceCollection()); builder.TokenType = typeof(object); // Act and assert - var exception = Assert.Throws(delegate { + var exception = Assert.Throws(delegate + { builder.AddEntityFrameworkCoreStores(); }); @@ -71,7 +81,8 @@ namespace OpenIddict.EntityFrameworkCore.Tests { [InlineData(typeof(OpenIddictAuthorizationStore))] [InlineData(typeof(OpenIddictScopeStore))] [InlineData(typeof(OpenIddictTokenStore))] - public void AddEntityFrameworkCoreStores_RegistersEntityFrameworkStores(Type type) { + public void AddEntityFrameworkCoreStores_RegistersEntityFrameworkStores(Type type) + { // Arrange var services = new ServiceCollection(); var builder = new OpenIddictBuilder(services); @@ -88,11 +99,13 @@ namespace OpenIddict.EntityFrameworkCore.Tests { [InlineData(typeof(OpenIddictAuthorizationStore, OpenIddictApplication, OpenIddictToken, DbContext, Guid>))] [InlineData(typeof(OpenIddictScopeStore, DbContext, Guid>))] [InlineData(typeof(OpenIddictTokenStore, OpenIddictApplication, OpenIddictAuthorization, DbContext, Guid>))] - public void AddEntityFrameworkCoreStores_KeyTypeIsInferredFromEntities(Type type) { + public void AddEntityFrameworkCoreStores_KeyTypeIsInferredFromEntities(Type type) + { // Arrange var services = new ServiceCollection(); - var builder = new OpenIddictBuilder(services) { + var builder = new OpenIddictBuilder(services) + { ApplicationType = typeof(OpenIddictApplication), AuthorizationType = typeof(OpenIddictAuthorization), ScopeType = typeof(OpenIddictScope), @@ -111,11 +124,13 @@ namespace OpenIddict.EntityFrameworkCore.Tests { [InlineData(typeof(OpenIddictAuthorizationStore))] [InlineData(typeof(OpenIddictScopeStore))] [InlineData(typeof(OpenIddictTokenStore))] - public void AddEntityFrameworkCoreStores_DefaultEntitiesCanBeReplaced(Type type) { + public void AddEntityFrameworkCoreStores_DefaultEntitiesCanBeReplaced(Type type) + { // Arrange var services = new ServiceCollection(); - var builder = new OpenIddictBuilder(services) { + var builder = new OpenIddictBuilder(services) + { ApplicationType = typeof(CustomApplication), AuthorizationType = typeof(CustomAuthorization), ScopeType = typeof(CustomScope), diff --git a/test/OpenIddict.Mvc.Tests/OpenIddict.Mvc.Tests.xproj b/test/OpenIddict.Mvc.Tests/OpenIddict.Mvc.Tests.xproj index 870bf75d..fd1ee162 100644 --- a/test/OpenIddict.Mvc.Tests/OpenIddict.Mvc.Tests.xproj +++ b/test/OpenIddict.Mvc.Tests/OpenIddict.Mvc.Tests.xproj @@ -4,7 +4,6 @@ 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - 8b4b0ccc-711b-4f9d-9de6-dd32bdd3bcca @@ -13,9 +12,11 @@ .\bin\ v4.6.1 - 2.0 + + + - + \ No newline at end of file diff --git a/test/OpenIddict.Mvc.Tests/OpenIddictExtensionsTests.cs b/test/OpenIddict.Mvc.Tests/OpenIddictExtensionsTests.cs index 9910dcf1..618711c2 100644 --- a/test/OpenIddict.Mvc.Tests/OpenIddictExtensionsTests.cs +++ b/test/OpenIddict.Mvc.Tests/OpenIddictExtensionsTests.cs @@ -3,10 +3,13 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Xunit; -namespace OpenIddict.Mvc.Tests { - public class OpenIddictExtensionsTests { +namespace OpenIddict.Mvc.Tests +{ + public class OpenIddictExtensionsTests + { [Fact] - public void AddMvcBinders_RegistersModelBinderProvider() { + public void AddMvcBinders_RegistersModelBinderProvider() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); diff --git a/test/OpenIddict.Mvc.Tests/OpenIddictModelBinderTests.cs b/test/OpenIddict.Mvc.Tests/OpenIddictModelBinderTests.cs index 0d094233..77964abc 100644 --- a/test/OpenIddict.Mvc.Tests/OpenIddictModelBinderTests.cs +++ b/test/OpenIddict.Mvc.Tests/OpenIddictModelBinderTests.cs @@ -12,23 +12,28 @@ using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; using Moq; using Xunit; -namespace OpenIddict.Mvc.Tests { - public class OpenIddictModelBinderTests { +namespace OpenIddict.Mvc.Tests +{ + public class OpenIddictModelBinderTests + { [Theory] [InlineData(typeof(object))] [InlineData(typeof(IList))] [InlineData(typeof(int[]))] - public async Task BindModelAsync_ThrowsAnExceptionForUnsupportedTypes(Type type) { + public async Task BindModelAsync_ThrowsAnExceptionForUnsupportedTypes(Type type) + { // Arrange var binder = new OpenIddictModelBinder(); var provider = new EmptyModelMetadataProvider(); - var context = new DefaultModelBindingContext { + var context = new DefaultModelBindingContext + { ModelMetadata = provider.GetMetadataForType(type) }; // Act and assert - var exception = await Assert.ThrowsAsync(delegate { + var exception = await Assert.ThrowsAsync(delegate + { return binder.BindModelAsync(context); }); @@ -36,13 +41,16 @@ namespace OpenIddict.Mvc.Tests { } [Fact] - public async Task BindModelAsync_ThrowsAnExceptionWhenRequestCannotBeFound() { + public async Task BindModelAsync_ThrowsAnExceptionWhenRequestCannotBeFound() + { // Arrange var binder = new OpenIddictModelBinder(); var provider = new EmptyModelMetadataProvider(); - var context = new DefaultModelBindingContext { - ActionContext = new ActionContext() { + var context = new DefaultModelBindingContext + { + ActionContext = new ActionContext() + { HttpContext = new DefaultHttpContext(), }, @@ -50,7 +58,8 @@ namespace OpenIddict.Mvc.Tests { }; // Act and assert - var exception = await Assert.ThrowsAsync(delegate { + var exception = await Assert.ThrowsAsync(delegate + { return binder.BindModelAsync(context); }); @@ -61,13 +70,16 @@ namespace OpenIddict.Mvc.Tests { } [Fact] - public async Task BindModelAsync_ReturnsNullWhenResponseCannotBeFound() { + public async Task BindModelAsync_ReturnsNullWhenResponseCannotBeFound() + { // Arrange var binder = new OpenIddictModelBinder(); var provider = new EmptyModelMetadataProvider(); - var context = new DefaultModelBindingContext { - ActionContext = new ActionContext() { + var context = new DefaultModelBindingContext + { + ActionContext = new ActionContext() + { HttpContext = new DefaultHttpContext(), }, @@ -85,7 +97,8 @@ namespace OpenIddict.Mvc.Tests { } [Fact] - public async Task BindModelAsync_ReturnsAmbientRequest() { + public async Task BindModelAsync_ReturnsAmbientRequest() + { // Arrange var binder = new OpenIddictModelBinder(); var provider = new EmptyModelMetadataProvider(); @@ -93,12 +106,15 @@ namespace OpenIddict.Mvc.Tests { var request = new OpenIdConnectRequest(); var features = new FeatureCollection(); - features.Set(new OpenIdConnectServerFeature { + features.Set(new OpenIdConnectServerFeature + { Request = request }); - var context = new DefaultModelBindingContext { - ActionContext = new ActionContext() { + var context = new DefaultModelBindingContext + { + ActionContext = new ActionContext() + { HttpContext = new DefaultHttpContext(features), }, @@ -117,7 +133,8 @@ namespace OpenIddict.Mvc.Tests { } [Fact] - public async Task BindModelAsync_ReturnsAmbientResponse() { + public async Task BindModelAsync_ReturnsAmbientResponse() + { // Arrange var binder = new OpenIddictModelBinder(); var provider = new EmptyModelMetadataProvider(); @@ -125,12 +142,15 @@ namespace OpenIddict.Mvc.Tests { var response = new OpenIdConnectResponse(); var features = new FeatureCollection(); - features.Set(new OpenIdConnectServerFeature { + features.Set(new OpenIdConnectServerFeature + { Response = response }); - var context = new DefaultModelBindingContext { - ActionContext = new ActionContext() { + var context = new DefaultModelBindingContext + { + ActionContext = new ActionContext() + { HttpContext = new DefaultHttpContext(features), }, @@ -152,7 +172,8 @@ namespace OpenIddict.Mvc.Tests { [InlineData(typeof(object))] [InlineData(typeof(IList))] [InlineData(typeof(int[]))] - public void GetBinder_ReturnsNullForUnsupportedTypes(Type type) { + public void GetBinder_ReturnsNullForUnsupportedTypes(Type type) + { // Arrange var provider = new OpenIddictModelBinder(); @@ -172,7 +193,8 @@ namespace OpenIddict.Mvc.Tests { [Theory] [InlineData(typeof(OpenIdConnectRequest))] [InlineData(typeof(OpenIdConnectResponse))] - public void GetBinder_ReturnsNonNullForSupportedTypes(Type type) { + public void GetBinder_ReturnsNonNullForSupportedTypes(Type type) + { // Arrange var binder = new OpenIddictModelBinder(); diff --git a/test/OpenIddict.Tests/OpenIddict.Tests.xproj b/test/OpenIddict.Tests/OpenIddict.Tests.xproj index 83034985..1eec5168 100644 --- a/test/OpenIddict.Tests/OpenIddict.Tests.xproj +++ b/test/OpenIddict.Tests/OpenIddict.Tests.xproj @@ -4,7 +4,6 @@ 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - 3e2fbdb3-dc82-4e97-8ebc-cc8b279110ff @@ -13,9 +12,11 @@ .\bin\ v4.6.1 - 2.0 + + + - + \ No newline at end of file diff --git a/test/OpenIddict.Tests/OpenIddictExtensionsTests.cs b/test/OpenIddict.Tests/OpenIddictExtensionsTests.cs index 9e5db918..f949f52f 100644 --- a/test/OpenIddict.Tests/OpenIddictExtensionsTests.cs +++ b/test/OpenIddict.Tests/OpenIddictExtensionsTests.cs @@ -12,10 +12,13 @@ using Microsoft.IdentityModel.Tokens; using Moq; using Xunit; -namespace OpenIddict.Tests { - public class OpenIddictExtensionsTests { +namespace OpenIddict.Tests +{ + public class OpenIddictExtensionsTests + { [Fact] - public void UseOpenIddict_ThrowsAnExceptionWhenServicesAreNotRegistered() { + public void UseOpenIddict_ThrowsAnExceptionWhenServicesAreNotRegistered() + { // Arrange var services = new ServiceCollection(); var builder = new ApplicationBuilder(services.BuildServiceProvider()); @@ -28,7 +31,8 @@ namespace OpenIddict.Tests { } [Fact] - public void UseOpenIddict_ThrowsAnExceptionWhenNoDistributedCacheIsRegisteredIfRequestCachingIsEnabled() { + public void UseOpenIddict_ThrowsAnExceptionWhenNoDistributedCacheIsRegisteredIfRequestCachingIsEnabled() + { // Arrange var services = new ServiceCollection(); @@ -45,7 +49,8 @@ namespace OpenIddict.Tests { } [Fact] - public void UseOpenIddict_ThrowsAnExceptionWhenNoFlowIsEnabled() { + public void UseOpenIddict_ThrowsAnExceptionWhenNoFlowIsEnabled() + { // Arrange var services = new ServiceCollection(); services.AddOpenIddict(); @@ -61,7 +66,8 @@ namespace OpenIddict.Tests { [Theory] [InlineData(OpenIdConnectConstants.GrantTypes.AuthorizationCode)] [InlineData(OpenIdConnectConstants.GrantTypes.Implicit)] - public void UseOpenIddict_ThrowsAnExceptionWhenAuthorizationEndpointIsDisabled(string flow) { + public void UseOpenIddict_ThrowsAnExceptionWhenAuthorizationEndpointIsDisabled(string flow) + { // Arrange var services = new ServiceCollection(); @@ -83,7 +89,8 @@ namespace OpenIddict.Tests { [InlineData(OpenIdConnectConstants.GrantTypes.ClientCredentials)] [InlineData(OpenIdConnectConstants.GrantTypes.Password)] [InlineData(OpenIdConnectConstants.GrantTypes.RefreshToken)] - public void UseOpenIddict_ThrowsAnExceptionWhenTokenEndpointIsDisabled(string flow) { + public void UseOpenIddict_ThrowsAnExceptionWhenTokenEndpointIsDisabled(string flow) + { // Arrange var services = new ServiceCollection(); @@ -102,7 +109,8 @@ namespace OpenIddict.Tests { } [Fact] - public void UseOpenIddict_ThrowsAnExceptionWhenTokenRevocationIsDisabled() { + public void UseOpenIddict_ThrowsAnExceptionWhenTokenRevocationIsDisabled() + { // Arrange var services = new ServiceCollection(); @@ -121,7 +129,8 @@ namespace OpenIddict.Tests { } [Fact] - public void UseOpenIddict_ThrowsAnExceptionWhenNoSigningKeyIsRegisteredIfTheImplicitFlowIsEnabled() { + public void UseOpenIddict_ThrowsAnExceptionWhenNoSigningKeyIsRegisteredIfTheImplicitFlowIsEnabled() + { // Arrange var services = new ServiceCollection(); @@ -140,7 +149,8 @@ namespace OpenIddict.Tests { } [Fact] - public void Configure_OptionsAreCorrectlyAmended() { + public void Configure_OptionsAreCorrectlyAmended() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -158,7 +168,8 @@ namespace OpenIddict.Tests { } [Fact] - public void UseOpenIddict_OpenIdConnectServerMiddlewareIsRegistered() { + public void UseOpenIddict_OpenIdConnectServerMiddlewareIsRegistered() + { // Arrange var services = new ServiceCollection(); @@ -182,7 +193,8 @@ namespace OpenIddict.Tests { } [Fact] - public void AddEphemeralSigningKey_SigningKeyIsCorrectlyAdded() { + public void AddEphemeralSigningKey_SigningKeyIsCorrectlyAdded() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -208,7 +220,8 @@ namespace OpenIddict.Tests { [InlineData(SecurityAlgorithms.EcdsaSha384Signature)] [InlineData(SecurityAlgorithms.EcdsaSha512Signature)] #endif - public void AddEphemeralSigningKey_SigningCredentialsUseSpecifiedAlgorithm(string algorithm) { + public void AddEphemeralSigningKey_SigningCredentialsUseSpecifiedAlgorithm(string algorithm) + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -234,7 +247,8 @@ namespace OpenIddict.Tests { [InlineData(SecurityAlgorithms.EcdsaSha384Signature)] [InlineData(SecurityAlgorithms.EcdsaSha512Signature)] #endif - public void AddSigningKey_SigningKeyIsCorrectlyAdded(string algorithm) { + public void AddSigningKey_SigningKeyIsCorrectlyAdded(string algorithm) + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -257,7 +271,8 @@ namespace OpenIddict.Tests { } [Fact] - public void AddSigningCertificate_SigningKeyIsCorrectlyAdded() { + public void AddSigningCertificate_SigningKeyIsCorrectlyAdded() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -278,7 +293,8 @@ namespace OpenIddict.Tests { } [Fact] - public void AllowAuthorizationCodeFlow_CodeFlowIsAddedToGrantTypes() { + public void AllowAuthorizationCodeFlow_CodeFlowIsAddedToGrantTypes() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -296,7 +312,8 @@ namespace OpenIddict.Tests { } [Fact] - public void AllowClientCredentialsFlow_ClientCredentialsFlowIsAddedToGrantTypes() { + public void AllowClientCredentialsFlow_ClientCredentialsFlowIsAddedToGrantTypes() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -314,7 +331,8 @@ namespace OpenIddict.Tests { } [Fact] - public void AllowCustomFlow_CustomFlowIsAddedToGrantTypes() { + public void AllowCustomFlow_CustomFlowIsAddedToGrantTypes() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -332,7 +350,8 @@ namespace OpenIddict.Tests { } [Fact] - public void AllowImplicitFlow_ImplicitFlowIsAddedToGrantTypes() { + public void AllowImplicitFlow_ImplicitFlowIsAddedToGrantTypes() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -350,7 +369,8 @@ namespace OpenIddict.Tests { } [Fact] - public void AllowPasswordFlow_PasswordFlowIsAddedToGrantTypes() { + public void AllowPasswordFlow_PasswordFlowIsAddedToGrantTypes() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -368,7 +388,8 @@ namespace OpenIddict.Tests { } [Fact] - public void AllowRefreshTokenFlow_RefreshTokenFlowIsAddedToGrantTypes() { + public void AllowRefreshTokenFlow_RefreshTokenFlowIsAddedToGrantTypes() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -386,7 +407,8 @@ namespace OpenIddict.Tests { } [Fact] - public void DisableConfigurationEndpoint_ConfigurationEndpointIsDisabled() { + public void DisableConfigurationEndpoint_ConfigurationEndpointIsDisabled() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -404,7 +426,8 @@ namespace OpenIddict.Tests { } [Fact] - public void DisableCryptographyEndpoint_CryptographyEndpointIsDisabled() { + public void DisableCryptographyEndpoint_CryptographyEndpointIsDisabled() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -422,7 +445,8 @@ namespace OpenIddict.Tests { } [Fact] - public void DisableSlidingExpiration_SlidingExpirationIsDisabled() { + public void DisableSlidingExpiration_SlidingExpirationIsDisabled() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -440,7 +464,8 @@ namespace OpenIddict.Tests { } [Fact] - public void DisableTokenRevocation_TokenRevocationIsDisabled() { + public void DisableTokenRevocation_TokenRevocationIsDisabled() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -458,7 +483,8 @@ namespace OpenIddict.Tests { } [Fact] - public void EnableAuthorizationEndpoint_AuthorizationEndpointIsEnabled() { + public void EnableAuthorizationEndpoint_AuthorizationEndpointIsEnabled() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -476,7 +502,8 @@ namespace OpenIddict.Tests { } [Fact] - public void EnableIntrospectionEndpoint_IntrospectionEndpointIsEnabled() { + public void EnableIntrospectionEndpoint_IntrospectionEndpointIsEnabled() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -494,7 +521,8 @@ namespace OpenIddict.Tests { } [Fact] - public void EnableLogoutEndpoint_LogoutEndpointIsEnabled() { + public void EnableLogoutEndpoint_LogoutEndpointIsEnabled() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -512,7 +540,8 @@ namespace OpenIddict.Tests { } [Fact] - public void EnableRequestCaching_RequestCachingIsEnabled() { + public void EnableRequestCaching_RequestCachingIsEnabled() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -530,7 +559,8 @@ namespace OpenIddict.Tests { } [Fact] - public void EnableRevocationEndpoint_RevocationEndpointIsEnabled() { + public void EnableRevocationEndpoint_RevocationEndpointIsEnabled() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -548,7 +578,8 @@ namespace OpenIddict.Tests { } [Fact] - public void EnableTokenEndpoint_TokenEndpointIsEnabled() { + public void EnableTokenEndpoint_TokenEndpointIsEnabled() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -566,7 +597,8 @@ namespace OpenIddict.Tests { } [Fact] - public void EnableUserinfoEndpoint_UserinfoEndpointIsEnabled() { + public void EnableUserinfoEndpoint_UserinfoEndpointIsEnabled() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -584,7 +616,8 @@ namespace OpenIddict.Tests { } [Fact] - public void RequireClientIdentification_ClientIdentificationIsEnforced() { + public void RequireClientIdentification_ClientIdentificationIsEnforced() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -602,7 +635,8 @@ namespace OpenIddict.Tests { } [Fact] - public void SetAccessTokenLifetime_DefaultAccessTokenLifetimeIsReplaced() { + public void SetAccessTokenLifetime_DefaultAccessTokenLifetimeIsReplaced() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -620,7 +654,8 @@ namespace OpenIddict.Tests { } [Fact] - public void SetAuthorizationCodeLifetime_DefaultAuthorizationCodeLifetimeIsReplaced() { + public void SetAuthorizationCodeLifetime_DefaultAuthorizationCodeLifetimeIsReplaced() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -638,7 +673,8 @@ namespace OpenIddict.Tests { } [Fact] - public void SetIdentityTokenLifetime_DefaultIdentityTokenLifetimeIsReplaced() { + public void SetIdentityTokenLifetime_DefaultIdentityTokenLifetimeIsReplaced() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -656,7 +692,8 @@ namespace OpenIddict.Tests { } [Fact] - public void SetRefreshTokenLifetime_DefaultRefreshTokenLifetimeIsReplaced() { + public void SetRefreshTokenLifetime_DefaultRefreshTokenLifetimeIsReplaced() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -674,7 +711,8 @@ namespace OpenIddict.Tests { } [Fact] - public void SetIssuer_AddressIsReplaced() { + public void SetIssuer_AddressIsReplaced() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -692,7 +730,8 @@ namespace OpenIddict.Tests { } [Fact] - public void UseDataProtectionProvider_DefaultProviderIsReplaced() { + public void UseDataProtectionProvider_DefaultProviderIsReplaced() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); @@ -710,7 +749,8 @@ namespace OpenIddict.Tests { } [Fact] - public void UseJsonWebTokens_AccessTokenHandlerIsCorrectlySet() { + public void UseJsonWebTokens_AccessTokenHandlerIsCorrectlySet() + { // Arrange var services = new ServiceCollection(); services.AddOptions(); diff --git a/test/OpenIddict.Tests/OpenIddictProviderTests.Authentication.cs b/test/OpenIddict.Tests/OpenIddictProviderTests.Authentication.cs index 3f6df57a..3422b12a 100644 --- a/test/OpenIddict.Tests/OpenIddictProviderTests.Authentication.cs +++ b/test/OpenIddict.Tests/OpenIddictProviderTests.Authentication.cs @@ -14,17 +14,21 @@ using OpenIddict.Core; using OpenIddict.Models; using Xunit; -namespace OpenIddict.Tests { - public partial class OpenIddictProviderTests { +namespace OpenIddict.Tests +{ + public partial class OpenIddictProviderTests + { [Fact] - public async Task ExtractAuthorizationRequest_UnsupportedRequestParameterIsRejected() { + public async Task ExtractAuthorizationRequest_UnsupportedRequestParameterIsRejected() + { // Arrange var server = CreateAuthorizationServer(); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", RedirectUri = "http://www.fabrikam.com/path", Request = "eyJhbGciOiJub25lIn0.eyJpc3MiOiJodHRwOi8vd3d3LmZhYnJpa2FtLmNvbSIsImF1ZCI6Imh0" + @@ -40,14 +44,16 @@ namespace OpenIddict.Tests { } [Fact] - public async Task ExtractAuthorizationRequest_UnsupportedRequestUriParameterIsRejected() { + public async Task ExtractAuthorizationRequest_UnsupportedRequestUriParameterIsRejected() + { // Arrange var server = CreateAuthorizationServer(); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", RedirectUri = "http://www.fabrikam.com/path", RequestUri = "http://www.fabrikam.com/request/GkurKxf5T0Y-mnPFCHqWOMiZi4VS138cQO_V7PZHAdM", @@ -61,14 +67,16 @@ namespace OpenIddict.Tests { } [Fact] - public async Task ExtractAuthorizationRequest_RequestIdParameterIsRejectedWhenRequestCachingIsDisabled() { + public async Task ExtractAuthorizationRequest_RequestIdParameterIsRejectedWhenRequestCachingIsDisabled() + { // Arrange var server = CreateAuthorizationServer(); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest + { RequestId = "EFAF3596-F868-497F-96BB-AA2AD1F8B7E7" }); @@ -78,9 +86,11 @@ namespace OpenIddict.Tests { } [Fact] - public async Task ExtractAuthorizationRequest_InvalidRequestIdParameterIsRejected() { + public async Task ExtractAuthorizationRequest_InvalidRequestIdParameterIsRejected() + { // Arrange - var server = CreateAuthorizationServer(builder => { + var server = CreateAuthorizationServer(builder => + { builder.Services.AddDistributedMemoryCache(); builder.EnableRequestCaching(); @@ -89,7 +99,8 @@ namespace OpenIddict.Tests { var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest + { RequestId = "EFAF3596-F868-497F-96BB-AA2AD1F8B7E7" }); @@ -99,14 +110,16 @@ namespace OpenIddict.Tests { } [Fact] - public async Task ValidateAuthorizationRequest_UnknownResponseTypeParameterIsRejected() { + public async Task ValidateAuthorizationRequest_UnknownResponseTypeParameterIsRejected() + { // Arrange var server = CreateAuthorizationServer(); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", RedirectUri = "http://www.fabrikam.com/path", ResponseType = "unknown_response_type" @@ -128,16 +141,19 @@ namespace OpenIddict.Tests { [InlineData(OpenIdConnectConstants.GrantTypes.Implicit, "id_token")] [InlineData(OpenIdConnectConstants.GrantTypes.Implicit, "id_token token")] [InlineData(OpenIdConnectConstants.GrantTypes.Implicit, "token")] - public async Task ValidateAuthorizationRequest_RequestIsRejectedWhenCorrespondingFlowIsDisabled(string flow, string type) { + public async Task ValidateAuthorizationRequest_RequestIsRejectedWhenCorrespondingFlowIsDisabled(string flow, string type) + { // Arrange - var server = CreateAuthorizationServer(builder => { + var server = CreateAuthorizationServer(builder => + { builder.Configure(options => options.GrantTypes.Remove(flow)); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", Nonce = "n-0S6_WzA2Mj", RedirectUri = "http://www.fabrikam.com/path", @@ -151,16 +167,19 @@ namespace OpenIddict.Tests { } [Fact] - public async Task ValidateAuthorizationRequest_RequestWithOfflineAccessScopeIsRejectedWhenRefreshTokenFlowIsDisabled() { + public async Task ValidateAuthorizationRequest_RequestWithOfflineAccessScopeIsRejectedWhenRefreshTokenFlowIsDisabled() + { // Arrange - var server = CreateAuthorizationServer(builder => { + var server = CreateAuthorizationServer(builder => + { builder.Configure(options => options.GrantTypes.Remove(OpenIdConnectConstants.GrantTypes.RefreshToken)); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", RedirectUri = "http://www.fabrikam.com/path", ResponseType = OpenIdConnectConstants.ResponseTypes.Code, @@ -173,14 +192,16 @@ namespace OpenIddict.Tests { } [Fact] - public async Task ValidateAuthorizationRequest_UnknownResponseModeParameterIsRejected() { + public async Task ValidateAuthorizationRequest_UnknownResponseModeParameterIsRejected() + { // Arrange var server = CreateAuthorizationServer(); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", RedirectUri = "http://www.fabrikam.com/path", ResponseMode = "unknown_response_mode", @@ -193,14 +214,16 @@ namespace OpenIddict.Tests { } [Fact] - public async Task ValidateAuthorizationRequest_RequestIsRejectedWhenRedirectUriIsMissing() { + public async Task ValidateAuthorizationRequest_RequestIsRejectedWhenRedirectUriIsMissing() + { // Arrange var server = CreateAuthorizationServer(); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", RedirectUri = null, ResponseType = OpenIdConnectConstants.ResponseTypes.Code @@ -212,14 +235,16 @@ namespace OpenIddict.Tests { } [Fact] - public async Task ValidateAuthorizationRequest_RequestIsRejectedWhenCodeChallengeMethodIsMissing() { + public async Task ValidateAuthorizationRequest_RequestIsRejectedWhenCodeChallengeMethodIsMissing() + { // Arrange var server = CreateAuthorizationServer(); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", CodeChallenge = "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM", CodeChallengeMethod = null, @@ -233,14 +258,16 @@ namespace OpenIddict.Tests { } [Fact] - public async Task ValidateAuthorizationRequest_RequestIsRejectedWhenCodeChallengeMethodIsPlain() { + public async Task ValidateAuthorizationRequest_RequestIsRejectedWhenCodeChallengeMethodIsPlain() + { // Arrange var server = CreateAuthorizationServer(); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", CodeChallenge = "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM", CodeChallengeMethod = OpenIdConnectConstants.CodeChallengeMethods.Plain, @@ -256,14 +283,16 @@ namespace OpenIddict.Tests { [Theory] [InlineData("code id_token token")] [InlineData("code token")] - public async Task ValidateAuthorizationRequest_CodeChallengeRequestWithForbiddenResponseTypeIsRejected(string type) { + public async Task ValidateAuthorizationRequest_CodeChallengeRequestWithForbiddenResponseTypeIsRejected(string type) + { // Arrange var server = CreateAuthorizationServer(); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", CodeChallenge = "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM", CodeChallengeMethod = OpenIdConnectConstants.CodeChallengeMethods.Sha256, @@ -279,21 +308,25 @@ namespace OpenIddict.Tests { } [Fact] - public async Task ValidateAuthorizationRequest_RequestIsRejectedWhenClientCannotBeFound() { + public async Task ValidateAuthorizationRequest_RequestIsRejectedWhenClientCannotBeFound() + { // Arrange - var manager = CreateApplicationManager(instance => { + var manager = CreateApplicationManager(instance => + { instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(null); }); - var server = CreateAuthorizationServer(builder => { + var server = CreateAuthorizationServer(builder => + { builder.Services.AddSingleton(manager); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", RedirectUri = "http://www.fabrikam.com/path", ResponseType = OpenIdConnectConstants.ResponseTypes.Code @@ -307,11 +340,13 @@ namespace OpenIddict.Tests { } [Fact] - public async Task ValidateAuthorizationRequest_RequestIsRejectedWhenClientHasNoRedirectUri() { + public async Task ValidateAuthorizationRequest_RequestIsRejectedWhenClientHasNoRedirectUri() + { // Arrange var application = new OpenIddictApplication(); - var manager = CreateApplicationManager(instance => { + var manager = CreateApplicationManager(instance => + { instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); @@ -319,14 +354,16 @@ namespace OpenIddict.Tests { .ReturnsAsync(false); }); - var server = CreateAuthorizationServer(builder => { + var server = CreateAuthorizationServer(builder => + { builder.Services.AddSingleton(manager); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", RedirectUri = "http://www.fabrikam.com/path", ResponseType = OpenIdConnectConstants.ResponseTypes.Code @@ -341,11 +378,13 @@ namespace OpenIddict.Tests { } [Fact] - public async Task ValidateAuthorizationRequest_RequestIsRejectedWhenRedirectUriIsInvalid() { + public async Task ValidateAuthorizationRequest_RequestIsRejectedWhenRedirectUriIsInvalid() + { // Arrange var application = new OpenIddictApplication(); - var manager = CreateApplicationManager(instance => { + var manager = CreateApplicationManager(instance => + { instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); @@ -356,14 +395,16 @@ namespace OpenIddict.Tests { .ReturnsAsync(false); }); - var server = CreateAuthorizationServer(builder => { + var server = CreateAuthorizationServer(builder => + { builder.Services.AddSingleton(manager); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", RedirectUri = "http://www.fabrikam.com/path", ResponseType = OpenIdConnectConstants.ResponseTypes.Code @@ -383,11 +424,13 @@ namespace OpenIddict.Tests { [InlineData("code token")] [InlineData("id_token token")] [InlineData("token")] - public async Task ValidateAuthorizationRequest_ImplicitOrHybridRequestIsRejectedWhenClientIsConfidential(string type) { + public async Task ValidateAuthorizationRequest_ImplicitOrHybridRequestIsRejectedWhenClientIsConfidential(string type) + { // Arrange var application = new OpenIddictApplication(); - var manager = CreateApplicationManager(instance => { + var manager = CreateApplicationManager(instance => + { instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); @@ -401,14 +444,16 @@ namespace OpenIddict.Tests { .ReturnsAsync(OpenIddictConstants.ClientTypes.Confidential); }); - var server = CreateAuthorizationServer(builder => { + var server = CreateAuthorizationServer(builder => + { builder.Services.AddSingleton(manager); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", Nonce = "n-0S6_WzA2Mj", RedirectUri = "http://www.fabrikam.com/path", @@ -428,12 +473,15 @@ namespace OpenIddict.Tests { } [Fact] - public async Task HandleAuthorizationRequest_RequestIsPersistedInDistributedCache() { + public async Task HandleAuthorizationRequest_RequestIsPersistedInDistributedCache() + { // Arrange var cache = new Mock(); - var server = CreateAuthorizationServer(builder => { - builder.Services.AddSingleton(CreateApplicationManager(instance => { + var server = CreateAuthorizationServer(builder => + { + builder.Services.AddSingleton(CreateApplicationManager(instance => + { var application = new OpenIddictApplication(); instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) @@ -457,7 +505,8 @@ namespace OpenIddict.Tests { var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", RedirectUri = "http://www.fabrikam.com/path", ResponseType = OpenIdConnectConstants.ResponseTypes.Token @@ -483,10 +532,13 @@ namespace OpenIddict.Tests { [InlineData("id_token")] [InlineData("id_token token")] [InlineData("token")] - public async Task HandleAuthorizationRequest_RequestsAreNotHandledLocally(string type) { + public async Task HandleAuthorizationRequest_RequestsAreNotHandledLocally(string type) + { // Arrange - var server = CreateAuthorizationServer(builder => { - builder.Services.AddSingleton(CreateApplicationManager(instance => { + var server = CreateAuthorizationServer(builder => + { + builder.Services.AddSingleton(CreateApplicationManager(instance => + { var application = new OpenIddictApplication(); instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) @@ -502,7 +554,8 @@ namespace OpenIddict.Tests { .ReturnsAsync(OpenIddictConstants.ClientTypes.Public); })); - builder.Services.AddSingleton(CreateTokenManager(instance => { + builder.Services.AddSingleton(CreateTokenManager(instance => + { var token = new OpenIddictToken(); instance.Setup(mock => mock.CreateAsync(OpenIdConnectConstants.TokenTypeHints.AuthorizationCode, "Bob le Magnifique", It.IsAny())) @@ -516,7 +569,8 @@ namespace OpenIddict.Tests { var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", Nonce = "n-0S6_WzA2Mj", RedirectUri = "http://www.fabrikam.com/path", @@ -531,16 +585,19 @@ namespace OpenIddict.Tests { } [Fact] - public async Task ApplyAuthorizationResponse_RequestIsRemovedFromDistributedCache() { + public async Task ApplyAuthorizationResponse_RequestIsRemovedFromDistributedCache() + { // Arrange - var request = new OpenIdConnectRequest { + var request = new OpenIdConnectRequest + { ClientId = "Fabrikam", RedirectUri = "http://www.fabrikam.com/path", ResponseType = OpenIdConnectConstants.ResponseTypes.Token }; var stream = new MemoryStream(); - using (var writer = new BsonWriter(stream)) { + using (var writer = new BsonWriter(stream)) + { writer.CloseOutput = false; var serializer = JsonSerializer.CreateDefault(); @@ -553,8 +610,10 @@ namespace OpenIddict.Tests { "b2ee7815-5579-4ff7-86b0-ba671b939d96")) .ReturnsAsync(stream.ToArray()); - var server = CreateAuthorizationServer(builder => { - builder.Services.AddSingleton(CreateApplicationManager(instance => { + var server = CreateAuthorizationServer(builder => + { + builder.Services.AddSingleton(CreateApplicationManager(instance => + { var application = new OpenIddictApplication(); instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) @@ -578,7 +637,8 @@ namespace OpenIddict.Tests { var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest + { RequestId = "b2ee7815-5579-4ff7-86b0-ba671b939d96" }); @@ -591,10 +651,13 @@ namespace OpenIddict.Tests { } [Fact] - public async Task ApplyAuthorizationResponse_ErroredRequestIsNotHandledLocallyWhenStatusCodeMiddlewareIsEnabled() { + public async Task ApplyAuthorizationResponse_ErroredRequestIsNotHandledLocallyWhenStatusCodeMiddlewareIsEnabled() + { // Arrange - var server = CreateAuthorizationServer(builder => { - builder.Services.AddSingleton(CreateApplicationManager(instance => { + var server = CreateAuthorizationServer(builder => + { + builder.Services.AddSingleton(CreateApplicationManager(instance => + { var application = new OpenIddictApplication(); instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) @@ -616,7 +679,8 @@ namespace OpenIddict.Tests { var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync("/authorize-status-code-middleware", new OpenIdConnectRequest { + var response = await client.PostAsync("/authorize-status-code-middleware", new OpenIdConnectRequest + { ClientId = null, RedirectUri = null, ResponseType = null diff --git a/test/OpenIddict.Tests/OpenIddictProviderTests.Discovery.cs b/test/OpenIddict.Tests/OpenIddictProviderTests.Discovery.cs index 457a5d7d..e354324f 100644 --- a/test/OpenIddict.Tests/OpenIddictProviderTests.Discovery.cs +++ b/test/OpenIddict.Tests/OpenIddictProviderTests.Discovery.cs @@ -10,10 +10,13 @@ using Newtonsoft.Json.Linq; using OpenIddict.Core; using Xunit; -namespace OpenIddict.Tests { - public partial class OpenIddictProviderTests { +namespace OpenIddict.Tests +{ + public partial class OpenIddictProviderTests + { [Fact] - public async Task HandleConfigurationRequest_PlainCodeChallengeMethodIsNotReturned() { + public async Task HandleConfigurationRequest_PlainCodeChallengeMethodIsNotReturned() + { // Arrange var server = CreateAuthorizationServer(); @@ -34,10 +37,13 @@ namespace OpenIddict.Tests { [InlineData(OpenIdConnectConstants.GrantTypes.Implicit)] [InlineData(OpenIdConnectConstants.GrantTypes.Password)] [InlineData(OpenIdConnectConstants.GrantTypes.RefreshToken)] - public async Task HandleConfigurationRequest_EnabledFlowsAreReturned(string flow) { + public async Task HandleConfigurationRequest_EnabledFlowsAreReturned(string flow) + { // Arrange - var server = CreateAuthorizationServer(builder => { - builder.Configure(options => { + var server = CreateAuthorizationServer(builder => + { + builder.Configure(options => + { options.GrantTypes.Clear(); options.GrantTypes.Add(flow); }); @@ -59,7 +65,8 @@ namespace OpenIddict.Tests { [InlineData(OpenIdConnectConstants.Scopes.Email)] [InlineData(OpenIdConnectConstants.Scopes.Phone)] [InlineData(OpenIddictConstants.Scopes.Roles)] - public async Task HandleConfigurationRequest_StandardScopesAreExposed(string scope) { + public async Task HandleConfigurationRequest_StandardScopesAreExposed(string scope) + { // Arrange var server = CreateAuthorizationServer(); @@ -73,7 +80,8 @@ namespace OpenIddict.Tests { } [Fact] - public async Task HandleConfigurationRequest_OfflineAccessScopeIsReturnedWhenRefreshTokenFlowIsEnabled() { + public async Task HandleConfigurationRequest_OfflineAccessScopeIsReturnedWhenRefreshTokenFlowIsEnabled() + { // Arrange var server = CreateAuthorizationServer(); @@ -88,10 +96,13 @@ namespace OpenIddict.Tests { } [Fact] - public async Task HandleConfigurationRequest_OfflineAccessScopeIsReturnedWhenRefreshTokenFlowIsDisabled() { + public async Task HandleConfigurationRequest_OfflineAccessScopeIsReturnedWhenRefreshTokenFlowIsDisabled() + { // Arrange - var server = CreateAuthorizationServer(builder => { - builder.Configure(options => { + var server = CreateAuthorizationServer(builder => + { + builder.Configure(options => + { // Note: at least one flow must be enabled. options.GrantTypes.Clear(); options.GrantTypes.Add(OpenIdConnectConstants.GrantTypes.AuthorizationCode); @@ -109,7 +120,8 @@ namespace OpenIddict.Tests { } [Fact] - public async Task HandleConfigurationRequest_ExternalProvidersAreCorrectlyReturned() { + public async Task HandleConfigurationRequest_ExternalProvidersAreCorrectlyReturned() + { // Arrange var server = CreateAuthorizationServer(); diff --git a/test/OpenIddict.Tests/OpenIddictProviderTests.Exchange.cs b/test/OpenIddict.Tests/OpenIddictProviderTests.Exchange.cs index 29c021cb..7af6e32d 100644 --- a/test/OpenIddict.Tests/OpenIddictProviderTests.Exchange.cs +++ b/test/OpenIddict.Tests/OpenIddictProviderTests.Exchange.cs @@ -15,23 +15,28 @@ using OpenIddict.Core; using OpenIddict.Models; using Xunit; -namespace OpenIddict.Tests { - public partial class OpenIddictProviderTests { +namespace OpenIddict.Tests +{ + public partial class OpenIddictProviderTests + { [Theory] [InlineData(OpenIdConnectConstants.GrantTypes.AuthorizationCode)] [InlineData(OpenIdConnectConstants.GrantTypes.ClientCredentials)] [InlineData(OpenIdConnectConstants.GrantTypes.Password)] [InlineData(OpenIdConnectConstants.GrantTypes.RefreshToken)] - public async Task ValidateTokenRequest_RequestIsRejectedWhenFlowIsNotEnabled(string flow) { + public async Task ValidateTokenRequest_RequestIsRejectedWhenFlowIsNotEnabled(string flow) + { // Arrange - var server = CreateAuthorizationServer(builder => { + var server = CreateAuthorizationServer(builder => + { builder.Configure(options => options.GrantTypes.Remove(flow)); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest + { Code = "SplxlOBeZQQYbYS6WxSbIA", GrantType = flow, Username = "johndoe", @@ -45,16 +50,19 @@ namespace OpenIddict.Tests { } [Fact] - public async Task ValidateTokenRequest_RequestWithOfflineAccessScopeIsRejectedWhenRefreshTokenFlowIsDisabled() { + public async Task ValidateTokenRequest_RequestWithOfflineAccessScopeIsRejectedWhenRefreshTokenFlowIsDisabled() + { // Arrange - var server = CreateAuthorizationServer(builder => { + var server = CreateAuthorizationServer(builder => + { builder.Configure(options => options.GrantTypes.Remove(OpenIdConnectConstants.GrantTypes.RefreshToken)); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest + { GrantType = OpenIdConnectConstants.GrantTypes.Password, Username = "johndoe", Password = "A3ddj3w", @@ -67,14 +75,16 @@ namespace OpenIddict.Tests { } [Fact] - public async Task ValidateTokenRequest_ClientCredentialsRequestWithOfflineAccessScopeIsRejected() { + public async Task ValidateTokenRequest_ClientCredentialsRequestWithOfflineAccessScopeIsRejected() + { // Arrange var server = CreateAuthorizationServer(); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest + { GrantType = OpenIdConnectConstants.GrantTypes.ClientCredentials, Scope = OpenIdConnectConstants.Scopes.OfflineAccess }); @@ -87,14 +97,16 @@ namespace OpenIddict.Tests { [Theory] [InlineData("client_id", "")] [InlineData("", "client_secret")] - public async Task ValidateTokenRequest_ClientCredentialsRequestIsRejectedWhenCredentialsAreMissing(string identifier, string secret) { + public async Task ValidateTokenRequest_ClientCredentialsRequestIsRejectedWhenCredentialsAreMissing(string identifier, string secret) + { // Arrange var server = CreateAuthorizationServer(); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest + { ClientId = identifier, ClientSecret = secret, GrantType = OpenIdConnectConstants.GrantTypes.ClientCredentials @@ -106,14 +118,16 @@ namespace OpenIddict.Tests { } [Fact] - public async Task ValidateTokenRequest_RequestWithoutClientIdIsRejectedWhenClientIdentificationIsRequired() { + public async Task ValidateTokenRequest_RequestWithoutClientIdIsRejectedWhenClientIdentificationIsRequired() + { // Arrange var server = CreateAuthorizationServer(builder => builder.RequireClientIdentification()); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest + { ClientId = null, GrantType = OpenIdConnectConstants.GrantTypes.Password, Username = "johndoe", @@ -126,21 +140,25 @@ namespace OpenIddict.Tests { } [Fact] - public async Task ValidateTokenRequest_RequestIsRejectedWhenClientCannotBeFound() { + public async Task ValidateTokenRequest_RequestIsRejectedWhenClientCannotBeFound() + { // Arrange - var manager = CreateApplicationManager(instance => { + var manager = CreateApplicationManager(instance => + { instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(null); }); - var server = CreateAuthorizationServer(builder => { + var server = CreateAuthorizationServer(builder => + { builder.Services.AddSingleton(manager); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", GrantType = OpenIdConnectConstants.GrantTypes.Password, Username = "johndoe", @@ -155,11 +173,13 @@ namespace OpenIddict.Tests { } [Fact] - public async Task ValidateTokenRequest_ClientCredentialsRequestFromPublicClientIsRejected() { + public async Task ValidateTokenRequest_ClientCredentialsRequestFromPublicClientIsRejected() + { // Arrange var application = new OpenIddictApplication(); - var manager = CreateApplicationManager(instance => { + var manager = CreateApplicationManager(instance => + { instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); @@ -167,14 +187,16 @@ namespace OpenIddict.Tests { .ReturnsAsync(OpenIddictConstants.ClientTypes.Public); }); - var server = CreateAuthorizationServer(builder => { + var server = CreateAuthorizationServer(builder => + { builder.Services.AddSingleton(manager); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", GrantType = OpenIdConnectConstants.GrantTypes.ClientCredentials @@ -189,11 +211,13 @@ namespace OpenIddict.Tests { } [Fact] - public async Task ValidateTokenRequest_ClientSecretCannotBeUsedByPublicClients() { + public async Task ValidateTokenRequest_ClientSecretCannotBeUsedByPublicClients() + { // Arrange var application = new OpenIddictApplication(); - var manager = CreateApplicationManager(instance => { + var manager = CreateApplicationManager(instance => + { instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); @@ -201,14 +225,16 @@ namespace OpenIddict.Tests { .ReturnsAsync(OpenIddictConstants.ClientTypes.Public); }); - var server = CreateAuthorizationServer(builder => { + var server = CreateAuthorizationServer(builder => + { builder.Services.AddSingleton(manager); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", GrantType = OpenIdConnectConstants.GrantTypes.Password, @@ -225,11 +251,13 @@ namespace OpenIddict.Tests { } [Fact] - public async Task ValidateTokenRequest_ClientSecretIsRequiredForConfidentialClients() { + public async Task ValidateTokenRequest_ClientSecretIsRequiredForConfidentialClients() + { // Arrange var application = new OpenIddictApplication(); - var manager = CreateApplicationManager(instance => { + var manager = CreateApplicationManager(instance => + { instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); @@ -237,14 +265,16 @@ namespace OpenIddict.Tests { .ReturnsAsync(OpenIddictConstants.ClientTypes.Confidential); }); - var server = CreateAuthorizationServer(builder => { + var server = CreateAuthorizationServer(builder => + { builder.Services.AddSingleton(manager); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", ClientSecret = null, GrantType = OpenIdConnectConstants.GrantTypes.Password, @@ -261,11 +291,13 @@ namespace OpenIddict.Tests { } [Fact] - public async Task ValidateTokenRequest_RequestIsRejectedWhenClientCredentialsAreInvalid() { + public async Task ValidateTokenRequest_RequestIsRejectedWhenClientCredentialsAreInvalid() + { // Arrange var application = new OpenIddictApplication(); - var manager = CreateApplicationManager(instance => { + var manager = CreateApplicationManager(instance => + { instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); @@ -276,14 +308,16 @@ namespace OpenIddict.Tests { .ReturnsAsync(false); }); - var server = CreateAuthorizationServer(builder => { + var server = CreateAuthorizationServer(builder => + { builder.Services.AddSingleton(manager); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", GrantType = OpenIdConnectConstants.GrantTypes.Password, @@ -301,7 +335,8 @@ namespace OpenIddict.Tests { } [Fact] - public async Task HandleTokenRequest_AuthorizationCodeRevocationIsIgnoredWhenTokenRevocationIsDisabled() { + public async Task HandleTokenRequest_AuthorizationCodeRevocationIsIgnoredWhenTokenRevocationIsDisabled() + { // Arrange var ticket = new AuthenticationTicket( new ClaimsPrincipal(), @@ -317,8 +352,10 @@ namespace OpenIddict.Tests { format.Setup(mock => mock.Unprotect("SplxlOBeZQQYbYS6WxSbIA")) .Returns(ticket); - var server = CreateAuthorizationServer(builder => { - builder.Services.AddSingleton(CreateApplicationManager(instance => { + var server = CreateAuthorizationServer(builder => + { + builder.Services.AddSingleton(CreateApplicationManager(instance => + { var application = new OpenIddictApplication(); instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) @@ -337,7 +374,8 @@ namespace OpenIddict.Tests { var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", Code = "SplxlOBeZQQYbYS6WxSbIA", GrantType = OpenIdConnectConstants.GrantTypes.AuthorizationCode @@ -348,7 +386,8 @@ namespace OpenIddict.Tests { } [Fact] - public async Task HandleTokenRequest_RefreshTokenRevocationIsIgnoredWhenTokenRevocationIsDisabled() { + public async Task HandleTokenRequest_RefreshTokenRevocationIsIgnoredWhenTokenRevocationIsDisabled() + { // Arrange var ticket = new AuthenticationTicket( new ClaimsPrincipal(), @@ -363,8 +402,10 @@ namespace OpenIddict.Tests { format.Setup(mock => mock.Unprotect("8xLOxBtZp8")) .Returns(ticket); - var server = CreateAuthorizationServer(builder => { - builder.Services.AddSingleton(CreateApplicationManager(instance => { + var server = CreateAuthorizationServer(builder => + { + builder.Services.AddSingleton(CreateApplicationManager(instance => + { var application = new OpenIddictApplication(); instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) @@ -383,7 +424,8 @@ namespace OpenIddict.Tests { var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest + { GrantType = OpenIdConnectConstants.GrantTypes.RefreshToken, RefreshToken = "8xLOxBtZp8" }); @@ -393,7 +435,8 @@ namespace OpenIddict.Tests { } [Fact] - public async Task HandleTokenRequest_RequestIsRejectedWhenAuthorizationCodeIsExpired() { + public async Task HandleTokenRequest_RequestIsRejectedWhenAuthorizationCodeIsExpired() + { // Arrange var ticket = new AuthenticationTicket( new ClaimsPrincipal(), @@ -409,13 +452,16 @@ namespace OpenIddict.Tests { format.Setup(mock => mock.Unprotect("SplxlOBeZQQYbYS6WxSbIA")) .Returns(ticket); - var manager = CreateTokenManager(instance => { + var manager = CreateTokenManager(instance => + { instance.Setup(mock => mock.FindByIdAsync("3E228451-1555-46F7-A471-951EFBA23A56", It.IsAny())) .ReturnsAsync(null); }); - var server = CreateAuthorizationServer(builder => { - builder.Services.AddSingleton(CreateApplicationManager(instance => { + var server = CreateAuthorizationServer(builder => + { + builder.Services.AddSingleton(CreateApplicationManager(instance => + { var application = new OpenIddictApplication(); instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) @@ -433,7 +479,8 @@ namespace OpenIddict.Tests { var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", Code = "SplxlOBeZQQYbYS6WxSbIA", GrantType = OpenIdConnectConstants.GrantTypes.AuthorizationCode @@ -447,7 +494,8 @@ namespace OpenIddict.Tests { } [Fact] - public async Task HandleTokenRequest_RequestIsRejectedWhenRefreshTokenIsExpired() { + public async Task HandleTokenRequest_RequestIsRejectedWhenRefreshTokenIsExpired() + { // Arrange var ticket = new AuthenticationTicket( new ClaimsPrincipal(), @@ -462,13 +510,16 @@ namespace OpenIddict.Tests { format.Setup(mock => mock.Unprotect("8xLOxBtZp8")) .Returns(ticket); - var manager = CreateTokenManager(instance => { + var manager = CreateTokenManager(instance => + { instance.Setup(mock => mock.FindByIdAsync("60FFF7EA-F98E-437B-937E-5073CC313103", It.IsAny())) .ReturnsAsync(null); }); - var server = CreateAuthorizationServer(builder => { - builder.Services.AddSingleton(CreateApplicationManager(instance => { + var server = CreateAuthorizationServer(builder => + { + builder.Services.AddSingleton(CreateApplicationManager(instance => + { var application = new OpenIddictApplication(); instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) @@ -486,7 +537,8 @@ namespace OpenIddict.Tests { var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest + { GrantType = OpenIdConnectConstants.GrantTypes.RefreshToken, RefreshToken = "8xLOxBtZp8" }); @@ -499,7 +551,8 @@ namespace OpenIddict.Tests { } [Fact] - public async Task HandleTokenRequest_AuthorizationCodeIsAutomaticallyRevoked() { + public async Task HandleTokenRequest_AuthorizationCodeIsAutomaticallyRevoked() + { // Arrange var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme); identity.AddClaim(ClaimTypes.NameIdentifier, "Bob le Bricoleur"); @@ -520,13 +573,16 @@ namespace OpenIddict.Tests { var token = new OpenIddictToken(); - var manager = CreateTokenManager(instance => { + var manager = CreateTokenManager(instance => + { instance.Setup(mock => mock.FindByIdAsync("3E228451-1555-46F7-A471-951EFBA23A56", It.IsAny())) .ReturnsAsync(token); }); - var server = CreateAuthorizationServer(builder => { - builder.Services.AddSingleton(CreateApplicationManager(instance => { + var server = CreateAuthorizationServer(builder => + { + builder.Services.AddSingleton(CreateApplicationManager(instance => + { var application = new OpenIddictApplication(); instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) @@ -544,7 +600,8 @@ namespace OpenIddict.Tests { var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", Code = "SplxlOBeZQQYbYS6WxSbIA", GrantType = OpenIdConnectConstants.GrantTypes.AuthorizationCode @@ -556,7 +613,8 @@ namespace OpenIddict.Tests { } [Fact] - public async Task HandleTokenRequest_RefreshTokenIsAutomaticallyRevokedWhenSlidingExpirationIsEnabled() { + public async Task HandleTokenRequest_RefreshTokenIsAutomaticallyRevokedWhenSlidingExpirationIsEnabled() + { // Arrange var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme); identity.AddClaim(ClaimTypes.NameIdentifier, "Bob le Bricoleur"); @@ -576,13 +634,16 @@ namespace OpenIddict.Tests { var token = new OpenIddictToken(); - var manager = CreateTokenManager(instance => { + var manager = CreateTokenManager(instance => + { instance.Setup(mock => mock.FindByIdAsync("60FFF7EA-F98E-437B-937E-5073CC313103", It.IsAny())) .ReturnsAsync(token); }); - var server = CreateAuthorizationServer(builder => { - builder.Services.AddSingleton(CreateApplicationManager(instance => { + var server = CreateAuthorizationServer(builder => + { + builder.Services.AddSingleton(CreateApplicationManager(instance => + { var application = new OpenIddictApplication(); instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) @@ -600,7 +661,8 @@ namespace OpenIddict.Tests { var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest + { GrantType = OpenIdConnectConstants.GrantTypes.RefreshToken, RefreshToken = "8xLOxBtZp8" }); @@ -616,7 +678,8 @@ namespace OpenIddict.Tests { [InlineData(OpenIdConnectConstants.GrantTypes.Password)] [InlineData(OpenIdConnectConstants.GrantTypes.RefreshToken)] [InlineData("urn:ietf:params:oauth:grant-type:custom_grant")] - public async Task HandleTokenRequest_RequestsAreNotHandledLocally(string flow) { + public async Task HandleTokenRequest_RequestsAreNotHandledLocally(string flow) + { // Arrange var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme); identity.AddClaim(ClaimTypes.NameIdentifier, "Bob le Bricoleur"); @@ -628,7 +691,8 @@ namespace OpenIddict.Tests { ticket.SetTicketId("60FFF7EA-F98E-437B-937E-5073CC313103"); - switch (flow) { + switch (flow) + { case OpenIdConnectConstants.GrantTypes.AuthorizationCode: ticket.SetUsage(OpenIdConnectConstants.Usages.AuthorizationCode); ticket.SetPresenters("Fabrikam"); @@ -646,13 +710,16 @@ namespace OpenIddict.Tests { var token = new OpenIddictToken(); - var manager = CreateTokenManager(instance => { + var manager = CreateTokenManager(instance => + { instance.Setup(mock => mock.FindByIdAsync("60FFF7EA-F98E-437B-937E-5073CC313103", It.IsAny())) .ReturnsAsync(token); }); - var server = CreateAuthorizationServer(builder => { - builder.Services.AddSingleton(CreateApplicationManager(instance => { + var server = CreateAuthorizationServer(builder => + { + builder.Services.AddSingleton(CreateApplicationManager(instance => + { var application = new OpenIddictApplication(); instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) @@ -676,7 +743,8 @@ namespace OpenIddict.Tests { var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", Code = "8xLOxBtZp8", diff --git a/test/OpenIddict.Tests/OpenIddictProviderTests.Introspection.cs b/test/OpenIddict.Tests/OpenIddictProviderTests.Introspection.cs index 918d0743..722d3385 100644 --- a/test/OpenIddict.Tests/OpenIddictProviderTests.Introspection.cs +++ b/test/OpenIddict.Tests/OpenIddictProviderTests.Introspection.cs @@ -16,17 +16,21 @@ using OpenIddict.Core; using OpenIddict.Models; using Xunit; -namespace OpenIddict.Tests { - public partial class OpenIddictProviderTests { +namespace OpenIddict.Tests +{ + public partial class OpenIddictProviderTests + { [Fact] - public async Task ExtractIntrospectionRequest_GetRequestsAreRejected() { + public async Task ExtractIntrospectionRequest_GetRequestsAreRejected() + { // Arrange var server = CreateAuthorizationServer(); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.GetAsync(IntrospectionEndpoint, new OpenIdConnectRequest { + var response = await client.GetAsync(IntrospectionEndpoint, new OpenIdConnectRequest + { Token = "2YotnFZFEjr1zCsicMWpAA" }); @@ -38,14 +42,16 @@ namespace OpenIddict.Tests { [Theory] [InlineData("client_id", "")] [InlineData("", "client_secret")] - public async Task ValidateIntrospectionRequest_ClientCredentialsRequestIsRejectedWhenCredentialsAreMissing(string identifier, string secret) { + public async Task ValidateIntrospectionRequest_ClientCredentialsRequestIsRejectedWhenCredentialsAreMissing(string identifier, string secret) + { // Arrange var server = CreateAuthorizationServer(); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest + { ClientId = identifier, ClientSecret = secret, Token = "2YotnFZFEjr1zCsicMWpAA" @@ -57,21 +63,25 @@ namespace OpenIddict.Tests { } [Fact] - public async Task ValidateIntrospectionRequest_RequestIsRejectedWhenClientCannotBeFound() { + public async Task ValidateIntrospectionRequest_RequestIsRejectedWhenClientCannotBeFound() + { // Arrange - var manager = CreateApplicationManager(instance => { + var manager = CreateApplicationManager(instance => + { instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(null); }); - var server = CreateAuthorizationServer(builder => { + var server = CreateAuthorizationServer(builder => + { builder.Services.AddSingleton(manager); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", Token = "2YotnFZFEjr1zCsicMWpAA" @@ -85,11 +95,13 @@ namespace OpenIddict.Tests { } [Fact] - public async Task ValidateIntrospectionRequest_RequestsSentByPublicClientsAreRejected() { + public async Task ValidateIntrospectionRequest_RequestsSentByPublicClientsAreRejected() + { // Arrange var application = new OpenIddictApplication(); - var manager = CreateApplicationManager(instance => { + var manager = CreateApplicationManager(instance => + { instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); @@ -97,14 +109,16 @@ namespace OpenIddict.Tests { .ReturnsAsync(OpenIddictConstants.ClientTypes.Public); }); - var server = CreateAuthorizationServer(builder => { + var server = CreateAuthorizationServer(builder => + { builder.Services.AddSingleton(manager); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", Token = "2YotnFZFEjr1zCsicMWpAA" @@ -119,11 +133,13 @@ namespace OpenIddict.Tests { } [Fact] - public async Task ValidateIntrospectionRequest_RequestIsRejectedWhenClientCredentialsAreInvalid() { + public async Task ValidateIntrospectionRequest_RequestIsRejectedWhenClientCredentialsAreInvalid() + { // Arrange var application = new OpenIddictApplication(); - var manager = CreateApplicationManager(instance => { + var manager = CreateApplicationManager(instance => + { instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); @@ -134,14 +150,16 @@ namespace OpenIddict.Tests { .ReturnsAsync(false); }); - var server = CreateAuthorizationServer(builder => { + var server = CreateAuthorizationServer(builder => + { builder.Services.AddSingleton(manager); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", Token = "2YotnFZFEjr1zCsicMWpAA" @@ -157,7 +175,8 @@ namespace OpenIddict.Tests { } [Fact] - public async Task HandleIntrospectionRequest_RequestIsRejectedWhenClientIsNotAValidAudience() { + public async Task HandleIntrospectionRequest_RequestIsRejectedWhenClientIsNotAValidAudience() + { // Arrange var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme); identity.AddClaim(ClaimTypes.NameIdentifier, "Bob le Bricoleur"); @@ -176,8 +195,10 @@ namespace OpenIddict.Tests { format.Setup(mock => mock.Unprotect("2YotnFZFEjr1zCsicMWpAA")) .Returns(ticket); - var server = CreateAuthorizationServer(builder => { - builder.Services.AddSingleton(CreateApplicationManager(instance => { + var server = CreateAuthorizationServer(builder => + { + builder.Services.AddSingleton(CreateApplicationManager(instance => + { var application = new OpenIddictApplication(); instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) @@ -196,7 +217,8 @@ namespace OpenIddict.Tests { var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", Token = "2YotnFZFEjr1zCsicMWpAA" @@ -208,7 +230,8 @@ namespace OpenIddict.Tests { } [Fact] - public async Task HandleIntrospectionRequest_AuthorizationCodeRevocationIsIgnoredWhenTokenRevocationIsDisabled() { + public async Task HandleIntrospectionRequest_AuthorizationCodeRevocationIsIgnoredWhenTokenRevocationIsDisabled() + { // Arrange var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme); identity.AddClaim(ClaimTypes.NameIdentifier, "Bob le Bricoleur"); @@ -226,8 +249,10 @@ namespace OpenIddict.Tests { format.Setup(mock => mock.Unprotect("2YotnFZFEjr1zCsicMWpAA")) .Returns(ticket); - var server = CreateAuthorizationServer(builder => { - builder.Services.AddSingleton(CreateApplicationManager(instance => { + var server = CreateAuthorizationServer(builder => + { + builder.Services.AddSingleton(CreateApplicationManager(instance => + { var application = new OpenIddictApplication(); instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) @@ -249,7 +274,8 @@ namespace OpenIddict.Tests { var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", Token = "2YotnFZFEjr1zCsicMWpAA" @@ -260,7 +286,8 @@ namespace OpenIddict.Tests { } [Fact] - public async Task HandleIntrospectionRequest_RefreshTokenRevocationIsIgnoredWhenTokenRevocationIsDisabled() { + public async Task HandleIntrospectionRequest_RefreshTokenRevocationIsIgnoredWhenTokenRevocationIsDisabled() + { // Arrange var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme); identity.AddClaim(ClaimTypes.NameIdentifier, "Bob le Bricoleur"); @@ -278,8 +305,10 @@ namespace OpenIddict.Tests { format.Setup(mock => mock.Unprotect("2YotnFZFEjr1zCsicMWpAA")) .Returns(ticket); - var server = CreateAuthorizationServer(builder => { - builder.Services.AddSingleton(CreateApplicationManager(instance => { + var server = CreateAuthorizationServer(builder => + { + builder.Services.AddSingleton(CreateApplicationManager(instance => + { var application = new OpenIddictApplication(); instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) @@ -301,7 +330,8 @@ namespace OpenIddict.Tests { var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", Token = "2YotnFZFEjr1zCsicMWpAA" @@ -312,7 +342,8 @@ namespace OpenIddict.Tests { } [Fact] - public async Task HandleIntrospectionRequest_RequestIsRejectedWhenAuthorizationCodeIsRevoked() { + public async Task HandleIntrospectionRequest_RequestIsRejectedWhenAuthorizationCodeIsRevoked() + { // Arrange var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme); identity.AddClaim(ClaimTypes.NameIdentifier, "Bob le Bricoleur"); @@ -330,13 +361,16 @@ namespace OpenIddict.Tests { format.Setup(mock => mock.Unprotect("2YotnFZFEjr1zCsicMWpAA")) .Returns(ticket); - var manager = CreateTokenManager(instance => { + var manager = CreateTokenManager(instance => + { instance.Setup(mock => mock.FindByIdAsync("3E228451-1555-46F7-A471-951EFBA23A56", It.IsAny())) .ReturnsAsync(null); }); - var server = CreateAuthorizationServer(builder => { - builder.Services.AddSingleton(CreateApplicationManager(instance => { + var server = CreateAuthorizationServer(builder => + { + builder.Services.AddSingleton(CreateApplicationManager(instance => + { var application = new OpenIddictApplication(); instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) @@ -357,7 +391,8 @@ namespace OpenIddict.Tests { var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", Token = "2YotnFZFEjr1zCsicMWpAA" @@ -371,7 +406,8 @@ namespace OpenIddict.Tests { } [Fact] - public async Task HandleIntrospectionRequest_RequestIsRejectedWhenRefreshTokenIsRevoked() { + public async Task HandleIntrospectionRequest_RequestIsRejectedWhenRefreshTokenIsRevoked() + { // Arrange var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme); identity.AddClaim(ClaimTypes.NameIdentifier, "Bob le Bricoleur"); @@ -389,13 +425,16 @@ namespace OpenIddict.Tests { format.Setup(mock => mock.Unprotect("2YotnFZFEjr1zCsicMWpAA")) .Returns(ticket); - var manager = CreateTokenManager(instance => { + var manager = CreateTokenManager(instance => + { instance.Setup(mock => mock.FindByIdAsync("3E228451-1555-46F7-A471-951EFBA23A56", It.IsAny())) .ReturnsAsync(null); }); - var server = CreateAuthorizationServer(builder => { - builder.Services.AddSingleton(CreateApplicationManager(instance => { + var server = CreateAuthorizationServer(builder => + { + builder.Services.AddSingleton(CreateApplicationManager(instance => + { var application = new OpenIddictApplication(); instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) @@ -416,7 +455,8 @@ namespace OpenIddict.Tests { var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(IntrospectionEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", Token = "2YotnFZFEjr1zCsicMWpAA" diff --git a/test/OpenIddict.Tests/OpenIddictProviderTests.Revocation.cs b/test/OpenIddict.Tests/OpenIddictProviderTests.Revocation.cs index c6a90aaa..9d41bfb5 100644 --- a/test/OpenIddict.Tests/OpenIddictProviderTests.Revocation.cs +++ b/test/OpenIddict.Tests/OpenIddictProviderTests.Revocation.cs @@ -18,19 +18,23 @@ using OpenIddict.Core; using OpenIddict.Models; using Xunit; -namespace OpenIddict.Tests { - public partial class OpenIddictProviderTests { +namespace OpenIddict.Tests +{ + public partial class OpenIddictProviderTests + { [Theory] [InlineData(OpenIdConnectConstants.TokenTypeHints.AccessToken)] [InlineData(OpenIdConnectConstants.TokenTypeHints.IdToken)] - public async Task ValidateRevocationRequest_UnknownTokenTokenHintIsRejected(string hint) { + public async Task ValidateRevocationRequest_UnknownTokenTokenHintIsRejected(string hint) + { // Arrange var server = CreateAuthorizationServer(); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(RevocationEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(RevocationEndpoint, new OpenIdConnectRequest + { Token = "SlAV32hkKG", TokenTypeHint = hint }); @@ -42,14 +46,16 @@ namespace OpenIddict.Tests { } [Fact] - public async Task ValidateRevocationRequest_RequestWithoutClientIdIsRejectedWhenClientIdentificationIsRequired() { + public async Task ValidateRevocationRequest_RequestWithoutClientIdIsRejectedWhenClientIdentificationIsRequired() + { // Arrange var server = CreateAuthorizationServer(builder => builder.RequireClientIdentification()); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(RevocationEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(RevocationEndpoint, new OpenIdConnectRequest + { Token = "SlAV32hkKG", TokenTypeHint = OpenIdConnectConstants.TokenTypeHints.RefreshToken }); @@ -60,21 +66,25 @@ namespace OpenIddict.Tests { } [Fact] - public async Task ValidateRevocationRequest_RequestIsRejectedWhenClientCannotBeFound() { + public async Task ValidateRevocationRequest_RequestIsRejectedWhenClientCannotBeFound() + { // Arrange - var manager = CreateApplicationManager(instance => { + var manager = CreateApplicationManager(instance => + { instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(null); }); - var server = CreateAuthorizationServer(builder => { + var server = CreateAuthorizationServer(builder => + { builder.Services.AddSingleton(manager); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(RevocationEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(RevocationEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", Token = "SlAV32hkKG", TokenTypeHint = OpenIdConnectConstants.TokenTypeHints.RefreshToken @@ -88,11 +98,13 @@ namespace OpenIddict.Tests { } [Fact] - public async Task ValidateRevocationRequest_ClientSecretCannotBeUsedByPublicClients() { + public async Task ValidateRevocationRequest_ClientSecretCannotBeUsedByPublicClients() + { // Arrange var application = new OpenIddictApplication(); - var manager = CreateApplicationManager(instance => { + var manager = CreateApplicationManager(instance => + { instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); @@ -100,14 +112,16 @@ namespace OpenIddict.Tests { .ReturnsAsync(OpenIddictConstants.ClientTypes.Public); }); - var server = CreateAuthorizationServer(builder => { + var server = CreateAuthorizationServer(builder => + { builder.Services.AddSingleton(manager); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(RevocationEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(RevocationEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", Token = "SlAV32hkKG", @@ -123,11 +137,13 @@ namespace OpenIddict.Tests { } [Fact] - public async Task ValidateRevocationRequest_ClientSecretIsRequiredForConfidentialClients() { + public async Task ValidateRevocationRequest_ClientSecretIsRequiredForConfidentialClients() + { // Arrange var application = new OpenIddictApplication(); - var manager = CreateApplicationManager(instance => { + var manager = CreateApplicationManager(instance => + { instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); @@ -135,14 +151,16 @@ namespace OpenIddict.Tests { .ReturnsAsync(OpenIddictConstants.ClientTypes.Confidential); }); - var server = CreateAuthorizationServer(builder => { + var server = CreateAuthorizationServer(builder => + { builder.Services.AddSingleton(manager); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(RevocationEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(RevocationEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", ClientSecret = null, Token = "SlAV32hkKG", @@ -158,11 +176,13 @@ namespace OpenIddict.Tests { } [Fact] - public async Task ValidateRevocationRequest_RequestIsRejectedWhenClientCredentialsAreInvalid() { + public async Task ValidateRevocationRequest_RequestIsRejectedWhenClientCredentialsAreInvalid() + { // Arrange var application = new OpenIddictApplication(); - var manager = CreateApplicationManager(instance => { + var manager = CreateApplicationManager(instance => + { instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) .ReturnsAsync(application); @@ -173,14 +193,16 @@ namespace OpenIddict.Tests { .ReturnsAsync(false); }); - var server = CreateAuthorizationServer(builder => { + var server = CreateAuthorizationServer(builder => + { builder.Services.AddSingleton(manager); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(RevocationEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(RevocationEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", ClientSecret = "7Fjfp0ZBr1KtDRbnfVdmIw", Token = "SlAV32hkKG", @@ -197,7 +219,8 @@ namespace OpenIddict.Tests { } [Fact] - public async Task HandleRevocationRequest_RequestIsRejectedWhenTokenIsAnAccessToken() { + public async Task HandleRevocationRequest_RequestIsRejectedWhenTokenIsAnAccessToken() + { // Arrange var ticket = new AuthenticationTicket( new ClaimsPrincipal(), @@ -212,14 +235,16 @@ namespace OpenIddict.Tests { format.Setup(mock => mock.Unprotect("SlAV32hkKG")) .Returns(ticket); - var server = CreateAuthorizationServer(builder => { + var server = CreateAuthorizationServer(builder => + { builder.Configure(options => options.AccessTokenFormat = format.Object); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(RevocationEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(RevocationEndpoint, new OpenIdConnectRequest + { Token = "SlAV32hkKG" }); @@ -231,7 +256,8 @@ namespace OpenIddict.Tests { } [Fact] - public async Task HandleRevocationRequest_RequestIsNotRejectedWhenTokenIsAnIdentityToken() { + public async Task HandleRevocationRequest_RequestIsNotRejectedWhenTokenIsAnIdentityToken() + { // Arrange var token = Mock.Of(mock => mock.ValidFrom == DateTime.UtcNow.AddDays(-1) && @@ -249,14 +275,16 @@ namespace OpenIddict.Tests { .Setup(mock => mock.ValidateToken("SlAV32hkKG", It.IsAny(), out token)) .Returns(new ClaimsPrincipal(identity)); - var server = CreateAuthorizationServer(builder => { + var server = CreateAuthorizationServer(builder => + { builder.Configure(options => options.IdentityTokenHandler = handler.Object); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(RevocationEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(RevocationEndpoint, new OpenIdConnectRequest + { Token = "SlAV32hkKG" }); @@ -272,7 +300,8 @@ namespace OpenIddict.Tests { } [Fact] - public async Task HandleRevocationRequest_TokenIsNotRevokedWhenItIsAlreadyInvalid() { + public async Task HandleRevocationRequest_TokenIsNotRevokedWhenItIsAlreadyInvalid() + { // Arrange var ticket = new AuthenticationTicket( new ClaimsPrincipal(), @@ -287,12 +316,14 @@ namespace OpenIddict.Tests { format.Setup(mock => mock.Unprotect("SlAV32hkKG")) .Returns(ticket); - var manager = CreateTokenManager(instance => { + var manager = CreateTokenManager(instance => + { instance.Setup(mock => mock.FindByIdAsync("3E228451-1555-46F7-A471-951EFBA23A56", It.IsAny())) .ReturnsAsync(null); }); - var server = CreateAuthorizationServer(builder => { + var server = CreateAuthorizationServer(builder => + { builder.Services.AddSingleton(manager); builder.Configure(options => options.AccessTokenFormat = format.Object); @@ -301,7 +332,8 @@ namespace OpenIddict.Tests { var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(RevocationEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(RevocationEndpoint, new OpenIdConnectRequest + { Token = "SlAV32hkKG" }); @@ -313,7 +345,8 @@ namespace OpenIddict.Tests { } [Fact] - public async Task HandleRevocationRequest_TokenIsSuccessfullyRevoked() { + public async Task HandleRevocationRequest_TokenIsSuccessfullyRevoked() + { // Arrange var ticket = new AuthenticationTicket( new ClaimsPrincipal(), @@ -330,12 +363,14 @@ namespace OpenIddict.Tests { var token = new OpenIddictToken(); - var manager = CreateTokenManager(instance => { + var manager = CreateTokenManager(instance => + { instance.Setup(mock => mock.FindByIdAsync("3E228451-1555-46F7-A471-951EFBA23A56", It.IsAny())) .ReturnsAsync(token); }); - var server = CreateAuthorizationServer(builder => { + var server = CreateAuthorizationServer(builder => + { builder.Services.AddSingleton(manager); builder.Configure(options => options.AccessTokenFormat = format.Object); @@ -344,7 +379,8 @@ namespace OpenIddict.Tests { var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(RevocationEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(RevocationEndpoint, new OpenIdConnectRequest + { Token = "SlAV32hkKG" }); diff --git a/test/OpenIddict.Tests/OpenIddictProviderTests.Serialization.cs b/test/OpenIddict.Tests/OpenIddictProviderTests.Serialization.cs index a410f8ee..f4eb0ce0 100644 --- a/test/OpenIddict.Tests/OpenIddictProviderTests.Serialization.cs +++ b/test/OpenIddict.Tests/OpenIddictProviderTests.Serialization.cs @@ -10,15 +10,20 @@ using OpenIddict.Core; using OpenIddict.Models; using Xunit; -namespace OpenIddict.Tests { - public partial class OpenIddictProviderTests { +namespace OpenIddict.Tests +{ + public partial class OpenIddictProviderTests + { [Fact] - public async Task SerializeAuthorizationCode_AuthorizationCodeIsNotPersistedWhenRevocationIsDisabled() { + public async Task SerializeAuthorizationCode_AuthorizationCodeIsNotPersistedWhenRevocationIsDisabled() + { // Arrange var manager = CreateTokenManager(); - var server = CreateAuthorizationServer(builder => { - builder.Services.AddSingleton(CreateApplicationManager(instance => { + var server = CreateAuthorizationServer(builder => + { + builder.Services.AddSingleton(CreateApplicationManager(instance => + { var application = new OpenIddictApplication(); instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) @@ -44,7 +49,8 @@ namespace OpenIddict.Tests { var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", RedirectUri = "http://www.fabrikam.com/path", ResponseType = OpenIdConnectConstants.ResponseTypes.Code @@ -57,11 +63,13 @@ namespace OpenIddict.Tests { } [Fact] - public async Task SerializeAuthorizationCode_AuthorizationCodeIsCorrectlyPersisted() { + public async Task SerializeAuthorizationCode_AuthorizationCodeIsCorrectlyPersisted() + { // Arrange var token = new OpenIddictToken(); - var manager = CreateTokenManager(instance => { + var manager = CreateTokenManager(instance => + { instance.Setup(mock => mock.CreateAsync(OpenIdConnectConstants.TokenTypeHints.AuthorizationCode, "Bob le Magnifique", It.IsAny())) .ReturnsAsync(token); @@ -69,8 +77,10 @@ namespace OpenIddict.Tests { .ReturnsAsync("3E228451-1555-46F7-A471-951EFBA23A56"); }); - var server = CreateAuthorizationServer(builder => { - builder.Services.AddSingleton(CreateApplicationManager(instance => { + var server = CreateAuthorizationServer(builder => + { + builder.Services.AddSingleton(CreateApplicationManager(instance => + { var application = new OpenIddictApplication(); instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) @@ -92,7 +102,8 @@ namespace OpenIddict.Tests { var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", RedirectUri = "http://www.fabrikam.com/path", ResponseType = OpenIdConnectConstants.ResponseTypes.Code @@ -106,11 +117,13 @@ namespace OpenIddict.Tests { } [Fact] - public async Task SerializeAuthorizationCode_ClientApplicationIsAutomaticallyAttached() { + public async Task SerializeAuthorizationCode_ClientApplicationIsAutomaticallyAttached() + { // Arrange var token = new OpenIddictToken(); - var manager = CreateTokenManager(instance => { + var manager = CreateTokenManager(instance => + { instance.Setup(mock => mock.CreateAsync(OpenIdConnectConstants.TokenTypeHints.AuthorizationCode, "Bob le Magnifique", It.IsAny())) .ReturnsAsync(token); @@ -121,8 +134,10 @@ namespace OpenIddict.Tests { .Returns(Task.FromResult(0)); }); - var server = CreateAuthorizationServer(builder => { - builder.Services.AddSingleton(CreateApplicationManager(instance => { + var server = CreateAuthorizationServer(builder => + { + builder.Services.AddSingleton(CreateApplicationManager(instance => + { var application = new OpenIddictApplication(); instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) @@ -147,7 +162,8 @@ namespace OpenIddict.Tests { var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", RedirectUri = "http://www.fabrikam.com/path", ResponseType = OpenIdConnectConstants.ResponseTypes.Code @@ -160,11 +176,13 @@ namespace OpenIddict.Tests { } [Fact] - public async Task SerializeAuthorizationCode_AuthorizationIsAutomaticallyAttached() { + public async Task SerializeAuthorizationCode_AuthorizationIsAutomaticallyAttached() + { // Arrange var token = new OpenIddictToken(); - var manager = CreateTokenManager(instance => { + var manager = CreateTokenManager(instance => + { instance.Setup(mock => mock.CreateAsync(OpenIdConnectConstants.TokenTypeHints.AuthorizationCode, "Bob le Magnifique", It.IsAny())) .ReturnsAsync(token); @@ -178,8 +196,10 @@ namespace OpenIddict.Tests { .Returns(Task.FromResult(0)); }); - var server = CreateAuthorizationServer(builder => { - builder.Services.AddSingleton(CreateApplicationManager(instance => { + var server = CreateAuthorizationServer(builder => + { + builder.Services.AddSingleton(CreateApplicationManager(instance => + { var application = new OpenIddictApplication(); instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) @@ -198,7 +218,8 @@ namespace OpenIddict.Tests { .ReturnsAsync("3E228451-1555-46F7-A471-951EFBA23A56"); })); - builder.Services.AddSingleton(CreateAuthorizationManager(instance => { + builder.Services.AddSingleton(CreateAuthorizationManager(instance => + { instance.Setup(mock => mock.FindByIdAsync("1AF06AB2-A0FC-4E3D-86AF-E04DA8C7BE70", It.IsAny())) .ReturnsAsync(new OpenIddictAuthorization()); })); @@ -209,7 +230,8 @@ namespace OpenIddict.Tests { var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(AuthorizationEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", RedirectUri = "http://www.fabrikam.com/path", ResponseType = OpenIdConnectConstants.ResponseTypes.Code, @@ -222,11 +244,13 @@ namespace OpenIddict.Tests { } [Fact] - public async Task SerializeRefreshToken_RefreshTokenIsNotPersistedWhenRevocationIsDisabled() { + public async Task SerializeRefreshToken_RefreshTokenIsNotPersistedWhenRevocationIsDisabled() + { // Arrange var manager = CreateTokenManager(); - var server = CreateAuthorizationServer(builder => { + var server = CreateAuthorizationServer(builder => + { builder.Services.AddSingleton(manager); builder.Configure(options => options.RevocationEndpointPath = PathString.Empty); @@ -237,7 +261,8 @@ namespace OpenIddict.Tests { var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest + { GrantType = OpenIdConnectConstants.GrantTypes.Password, Username = "johndoe", Password = "A3ddj3w", @@ -251,11 +276,13 @@ namespace OpenIddict.Tests { } [Fact] - public async Task SerializeRefreshToken_RefreshTokenIsCorrectlyPersisted() { + public async Task SerializeRefreshToken_RefreshTokenIsCorrectlyPersisted() + { // Arrange var token = new OpenIddictToken(); - var manager = CreateTokenManager(instance => { + var manager = CreateTokenManager(instance => + { instance.Setup(mock => mock.CreateAsync(OpenIdConnectConstants.TokenTypeHints.RefreshToken, "Bob le Magnifique", It.IsAny())) .ReturnsAsync(token); @@ -263,14 +290,16 @@ namespace OpenIddict.Tests { .ReturnsAsync("3E228451-1555-46F7-A471-951EFBA23A56"); }); - var server = CreateAuthorizationServer(builder => { + var server = CreateAuthorizationServer(builder => + { builder.Services.AddSingleton(manager); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest + { GrantType = OpenIdConnectConstants.GrantTypes.Password, Username = "johndoe", Password = "A3ddj3w", @@ -285,11 +314,13 @@ namespace OpenIddict.Tests { } [Fact] - public async Task SerializeRefreshToken_ClientApplicationIsAutomaticallyAttached() { + public async Task SerializeRefreshToken_ClientApplicationIsAutomaticallyAttached() + { // Arrange var token = new OpenIddictToken(); - var manager = CreateTokenManager(instance => { + var manager = CreateTokenManager(instance => + { instance.Setup(mock => mock.CreateAsync(OpenIdConnectConstants.TokenTypeHints.RefreshToken, "Bob le Magnifique", It.IsAny())) .ReturnsAsync(token); @@ -300,8 +331,10 @@ namespace OpenIddict.Tests { .Returns(Task.FromResult(0)); }); - var server = CreateAuthorizationServer(builder => { - builder.Services.AddSingleton(CreateApplicationManager(instance => { + var server = CreateAuthorizationServer(builder => + { + builder.Services.AddSingleton(CreateApplicationManager(instance => + { var application = new OpenIddictApplication(); instance.Setup(mock => mock.FindByClientIdAsync("Fabrikam", It.IsAny())) @@ -320,7 +353,8 @@ namespace OpenIddict.Tests { var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest + { ClientId = "Fabrikam", GrantType = OpenIdConnectConstants.GrantTypes.Password, Username = "johndoe", @@ -335,11 +369,13 @@ namespace OpenIddict.Tests { } [Fact] - public async Task SerializeRefreshToken_AuthorizationIsAutomaticallyAttached() { + public async Task SerializeRefreshToken_AuthorizationIsAutomaticallyAttached() + { // Arrange var token = new OpenIddictToken(); - var manager = CreateTokenManager(instance => { + var manager = CreateTokenManager(instance => + { instance.Setup(mock => mock.CreateAsync(OpenIdConnectConstants.TokenTypeHints.RefreshToken, "Bob le Magnifique", It.IsAny())) .ReturnsAsync(token); @@ -350,8 +386,10 @@ namespace OpenIddict.Tests { .Returns(Task.FromResult(0)); }); - var server = CreateAuthorizationServer(builder => { - builder.Services.AddSingleton(CreateAuthorizationManager(instance => { + var server = CreateAuthorizationServer(builder => + { + builder.Services.AddSingleton(CreateAuthorizationManager(instance => + { instance.Setup(mock => mock.FindByIdAsync("1AF06AB2-A0FC-4E3D-86AF-E04DA8C7BE70", It.IsAny())) .ReturnsAsync(new OpenIddictAuthorization()); })); @@ -362,7 +400,8 @@ namespace OpenIddict.Tests { var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(TokenEndpoint, new OpenIdConnectRequest + { GrantType = OpenIdConnectConstants.GrantTypes.Password, Username = "johndoe", Password = "A3ddj3w", diff --git a/test/OpenIddict.Tests/OpenIddictProviderTests.Session.cs b/test/OpenIddict.Tests/OpenIddictProviderTests.Session.cs index c7c263b5..f216c09a 100644 --- a/test/OpenIddict.Tests/OpenIddictProviderTests.Session.cs +++ b/test/OpenIddict.Tests/OpenIddictProviderTests.Session.cs @@ -11,17 +11,21 @@ using OpenIddict.Core; using OpenIddict.Models; using Xunit; -namespace OpenIddict.Tests { - public partial class OpenIddictProviderTests { +namespace OpenIddict.Tests +{ + public partial class OpenIddictProviderTests + { [Fact] - public async Task ExtractLogoutRequest_RequestIdParameterIsRejectedWhenRequestCachingIsDisabled() { + public async Task ExtractLogoutRequest_RequestIdParameterIsRejectedWhenRequestCachingIsDisabled() + { // Arrange var server = CreateAuthorizationServer(); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(LogoutEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(LogoutEndpoint, new OpenIdConnectRequest + { RequestId = "EFAF3596-F868-497F-96BB-AA2AD1F8B7E7" }); @@ -31,9 +35,11 @@ namespace OpenIddict.Tests { } [Fact] - public async Task ExtractLogoutRequest_InvalidRequestIdParameterIsRejected() { + public async Task ExtractLogoutRequest_InvalidRequestIdParameterIsRejected() + { // Arrange - var server = CreateAuthorizationServer(builder => { + var server = CreateAuthorizationServer(builder => + { builder.Services.AddDistributedMemoryCache(); builder.EnableRequestCaching(); @@ -42,7 +48,8 @@ namespace OpenIddict.Tests { var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(LogoutEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(LogoutEndpoint, new OpenIdConnectRequest + { RequestId = "EFAF3596-F868-497F-96BB-AA2AD1F8B7E7" }); @@ -52,21 +59,25 @@ namespace OpenIddict.Tests { } [Fact] - public async Task ValidateLogoutRequest_RequestIsRejectedWhenRedirectUriIsInvalid() { + public async Task ValidateLogoutRequest_RequestIsRejectedWhenRedirectUriIsInvalid() + { // Arrange - var manager = CreateApplicationManager(instance => { + var manager = CreateApplicationManager(instance => + { instance.Setup(mock => mock.FindByLogoutRedirectUri("http://www.fabrikam.com/path", It.IsAny())) .ReturnsAsync(null); }); - var server = CreateAuthorizationServer(builder => { + var server = CreateAuthorizationServer(builder => + { builder.Services.AddSingleton(manager); }); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(LogoutEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(LogoutEndpoint, new OpenIdConnectRequest + { PostLogoutRedirectUri = "http://www.fabrikam.com/path" }); @@ -78,12 +89,15 @@ namespace OpenIddict.Tests { } [Fact] - public async Task HandleLogoutRequest_RequestIsPersistedInDistributedCache() { + public async Task HandleLogoutRequest_RequestIsPersistedInDistributedCache() + { // Arrange var cache = new Mock(); - var server = CreateAuthorizationServer(builder => { - builder.Services.AddSingleton(CreateApplicationManager(instance => { + var server = CreateAuthorizationServer(builder => + { + builder.Services.AddSingleton(CreateApplicationManager(instance => + { var application = new OpenIddictApplication(); instance.Setup(mock => mock.FindByLogoutRedirectUri("http://www.fabrikam.com/path", It.IsAny())) @@ -98,7 +112,8 @@ namespace OpenIddict.Tests { var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(LogoutEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(LogoutEndpoint, new OpenIdConnectRequest + { PostLogoutRedirectUri = "http://www.fabrikam.com/path" }); @@ -115,10 +130,13 @@ namespace OpenIddict.Tests { } [Fact] - public async Task HandleLogoutRequest_RequestsAreNotHandledLocally() { + public async Task HandleLogoutRequest_RequestsAreNotHandledLocally() + { // Arrange - var server = CreateAuthorizationServer(builder => { - builder.Services.AddSingleton(CreateApplicationManager(instance => { + var server = CreateAuthorizationServer(builder => + { + builder.Services.AddSingleton(CreateApplicationManager(instance => + { var application = new OpenIddictApplication(); instance.Setup(mock => mock.FindByLogoutRedirectUri("http://www.fabrikam.com/path", It.IsAny())) @@ -129,7 +147,8 @@ namespace OpenIddict.Tests { var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(LogoutEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(LogoutEndpoint, new OpenIdConnectRequest + { PostLogoutRedirectUri = "http://www.fabrikam.com/path", State = "af0ifjsldkj" }); @@ -139,10 +158,13 @@ namespace OpenIddict.Tests { } [Fact] - public async Task ApplyLogoutResponse_ErroredRequestIsNotHandledLocallyWhenStatusCodeMiddlewareIsEnabled() { + public async Task ApplyLogoutResponse_ErroredRequestIsNotHandledLocallyWhenStatusCodeMiddlewareIsEnabled() + { // Arrange - var server = CreateAuthorizationServer(builder => { - builder.Services.AddSingleton(CreateApplicationManager(instance => { + var server = CreateAuthorizationServer(builder => + { + builder.Services.AddSingleton(CreateApplicationManager(instance => + { instance.Setup(mock => mock.FindByLogoutRedirectUri("http://www.fabrikam.com/path", It.IsAny())) .ReturnsAsync(null); })); @@ -153,7 +175,8 @@ namespace OpenIddict.Tests { var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync("/logout-status-code-middleware", new OpenIdConnectRequest { + var response = await client.PostAsync("/logout-status-code-middleware", new OpenIdConnectRequest + { PostLogoutRedirectUri = "http://www.fabrikam.com/path" }); diff --git a/test/OpenIddict.Tests/OpenIddictProviderTests.Userinfo.cs b/test/OpenIddict.Tests/OpenIddictProviderTests.Userinfo.cs index 2786c848..be80b2a3 100644 --- a/test/OpenIddict.Tests/OpenIddictProviderTests.Userinfo.cs +++ b/test/OpenIddict.Tests/OpenIddictProviderTests.Userinfo.cs @@ -3,16 +3,20 @@ using AspNet.Security.OpenIdConnect.Client; using AspNet.Security.OpenIdConnect.Primitives; using Xunit; -namespace OpenIddict.Tests { - public partial class OpenIddictProviderTests { +namespace OpenIddict.Tests +{ + public partial class OpenIddictProviderTests + { [Fact] - public async Task ExtractUserinfoRequest_RequestIsHandledByUserCode() { + public async Task ExtractUserinfoRequest_RequestIsHandledByUserCode() + { // Arrange var server = CreateAuthorizationServer(); var client = new OpenIdConnectClient(server.CreateClient()); // Act - var response = await client.PostAsync(UserinfoEndpoint, new OpenIdConnectRequest { + var response = await client.PostAsync(UserinfoEndpoint, new OpenIdConnectRequest + { AccessToken = "SlAV32hkKG" }); diff --git a/test/OpenIddict.Tests/OpenIddictProviderTests.cs b/test/OpenIddict.Tests/OpenIddictProviderTests.cs index 6c2ef445..3bcd5215 100644 --- a/test/OpenIddict.Tests/OpenIddictProviderTests.cs +++ b/test/OpenIddict.Tests/OpenIddictProviderTests.cs @@ -22,8 +22,10 @@ using Newtonsoft.Json; using OpenIddict.Core; using OpenIddict.Models; -namespace OpenIddict.Tests { - public partial class OpenIddictProviderTests { +namespace OpenIddict.Tests +{ + public partial class OpenIddictProviderTests + { public const string AuthorizationEndpoint = "/connect/authorize"; public const string ConfigurationEndpoint = "/.well-known/openid-configuration"; public const string IntrospectionEndpoint = "/connect/introspect"; @@ -32,14 +34,16 @@ namespace OpenIddict.Tests { public const string TokenEndpoint = "/connect/token"; public const string UserinfoEndpoint = "/connect/userinfo"; - private static TestServer CreateAuthorizationServer(Action configuration = null) { + private static TestServer CreateAuthorizationServer(Action configuration = null) + { var builder = new WebHostBuilder(); builder.UseEnvironment("Testing"); builder.ConfigureLogging(options => options.AddDebug()); - builder.ConfigureServices(services => { + builder.ConfigureServices(services => + { services.AddAuthentication(); services.AddOptions(); @@ -82,18 +86,23 @@ namespace OpenIddict.Tests { configuration?.Invoke(instance); }); - builder.Configure(app => { - app.UseStatusCodePages(context => { + builder.Configure(app => + { + app.UseStatusCodePages(context => + { context.HttpContext.Response.Headers[HeaderNames.ContentType] = "application/json"; - return context.HttpContext.Response.WriteAsync(JsonConvert.SerializeObject(new { + return context.HttpContext.Response.WriteAsync(JsonConvert.SerializeObject(new + { error_custom = OpenIdConnectConstants.Errors.InvalidRequest })); }); - app.Use(next => context => { + app.Use(next => context => + { if (context.Request.Path != "/authorize-status-code-middleware" && - context.Request.Path != "/logout-status-code-middleware") { + context.Request.Path != "/logout-status-code-middleware") + { var feature = context.Features.Get(); feature.Enabled = false; } @@ -105,13 +114,15 @@ namespace OpenIddict.Tests { // Note: the following client_id/client_secret are fake and are only // used to test the metadata returned by the discovery endpoint. - app.UseFacebookAuthentication(new FacebookOptions { + app.UseFacebookAuthentication(new FacebookOptions + { ClientId = "16018790-E88E-4553-8036-BB342579FF19", ClientSecret = "3D6499AF-5607-489B-815A-F3ACF1617296", SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme }); - app.UseGoogleAuthentication(new GoogleOptions { + app.UseGoogleAuthentication(new GoogleOptions + { ClientId = "BAF437A5-87FA-4D06-8EFD-F9BA96CCEDC4", ClientSecret = "27DF07D3-6B03-4EE0-95CD-3AC16782216B", SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme @@ -119,9 +130,11 @@ namespace OpenIddict.Tests { app.UseOpenIddict(); - app.Run(context => { + app.Run(context => + { var request = context.GetOpenIdConnectRequest(); - if (request.IsAuthorizationRequest() || request.IsTokenRequest()) { + if (request.IsAuthorizationRequest() || request.IsTokenRequest()) + { var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme); identity.AddClaim(ClaimTypes.NameIdentifier, "Bob le Magnifique"); @@ -137,14 +150,17 @@ namespace OpenIddict.Tests { return context.Authentication.SignInAsync(ticket.AuthenticationScheme, ticket.Principal, ticket.Properties); } - else if (request.IsLogoutRequest()) { + else if (request.IsLogoutRequest()) + { return context.Authentication.SignOutAsync(OpenIdConnectServerDefaults.AuthenticationScheme); } - else if (request.IsUserinfoRequest()) { + else if (request.IsUserinfoRequest()) + { context.Response.Headers[HeaderNames.ContentType] = "application/json"; - return context.Response.WriteAsync(JsonConvert.SerializeObject(new { + return context.Response.WriteAsync(JsonConvert.SerializeObject(new + { access_token = request.AccessToken, sub = "Bob le Bricoleur" })); @@ -157,7 +173,8 @@ namespace OpenIddict.Tests { return new TestServer(builder); } - private static OpenIddictApplicationManager CreateApplicationManager(Action>> setup = null) { + private static OpenIddictApplicationManager CreateApplicationManager(Action>> setup = null) + { var manager = new Mock>( Mock.Of>(), Mock.Of>>()); @@ -167,7 +184,8 @@ namespace OpenIddict.Tests { return manager.Object; } - private static OpenIddictAuthorizationManager CreateAuthorizationManager(Action>> setup = null) { + private static OpenIddictAuthorizationManager CreateAuthorizationManager(Action>> setup = null) + { var manager = new Mock>( Mock.Of>(), Mock.Of>>()); @@ -177,7 +195,8 @@ namespace OpenIddict.Tests { return manager.Object; } - private static OpenIddictTokenManager CreateTokenManager(Action>> setup = null) { + private static OpenIddictTokenManager CreateTokenManager(Action>> setup = null) + { var manager = new Mock>( Mock.Of>(), Mock.Of>>());