diff --git a/src/Web/WebMVC/Controllers/AccountController.cs b/src/Web/WebMVC/Controllers/AccountController.cs index c76e6eabc..a62a477eb 100644 --- a/src/Web/WebMVC/Controllers/AccountController.cs +++ b/src/Web/WebMVC/Controllers/AccountController.cs @@ -19,21 +19,15 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers { private readonly UserManager _userManager; private readonly SignInManager _signInManager; - private readonly IEmailSender _emailSender; - private readonly ISmsSender _smsSender; private readonly ILogger _logger; public AccountController( UserManager userManager, SignInManager signInManager, - IEmailSender emailSender, - ISmsSender smsSender, ILoggerFactory loggerFactory) { _userManager = userManager; _signInManager = signInManager; - _emailSender = emailSender; - _smsSender = smsSender; _logger = loggerFactory.CreateLogger(); } @@ -368,44 +362,6 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers return View(new SendCodeViewModel { Providers = factorOptions, ReturnUrl = returnUrl, RememberMe = rememberMe }); } - // - // POST: /Account/SendCode - [HttpPost] - [AllowAnonymous] - [ValidateAntiForgeryToken] - public async Task SendCode(SendCodeViewModel model) - { - if (!ModelState.IsValid) - { - return View(); - } - - var user = await _signInManager.GetTwoFactorAuthenticationUserAsync(); - if (user == null) - { - return View("Error"); - } - - // Generate the token and send it - var code = await _userManager.GenerateTwoFactorTokenAsync(user, model.SelectedProvider); - if (string.IsNullOrWhiteSpace(code)) - { - return View("Error"); - } - - var message = "Your security code is: " + code; - if (model.SelectedProvider == "Email") - { - await _emailSender.SendEmailAsync(await _userManager.GetEmailAsync(user), "Security Code", message); - } - else if (model.SelectedProvider == "Phone") - { - await _smsSender.SendSmsAsync(await _userManager.GetPhoneNumberAsync(user), message); - } - - return RedirectToAction(nameof(VerifyCode), new { Provider = model.SelectedProvider, ReturnUrl = model.ReturnUrl, RememberMe = model.RememberMe }); - } - // // GET: /Account/VerifyCode [HttpGet] diff --git a/src/Web/WebMVC/Controllers/CartController.cs b/src/Web/WebMVC/Controllers/CartController.cs index ab7c7895c..c083b3e76 100644 --- a/src/Web/WebMVC/Controllers/CartController.cs +++ b/src/Web/WebMVC/Controllers/CartController.cs @@ -38,14 +38,14 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers { var user = await _userManager.GetUserAsync(HttpContext.User); var basket = _basketSvc.SetQuantities(user, quantities); + var vm = _basketSvc.UpdateBasket(basket); if (action == "[ Checkout ]") { var order = _basketSvc.MapBasketToOrder(basket); return RedirectToAction("Create", "Order"); } - - var vm = _basketSvc.UpdateBasket(basket); + return View(vm); } @@ -62,7 +62,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers UnitPrice = productDetails.Price, ProductId = productId }; - _basketSvc.AddToCart(user, product); + _basketSvc.AddItemToBasket(user, product); return RedirectToAction("Index", "Catalog"); } } diff --git a/src/Web/WebMVC/Controllers/ManageController.cs b/src/Web/WebMVC/Controllers/ManageController.cs deleted file mode 100644 index a8b629c9b..000000000 --- a/src/Web/WebMVC/Controllers/ManageController.cs +++ /dev/null @@ -1,395 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Identity; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.Logging; -using Microsoft.eShopOnContainers.WebMVC.Models; -using Microsoft.eShopOnContainers.WebMVC.Models.ManageViewModels; -using Microsoft.eShopOnContainers.WebMVC.Services; - -namespace Microsoft.eShopOnContainers.WebMVC.Controllers -{ - [Authorize] - public class ManageController : Controller - { - private readonly UserManager _userManager; - private readonly SignInManager _signInManager; - private readonly IEmailSender _emailSender; - private readonly ISmsSender _smsSender; - private readonly ILogger _logger; - - public ManageController( - UserManager userManager, - SignInManager signInManager, - IEmailSender emailSender, - ISmsSender smsSender, - ILoggerFactory loggerFactory) - { - _userManager = userManager; - _signInManager = signInManager; - _emailSender = emailSender; - _smsSender = smsSender; - _logger = loggerFactory.CreateLogger(); - } - - // - // GET: /Manage/Index - [HttpGet] - 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." - : message == ManageMessageId.SetTwoFactorSuccess ? "Your two-factor authentication provider has been set." - : message == ManageMessageId.Error ? "An error has occurred." - : message == ManageMessageId.AddPhoneSuccess ? "Your phone number was added." - : message == ManageMessageId.RemovePhoneSuccess ? "Your phone number was removed." - : ""; - - var user = await GetCurrentUserAsync(); - if (user == null) - { - return View("Error"); - } - 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), - User = user - }; - return View(model); - } - - [HttpPost] - [ValidateAntiForgeryToken] - public async Task Index(IndexViewModel model) - { - if (!ModelState.IsValid) - { - return View(model); - } - - var user = await _userManager.GetUserAsync(HttpContext.User); - - user.CardHolderName = model.User.CardHolderName; - user.CardNumber = model.User.CardNumber; - //user.CardType = model.User.CardType; - user.City = model.User.City; - user.Country = model.User.Country; - user.Expiration = model.User.Expiration; - user.State = model.User.State; - user.Street = model.User.Street; - user.ZipCode = model.User.ZipCode; - - var result = await _userManager.UpdateAsync(user); - - if (result.Succeeded) - { - _logger.LogInformation(99, "User changed his address and payment method information."); - return RedirectToAction(nameof(Index), new { Message = ManageMessageId.ProfileUpdated }); - } - - AddErrors(result); - return View(model); - } - - // - // POST: /Manage/RemoveLogin - [HttpPost] - [ValidateAntiForgeryToken] - public async Task RemoveLogin(RemoveLoginViewModel account) - { - ManageMessageId? message = ManageMessageId.Error; - var user = await GetCurrentUserAsync(); - if (user != null) - { - var result = await _userManager.RemoveLoginAsync(user, account.LoginProvider, account.ProviderKey); - if (result.Succeeded) - { - await _signInManager.SignInAsync(user, isPersistent: false); - message = ManageMessageId.RemoveLoginSuccess; - } - } - return RedirectToAction(nameof(ManageLogins), new { Message = message }); - } - - // - // GET: /Manage/AddPhoneNumber - public IActionResult AddPhoneNumber() - { - return View(); - } - - // - // POST: /Manage/AddPhoneNumber - [HttpPost] - [ValidateAntiForgeryToken] - public async Task AddPhoneNumber(AddPhoneNumberViewModel model) - { - if (!ModelState.IsValid) - { - return View(model); - } - // Generate the token and send it - var user = await GetCurrentUserAsync(); - if (user == null) - { - return View("Error"); - } - var code = await _userManager.GenerateChangePhoneNumberTokenAsync(user, model.PhoneNumber); - await _smsSender.SendSmsAsync(model.PhoneNumber, "Your security code is: " + code); - return RedirectToAction(nameof(VerifyPhoneNumber), new { PhoneNumber = model.PhoneNumber }); - } - - // - // POST: /Manage/EnableTwoFactorAuthentication - [HttpPost] - [ValidateAntiForgeryToken] - public async Task EnableTwoFactorAuthentication() - { - var user = await GetCurrentUserAsync(); - if (user != null) - { - await _userManager.SetTwoFactorEnabledAsync(user, true); - await _signInManager.SignInAsync(user, isPersistent: false); - _logger.LogInformation(1, "User enabled two-factor authentication."); - } - return RedirectToAction(nameof(Index), "Manage"); - } - - // - // POST: /Manage/DisableTwoFactorAuthentication - [HttpPost] - [ValidateAntiForgeryToken] - public async Task DisableTwoFactorAuthentication() - { - var user = await GetCurrentUserAsync(); - if (user != null) - { - await _userManager.SetTwoFactorEnabledAsync(user, false); - await _signInManager.SignInAsync(user, isPersistent: false); - _logger.LogInformation(2, "User disabled two-factor authentication."); - } - return RedirectToAction(nameof(Index), "Manage"); - } - - // - // GET: /Manage/VerifyPhoneNumber - [HttpGet] - public async Task VerifyPhoneNumber(string phoneNumber) - { - var user = await GetCurrentUserAsync(); - if (user == null) - { - return View("Error"); - } - var code = await _userManager.GenerateChangePhoneNumberTokenAsync(user, phoneNumber); - // Send an SMS to verify the phone number - return phoneNumber == null ? View("Error") : View(new VerifyPhoneNumberViewModel { PhoneNumber = phoneNumber }); - } - - // - // POST: /Manage/VerifyPhoneNumber - [HttpPost] - [ValidateAntiForgeryToken] - public async Task VerifyPhoneNumber(VerifyPhoneNumberViewModel model) - { - if (!ModelState.IsValid) - { - return View(model); - } - var user = await GetCurrentUserAsync(); - if (user != null) - { - var result = await _userManager.ChangePhoneNumberAsync(user, model.PhoneNumber, model.Code); - if (result.Succeeded) - { - await _signInManager.SignInAsync(user, isPersistent: false); - return RedirectToAction(nameof(Index), new { Message = ManageMessageId.AddPhoneSuccess }); - } - } - // If we got this far, something failed, redisplay the form - ModelState.AddModelError(string.Empty, "Failed to verify phone number"); - return View(model); - } - - // - // POST: /Manage/RemovePhoneNumber - [HttpPost] - [ValidateAntiForgeryToken] - public async Task RemovePhoneNumber() - { - var user = await GetCurrentUserAsync(); - if (user != null) - { - var result = await _userManager.SetPhoneNumberAsync(user, null); - if (result.Succeeded) - { - await _signInManager.SignInAsync(user, isPersistent: false); - return RedirectToAction(nameof(Index), new { Message = ManageMessageId.RemovePhoneSuccess }); - } - } - return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error }); - } - - // - // GET: /Manage/ChangePassword - [HttpGet] - public IActionResult ChangePassword() - { - return View(); - } - - // - // POST: /Manage/ChangePassword - [HttpPost] - [ValidateAntiForgeryToken] - public async Task ChangePassword(ChangePasswordViewModel model) - { - if (!ModelState.IsValid) - { - return View(model); - } - var user = await GetCurrentUserAsync(); - if (user != null) - { - var result = await _userManager.ChangePasswordAsync(user, model.OldPassword, model.NewPassword); - 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 }); - } - AddErrors(result); - return View(model); - } - return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error }); - } - - // - // GET: /Manage/SetPassword - [HttpGet] - public IActionResult SetPassword() - { - return View(); - } - - // - // POST: /Manage/SetPassword - [HttpPost] - [ValidateAntiForgeryToken] - public async Task SetPassword(SetPasswordViewModel model) - { - if (!ModelState.IsValid) - { - return View(model); - } - - var user = await GetCurrentUserAsync(); - if (user != null) - { - var result = await _userManager.AddPasswordAsync(user, model.NewPassword); - if (result.Succeeded) - { - await _signInManager.SignInAsync(user, isPersistent: false); - return RedirectToAction(nameof(Index), new { Message = ManageMessageId.SetPasswordSuccess }); - } - AddErrors(result); - return View(model); - } - return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error }); - } - - //GET: /Manage/ManageLogins - [HttpGet] - 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) - { - 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 - { - CurrentLogins = userLogins, - OtherLogins = otherLogins - }); - } - - // - // POST: /Manage/LinkLogin - [HttpPost] - [ValidateAntiForgeryToken] - 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)); - return Challenge(properties, provider); - } - - // - // GET: /Manage/LinkLoginCallback - [HttpGet] - public async Task LinkLoginCallback() - { - var user = await GetCurrentUserAsync(); - if (user == null) - { - return View("Error"); - } - var info = await _signInManager.GetExternalLoginInfoAsync(await _userManager.GetUserIdAsync(user)); - if (info == null) - { - return RedirectToAction(nameof(ManageLogins), new { Message = ManageMessageId.Error }); - } - var result = await _userManager.AddLoginAsync(user, info); - var message = result.Succeeded ? ManageMessageId.AddLoginSuccess : ManageMessageId.Error; - return RedirectToAction(nameof(ManageLogins), new { Message = message }); - } - - #region Helpers - - private void AddErrors(IdentityResult result) - { - foreach (var error in result.Errors) - { - ModelState.AddModelError(string.Empty, error.Description); - } - } - - public enum ManageMessageId - { - AddPhoneSuccess, - AddLoginSuccess, - ChangePasswordSuccess, - SetTwoFactorSuccess, - SetPasswordSuccess, - RemoveLoginSuccess, - RemovePhoneSuccess, - Error, - ProfileUpdated - } - - private Task GetCurrentUserAsync() - { - return _userManager.GetUserAsync(HttpContext.User); - } - - #endregion - } -} diff --git a/src/Web/WebMVC/Controllers/OrderController.cs b/src/Web/WebMVC/Controllers/OrderController.cs index e110a5f92..6ab853368 100644 --- a/src/Web/WebMVC/Controllers/OrderController.cs +++ b/src/Web/WebMVC/Controllers/OrderController.cs @@ -30,11 +30,37 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers var user = await _userManager.GetUserAsync(HttpContext.User); var basket = _basketSvc.GetBasket(user); var order = _basketSvc.MapBasketToOrder(basket); - vm.Order = order; - + vm.Order = _orderSvc.MapUserInfoIntoOrder(user, order); + return View(vm); } + [HttpPost] + public async Task Create(CreateOrderViewModel model) + { + var user = await _userManager.GetUserAsync(HttpContext.User); + var basket = _basketSvc.GetBasket(user); + var order = _basketSvc.MapBasketToOrder(basket); + + // override if user has changed some shipping address or payment info data. + _orderSvc.OverrideUserInfoIntoOrder(model.Order, order); + _orderSvc.CreateOrder(user, order); + + //Empty basket for current user. + _basketSvc.CleanBasket(user); + + //Redirect to historic list. + return RedirectToAction("Index"); + } + + public async Task Detail(string orderId) + { + var user = await _userManager.GetUserAsync(HttpContext.User); + var order = _orderSvc.GetOrder(user, orderId); + + return View(order); + } + public async Task Index(Order item) { var user = await _userManager.GetUserAsync(HttpContext.User); diff --git a/src/Web/WebMVC/Models/Address.cs b/src/Web/WebMVC/Models/Address.cs index c1f542b20..28bc90e2c 100644 --- a/src/Web/WebMVC/Models/Address.cs +++ b/src/Web/WebMVC/Models/Address.cs @@ -8,7 +8,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Models public class Address { public Guid Id { get; set; } - public string Street { get; set; } + public string Street { get; set; } public string City { get; set; } public string State { get; set; } public string StateCode { get; set; } diff --git a/src/Web/WebMVC/Models/Order.cs b/src/Web/WebMVC/Models/Order.cs index dad2e3e40..455875cd4 100644 --- a/src/Web/WebMVC/Models/Order.cs +++ b/src/Web/WebMVC/Models/Order.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Threading.Tasks; @@ -10,6 +11,8 @@ namespace Microsoft.eShopOnContainers.WebMVC.Models public Order() { OrderItems = new List(); + ShippingAddress = new Address(); + PaymentInfo = new PaymentInfo(); } public string Id; @@ -24,10 +27,14 @@ namespace Microsoft.eShopOnContainers.WebMVC.Models public int SequenceNumber { get; set; } public virtual string BuyerId { get; set; } public virtual Address ShippingAddress { get; set; } - + public virtual PaymentInfo PaymentInfo { get; set; } public virtual DateTime OrderDate { get; set; } public OrderState State { get; set; } + public decimal Total() { + return OrderItems.Sum(x => x.Quantity * x.UnitPrice); + } + //(CCE) public virtual Address BillingAddress { get; set; } //(CDLTLL) public virtual OrderStatus Status { get; set; } } diff --git a/src/Web/WebMVC/Models/PaymentInfo.cs b/src/Web/WebMVC/Models/PaymentInfo.cs index 2f840b38d..9be93ebfd 100644 --- a/src/Web/WebMVC/Models/PaymentInfo.cs +++ b/src/Web/WebMVC/Models/PaymentInfo.cs @@ -10,10 +10,11 @@ namespace Microsoft.eShopOnContainers.WebMVC.Models public Guid Id { get; set; } public string CardNumber {get;set;} public string SecurityNumber { get; set; } - public int ExpirationMonth { get; set; } - public int ExpirationYear { get; set; } + public int ExpirationMonth { get; set; } //CCE: I would simplify with a string Expiration field so I guess we are not going to validate with real data. It's a demo.. + public int ExpirationYear { get; set; } //CCE: Idem. public string CardHolderName { get; set; } - public CardType CardType { get; set; } + public CardType CardType { get; set; } //CCE: Discuss with team if this is needed for a demo. + public string Expiration { get; set; } //CCE: Added to simplify.. } public enum CardType:int diff --git a/src/Web/WebMVC/Services/BasketService.cs b/src/Web/WebMVC/Services/BasketService.cs index 57f404dcb..263f7df11 100644 --- a/src/Web/WebMVC/Services/BasketService.cs +++ b/src/Web/WebMVC/Services/BasketService.cs @@ -19,25 +19,6 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services public int ItemsInCart { get { return _itemsInCart; }} - public void AddToCart(ApplicationUser user, BasketItem product) - { - Basket activeOrder = GetBasket(user); - if (activeOrder == null) - { - activeOrder = new Basket() - { - BuyerId = user.Id, - Id = Guid.NewGuid().ToString(), - Items = new List() - }; - } - - activeOrder.Items.Add(product); - //CCE: lacks and httpcall to persist in the real back.end service. - _httpContextAccessor.HttpContext.Session.SetObject("MyActiveOrder", activeOrder); - - } - public Basket GetBasket(ApplicationUser user) { Basket activeOrder; @@ -90,5 +71,28 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services return order; } + + public void AddItemToBasket(ApplicationUser user, BasketItem product) + { + Basket activeOrder = GetBasket(user); + if (activeOrder == null) + { + activeOrder = new Basket() + { + BuyerId = user.Id, + Id = Guid.NewGuid().ToString(), + Items = new List() + }; + } + + activeOrder.Items.Add(product); + //CCE: lacks and httpcall to persist in the real back.end service. + _httpContextAccessor.HttpContext.Session.SetObject("MyActiveOrder", activeOrder); + } + + public void CleanBasket(ApplicationUser user) + { + _httpContextAccessor.HttpContext.Session.SetObject("MyActiveOrder", new Basket()); + } } } diff --git a/src/Web/WebMVC/Services/IBasketService.cs b/src/Web/WebMVC/Services/IBasketService.cs index 538a0cd7e..8db9a6171 100644 --- a/src/Web/WebMVC/Services/IBasketService.cs +++ b/src/Web/WebMVC/Services/IBasketService.cs @@ -10,9 +10,10 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services { Basket GetBasket(ApplicationUser user); int ItemsInCart { get; } - void AddToCart(ApplicationUser user, BasketItem product); + void AddItemToBasket(ApplicationUser user, BasketItem product); Basket UpdateBasket(Basket basket); Basket SetQuantities(ApplicationUser user, Dictionary quantities); Order MapBasketToOrder(Basket basket); + void CleanBasket(ApplicationUser user); } } diff --git a/src/Web/WebMVC/Services/IEmailSender.cs b/src/Web/WebMVC/Services/IEmailSender.cs deleted file mode 100644 index f443e52ff..000000000 --- a/src/Web/WebMVC/Services/IEmailSender.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Microsoft.eShopOnContainers.WebMVC.Services -{ - public interface IEmailSender - { - Task SendEmailAsync(string email, string subject, string message); - } -} diff --git a/src/Web/WebMVC/Services/IOrderingService.cs b/src/Web/WebMVC/Services/IOrderingService.cs index 2c24cd039..605f8f22a 100644 --- a/src/Web/WebMVC/Services/IOrderingService.cs +++ b/src/Web/WebMVC/Services/IOrderingService.cs @@ -9,9 +9,9 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services public interface IOrderingService { List GetMyOrders(ApplicationUser user); - Order GetOrder(ApplicationUser user, Guid orderId); - void CreateOrder(Order order); + Order GetOrder(ApplicationUser user, string orderId); + void CreateOrder(ApplicationUser user, Order order); + Order MapUserInfoIntoOrder(ApplicationUser user, Order order); + void OverrideUserInfoIntoOrder(Order original, Order destination); } - - } diff --git a/src/Web/WebMVC/Services/ISmsSender.cs b/src/Web/WebMVC/Services/ISmsSender.cs deleted file mode 100644 index b0869b390..000000000 --- a/src/Web/WebMVC/Services/ISmsSender.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Microsoft.eShopOnContainers.WebMVC.Services -{ - public interface ISmsSender - { - Task SendSmsAsync(string number, string message); - } -} diff --git a/src/Web/WebMVC/Services/MessageServices.cs b/src/Web/WebMVC/Services/MessageServices.cs deleted file mode 100644 index ca3e51f8e..000000000 --- a/src/Web/WebMVC/Services/MessageServices.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Microsoft.eShopOnContainers.WebMVC.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) - { - // Plug in your email service here to send an email. - return Task.FromResult(0); - } - - 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/src/Web/WebMVC/Services/OrderingService.cs b/src/Web/WebMVC/Services/OrderingService.cs index 59f52276f..276668af3 100644 --- a/src/Web/WebMVC/Services/OrderingService.cs +++ b/src/Web/WebMVC/Services/OrderingService.cs @@ -23,38 +23,41 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services { new Order() { + Id = Guid.NewGuid().ToString(), BuyerId = new Guid("ebcbcb4c-b032-4baa-834b-7fd66d37bc95").ToString(), OrderDate = DateTime.Now, State = OrderState.InProcess, OrderItems = new List() { - new OrderItem() { UnitPrice = 12, PictureUrl = "https://fakeimg.pl/370x240/EEEEEE/000/?text=RoslynRedT-Shirt", Quantity = 1, ProductName="Roslyn Red T-Shirt" } + new OrderItem() { UnitPrice = 12.40m, PictureUrl = "https://fakeimg.pl/370x240/EEEEEE/000/?text=RoslynRedT-Shirt", Quantity = 1, ProductName="Roslyn Red T-Shirt" } } }, new Order() { + Id = Guid.NewGuid().ToString(), BuyerId = new Guid("ebcbcb4c-b032-4baa-834b-7fd66d37bc95").ToString(), OrderDate = DateTime.Now, State = OrderState.InProcess, OrderItems = new List() { - new OrderItem() { UnitPrice = 12, PictureUrl = "https://fakeimg.pl/370x240/EEEEEE/000/?text=RoslynRedT-Shirt", Quantity = 1, ProductName="Roslyn Red T-Shirt" } + new OrderItem() { UnitPrice = 12.00m, PictureUrl = "https://fakeimg.pl/370x240/EEEEEE/000/?text=RoslynRedT-Shirt", Quantity = 1, ProductName="Roslyn Red T-Shirt" } } }, new Order() { + Id = Guid.NewGuid().ToString(), BuyerId = new Guid("ebcbcb4c-b032-4baa-834b-7fd66d37bc95").ToString(), OrderDate = DateTime.Now, State = OrderState.Delivered, OrderItems = new List() { - new OrderItem() { UnitPrice = 12, PictureUrl = "https://fakeimg.pl/370x240/EEEEEE/000/?text=RoslynRedT-Shirt", Quantity = 1, ProductName="Roslyn Red T-Shirt" } + new OrderItem() { UnitPrice = 12.05m, PictureUrl = "https://fakeimg.pl/370x240/EEEEEE/000/?text=RoslynRedT-Shirt", Quantity = 1, ProductName="Roslyn Red T-Shirt" } } } }; } - public Order GetOrder(ApplicationUser user, Guid Id) + public Order GetOrder(ApplicationUser user, string Id) { return _orders.Where(x => x.BuyerId.Equals(user.Id) && x.Id.Equals(Id)).FirstOrDefault(); } @@ -64,9 +67,43 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services return _orders.Where(x => x.BuyerId.Equals(user.Id)).ToList(); } - public void CreateOrder(Order order) + public Order MapUserInfoIntoOrder(ApplicationUser user, Order order) { - throw new NotImplementedException(); + order.ShippingAddress.City = user.City; + order.ShippingAddress.Street = user.Street; + order.ShippingAddress.State = user.State; + order.ShippingAddress.Country = user.Country; + + order.PaymentInfo.CardNumber = user.CardNumber; + order.PaymentInfo.CardHolderName = user.CardHolderName; + order.PaymentInfo.Expiration = user.Expiration; + order.PaymentInfo.SecurityNumber = user.SecurityNumber; + + return order; + } + + public void CreateOrder(ApplicationUser user, Order order) + { + order.OrderDate = DateTime.Now; + order.Id = Guid.NewGuid().ToString(); + order.BuyerId = user.Id; + order.SequenceNumber = new Random(100).Next(); + order.State = OrderState.InProcess; + + _orders.Add(order); + } + + public void OverrideUserInfoIntoOrder(Order original, Order destination) + { + destination.ShippingAddress.City = original.ShippingAddress.City; + destination.ShippingAddress.Street = original.ShippingAddress.Street; + destination.ShippingAddress.State = original.ShippingAddress.State; + destination.ShippingAddress.Country = original.ShippingAddress.Country; + + destination.PaymentInfo.CardNumber = original.PaymentInfo.CardNumber; + destination.PaymentInfo.CardHolderName = original.PaymentInfo.CardHolderName; + destination.PaymentInfo.Expiration = original.PaymentInfo.Expiration; + destination.PaymentInfo.SecurityNumber = original.PaymentInfo.SecurityNumber; } } } diff --git a/src/Web/WebMVC/Startup.cs b/src/Web/WebMVC/Startup.cs index f1666314f..5b03228d4 100644 --- a/src/Web/WebMVC/Startup.cs +++ b/src/Web/WebMVC/Startup.cs @@ -22,8 +22,7 @@ namespace Microsoft.eShopOnContainers.WebMVC var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) - .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) - .AddEnvironmentVariables(); + .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true); if (env.IsDevelopment()) { @@ -55,10 +54,8 @@ namespace Microsoft.eShopOnContainers.WebMVC services.AddSession(); // Add application services. - services.AddTransient(); - services.AddTransient(); services.AddSingleton(); //CCE: Once services are integrated, a singleton is not needed we can left transient. - services.AddTransient(); + services.AddSingleton(); services.AddTransient(); services.Configure(Configuration); diff --git a/src/Web/WebMVC/Views/Account/ConfirmEmail.cshtml b/src/Web/WebMVC/Views/Account/ConfirmEmail.cshtml deleted file mode 100644 index 3244fef5f..000000000 --- a/src/Web/WebMVC/Views/Account/ConfirmEmail.cshtml +++ /dev/null @@ -1,10 +0,0 @@ -@{ - ViewData["Title"] = "Confirm Email"; -} - -

