Exemplo n.º 1
0
        private async Task <ActionResult> CreateUserAsync(ApplicationUser user, string pwd = null)
        {
            IdentityResult identityResult;

            if (pwd == null)
            {
                identityResult = await _signInManager.UserManager.CreateAsync(user);
            }
            else
            {
                identityResult = await _signInManager.UserManager.CreateAsync(user, pwd);
            }

            if (!identityResult.Succeeded)
            {
                var pb = new ModelStateBuilder <RegistrationRequest>(this, identityResult)
                         .SetIdentityErrorEmail(e => e.Email)
                         .SetIdentityErrorPassword(e => e.Password);

                if (pb.HasProblem(e => e.Email, ProblemDetailsFieldType.DuplicateUserName))
                {
                    return(this.Conflict());
                }

                return(this.BadRequest());
            }

            await AddDefaultRolesAsync(user);

            return(null);
        }
Exemplo n.º 2
0
        public async Task <IActionResult> ChangePassword([FromBody] ChangePasswordRequest model)
        {
            var user = await _userManager.FindByIdAsync(model.UserId);

            if (user == null)
            {
                var pb = new ModelStateBuilder <object>(this);
                pb.SetFieldError(nameof(model.UserId), ProblemDetailsFieldType.UserNotFound);
                return(this.NotFound());
            }

            // Força a confirmação do email pois o usuário pode ter acabado de criar a conta
            // mas não ter recebido o email de confirmação, sendo assim, ele nunca poderá logar,
            // ele, naturalmente, usará o "esqueci minha senha".
            if (_signInManager.Options.SignIn.RequireConfirmedEmail && !user.EmailConfirmed)
            {
                user.EmailConfirmed = true;
            }

            var identityResult = await _userManager.ResetPasswordAsync(user, model.Code, model.Password);

            if (!identityResult.Succeeded)
            {
                var pb = new ModelStateBuilder <ChangePasswordRequest>(this, identityResult)
                         .SetIdentityErrorPassword(e => e.Password)
                         .SetIdentityErrorCode(e => e.Code);

                return(this.BadRequest());
            }

            return(Ok());
        }
Exemplo n.º 3
0
        public async Task <IActionResult> Put([FromBody] ApplicationUser model)
        {
            var user = await GetCurrentUser();

            if (user == null)
            {
                this.SetUserNotFound();
                return(this.NotFound());
            }

            user.FirstName   = model.FirstName;
            user.LastName    = model.LastName;
            user.Gender      = model.Gender;
            user.DateOfBirth = model.DateOfBirth;

            var identityResult = await _signInManager.UserManager.UpdateAsync(user);

            if (!identityResult.Succeeded)
            {
                var pb = new ModelStateBuilder <ApplicationUser>(this, identityResult)
                         .SetIdentityErrorEmail(e => e.Email);
                return(this.BadRequest());
            }

            return(Ok());
        }
Exemplo n.º 4
0
        public async Task <IActionResult> ResetPassword([FromBody] ResetEmailRequest model)
        {
            var user = await _userManager.FindByEmailAsync(model.Email);

            if (user == null)
            {
                var pb = new ModelStateBuilder <ResetEmailRequest>(this);
                pb.SetFieldError(f => f.Email, ProblemDetailsFieldType.UserNotFound);
                return(this.NotFound());
            }

            _emailService.ResetPassword(model.UrlCallbackConfirmation, user);
            return(Ok());
        }
