示例#1
0
        public async Task <IActionResult> EditUserInfo(EditUserInfoViewModel model)
        {
            var user = await _userManager.GetUserAsync(User);

            if (user == null)
            {
                await _signInManager.SignOutAsync();

                _notice.AddErrors(ModelState);
                return(View(model));
            }

            var emailToMakePrimary = _userManager.NormalizeKey(model.Email);
            var userLogins         = await _userManager.GetLoginsAsync(user);

            model.Logins = userLogins; // Since model binding doesn't work with IList

            if (!ModelState.IsValid)
            {
                return(View(model));
            }

            user.UserName        = model.UserName;
            user.FullName        = model.FullName;
            user.SendCodesViaSms = model.SendCodesViaSms;
            user.MobileNumber    = model.MobileNumber;

            // If the user's email is confirmed (ie. local login) and they provided a different email that exists, set it to the primary
            if (user.EmailConfirmed &&
                user.NormalizedEmail != emailToMakePrimary &&
                userLogins.Any(l => l.LoginProvider == "Email" && l.ProviderKey == emailToMakePrimary))
            {
                user.Email = emailToMakePrimary;
            }

            // Update sumbitted user info, including changing email if required
            var updateResult = await _userManager.UpdateAsync(user);

            if (!updateResult.Succeeded)
            {
                _notice.AddErrors(ModelState, updateResult);
                return(View(model));
            }

            await _events.AddEvent(AuthEventType.EditUserInfo,
                                   JsonConvert.SerializeObject(model), user);

            await _signInManager.RefreshSignInAsync(user);

            return(_notice.Success(this, "Your profile has been updated."));
        }