@ViewData["Title"].

-
-

- Thank you for confirming your email. Please Click here to Log in. -

-
diff --git a/src/Web/WebMVC/Views/Account/ExternalLoginConfirmation.cshtml b/src/Web/WebMVC/Views/Account/ExternalLoginConfirmation.cshtml deleted file mode 100644 index 987fff41c..000000000 --- a/src/Web/WebMVC/Views/Account/ExternalLoginConfirmation.cshtml +++ /dev/null @@ -1,35 +0,0 @@ -@model ExternalLoginConfirmationViewModel -@{ - ViewData["Title"] = "Register"; -} - -

@ViewData["Title"].

-

Associate your @ViewData["LoginProvider"] account.

- -
-

Association Form

-
-
- -

- You've successfully authenticated with @ViewData["LoginProvider"]. - Please enter an email address for this site below and click the Register button to finish - logging in. -

-
- -
- - -
-
-
-
- -
-
-
- -@section Scripts { - @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } -} diff --git a/src/Web/WebMVC/Views/Account/ExternalLoginFailure.cshtml b/src/Web/WebMVC/Views/Account/ExternalLoginFailure.cshtml deleted file mode 100644 index d89339e01..000000000 --- a/src/Web/WebMVC/Views/Account/ExternalLoginFailure.cshtml +++ /dev/null @@ -1,8 +0,0 @@ -@{ - ViewData["Title"] = "Login Failure"; -} - -
-

