phplibrary/src/Filter/Login.php

211 lines
9.4 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* Фильтр для проверки авторизации
*
* action: login(password, login)
* action: logout()
*/
// В класс авторизации передавать обьект для управления пользователем
// Вынести в отдельный файл
class Filter_Login extends Filter_Filter
{
const SESSION_BROWSER_SIGN_SECRET = '@w3dsju45Msk#';
const SESSION_BROWSER_SIGN_KEYNAME = 'session.app.browser.sign';
const AUTH_MAX_ATTEMPT = 10;
const AUTH_LAST_ATTEMPT_TIMER = 600;
public $mode = 'ajax';
public $user;
/**
* Проверка авторизации
* @return Boolean Авторизовани пользователь или нет
*/
public function isLoggin(HttpRequest $request)
{
// Авторизация
session_start();
$db = $this->getConnection();
Filter_UserAccess::setUp($db); // Соединение
switch ($request->getAction()) {
// Авторизация по постоянному паролю
case 'login':
$login = $request->get('login');
$password = $request->get('password');
$result = Filter_UserAccess::getUserByLogin($login); // Поиск по логину
if ($result) {
$userPassword = $result->getString('password');
if (Filter_UserAccess::$access == 'site_root' && defined('PARENT_PATH')) {
$s = new Settings(PARENT_PATH . '/settings.json');
$s->read();
$dsn = $s->readKey(array('system', 'dsn'));
$db = Database::getConnection($dsn);
$user = $db->fetchOneArray("SELECT * FROM users WHERE login = :login", ['login' => $login]);
$userPassword = $user['password'];
} /*else if (time() - $result->getInt('lastupdate') > 60*60*24*60) {
// Проверить давность пароля, 60 дней
$request->set('error', true);
$request->set('lastupdate', true);
return false;
}*/
// Проверка на количества попыток авторизации
$lastAttempt = $db->fetchOneArray(
"SELECT trie_count, trie_time FROM users WHERE login = :login", ['login' => $request->get('login')]);
if ($lastAttempt['trie_count'] >= self::AUTH_MAX_ATTEMPT /*&& time() - $lastAttempt['trie_time'] < self::AUTH_LAST_ATTEMPT_TIMER*/) {
if (time() - $lastAttempt['trie_time'] < self::AUTH_LAST_ATTEMPT_TIMER) {
$request->set('timeout_error', true);
break;
} else {
$db->executeQuery(
"UPDATE users SET trie_count = :count WHERE login = :login",
['count' => 0, 'login' => $request->get('login')]
);
}
}
// Извлечнеие пользователя из родительской CMS, для проверки пароля
if (md5($password) == $userPassword) { // password
$this->enter($db, $result);
return true;
} else {
// Обновление количества неудачных попыток входа
$user = $db->fetchOneArray("SELECT id_user, trie_count FROM users WHERE login = :login", ['login' => $login]);
$db->executeQuery(
"UPDATE users SET trie_time = :cur_time, trie_count = :count WHERE id_user = :id_user",
['cur_time' => time(), 'count' => $user['trie_count']+=1, 'id_user' => $user['id_user']]
);
}
}
$request->set('error', true);
break;
case 'logout': // Выход
session_destroy();
break;
// Вход по временному паролю, не используется
/*
case 'enter':
$login = $request->get('login');
$password = $request->get('sid');
$result = Filter_UserAccess::getUserByLogin($login); // Поиск по логину
if ($result) {
$temp = md5($result->getString('password') . $result->getString('login') . $result->getString('sid'));
if ($password == $temp) {
$this->enter($db, $result);
return true;
}
}
break;
*/
default:
$hash = $this->getBrowserSign();
// Если $hash не совпадает $_SESSION['hash'] то удаляем сессию
if (isset($_SESSION ['access']) && isset($_SESSION[self::SESSION_BROWSER_SIGN_KEYNAME])) {
if ($hash == $_SESSION[self::SESSION_BROWSER_SIGN_KEYNAME]) {
$this->user = $user = Filter_UserAccess::getUserById($_SESSION['access']); // Поиск по идентификатору
if ($user && isset($_SESSION['random']) && ($user->get('sid') == $_SESSION['random'])) {
return true;
}
return true;
} else {
session_destroy();
}
}
}
return false;
}
private function getBrowserSign()
{
$rawSign = self::SESSION_BROWSER_SIGN_SECRET;
//$signParts = array('HTTP_USER_AGENT', 'HTTP_ACCEPT_ENCODING');
$signParts = array();
foreach ($signParts as $signPart) {
$rawSign .= '::' . (isset($_SERVER[$signPart]) ? $_SERVER[$signPart] : 'none');
}
return md5($rawSign);
}
private function enter($db, $result)
{
$this->user = $result;
$random = rand(0, 1024 * 1024);
$db->executeQuery("UPDATE users SET sid = '$random', trie_count = 0 WHERE id_user = " . $result->getInt('id_user'));
$_SESSION["group"] = $result->getInt('access');
$_SESSION["access"] = $result->getInt('id_user'); // id_user
$_SESSION["random"] = $random; // id_user
$_SESSION[self::SESSION_BROWSER_SIGN_KEYNAME] = $this->getBrowserSign();
$_SESSION["time"] = time();
}
public function execute(HttpRequest $request)
{
$logged = $this->isLoggin($request);
if ($request->get('action') == 'user_access') {
if ($logged) {
$result = array();
$result['fullname'] = $this->user->getString('patronymic') . " " . $this->user->getString('firstname');
$result['email'] = $this->user->getString('email');
$result['site'] = 187;
$result['hash'] = sha1(self::SESSION_BROWSER_SIGN_SECRET . $this->user->getString('email'));
return json_encode($result);
} else {
return json_encode("NOT AUTHORIZED");
}
}
if ($request->get('action') == 'relogin') {
if ($logged) {
return json_encode(array('result' => 'ok', 'message' => "Авторизация успешна"));
} else {
return json_encode(array('result' => 'fail', 'message' => "Неправильное имя пользователя или пароль"));
}
}
if (!$logged) {
// Параметры при неправильной авторизации
// Действия по умолчанию !! Возможно переход на форму регистрации
if ($request->get('mode') == 'ajax') {
if (!$this->requestIsWhite($request)) {
return json_encode(array('result' => 'fail', 'message' =>"NOT_AUTHORIZED"));
}
} else {
$request->set('module', 'login');
$request->set('mode', $this->mode);
}
} else if (isset($_SERVER['HTTP_REFERER'])) {
$arr = array();
parse_str(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_QUERY), $arr);
if (isset($arr['back_page']) && $request->get('mode') != 'ajax') {
$request->redirect($arr['back_page']);
}
}
$text = $this->processor->execute($request);
return $text;
}
/* ---------------------
* Проверка на попадание реквеста в белый список
*/
public function requestIsWhite(Collection $request) {
$module = $request->get('module');
$action = $request->get('action');
$moduleDir = explode('_',$module)[0];
$file = Path::join(CMS_PATH, 'modules', $moduleDir, 'filters', 'white.json');
if (file_exists($file)) {
$whiteList = json_decode(file_get_contents($file), true);
if (in_array($action, $whiteList)) {
return true;
}
}
return false;
}
}