context: using System;
  using System.Globalization;
  using System.Linq;
  using System.Security.Claims;
  using System.Threading.Tasks;
  using System.Web;
  using System.Web.Mvc;
  using Microsoft.AspNet.Identity;
  using Microsoft.AspNet.Identity.Owin;
  using Microsoft.Owin.Security;
  using Nsk.OnlineStore.Web.Site.Models;
  
  namespace Nsk.OnlineStore.Web.Site.Controllers
  {
      [Authorize]
      public class AccountController : Controller
      {
          private ApplicationSignInManager _signInManager;
          private ApplicationUserManager _userManager;
          public AccountController()
          {
          }
  
          public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager)
          {
              UserManager = userManager;
              SignInManager = signInManager;
          }
  
          public ApplicationSignInManager SignInManager
          {
              get
              {
                  return _signInManager ?? HttpContext.GetOwinContext().Get<ApplicationSignInManager>();
              }
  
              private set
              {
                  _signInManager = value;
              }
          }
  
          public ApplicationUserManager UserManager
          {
              get
              {
                  return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
              }
  
              private set
              {
                  _userManager = value;
              }
          }
  
          //
          // GET: /Account/Login
          [AllowAnonymous]
          public ActionResult Login(string returnUrl)
          {
              ViewBag.ReturnUrl = returnUrl;
              return View();
          }
  
          //
          // POST: /Account/Login
          [HttpPost]
          [AllowAnonymous]
          [ValidateAntiForgeryToken]
          public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
          {
              if (!ModelState.IsValid)
              {
                  return View(model);
              }
  
              // This doesn't count login failures towards account lockout
              // To enable password failures to trigger account lockout, change to shouldLockout: true
              var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
              switch (result)
              {
                  case SignInStatus.Success:
                      return RedirectToLocal(returnUrl);
                  case SignInStatus.LockedOut:
                      return View("Lockout");
                  case SignInStatus.RequiresVerification:
                      return RedirectToAction("SendCode", new
                      {
                      ReturnUrl = returnUrl, RememberMe = model.RememberMe
                      }
  
                      );
                  case SignInStatus.Failure:
                  default:
                      ModelState.AddModelError("", "Invalid login attempt.");
                      return View(model);
              }
          }
  
          //
          // GET: /Account/VerifyCode
          [AllowAnonymous]
          public async Task<ActionResult> VerifyCode(string provider, string returnUrl, bool rememberMe)
          {
              // Require that the user has already logged in via username/password or external login
              if (!await SignInManager.HasBeenVerifiedAsync())
              {
                  return View("Error");
              }
  
              return View(new VerifyCodeViewModel{Provider = provider, ReturnUrl = returnUrl, RememberMe = rememberMe});
          }
  
          //
          // POST: /Account/VerifyCode
          [HttpPost]
          [AllowAnonymous]
          [ValidateAntiForgeryToken]
          public async Task<ActionResult> VerifyCode(VerifyCodeViewModel model)
          {
              if (!ModelState.IsValid)
              {
                  return View(model);
              }
  
              // The following code protects for brute force attacks against the two factor codes. 
              // 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, isPersistent: model.RememberMe, rememberBrowser: model.RememberBrowser);
              switch (result)
              {
                  case SignInStatus.Success:
                      return RedirectToLocal(model.ReturnUrl);
                  case SignInStatus.LockedOut:
                      return View("Lockout");
                  case SignInStatus.Failure:
                  default:
                      ModelState.AddModelError("", "Invalid code.");
                      return View(model);
              }
          }
  
          //
          // GET: /Account/Register
          [AllowAnonymous]
          public ActionResult Register()
          {
              return View();
          }
  
          //
          // POST: /Account/Register
          [HttpPost]
          [AllowAnonymous]
          [ValidateAntiForgeryToken]
          public async Task<ActionResult> Register(RegisterViewModel model)
          {
              if (ModelState.IsValid)
              {
                  var user = new ApplicationUser{UserName = model.Email, Email = model.Email, CustomerId = model.CustomerId};
                  var result = await UserManager.CreateAsync(user, model.Password);
                  if (result.Succeeded)
                  {
                      await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
                      // 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.Id);
                      // var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
                      // await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>");
                      return RedirectToAction("Index", "Home");
                  }
  
                  AddErrors(result);
              }
  
              // If we got this far, something failed, redisplay form
              return View(model);
          }
  
          //
          // GET: /Account/ConfirmEmail
          [AllowAnonymous]
          public async Task<ActionResult> ConfirmEmail(string userId, string code)
          {
              if (userId == null || code == null)
              {
                  return View("Error");
              }
  
              var result = await UserManager.ConfirmEmailAsync(userId, code);
              return View(result.Succeeded ? "ConfirmEmail" : "Error");
          }
  
          //
          // GET: /Account/ForgotPassword
          [AllowAnonymous]
          public ActionResult ForgotPassword()
          {
              return View();
          }
  
          //
          // POST: /Account/ForgotPassword
          [HttpPost]
          [AllowAnonymous]
          [ValidateAntiForgeryToken]
          public async Task<ActionResult> ForgotPassword(ForgotPasswordViewModel model)
          {
              if (ModelState.IsValid)
              {
                  var user = await UserManager.FindByNameAsync(model.Email);
                  if (user == null || !(await UserManager.IsEmailConfirmedAsync(user.Id)))
                  {
                      // Don't reveal that the user does not exist or is not confirmed
                      return View("ForgotPasswordConfirmation");
                  }
              // 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.Id);
              // var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);		
              // await UserManager.SendEmailAsync(user.Id, "Reset Password", "Please reset your password by clicking <a href=\"" + callbackUrl + "\">here</a>");
              // return RedirectToAction("ForgotPasswordConfirmation", "Account");
              }
  
              // If we got this far, something failed, redisplay form
              return View(model);
          }
  
          //
          // GET: /Account/ForgotPasswordConfirmation
          [AllowAnonymous]
          public ActionResult ForgotPasswordConfirmation()
          {
              return View();
          }
  
          //
          // GET: /Account/ResetPassword
          [AllowAnonymous]
          public ActionResult ResetPassword(string code)
          {
  
gt:             return code == null ? View("Error") : View();