示例#2
0
        public async Task <IActionResult> Login(LoginViewModel model, string returnUrl = null)
        {
            if (!ModelState.IsValid)
            {
                return(View(model));
            }

            AuthOperation attemptedOperation;

            ApplicationUser userToSignTokenWith;

            var email = _userManager.NormalizeKey(model.Email);

            var userWithConfirmedEmail = await _userManager.FindByLoginAsync("Email", email);

            var userCurrentlySignedIn = await _userManager.GetUserAsync(User);

            if (userCurrentlySignedIn == null) // No locally signed-in user (trying to register or login)
            {
                // Clear the existing external cookie to ensure a clean login process
                await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);

                if (userWithConfirmedEmail == null) // Email not associated with any other accounts (trying to register)
                {
                    userToSignTokenWith = new ApplicationUser()
                    {
                        Id            = email,
                        Email         = email,
                        SecurityStamp = TemporarySecurityStamp
                    };

                    attemptedOperation = AuthOperation.Registering;
                }
                else // Email associated with an account (trying to login)
                {
                    userToSignTokenWith = userWithConfirmedEmail;
                    attemptedOperation  = AuthOperation.LoggingIn;
                }
            }
            else // A user is currently locally signed-in (trying to add email)
            {
                userToSignTokenWith = userCurrentlySignedIn;

                if (userWithConfirmedEmail == null) // Email not associated with any other accounts (trying to add a novel email)
                {
                    // Check to see if user reached max logins
                    if (DidReachMaxLoginsAllowed(userCurrentlySignedIn))
                    {
                        return(View(nameof(Login), new LoginViewModel
                        {
                            MaxLoginsAllowed = MaxLoginsAllowed,
                            DidReachMaxLoginsAllowed = true
                        }));
                    }

                    attemptedOperation = AuthOperation.AddingNovelEmail;
                }
                else // Email associated with another user's account
                {
                    if (userWithConfirmedEmail.Id == userCurrentlySignedIn.Id) // Email already added to user's account
                    {
                        _notice.AddErrors(ModelState, "This email is already in your account.");
                        return(View(model));
                    }
                    else // Email associated with another account that's not the user's
                    {
                        attemptedOperation = AuthOperation.AddingOtherUserEmail;
                    }
                }
            }

            var token   = "";
            var purpose = "";

            switch (attemptedOperation)
            {
            case AuthOperation.AddingOtherUserEmail:
                purpose = "AddEmail";
                break;

            case AuthOperation.AddingNovelEmail:
                purpose = "AddEmail";
                token   = await _userManager.GenerateUserTokenAsync(userToSignTokenWith, "Email", purpose);

                break;

            case AuthOperation.Registering:
            case AuthOperation.LoggingIn:
                purpose = "RegisterOrLogin";
                token   = await _userManager.GenerateUserTokenAsync(userToSignTokenWith, "Email", purpose);

                break;
            }

            // Add a space every 3 characters for readability
            token = String.Concat(token.SelectMany((c, i)
                                                   => (i + 1) % 3 == 0 ? $"{c} " : $"{c}")).Trim();

            var callbackUrl = Url.TokenInputLink(Request.Scheme,
                                                 new TokenInputViewModel
            {
                Token      = token,
                RememberMe = model.RememberMe,
                ReturnUrl  = returnUrl,
                Email      = email,
                Purpose    = purpose
            });

            // Will not wait for email to be sent
            #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
            _emailSender.SendTokenAsync(email, attemptedOperation, callbackUrl, token);
            #pragma warning restore CS4014

            return(View(nameof(TokenInput),
                        new TokenInputViewModel
            {
                RememberMe = model.RememberMe,
                ReturnUrl = returnUrl,
                Email = email,
                Purpose = purpose
            }));
        }
        public async Task <IActionResult> Create([Bind("Email,Name,PinCode")] BarcoMemberViewModel barcoMember)
        {
            //Register locally
            var email = _userManager.NormalizeKey(barcoMember.Email);

            var userEmpty = new ApplicationUser()
            {
                UserName      = email,
                Email         = email,
                DateCreated   = DateTimeOffset.UtcNow,
                SecurityStamp = new Guid().ToString(),

                FullName       = barcoMember.Name,
                NickName       = barcoMember.Name.Split()[0],
                PinCode        = barcoMember.PinCode,
                EmailConfirmed = true
            };

            var userWithConfirmedEmail = await _userManager.FindByLoginAsync("Email", email);

            if (userWithConfirmedEmail != null) //user does not exist
            {
                _notice.AddErrors(ModelState);
                return(View(nameof(Create)));
            }

            var info = new UserLoginInfo("Email", userEmpty.Email, "Email");

            var createResult = await _userManager.CreateAsync(userEmpty);

            if (createResult.Succeeded)
            {
                var addLoginResult = await _userManager.AddLoginAsync(userEmpty, info);

                if (addLoginResult.Succeeded)
                {
                    var user = await _userManager.FindByNameAsync(userEmpty.UserName); // This works because usernames are unique

                    var makeAdminResult = await _userManager.AddToRolesAsync(user, new[] { Constants.ROTA_ROLE, Constants.WOLF_ROLE });

                    await _events.AddEvent(AuthEventType.Register, JsonConvert.SerializeObject(new
                    {
                        LoginProvider = info?.LoginProvider ?? "Email",
                        ProviderKey   = info?.ProviderKey ?? email
                    }), user);

                    //Register with application
                    try
                    {
                        var createBarcoUserResult = await new HttpClient().PostAsync("http://localhost:8000/api/BarcoMembers", new JsonContent(new
                        {
                            Name       = user.FullName,
                            NickName   = user.NickName,
                            UserName   = user.UserName,
                            RotaStatus = barcoMember.RotaStatus
                        }));
                    }
                    catch (Exception)
                    {
                        //mute
                    }

                    return(RedirectToAction(nameof(Index)));
                }
                else
                {
                    _notice.AddErrors(ModelState, addLoginResult);
                }
            }
            else
            {
                _notice.AddErrors(ModelState, createResult);
            }

            await _userManager.DeleteAsync(userEmpty); // TODO: make atomic

            return(RedirectToAction(nameof(Index)));
        }