Exemple #1
0
        public async Task <IActionResult> RequestPasswordReset([FromBody] string email)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(email))
                {
                    CoreFunc.Error(ref ErrorsList, "Email is required!");
                    return(StatusCode(412, ErrorsList));
                }

                User user = await _UserManager
                            .FindByEmailAsync(email).ConfigureAwait(false);

                if (user == null)
                {
                    CoreFunc.Error(ref ErrorsList, "Email not registered");
                    return(StatusCode(412, ErrorsList));
                }
                RegistrationMethod registrationMethod = await _DbContext.RegistrationMethods.FirstOrDefaultAsync(rm => rm.User.Id == user.Id).ConfigureAwait(false);

                if (registrationMethod.Type != RegistrationTypes.Application)
                {
                    CoreFunc.Error(ref ErrorsList, $"Your account is linked to your {registrationMethod.Type} account.");
                    return(StatusCode(412, ErrorsList));
                }

                if (user.LockoutEnabled)
                {
                    var currentLockoutDate =
                        await _UserManager.GetLockoutEndDateAsync(user).ConfigureAwait(false);

                    if (user.LockoutEnd > DateTimeOffset.UtcNow)
                    {
                        CoreFunc.Error(ref ErrorsList, string.Format("Account Locked for {0}"
                                                                     , CoreFunc.CompareWithCurrentTime(user.LockoutEnd)));
                        return(StatusCode(412, ErrorsList));
                    }
                    await _UserManager.SetLockoutEnabledAsync(user, false).ConfigureAwait(false);

                    await _UserManager.ResetAccessFailedCountAsync(user).ConfigureAwait(false);
                }

                Request.Headers.TryGetValue("Origin", out StringValues OriginValue);
                if (!await _EmailService.PasswordResetAsync(user, OriginValue).ConfigureAwait(false))
                {
                    CoreFunc.Error(ref ErrorsList, "Unable to send email.");
                    return(StatusCode(417, ErrorsList));
                }

                return(Created("", "Created"));
            }

            catch (Exception ex)
            {
                CoreFunc.Error(ref ErrorsList, _LoggingService.LogException(Request.Path, ex, User));
                return(StatusCode(417, ErrorsList));
            }
        }
        public async Task <IActionResult> Login(LoginInfo loginInfo)
        {
            try
            {
                IEnumerable <string> policies = AppFunc.GetCurrentRequestPolicies(Request, out AppTypes apptype);
                if (apptype == AppTypes.Invalid)
                {
                    CoreFunc.Error(ref ErrorsList, "Unauthorised Application Access. 🤔");
                    return(Unauthorized(ErrorsList));
                }
                /// If email parameter is empty
                /// return "unauthorized" response (stop code execution)
                if (string.IsNullOrWhiteSpace(loginInfo.Email))
                {
                    /// in the case any exceptions return the following error
                    CoreFunc.Error(ref ErrorsList, "Email is required!");
                    return(Unauthorized(ErrorsList));
                }

                /// Find the user with the provided email address
                User user = await _DbContext.Users
                            .Include(u => u.Role)
                            .Include(u => u.RegistrationMethod)
                            .FirstOrDefaultAsync(r => r.Email.Equals(loginInfo.Email))
                            .ConfigureAwait(false);

                /// if no user is found on the database
                if (user == null)
                {
                    /// in the case any exceptions return the following error
                    CoreFunc.Error(ref ErrorsList, "Email not registered");
                    return(Unauthorized(ErrorsList));
                }
                if (!await IsUserPolicyAccepted(user, policies).ConfigureAwait(false))
                {
                    CoreFunc.Error(ref ErrorsList, "You do not have permission to login here.");
                    return(Unauthorized(ErrorsList));
                }

                if (user.RegistrationMethod.Type != RegistrationTypes.Application)
                {
                    /// in the case any exceptions return the following error
                    CoreFunc.Error(ref ErrorsList, $"Please use {user.RegistrationMethod.Type} to login.");
                    return(StatusCode(403, ErrorsList));
                }

                if (string.IsNullOrWhiteSpace(loginInfo.Password))
                {
                    /// in the case any exceptions return the following error
                    CoreFunc.Error(ref ErrorsList, "Password is required!");
                    return(Unauthorized(ErrorsList));
                }

                /// Check if user's account is locked
                if (user.LockoutEnabled)
                {
                    /// get the current lockout end dateTime
                    var currentLockoutDate =
                        await _UserManager.GetLockoutEndDateAsync(user).ConfigureAwait(false);

                    /// if the user's lockout is not expired (stop code execution)
                    if (user.LockoutEnd > DateTimeOffset.UtcNow)
                    {
                        /// in the case any exceptions return the following error
                        CoreFunc.Error(ref ErrorsList, string.Format("Account Locked for {0}"
                                                                     , CoreFunc.CompareWithCurrentTime(user.LockoutEnd)));
                        return(Unauthorized(ErrorsList));
                    }
                    /// else lockout time has expired
                    // disable user lockout
                    await _UserManager.SetLockoutEnabledAsync(user, false).ConfigureAwait(false);

                    await _UserManager.ResetAccessFailedCountAsync(user).ConfigureAwait(false);
                }

                /// else user account is not locked
                // Attempt to sign in the user
                var SignInResult = await _SignInManager
                                   .PasswordSignInAsync(user, loginInfo.Password, loginInfo.RememberMe, false).ConfigureAwait(false);

                /// If password sign-in succeeds
                // responded ok 200 status code with
                //the user's role attached (stop code execution)
                if (!SignInResult.Succeeded)
                {
                    /// else login attempt failed
                    /// increase and update the user's failed login attempt by 1
                    await _UserManager.AccessFailedAsync(user).ConfigureAwait(false);

                    /// if failed login attempt is less than/ equal to 5 (stop code execution)
                    if (user.AccessFailedCount <= 5)
                    {
                        /// in the case any exceptions return the following error
                        CoreFunc.Error(ref ErrorsList, "Incorrect Password!");
                        return(Unauthorized(ErrorsList));
                    }

                    /// else user has tried their password more than 15 times
                    // lock the user and ask them to reset their password
                    user.LockoutEnabled = true;
                    user.LockoutEnd     = DateTimeOffset.UtcNow.AddMinutes(user.AccessFailedCount);

                    /// in the case any exceptions return the following error
                    CoreFunc.Error(ref ErrorsList, string.Format("Account Locked for {0}"
                                                                 , CoreFunc.CompareWithCurrentTime(user.LockoutEnd)));
                    return(Unauthorized(ErrorsList));
                }
                user.Role = (await _DbContext.Users.AsNoTracking()
                             .Include(u => u.Role)
                             .FirstOrDefaultAsync(u => u.Id == user.Id)
                             .ConfigureAwait(false))
                            ?.Role;

                return(Ok(user));
            }
            catch (Exception ex)
            {
                CoreFunc.Error(ref ErrorsList, _LoggingService.LogException(Request.Path, ex, User));
                return(StatusCode(417, ErrorsList));
            }
        }