Exemplo n.º 5
0
        public async Task <IActionResult> Login([FromBody] LoginRequest loginModel)
        {
            // This doesn't count login failures towards account lockout
            // To enable password failures to trigger account lockout, set lockoutOnFailure: true
            var identityResult = await _signInManager.PasswordSignInAsync(loginModel.Email, loginModel.Password, false, lockoutOnFailure : true);

            // if (result.RequiresTwoFactor)
            // {
            //     return Ok();
            // }

            if (!identityResult.Succeeded)
            {
                var pb = new ModelStateBuilder <LoginRequest>(this);

                if (identityResult.IsLockedOut)
                {
                    pb.SetFieldError(f => f.Email, ProblemDetailsFieldType.IsLockedOut);
                    return(this.Locked());
                }
                else if (identityResult.IsNotAllowed)
                {
                    pb.SetFieldError(f => f.Email, ProblemDetailsFieldType.IsNotAllowed);
                    return(this.Unauthorized());
                }
                else
                {
                    pb.SetFieldError(f => f.Email, ProblemDetailsFieldType.UserNotFound);
                    return(this.NotFound());
                }
            }

            var user = await _userManager.FindByNameAsync(loginModel.Email);

            var token = await LoginResponse.GenerateWithTokenAsync(_jwtFactory, _appConfig, user);

            if (token == null)
            {
                var pb = new ModelStateBuilder <LoginRequest>(this);
                pb.SetFieldError(f => f.Email, ProblemDetailsFieldType.JwtError);
                return(this.BadRequest());
            }
            else
            {
                token.RequiresTwoFactor = identityResult.RequiresTwoFactor;
                return(this.Ok(token));
            }
        }
Exemplo n.º 6
0
        public async Task <ActionResult <LoginResponse> > Register([FromBody] RegistrationRequest model)
        {
            var user = new ApplicationUser();

            user.UserName    = model.Email;
            user.Email       = model.Email;
            user.FirstName   = model.FirstName;
            user.LastName    = model.LastName;
            user.DateOfBirth = model.DateOfBirth;

            var actionResultError = await CreateUserAsync(user, model.Password);

            if (actionResultError != null)
            {
                return(actionResultError);
            }

            // Register as locked if enabled
            // if (_appConfig.NewUserAsLocked)

            if (_signInManager.Options.SignIn.RequireConfirmedEmail)
            {
                // var lockoutEndDate = new DateTime(2999,01,01);
                // await _userManager.SetLockoutEnabledAsync(userIdentity, true);
                // await  _userManager.SetLockoutEndDateAsync(userIdentity, lockoutEndDate);

                _emailService.ConfirmRegister(model.UrlCallbackConfirmation, user);
                var authModel = LoginResponse.Generate(_signInManager.Options.SignIn);
                return(this.OkCreated(authModel));
            }
            else
            {
                var authModel = await LoginResponse.GenerateWithTokenAsync(_jwtFactory, _appConfig, user);

                if (authModel == null)
                {
                    var pb = new ModelStateBuilder <RegistrationRequest>(this);
                    pb.SetFieldError(f => f.Email, ProblemDetailsFieldType.JwtError);
                    return(this.BadRequest());
                }

                return(this.OkCreated(authModel));
            }
        }
Exemplo n.º 7
0
        public async Task <IActionResult> ChangePassword(ChangePasswordProfileRequest request)
        {
            var user = await this.GetCurrentUser();

            if (user == null)
            {
                this.SetUserNotFound();
                return(this.NotFound());
            }

            IdentityResult identityResult;

            if (string.IsNullOrEmpty(request.PasswordCurrent) && !await _signInManager.UserManager.HasPasswordAsync(user))
            {
                // 1) Se não existir senha cadastrada: Cadastro proveniente de alguma rede social
                identityResult = await _signInManager.UserManager.AddPasswordAsync(user, request.Password);
            }
            else if (string.IsNullOrWhiteSpace(request.PasswordCurrent))
            {
                // 2) Se o usuário tem senha, mas não preencheu o campo
                new ModelStateBuilder <ChangePasswordProfileRequest>(this)
                .SetFieldError(e => e.PasswordCurrent, ProblemDetailsFieldType.Required);
                return(this.BadRequest());
            }
            else
            {
                // 3) Se existir senha cadastrada ou se ele digitou algo no campo "senha corrente"
                identityResult = await _signInManager.UserManager.ChangePasswordAsync(user, request.PasswordCurrent, request.Password);
            }

            if (!identityResult.Succeeded)
            {
                // 1) Adiciona no campo PasswordCurrent apenas se o erro for igual a PasswordMismatch
                // 2) Adiciona no campo Password apenas se o erro for diferente de PasswordMismatch
                var pb = new ModelStateBuilder <ChangePasswordProfileRequest>(this, identityResult)
                         .SetIdentityErrorPassword(e => e.PasswordCurrent, t => t == ProblemDetailsFieldType.PasswordMismatch)
                         .SetIdentityErrorPassword(e => e.Password, t => t != ProblemDetailsFieldType.PasswordMismatch);

                return(this.BadRequest());
            }

            return(Ok());
        }
