diff --git a/src/MusicStore/Areas/Admin/Controllers/StoreManagerController.cs b/src/MusicStore/Areas/Admin/Controllers/StoreManagerController.cs index 47fe4070c8..f6b52ffb38 100644 --- a/src/MusicStore/Areas/Admin/Controllers/StoreManagerController.cs +++ b/src/MusicStore/Areas/Admin/Controllers/StoreManagerController.cs @@ -9,6 +9,7 @@ using MusicStore.Hubs; using MusicStore.ViewModels; using Microsoft.Framework.Cache.Memory; using System; +using System.Threading.Tasks; namespace MusicStore.Areas.Admin.Controllers { @@ -97,12 +98,12 @@ namespace MusicStore.Areas.Admin.Controllers // POST: /StoreManager/Create [HttpPost] [ValidateAntiForgeryToken] - public IActionResult Create(Album album) + public async Task Create(Album album) { if (ModelState.IsValid) { - db.Albums.Add(album); - db.SaveChanges(); + await db.Albums.AddAsync(album, Context.RequestAborted); + await db.SaveChangesAsync(Context.RequestAborted); annoucementHub.Clients.All.announcement(new AlbumData() { Title = album.Title, Url = Url.Action("Details", "Store", new { id = album.AlbumId }) }); cache.Remove("latestAlbum"); return RedirectToAction("Index"); @@ -133,12 +134,12 @@ namespace MusicStore.Areas.Admin.Controllers // POST: /StoreManager/Edit/5 [HttpPost] [ValidateAntiForgeryToken] - public IActionResult Edit(Album album) + public async Task Edit(Album album) { if (ModelState.IsValid) { db.ChangeTracker.Entry(album).State = EntityState.Modified; - db.SaveChanges(); + await db.SaveChangesAsync(Context.RequestAborted); //Invalidate the cache entry as it is modified cache.Remove(string.Format("album_{0}", album.AlbumId)); return RedirectToAction("Index"); @@ -160,14 +161,14 @@ namespace MusicStore.Areas.Admin.Controllers // // POST: /StoreManager/RemoveAlbum/5 [HttpPost, ActionName("RemoveAlbum")] - public IActionResult RemoveAlbumConfirmed(int id) + public async Task RemoveAlbumConfirmed(int id) { Album album = db.Albums.Where(a => a.AlbumId == id).FirstOrDefault(); if (album != null) { db.Albums.Remove(album); - db.SaveChanges(); + await db.SaveChangesAsync(Context.RequestAborted); //Remove the cache entry as it is removed cache.Remove(string.Format("album_{0}", id)); } diff --git a/src/MusicStore/Controllers/AccountController.cs b/src/MusicStore/Controllers/AccountController.cs index 9d0ea2161b..e46723ec67 100644 --- a/src/MusicStore/Controllers/AccountController.cs +++ b/src/MusicStore/Controllers/AccountController.cs @@ -46,7 +46,7 @@ namespace MusicStore.Controllers // This doesn't count login failures towards account lockout // To enable password failures to trigger account lockout, change to shouldLockout: true - var signInStatus = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false); + var signInStatus = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false, cancellationToken: Context.RequestAborted); switch (signInStatus) { case SignInStatus.Success: @@ -67,7 +67,7 @@ namespace MusicStore.Controllers [AllowAnonymous] public async Task VerifyCode(string provider, bool rememberMe, string returnUrl = null) { - var user = await SignInManager.GetTwoFactorAuthenticationUserAsync(); + var user = await SignInManager.GetTwoFactorAuthenticationUserAsync(cancellationToken: Context.RequestAborted); if (user == null) { return View("Error"); @@ -77,7 +77,7 @@ namespace MusicStore.Controllers #if DEMO if (user != null) { - ViewBag.Code = await UserManager.GenerateTwoFactorTokenAsync(user, provider); + ViewBag.Code = await UserManager.GenerateTwoFactorTokenAsync(user, provider, cancellationToken: Context.RequestAborted); } #endif return View(new VerifyCodeViewModel { Provider = provider, ReturnUrl = returnUrl, RememberMe = rememberMe }); @@ -99,7 +99,7 @@ namespace MusicStore.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. // You can configure the account lockout settings in IdentityConfig - var result = await SignInManager.TwoFactorSignInAsync(model.Provider, model.Code, model.RememberMe, model.RememberBrowser); + var result = await SignInManager.TwoFactorSignInAsync(model.Provider, model.Code, model.RememberMe, model.RememberBrowser, cancellationToken: Context.RequestAborted); switch (result) { case SignInStatus.Success: @@ -131,7 +131,7 @@ namespace MusicStore.Controllers if (ModelState.IsValid) { var user = new ApplicationUser { UserName = model.Email, Email = model.Email }; - var result = await UserManager.CreateAsync(user, model.Password); + var result = await UserManager.CreateAsync(user, model.Password, cancellationToken: Context.RequestAborted); if (result.Succeeded) { //Bug: Remember browser option missing? @@ -140,9 +140,9 @@ namespace MusicStore.Controllers // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771 // Send an email with this link - string code = await UserManager.GenerateEmailConfirmationTokenAsync(user); + string code = await UserManager.GenerateEmailConfirmationTokenAsync(user, cancellationToken: Context.RequestAborted); var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Context.Request.Scheme); - await UserManager.SendEmailAsync(user, "Confirm your account", "Please confirm your account by clicking here"); + await UserManager.SendEmailAsync(user, "Confirm your account", "Please confirm your account by clicking here", cancellationToken: Context.RequestAborted); #if !DEMO return RedirectToAction("Index", "Home"); #else @@ -168,12 +168,12 @@ namespace MusicStore.Controllers return View("Error"); } - var user = await SignInManager.UserManager.FindByIdAsync(userId); + var user = await SignInManager.UserManager.FindByIdAsync(userId, cancellationToken: Context.RequestAborted); if (user == null) { return View("Error"); } - var result = await UserManager.ConfirmEmailAsync(user, code); + var result = await UserManager.ConfirmEmailAsync(user, code, cancellationToken: Context.RequestAborted); return View(result.Succeeded ? "ConfirmEmail" : "Error"); } @@ -194,8 +194,8 @@ namespace MusicStore.Controllers { if (ModelState.IsValid) { - var user = await UserManager.FindByNameAsync(model.Email); - if (user == null || !(await UserManager.IsEmailConfirmedAsync(user))) + var user = await UserManager.FindByNameAsync(model.Email, cancellationToken: Context.RequestAborted); + if (user == null || !(await UserManager.IsEmailConfirmedAsync(user, cancellationToken: Context.RequestAborted))) { // Don't reveal that the user does not exist or is not confirmed return View("ForgotPasswordConfirmation"); @@ -203,9 +203,9 @@ namespace MusicStore.Controllers // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771 // Send an email with this link - string code = await UserManager.GeneratePasswordResetTokenAsync(user); + string code = await UserManager.GeneratePasswordResetTokenAsync(user, cancellationToken: Context.RequestAborted); var callbackUrl = Url.Action("ResetPassword", "Account", new { code = code }, protocol: Context.Request.Scheme); - await UserManager.SendEmailAsync(user, "Reset Password", "Please reset your password by clicking here"); + await UserManager.SendEmailAsync(user, "Reset Password", "Please reset your password by clicking here", cancellationToken: Context.RequestAborted); #if !DEMO return RedirectToAction("ForgotPasswordConfirmation"); #else @@ -250,13 +250,13 @@ namespace MusicStore.Controllers { return View(model); } - var user = await UserManager.FindByNameAsync(model.Email); + var user = await UserManager.FindByNameAsync(model.Email, cancellationToken: Context.RequestAborted); if (user == null) { // Don't reveal that the user does not exist return RedirectToAction("ResetPasswordConfirmation", "Account"); } - var result = await UserManager.ResetPasswordAsync(user, model.Code, model.Password); + var result = await UserManager.ResetPasswordAsync(user, model.Code, model.Password, cancellationToken: Context.RequestAborted); if (result.Succeeded) { return RedirectToAction("ResetPasswordConfirmation", "Account"); @@ -292,7 +292,7 @@ namespace MusicStore.Controllers public async Task SendCode(bool rememberMe, string returnUrl = null) { //TODO : Default rememberMe as well? - var user = await SignInManager.GetTwoFactorAuthenticationUserAsync(); + var user = await SignInManager.GetTwoFactorAuthenticationUserAsync(cancellationToken: Context.RequestAborted); if (user == null) { return View("Error"); @@ -315,7 +315,7 @@ namespace MusicStore.Controllers } // Generate the token and send it - if (!await SignInManager.SendTwoFactorCodeAsync(model.SelectedProvider)) + if (!await SignInManager.SendTwoFactorCodeAsync(model.SelectedProvider, cancellationToken: Context.RequestAborted)) { return View("Error"); } @@ -327,6 +327,7 @@ namespace MusicStore.Controllers [AllowAnonymous] public async Task ExternalLoginCallback(string returnUrl = null) { + //https://github.com/aspnet/Identity/issues/216 var loginInfo = await Context.GetExternalLoginInfo(); if (loginInfo == null) { @@ -334,7 +335,7 @@ namespace MusicStore.Controllers } // Sign in the user with this external login provider if the user already has a login - var result = await SignInManager.ExternalLoginSignInAsync(loginInfo.LoginProvider, loginInfo.ProviderKey, isPersistent: false); + var result = await SignInManager.ExternalLoginSignInAsync(loginInfo.LoginProvider, loginInfo.ProviderKey, isPersistent: false, cancellationToken: Context.RequestAborted); switch (result) { case SignInStatus.Success: @@ -369,29 +370,30 @@ namespace MusicStore.Controllers if (ModelState.IsValid) { // Get the information about the user from the external login provider + //https://github.com/aspnet/Identity/issues/216 var info = await Context.GetExternalLoginInfo(); if (info == null) { return View("ExternalLoginFailure"); } var user = new ApplicationUser { UserName = model.Email, Email = model.Email }; - var result = await UserManager.CreateAsync(user); + var result = await UserManager.CreateAsync(user, cancellationToken: Context.RequestAborted); #if TESTING //Just for automated testing adding a claim named 'ManageStore' - Not required for production var manageClaim = info.ExternalIdentity.Claims.Where(c => c.Type == "ManageStore").FirstOrDefault(); if (manageClaim != null) { - await UserManager.AddClaimAsync(user, manageClaim); + await UserManager.AddClaimAsync(user, manageClaim, cancellationToken: Context.RequestAborted); } #endif if (result.Succeeded) { - result = await UserManager.AddLoginAsync(user, info); + result = await UserManager.AddLoginAsync(user, info, cancellationToken: Context.RequestAborted); if (result.Succeeded) { - await SignInManager.SignInAsync(user, isPersistent: false); + await SignInManager.SignInAsync(user, isPersistent: false, cancellationToken: Context.RequestAborted); return RedirectToLocal(returnUrl); } } @@ -432,7 +434,7 @@ namespace MusicStore.Controllers private async Task GetCurrentUserAsync() { - return await UserManager.FindByIdAsync(Context.User.Identity.GetUserId()); + return await UserManager.FindByIdAsync(Context.User.Identity.GetUserId(), cancellationToken: Context.RequestAborted); } private ActionResult RedirectToLocal(string returnUrl) diff --git a/src/MusicStore/Controllers/CheckoutController.cs b/src/MusicStore/Controllers/CheckoutController.cs index 22550646ef..6d84dcb4b1 100644 --- a/src/MusicStore/Controllers/CheckoutController.cs +++ b/src/MusicStore/Controllers/CheckoutController.cs @@ -49,14 +49,14 @@ namespace MusicStore.Controllers order.OrderDate = DateTime.Now; //Add the Order - db.Orders.Add(order); + await db.Orders.AddAsync(order, Context.RequestAborted); //Process the order var cart = ShoppingCart.GetCart(db, Context); cart.CreateOrder(order); // Save all changes - db.SaveChanges(); + await db.SaveChangesAsync(Context.RequestAborted); return RedirectToAction("Complete", new { id = order.OrderId }); diff --git a/src/MusicStore/Controllers/ManageController.cs b/src/MusicStore/Controllers/ManageController.cs index 62b59dece9..f3746f2bbf 100644 --- a/src/MusicStore/Controllers/ManageController.cs +++ b/src/MusicStore/Controllers/ManageController.cs @@ -40,11 +40,11 @@ namespace MusicStore.Controllers var user = await GetCurrentUserAsync(); var model = new IndexViewModel { - HasPassword = await UserManager.HasPasswordAsync(user), - PhoneNumber = await UserManager.GetPhoneNumberAsync(user), - TwoFactor = await UserManager.GetTwoFactorEnabledAsync(user), - Logins = await UserManager.GetLoginsAsync(user), - BrowserRemembered = await SignInManager.IsTwoFactorClientRememberedAsync(user) + HasPassword = await UserManager.HasPasswordAsync(user, cancellationToken: Context.RequestAborted), + PhoneNumber = await UserManager.GetPhoneNumberAsync(user, cancellationToken: Context.RequestAborted), + TwoFactor = await UserManager.GetTwoFactorEnabledAsync(user, cancellationToken: Context.RequestAborted), + Logins = await UserManager.GetLoginsAsync(user, cancellationToken: Context.RequestAborted), + BrowserRemembered = await SignInManager.IsTwoFactorClientRememberedAsync(user, cancellationToken: Context.RequestAborted) }; return View(model); @@ -60,10 +60,10 @@ namespace MusicStore.Controllers var user = await GetCurrentUserAsync(); if (user != null) { - var result = await UserManager.RemoveLoginAsync(user, loginProvider, providerKey); + var result = await UserManager.RemoveLoginAsync(user, loginProvider, providerKey, cancellationToken: Context.RequestAborted); if (result.Succeeded) { - await SignInManager.SignInAsync(user, isPersistent: false); + await SignInManager.SignInAsync(user, isPersistent: false, cancellationToken: Context.RequestAborted); message = ManageMessageId.RemoveLoginSuccess; } } @@ -88,6 +88,7 @@ namespace MusicStore.Controllers return View(model); } // Generate the token and send it + //https://github.com/aspnet/Identity/issues/217 var code = await UserManager.GenerateChangePhoneNumberTokenAsync(await GetCurrentUserAsync(), model.Number); if (UserManager.SmsService != null) { @@ -96,7 +97,7 @@ namespace MusicStore.Controllers Destination = model.Number, Body = "Your security code is: " + code }; - await UserManager.SmsService.SendAsync(message); + await UserManager.SmsService.SendAsync(message, cancellationToken: Context.RequestAborted); } return RedirectToAction("VerifyPhoneNumber", new { PhoneNumber = model.Number }); @@ -111,9 +112,9 @@ namespace MusicStore.Controllers var user = await GetCurrentUserAsync(); if (user != null) { - await UserManager.SetTwoFactorEnabledAsync(user, true); + await UserManager.SetTwoFactorEnabledAsync(user, true, cancellationToken: Context.RequestAborted); // TODO: flow remember me somehow? - await SignInManager.SignInAsync(user, isPersistent: false); + await SignInManager.SignInAsync(user, isPersistent: false, cancellationToken: Context.RequestAborted); } return RedirectToAction("Index", "Manage"); } @@ -127,8 +128,8 @@ namespace MusicStore.Controllers var user = await GetCurrentUserAsync(); if (user != null) { - await UserManager.SetTwoFactorEnabledAsync(user, false); - await SignInManager.SignInAsync(user, isPersistent: false); + await UserManager.SetTwoFactorEnabledAsync(user, false, cancellationToken: Context.RequestAborted); + await SignInManager.SignInAsync(user, isPersistent: false, cancellationToken: Context.RequestAborted); } return RedirectToAction("Index", "Manage"); } @@ -140,6 +141,7 @@ namespace MusicStore.Controllers // This code allows you exercise the flow without actually sending codes // For production use please register a SMS provider in IdentityConfig and generate a code here. #if DEMO + //https://github.com/aspnet/Identity/issues/217 ViewBag.Code = await UserManager.GenerateChangePhoneNumberTokenAsync(await GetCurrentUserAsync(), phoneNumber); #endif return phoneNumber == null ? View("Error") : View(new VerifyPhoneNumberViewModel { PhoneNumber = phoneNumber }); @@ -158,10 +160,10 @@ namespace MusicStore.Controllers var user = await GetCurrentUserAsync(); if (user != null) { - var result = await UserManager.ChangePhoneNumberAsync(user, model.PhoneNumber, model.Code); + var result = await UserManager.ChangePhoneNumberAsync(user, model.PhoneNumber, model.Code, cancellationToken: Context.RequestAborted); if (result.Succeeded) { - await SignInManager.SignInAsync(user, isPersistent: false); + await SignInManager.SignInAsync(user, isPersistent: false, cancellationToken: Context.RequestAborted); return RedirectToAction("Index", new { Message = ManageMessageId.AddPhoneSuccess }); } } @@ -177,10 +179,10 @@ namespace MusicStore.Controllers var user = await GetCurrentUserAsync(); if (user != null) { - var result = await UserManager.SetPhoneNumberAsync(user, null); + var result = await UserManager.SetPhoneNumberAsync(user, null, cancellationToken: Context.RequestAborted); if (result.Succeeded) { - await SignInManager.SignInAsync(user, isPersistent: false); + await SignInManager.SignInAsync(user, isPersistent: false, cancellationToken: Context.RequestAborted); return RedirectToAction("Index", new { Message = ManageMessageId.RemovePhoneSuccess }); } } @@ -207,10 +209,10 @@ namespace MusicStore.Controllers var user = await GetCurrentUserAsync(); if (user != null) { - var result = await UserManager.ChangePasswordAsync(user, model.OldPassword, model.NewPassword); + var result = await UserManager.ChangePasswordAsync(user, model.OldPassword, model.NewPassword, cancellationToken: Context.RequestAborted); if (result.Succeeded) { - await SignInManager.SignInAsync(user, isPersistent: false); + await SignInManager.SignInAsync(user, isPersistent: false, cancellationToken: Context.RequestAborted); return RedirectToAction("Index", new { Message = ManageMessageId.ChangePasswordSuccess }); } AddErrors(result); @@ -240,10 +242,10 @@ namespace MusicStore.Controllers var user = await GetCurrentUserAsync(); if (user != null) { - var result = await UserManager.AddPasswordAsync(user, model.NewPassword); + var result = await UserManager.AddPasswordAsync(user, model.NewPassword, cancellationToken: Context.RequestAborted); if (result.Succeeded) { - await SignInManager.SignInAsync(user, isPersistent: false); + await SignInManager.SignInAsync(user, isPersistent: false, cancellationToken: Context.RequestAborted); return RedirectToAction("Index", new { Message = ManageMessageId.SetPasswordSuccess }); } AddErrors(result); @@ -261,8 +263,8 @@ namespace MusicStore.Controllers var user = await GetCurrentUserAsync(); if (user != null) { - await SignInManager.RememberTwoFactorClientAsync(user); - await SignInManager.SignInAsync(user, isPersistent: false); + await SignInManager.RememberTwoFactorClientAsync(user, cancellationToken: Context.RequestAborted); + await SignInManager.SignInAsync(user, isPersistent: false, cancellationToken: Context.RequestAborted); } return RedirectToAction("Index", "Manage"); } @@ -291,7 +293,7 @@ namespace MusicStore.Controllers { return View("Error"); } - var userLogins = await UserManager.GetLoginsAsync(user); + var userLogins = await UserManager.GetLoginsAsync(user, cancellationToken: Context.RequestAborted); var otherLogins = Context.GetExternalAuthenticationTypes().Where(auth => userLogins.All(ul => auth.AuthenticationType != ul.LoginProvider)).ToList(); ViewBag.ShowRemoveButton = user.PasswordHash != null || userLogins.Count > 1; return View(new ManageLoginsViewModel @@ -322,6 +324,7 @@ namespace MusicStore.Controllers { return View("Error"); } + //https://github.com/aspnet/Identity/issues/216 var loginInfo = await Context.GetExternalLoginInfo(User.Identity.GetUserId()); if (loginInfo == null) { @@ -345,7 +348,7 @@ namespace MusicStore.Controllers //TODO: No caller - do we need this? private async Task HasPhoneNumber() { - var user = await UserManager.FindByIdAsync(User.Identity.GetUserId()); + var user = await UserManager.FindByIdAsync(User.Identity.GetUserId(), cancellationToken: Context.RequestAborted); if (user != null) { return user.PhoneNumber != null; @@ -367,7 +370,7 @@ namespace MusicStore.Controllers private async Task GetCurrentUserAsync() { - return await UserManager.FindByIdAsync(Context.User.Identity.GetUserId()); + return await UserManager.FindByIdAsync(Context.User.Identity.GetUserId(), cancellationToken: Context.RequestAborted); } private IActionResult RedirectToLocal(string returnUrl) diff --git a/src/MusicStore/Controllers/ShoppingCartController.cs b/src/MusicStore/Controllers/ShoppingCartController.cs index b13bf6867f..828cf10469 100644 --- a/src/MusicStore/Controllers/ShoppingCartController.cs +++ b/src/MusicStore/Controllers/ShoppingCartController.cs @@ -37,7 +37,7 @@ namespace MusicStore.Controllers // // GET: /ShoppingCart/AddToCart/5 - public IActionResult AddToCart(int id) + public async Task AddToCart(int id) { // Retrieve the album from the database var addedAlbum = db.Albums @@ -48,7 +48,7 @@ namespace MusicStore.Controllers cart.AddToCart(addedAlbum); - db.SaveChanges(); + await db.SaveChangesAsync(Context.RequestAborted); // Go back to the main store page for more shopping return RedirectToAction("Index"); @@ -89,7 +89,7 @@ namespace MusicStore.Controllers // Remove from cart int itemCount = cart.RemoveFromCart(id); - db.SaveChanges(); + await db.SaveChangesAsync(Context.RequestAborted); string removed = (itemCount > 0) ? " 1 copy of " : string.Empty; diff --git a/src/MusicStore/StartupNtlmAuthentication.cs b/src/MusicStore/StartupNtlmAuthentication.cs index d9b52d4038..c28d70f93a 100644 --- a/src/MusicStore/StartupNtlmAuthentication.cs +++ b/src/MusicStore/StartupNtlmAuthentication.cs @@ -11,6 +11,7 @@ using Microsoft.AspNet.Server.WebListener; using System.Security.Claims; using System.Security.Principal; using Microsoft.Framework.Cache.Memory; +using Microsoft.AspNet.Identity; namespace MusicStore { @@ -82,7 +83,7 @@ namespace MusicStore }); // Add Identity services to the services container - services.AddIdentitySqlServer(); + services.AddDefaultIdentity(configuration); // Add MVC services to the services container services.AddMvc();