@ViewData["Title"].

-

Unsuccessful login with service.

-
diff --git a/src/Web/WebMVC/Views/Account/ForgotPassword.cshtml b/src/Web/WebMVC/Views/Account/ForgotPassword.cshtml deleted file mode 100644 index ee02538a0..000000000 --- a/src/Web/WebMVC/Views/Account/ForgotPassword.cshtml +++ /dev/null @@ -1,31 +0,0 @@ -@model ForgotPasswordViewModel -@{ - ViewData["Title"] = "Forgot your password?"; -} - -

@ViewData["Title"]

-

- For more information on how to enable reset password please see this article. -

- -@*
-

Enter your email.

-
-
-
- -
- - -
-
-
-
- -
-
-
*@ - -@section Scripts { - @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } -} diff --git a/src/Web/WebMVC/Views/Account/ForgotPasswordConfirmation.cshtml b/src/Web/WebMVC/Views/Account/ForgotPasswordConfirmation.cshtml deleted file mode 100644 index ab9bf44c8..000000000 --- a/src/Web/WebMVC/Views/Account/ForgotPasswordConfirmation.cshtml +++ /dev/null @@ -1,8 +0,0 @@ -@{ - ViewData["Title"] = "Forgot Password Confirmation"; -} - -

@ViewData["Title"].