Exemplo n.º 8
0
        public async Task <IActionResult> ConfirmEmail([FromBody] CodeConfirmationRequest model)
        {
            var user = await _userManager.FindByIdAsync(model.UserId);

            if (user == null)
            {
                var pb = new ModelStateBuilder <object>(this);
                pb.SetFieldError(nameof(model.UserId), ProblemDetailsFieldType.UserNotFound);
                return(this.NotFound());
            }

            var identityResult = await _userManager.ConfirmEmailAsync(user, model.Code);

            if (!identityResult.Succeeded)
            {
                var pb = new ModelStateBuilder <object>(this);
                pb.SetFieldError(nameof(model.Code), ProblemDetailsFieldType.Invalid, "Invalid token.");
                return(this.BadRequest());
            }

            return(Ok());
        }
Exemplo n.º 9
0
        public async Task <IActionResult> LoginFacebook([FromBody] LoginFacebookRequest model)
        {
            const string provider = "Facebook";
            var          client   = new HttpClient();

            // 1. generate an app access token
            var appAccessTokenResponse = await client.GetStringAsync($"https://graph.facebook.com/oauth/access_token?client_id={_appConfig.Facebook.AppId}&client_secret={_appConfig.Facebook.AppSecret}&grant_type=client_credentials");

            var appAccessToken = JsonConvert.DeserializeObject <FacebookAppAccessToken>(appAccessTokenResponse);

            // 2. validate the user access token
            var userAccessTokenValidationResponse = await client.GetStringAsync($"https://graph.facebook.com/debug_token?input_token={model.AccessToken}&access_token={appAccessToken.AccessToken}");

            var userAccessTokenValidation = JsonConvert.DeserializeObject <FacebookUserAccessTokenValidation>(userAccessTokenValidationResponse);

            if (userAccessTokenValidation?.Data?.IsValid == false)
            {
                var pb = new ModelStateBuilder <LoginFacebookRequest>(this)
                         .SetFieldError(e => e.AccessToken, ProblemDetailsFieldType.Invalid, "Invalid facebook token.");
                return(this.BadRequest());
            }

            // 3. we've got a valid token so we can request user data from fb
            var userInfoResponse = await client.GetStringAsync($"https://graph.facebook.com/v2.8/me?fields=id,email,first_name,last_name,name,gender,locale,birthday,picture&access_token={model.AccessToken}");

            var userInfo = JsonConvert.DeserializeObject <FacebookUserData>(userInfoResponse);

            // 4. check if login with facebook already exists
            var user = await _userManager.FindByLoginAsync(provider, userInfo.Id.ToString());

            if (user == null)
            {
                user = new ApplicationUser
                {
                    FirstName  = userInfo.FirstName,
                    LastName   = userInfo.LastName,
                    Email      = userInfo.Email,
                    UserName   = userInfo.Email,
                    PictureUrl = userInfo.Picture.Data.Url,
                    // LockoutEnabled = false // verificar
                };

                // 5. if user not exists, create the user
                var actionResultError = await CreateUserAsync(user);

                if (actionResultError != null)
                {
                    return(actionResultError);
                }

                // 6. create the login for the user
                var login          = new UserLoginInfo(provider, userInfo.Id.ToString(), provider);
                var resultAddLogin = await _userManager.AddLoginAsync(user, login);

                if (!resultAddLogin.Succeeded)
                {
                    var pb = new ModelStateBuilder <LoginFacebookRequest>(this)
                             .SetFieldError(e => e.AccessToken, ProblemDetailsFieldType.Invalid, "Invalid associate facebook user");
                    return(this.BadRequest());
                }
            }

            // 7. generate the jwt for the local user...
            var token = await LoginResponse.GenerateWithTokenAsync(_jwtFactory, _appConfig, user);

            if (token == null)
            {
                var pb = new ModelStateBuilder <LoginRequest>(this);
                pb.SetFieldError(f => f.Email, ProblemDetailsFieldType.JwtError);
                return(this.BadRequest());
            }
            else
            {
                token.RequiresTwoFactor = false;
                return(this.Ok(token));
            }
        }