public ActionResult ExternalLoginConfirmation(RegisterExternalLoginModel model, string returnUrl) { string provider; string providerUserId; if (UserHelper.CustomerSession.IsRegistered || !_oAuthSecurity.TryDeserializeProviderUserId(model.ExternalLoginData, out provider, out providerUserId)) { return RedirectToLocal(returnUrl); } if (ModelState.IsValid) { var user = _userClient.GetAccountByUserName(model.UserName.ToLower()); //If user has local account then password must be correct in order to associate it with external account if (user != null && _oAuthSecurity.HasLocalAccount(user.AccountId.ToString(CultureInfo.InvariantCulture))) { if (user.StoreId != UserHelper.CustomerSession.StoreId) { var store = StoreHelper.StoreClient.GetStoreById(user.StoreId); var storeName = store != null ? store.Name : user.StoreId; ModelState.AddModelError("", string.Format("This user name is already registered with store '{0}'. Use different user name or login to store '{0}'.", storeName).Localize()); } else if (string.IsNullOrEmpty(model.NewPassword) || !_webSecurity.Login(model.UserName, model.NewPassword)) { ModelState.AddModelError("", "This user name is already used. Use correct password or another user name.".Localize()); } } else { //If there is any extrenal account associated with given user name, then we cannot allow //associate any more external logins, because someone could steal account by mapping his own external login var externalAccounts = _oAuthSecurity.GetAccountsFromUserName(model.UserName); if (externalAccounts.Count > 0) { ModelState.AddModelError("", "This user name is already associated with external account. Use different user name.".Localize()); } else if (model.CreateLocalLogin) { if (string.IsNullOrEmpty(model.NewPassword) || !model.NewPassword.Equals(model.ConfirmPassword)) { ModelState.AddModelError("", "You must specifiy a valid password.".Localize()); } } } if (ModelState.IsValid) { // Check if user already exists if (user == null) { var id = Guid.NewGuid().ToString(); user = new Account { MemberId = id, UserName = model.UserName, StoreId = UserHelper.CustomerSession.StoreId, RegisterType = RegisterType.GuestUser.GetHashCode(), AccountState = AccountState.Approved.GetHashCode() }; // Insert a new user into the database _userClient.CreateAccount(user); //Create contact _userClient.CreateContact(new Contact { MemberId = id, FullName = model.UserName }); } //Create internal login if (model.CreateLocalLogin && !_oAuthSecurity.HasLocalAccount(user.AccountId.ToString(CultureInfo.InvariantCulture))) { _webSecurity.CreateAccount(model.UserName, model.NewPassword); } //Associate external login with user or create new _oAuthSecurity.CreateOrUpdateAccount(provider, providerUserId, model.UserName); if (_oAuthSecurity.Login(provider, providerUserId, false)) { UserHelper.OnPostLogon(model.UserName); return RedirectToLocal(returnUrl); } ModelState.AddModelError("", "Failed to login".Localize()); } } ViewBag.ProviderDisplayName = _oAuthSecurity.GetOAuthClientData(provider).DisplayName; ViewBag.ReturnUrl = returnUrl; return View(model); }
public async Task<ActionResult> ExternalLoginConfirmation(RegisterExternalLoginModel model, string returnUrl) { var info = await AuthenticationManager.GetExternalLoginInfoAsync(); if (UserHelper.CustomerSession.IsRegistered || info == null) { return RedirectToLocal(returnUrl); } if (ModelState.IsValid) { var user = _userClient.GetAccountByUserName(model.Email.ToLower()); var appUser = await UserManager.FindByNameAsync(model.Email); //TODO: there is no guarantee that user is connected by userName if (user != null && appUser == null || user == null && appUser != null || user != null && user.AccountId != appUser.Id) { return View("ExternalLoginFailure"); } //If user has local account then password must be correct in order to associate it with external account if (appUser != null && await UserManager.HasPasswordAsync(appUser.Id)) { if (user.StoreId != UserHelper.CustomerSession.StoreId) { var store = StoreHelper.StoreClient.GetStoreById(user.StoreId); var storeName = store != null ? store.Name : user.StoreId; ModelState.AddModelError("", string.Format("This user name is already registered with store '{0}'. Use different user name or login to store '{0}'.", storeName).Localize()); } else if (string.IsNullOrEmpty(model.NewPassword) || await _identitySecurity.LoginAsync(model.Email, model.NewPassword) != SignInStatus.Success) { ModelState.AddModelError("", "This user name is already used. Use correct password or another user name.".Localize()); } } else if (model.CreateLocalLogin && (string.IsNullOrEmpty(model.NewPassword) || !model.NewPassword.Equals(model.ConfirmPassword))) { ModelState.AddModelError("", "You must specifiy a valid password.".Localize()); } if (ModelState.IsValid) { // Check if user already exists if (user == null) { var id = Guid.NewGuid().ToString(); user = new Account { MemberId = id, UserName = model.Email, StoreId = UserHelper.CustomerSession.StoreId, RegisterType = RegisterType.GuestUser.GetHashCode(), AccountState = AccountState.Approved.GetHashCode() }; // Insert a new user into the database _userClient.CreateAccount(user); //Create contact _userClient.CreateContact(new Contact { MemberId = id, FullName = model.Email }); } if (appUser == null) { var result = await _identitySecurity.CreateAccountAsync(model.Email, model.CreateLocalLogin ? model.NewPassword : null); if (result.Succeeded) { appUser = await UserManager.FindByNameAsync(model.Email); result = await UserManager.AddLoginAsync(appUser.Id, info.Login); if (result.Succeeded) { await SignInManager.SignInAsync(appUser, isPersistent: false, rememberBrowser: false); await UserHelper.OnPostLogonAsync(model.Email); return RedirectToLocal(returnUrl); } } AddErrors(result); } } } ViewBag.ProviderDisplayName = info.Login.LoginProvider; ViewBag.ReturnUrl = returnUrl; return View(model); }