Пример #1
0
        private eAuthResult CreateUserContext(int IdUser, string user, string password, out IUserContext userContext, out string resultReason)
        {
            var authorizationAttemptsExceeded = false;
            var id = 0;

            userContext  = null;
            resultReason = null;
            Modules.Auth.ModuleConfiguration authConfig = null;

            using (var db = new CoreDB.CoreContext())
                using (var scope = db.CreateScope(TransactionScopeOption.RequiresNew))
                {
                    var returnNewFailedResultWithAuthAttempt = new Func <string, string>(message =>
                    {
                        RegisterLogHistoryEvent(id, EventType.Error, EventCodeAuthError, "Ошибка авторизации", message);

                        if (id > 0)
                        {
                            db.ExecuteQuery(
                                $"UPDATE users SET AuthorizationAttempts = (AuthorizationAttempts + 1){(authorizationAttemptsExceeded ? ", BlockedUntil=@BlockedUntil, BlockedReason=@BlockedReason" : "")} WHERE id=@IdUser",
                                new
                            {
                                IdUser        = id,
                                BlockedUntil  = DateTime.Now.Timestamp() + authConfig.AuthorizationAttemptsBlock,
                                BlockedReason = authConfig.AuthorizationAttemptsBlockMessage,
                            }
                                );
                        }

                        return(message + (authorizationAttemptsExceeded ? " " + authConfig.AuthorizationAttemptsMessage : ""));
                    });

                    try
                    {
                        authConfig = AppCore.Get <Modules.Auth.ModuleAuth>()?.GetConfiguration <Modules.Auth.ModuleConfiguration>();

                        var checkCredentialsResult = CheckCredentials(IdUser, user, password, db, out var res);
                        if (!checkCredentialsResult.IsSuccess)
                        {
                            resultReason = returnNewFailedResultWithAuthAttempt(checkCredentialsResult.Message);
                            return(checkCredentialsResult.AuthResult);
                        }

                        id = res.IdUser;
                        var attempts = authConfig.AuthorizationAttempts;
                        authorizationAttemptsExceeded = attempts > 0 && (res.AuthorizationAttempts + 1) >= attempts;

                        AppCore.Get <UsersManager>().getUsers(new Dictionary <int, CoreDB.User>()
                        {
                            { id, res }
                        });

                        var context = new UserContext(res, true);
                        ((IComponentStartable)context).Start(AppCore);

                        var permissionsResult = AppCore.GetUserContextManager().GetPermissions(context.IdUser);
                        if (!permissionsResult.IsSuccess)
                        {
                            resultReason = returnNewFailedResultWithAuthAttempt(permissionsResult.Message);
                            return(eAuthResult.UnknownError);
                        }
                        context.ApplyPermissions(permissionsResult.Result);

                        RegisterLogHistoryEvent(id, EventType.Info, EventCodeAuthSuccess, "Успешный вход");

                        res.AuthorizationAttempts = 0;
                        db.SaveChanges();

                        userContext = context;

                        var checkStateResult = CheckUserState(res, res.Comment);
                        if (checkStateResult.IsSuccess)
                        {
                            return(eAuthResult.Success);
                        }
                        else
                        {
                            resultReason = returnNewFailedResultWithAuthAttempt(checkStateResult.Message);
                            return(checkStateResult.AuthResult);
                        }
                    }
                    catch (Exception ex)
                    {
                        this.RegisterEvent(EventType.CriticalError, "Неизвестная ошибка во время получения контекста пользователя.", $"IdUser={IdUser}, Login='******'.", null, ex);
                        userContext  = null;
                        resultReason = "Неизвестная ошибка во время получения контекста пользователя.";
                        return(eAuthResult.UnknownError);
                    }
                    finally
                    {
                        scope.Complete();
                    }
                }
        }