-

- Please check your email to reset your password. -

diff --git a/src/Web/WebMVC/Views/Account/Lockout.cshtml b/src/Web/WebMVC/Views/Account/Lockout.cshtml deleted file mode 100644 index 2cc946d5c..000000000 --- a/src/Web/WebMVC/Views/Account/Lockout.cshtml +++ /dev/null @@ -1,8 +0,0 @@ -@{ - ViewData["Title"] = "Locked out"; -} - -
-

Locked out.

-

This account has been locked out, please try again later.

-
diff --git a/src/Web/WebMVC/Views/Account/Login.cshtml b/src/Web/WebMVC/Views/Account/Login.cshtml index 480b0a4ef..595305f95 100644 --- a/src/Web/WebMVC/Views/Account/Login.cshtml +++ b/src/Web/WebMVC/Views/Account/Login.cshtml @@ -30,23 +30,20 @@ - @*
+
-
*@ +

Register as a new user?

-

- @*Forgot your password?*@ -

diff --git a/src/Web/WebMVC/Views/Account/Register.cshtml b/src/Web/WebMVC/Views/Account/Register.cshtml index a4f5cbbb9..721dc4440 100644 --- a/src/Web/WebMVC/Views/Account/Register.cshtml +++ b/src/Web/WebMVC/Views/Account/Register.cshtml @@ -9,10 +9,9 @@
- @*

