public async Task <IActionResult> Validate(IList <TicketDetailViewModel> model, CancellationToken cancellationToken) { // Repopulate ticket type as that information isn't submitted back to us. var ticketTypes = await _orderService.GetTicketTypesAsync(cancellationToken : cancellationToken); foreach (var ticket in model) { var ticketType = ticketTypes.FirstOrDefault(x => x.Id == ticket.TicketType.Id); ticket.TicketType = ticketType != null ? new TicketTypeViewModel(ticketType) : null; } if (ModelState.IsValid) { HttpContext.Session.Set(ActiveOrderSessionKey, model); var viewModel = new ValidateOrderViewModel { TicketDetails = model, TicketOrderHashBase64 = Convert.ToBase64String(HttpContext.Session.GetValueHash(ActiveOrderSessionKey)), }; return(View(viewModel)); } // If we get here, something has gone wrong... return(View("TicketDetail", model)); }
public async Task <IActionResult> Confirm(ValidateOrderViewModel model, CancellationToken cancellationToken) { // Get the ticket details (we'll want them for the validation page if something goes wrong) model.TicketDetails = HttpContext.Session.Get <IList <TicketDetailViewModel> >(ActiveOrderSessionKey); if (ModelState.IsValid) { // secureValidation = false since there is no risk to a malicous user correctly determining the hash through timing attacks var sessionHasNotChanged = HttpContext.Session.ValidateValueHash(ActiveOrderSessionKey, Convert.FromBase64String(model.TicketOrderHashBase64), secureValidation: false); if (sessionHasNotChanged) { var user = await _userService.GetCurrentUserAsync(cancellationToken); var tickets = new List <Models.Ticket>(); foreach (var ticketViewModel in model.TicketDetails) { tickets.Add(GetTicketEntityFromViewModel(ticketViewModel)); } var order = await _orderService.CreateOrderAsync(user, tickets, cancellationToken : cancellationToken); return(RedirectToAction("Index", "Checkout", new { orderId = order.Id })); } } // If we get here, something has gone wrong... return(View("Validate", model)); }