Example #1
0
        public async Task <IActionResult> EditProfileAsync(EditProfileViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return(View(model));
            }

            var user = await GetCurrentUserAsync();

            if (user != null)
            {
                // update all user claims
                var result = await UpdateUserClaims(user, model.ToClaims());

                if (result.Succeeded)
                {
                    return(RedirectToAction(nameof(Index), new { Message = ManageMessageId.SetPasswordSuccess }));
                }
                AddErrors(result);
                return(View(model));
            }
            return(RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error }));
        }
Example #2
0
        public async Task <IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
            {
                return(Page());
            }

            IList <IdentityResult> resultFinal = new List <IdentityResult>();

            bool confirmationEmailSent = false;
            bool confirmationSmsSent   = false;

            using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                try
                {
                    var id         = _manager.GetUserId(User);
                    var systemUser = await _manager.FindByIdAsync(id);

                    if ((systemUser.NormalizedEmail != _manager.KeyNormalizer.Normalize(EditProfileViewModel.Email) || systemUser.PhoneNumber != EditProfileViewModel.PhoneNumber) &&
                        (string.IsNullOrWhiteSpace(Password) || !await _manager.CheckPasswordAsync(systemUser, Password)))
                    {
                        ModelState.AddModelError(nameof(Password), "Invalid password when changing email or phone number");
                        return(Page());
                    }

                    EditProfileViewModel.UpdatedAt = DateTime.UtcNow;
                    var newValues     = EditProfileViewModel.ToClaims();
                    var currentValues = await _manager.GetClaimsAsync(systemUser);

                    var toInsert = newValues.Where(nv => !currentValues.Select(c => c.Type).Distinct().Contains(nv.Type));
                    var toUpdate = newValues.Where(nv => currentValues.Select(c => c.Type).Distinct().Contains(nv.Type) &&
                                                   currentValues.Where(c => c.Type == nv.Type).Single().Value != newValues.Where(c => c.Type == nv.Type).Single().Value);
                    var toRemove = currentValues.Where(ov => !newValues.Select(c => c.Type).Distinct().Contains(ov.Type) ||
                                                       string.IsNullOrWhiteSpace(newValues.Where(c => c.Type == ov.Type).Single().Value));

                    var resultAdd = await _manager.AddClaimsAsync(systemUser, toInsert);

                    var resultRemove = await _manager.RemoveClaimsAsync(systemUser, toRemove);

                    resultFinal.Add(resultAdd);
                    resultFinal.Add(resultRemove);

                    foreach (var newClaim in toUpdate)
                    {
                        var oldClaim = User.Claims.SingleOrDefault(c => c.Type == newClaim.Type);
                        if (oldClaim != null)
                        {
                            resultFinal.Add(await _manager.ReplaceClaimAsync(systemUser, oldClaim, newClaim));
                        }
                    }

                    if (resultFinal.Any(r => !r.Succeeded))
                    {
                        var errors = resultFinal.Where(r => !r.Succeeded);
                        foreach (var error in errors.SelectMany(e => e.Errors))
                        {
                            ModelState.AddModelError(error.Code, error.Description);
                        }
                        scope.Dispose();

                        return(Page());
                    }
                    else
                    {
                        if (RefreshSignIn)
                        {
                            await _signInManager.SignInAsync(systemUser, RememberMe);
                        }

                        scope.Complete();

                        if (systemUser.NormalizedEmail != _manager.KeyNormalizer.Normalize(EditProfileViewModel.Email))
                        {
                            var token = await _manager.GenerateChangeEmailTokenAsync(systemUser, EditProfileViewModel.Email);

                            var callbackUrl = Url.Page("/Account/ConfirmEmail", pageHandler: null, values: new { userId = id, token, newEmail = EditProfileViewModel.Email }, protocol: Request.Scheme);
                            await _emailSender.SendEmailConfirmationEmailAsync(EditProfileViewModel.Email, callbackUrl);

                            confirmationEmailSent = true;
                        }

                        if (systemUser.PhoneNumber != EditProfileViewModel.PhoneNumber)
                        {
                            var token = await _manager.GenerateChangePhoneNumberTokenAsync(systemUser, EditProfileViewModel.PhoneNumber);

                            var callbackUrl = Url.Page("/Account/ConfirmPhoneNumber", pageHandler: null, values: new { userId = id, token, newNumber = EditProfileViewModel.PhoneNumber }, protocol: Request.Scheme);
                            await _smsSender.SendPhoneNumberChangeConfirmationSMSAsync(EditProfileViewModel.PhoneNumber, callbackUrl);

                            confirmationSmsSent = true;
                        }

                        return(RedirectToPage("Index", new { profileUpdated = true, confirmationEmailSent, confirmationSmsSent }));
                    }
                }
                catch (Exception)
                {
                    scope.Dispose();
                    throw;
                }
            }
        }
        public async Task <IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
            {
                return(Page());
            }

            bool confirmationEmailSent = false;

            //var id = _userManager.GetUserId(User);

            using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                try
                {
                    IList <IdentityResult> resultFinal = new List <IdentityResult>();
                    var systemUser = await _userManager.FindByIdAsync(EditProfileViewModel.Id.ToString());

                    var oldEmail = systemUser.Email;

                    //Profile update
                    EditProfileViewModel.UpdatedAt = DateTime.UtcNow;
                    var newValues     = EditProfileViewModel.ToClaims();
                    var currentValues = await _userManager.GetClaimsAsync(systemUser);

                    var toInsert = newValues.Where(nv => !currentValues.Select(c => c.Type).Distinct().Contains(nv.Type));
                    var toUpdate = newValues.Where(nv => currentValues.Select(c => c.Type).Distinct().Contains(nv.Type) &&
                                                   currentValues.Where(c => c.Type == nv.Type).Single().Value != newValues.Where(c => c.Type == nv.Type).Single().Value);
                    var toRemove = currentValues.Where(ov => !newValues.Select(c => c.Type).Distinct().Contains(ov.Type) ||
                                                       string.IsNullOrWhiteSpace(newValues.Where(c => c.Type == ov.Type).Single().Value));

                    var resultAdd = await _userManager.AddClaimsAsync(systemUser, toInsert);

                    var resultRemove = await _userManager.RemoveClaimsAsync(systemUser, toRemove);

                    resultFinal.Add(resultAdd);
                    resultFinal.Add(resultRemove);

                    foreach (var newClaim in toUpdate)
                    {
                        var oldClaim = User.Claims.SingleOrDefault(c => c.Type == newClaim.Type);
                        if (oldClaim != null)
                        {
                            resultFinal.Add(await _userManager.ReplaceClaimAsync(systemUser, oldClaim, newClaim));
                        }
                    }

                    //Email update
                    if (systemUser.NormalizedEmail != _userManager.KeyNormalizer.Normalize(EditProfileViewModel.Email))
                    {
                        var token = await _userManager.GenerateChangeEmailTokenAsync(systemUser, EditProfileViewModel.Email);

                        var resultEmailChange = await _userManager.ChangeEmailAsync(systemUser, EditProfileViewModel.Email, token);

                        resultFinal.Add(resultEmailChange);
                        if (resultEmailChange.Succeeded)
                        {
                            await _emailSender.SendEmailChangeAlertEmailAsync(systemUser.Email);

                            confirmationEmailSent = true;
                        }
                    }

                    if (systemUser.PhoneNumber != EditProfileViewModel.PhoneNumber)
                    {
                        var token = await _userManager.GenerateChangePhoneNumberTokenAsync(systemUser, EditProfileViewModel.PhoneNumber);

                        var resultPhoneChange = await _userManager.ChangePhoneNumberAsync(systemUser, EditProfileViewModel.PhoneNumber, token);

                        resultFinal.Add(resultPhoneChange);
                        if (resultPhoneChange.Succeeded)
                        {
                            await _emailSender.SendPhoneNumberChangeAlertEmailAsync(systemUser.Email);

                            confirmationEmailSent = true;
                        }
                    }

                    //Role Update
                    var userRoles = await _userManager.GetRolesAsync(systemUser);

                    var rolesToAdd    = RoleChecks.Where(r => r.Value && !userRoles.Contains(r.Key)).Select(r => r.Key).ToList();
                    var rolesToRemove = RoleChecks.Where(r => !r.Value && userRoles.Contains(r.Key)).Select(r => r.Key).ToList();

                    var roleAddResult = await _userManager.AddToRolesAsync(systemUser, rolesToAdd);

                    var roleRemoveResult = await _userManager.RemoveFromRolesAsync(systemUser, rolesToRemove);

                    resultFinal.Add(roleAddResult);
                    resultFinal.Add(roleRemoveResult);

                    //Final Check
                    if (resultFinal.Any(r => !r.Succeeded))
                    {
                        var errors = resultFinal.Where(r => !r.Succeeded);
                        foreach (var error in errors.SelectMany(e => e.Errors))
                        {
                            ModelState.AddModelError(error.Code, error.Description);
                        }
                        scope.Dispose();

                        return(Page());
                    }
                    else
                    {
                        if (resultFinal.Any(r => r.Succeeded))
                        {
                            await _emailSender.SendProfileChangeAlertEmailAsync(oldEmail);
                        }

                        scope.Complete();
                        return(RedirectToPage("List", new { profileUpdated = true, confirmationEmailSent }));
                    }
                }
                catch (Exception)
                {
                    scope.Dispose();
                    throw;
                }
            }
        }