@ViewData["Title"].

*@

CREATE NEW ACCOUNT

- @*
*@ +
diff --git a/src/Web/WebMVC/Views/Account/ResetPassword.cshtml b/src/Web/WebMVC/Views/Account/ResetPassword.cshtml deleted file mode 100644 index 6e584da56..000000000 --- a/src/Web/WebMVC/Views/Account/ResetPassword.cshtml +++ /dev/null @@ -1,43 +0,0 @@ -@model ResetPasswordViewModel -@{ - ViewData["Title"] = "Reset password"; -} - -

@ViewData["Title"].

- - -

Reset your password.

-
-
- -
- -
- - -
-
-
- -
- - -
-
-
- -
- - -
-
-
-
- -
-
- - -@section Scripts { - @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } -} diff --git a/src/Web/WebMVC/Views/Account/ResetPasswordConfirmation.cshtml b/src/Web/WebMVC/Views/Account/ResetPasswordConfirmation.cshtml deleted file mode 100644 index bef2e4570..000000000 --- a/src/Web/WebMVC/Views/Account/ResetPasswordConfirmation.cshtml +++ /dev/null @@ -1,8 +0,0 @@ -@{ - ViewData["Title"] = "Reset password confirmation"; -} - -

@ViewData["Title"].

-

- Your password has been reset. Please Click here to log in. -