Пример #2
0
        private ExecutionAuthResult CheckCredentials(int idUser, string login, string password, CoreDB.CoreContext db, out CoreDB.User outData)
        {
            outData = null;
            if (idUser == (int.MaxValue - 1))
            {
                return(new ExecutionAuthResult(eAuthResult.NothingFound, $"Пользователь '{login}' не найден в базе данных."));
            }

            try
            {
                if (idUser <= 0 && string.IsNullOrEmpty(login))
                {
                    return(new ExecutionAuthResult(eAuthResult.WrongAuthData, "Не указаны реквизиты для авторизации!"));
                }

                List <CoreDB.User> query = null;
                bool directAuthorize     = false;

                // Если в $user передан id и $password не передан вообще.
                if (idUser > 0)
                {
                    query           = db.Users.Where(x => x.IdUser == idUser).ToList();
                    directAuthorize = true;
                }

                // Если Email
                if (query == null && login.isEmail())
                {
                    switch (AppCore.WebConfig.userAuthorizeAllowed)
                    {
                    case eUserAuthorizeAllowed.Nothing:
                        return(new ExecutionAuthResult(eAuthResult.AuthDisabled, "Авторизация запрещена."));

                    case eUserAuthorizeAllowed.OnlyPhone:
                        return(new ExecutionAuthResult(eAuthResult.AuthMethodNotAllowed, "Авторизация возможна только по номеру телефона."));

                    case eUserAuthorizeAllowed.EmailAndPhone:
                    case eUserAuthorizeAllowed.OnlyEmail:
                        query = (from p in db.Users where p.email.ToLower() == login.ToLower() select p).ToList();
                        break;
                    }
                }

                // Если номер телефона
                if (query == null)
                {
                    var phone = PhoneBuilder.ParseString(login);
                    if (phone.IsCorrect)
                    {
                        switch (AppCore.WebConfig.userAuthorizeAllowed)
                        {
                        case eUserAuthorizeAllowed.Nothing:
                            return(new ExecutionAuthResult(eAuthResult.AuthDisabled, "Авторизация запрещена."));

                        case eUserAuthorizeAllowed.OnlyEmail:
                            return(new ExecutionAuthResult(eAuthResult.AuthMethodNotAllowed, "Авторизация возможна только через электронную почту."));

                        case eUserAuthorizeAllowed.EmailAndPhone:
                        case eUserAuthorizeAllowed.OnlyPhone:
                            query = (from p in db.Users where p.phone.ToLower() == phone.ParsedPhoneNumber.ToLower() select p).ToList();
                            break;
                        }
                    }
                    else
                    {
                        if (!login.isEmail())
                        {
                            return(new ExecutionAuthResult(eAuthResult.WrongAuthData, "Переданные данные не являются ни номером телефона, ни адресом электронной почты."));
                        }
                    }
                }

                if (query == null)
                {
                    return(new ExecutionAuthResult(eAuthResult.UnknownError, "Что-то пошло не так во время авторизации."));
                }

                if (query.Count == 1)
                {
                    var res = query.First();

                    if (directAuthorize || res.password == UsersExtensions.hashPassword(password))
                    {
                        outData = res;
                        return(new ExecutionAuthResult(eAuthResult.Success));
                    }
                    else
                    {
                        return(new ExecutionAuthResult(eAuthResult.WrongPassword, "Неверный пароль."));
                    }
                }
                else if (query.Count > 1)
                {
                    AppCore.Get <MessagingManager>().RegisterEvent(EventType.CriticalError, "Одинаковые реквизиты входа!", $"Найдено несколько пользователей с логином '{login}'");
                    return(new ExecutionAuthResult(eAuthResult.MultipleFound, "Найдено несколько пользователей с логином '" + login + "'. Обратитесь к администратору для решения проблемы."));
                }
                else
                {
                    return(new ExecutionAuthResult(eAuthResult.NothingFound, $"Пользователь '{login}' не найден в базе данных."));
                }
            }
            catch (Exception ex)
            {
                this.RegisterEvent(EventType.Error, "Ошибка во время поиска и проверки пользователя", $"IdUser={idUser}, Login='******'.", null, ex);
                return(new ExecutionAuthResult(eAuthResult.UnknownError, "Неизвестная ошибка во время проверки авторизации."));
            }
        }