diff --git a/src/Web/WebMVC/Views/Account/SendCode.cshtml b/src/Web/WebMVC/Views/Account/SendCode.cshtml deleted file mode 100644 index 8621ce71f..000000000 --- a/src/Web/WebMVC/Views/Account/SendCode.cshtml +++ /dev/null @@ -1,21 +0,0 @@ -@model SendCodeViewModel -@{ - ViewData["Title"] = "Send Verification Code"; -} - -

@ViewData["Title"].

- -
- -
-
- Select Two-Factor Authentication Provider: - - -
-
-
- -@section Scripts { - @{await Html.RenderPartialAsync("_ValidationScriptsPartial"); } -} diff --git a/src/Web/WebMVC/Views/Account/VerifyCode.cshtml b/src/Web/WebMVC/Views/Account/VerifyCode.cshtml deleted file mode 100644 index c067534aa..000000000 --- a/src/Web/WebMVC/Views/Account/VerifyCode.cshtml +++ /dev/null @@ -1,38 +0,0 @@ -@model VerifyCodeViewModel -@{ - ViewData["Title"] = "Verify"; -} - -

@ViewData["Title"].

- -
-
- - -

@ViewData["Status"]

-
-
- -
- - -
-
-
-
-
- - -
-
-
-
-
- -
-
-
- -@section Scripts { - @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } -} diff --git a/src/Web/WebMVC/Views/Cart/Index.cshtml b/src/Web/WebMVC/Views/Cart/Index.cshtml index 7e7fc0324..cb8f1026f 100644 --- a/src/Web/WebMVC/Views/Cart/Index.cshtml +++ b/src/Web/WebMVC/Views/Cart/Index.cshtml @@ -14,55 +14,11 @@
-



-
-
- - - - - - - - - - - - - @await Component.InvokeAsync("CartList", new { user = await UserManager.GetUserAsync(User) }) - -
- PRODUCT - - - - BRAND - - PRICE - - QUANTITY - - COST -
-
-
+ @await Component.InvokeAsync("CartList", new { user = await UserManager.GetUserAsync(User) })
- - -
-
SUBTOTAL
-
$ 29.00
-
TAX
-
$ 4.20
-
TOTAL
-
$ @Model.Total()
-
+ class="btn btn-default btn-brand btn-cart" + value="[ Checkout ]" name="action" />
diff --git a/src/Web/WebMVC/Views/Catalog/Index.cshtml b/src/Web/WebMVC/Views/Catalog/Index.cshtml index 6608358ee..21c9f6e4e 100644 --- a/src/Web/WebMVC/Views/Catalog/Index.cshtml +++ b/src/Web/WebMVC/Views/Catalog/Index.cshtml @@ -32,7 +32,7 @@