From 6a9ef3534b4240c121542303cb2fadfee8459d83 Mon Sep 17 00:00:00 2001 From: anatoly Date: Tue, 28 Jun 2022 15:57:41 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A2=D0=B5=D0=BF=D0=B5=D1=80=D1=8C=20=D0=BC?= =?UTF-8?q?=D0=BE=D0=B6=D0=BD=D0=BE=20=D0=B4=D0=B5=D0=BB=D0=B0=D1=82=D1=8C?= =?UTF-8?q?=20=D1=82=D0=B0=D0=BA:=20curl=20-d=20'login=3Dmanager&password?= =?UTF-8?q?=3D1'=20-X=20POST=20http://10.1.1.1:8090/sites/demo/admin/=3Fac?= =?UTF-8?q?tion=3Dapi=5Fkey?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit С полученным ключом будут доступны команды, прописанные в json-ке как доступные с ключом --- src/Filter/Login.php | 114 +++++++++++++++++++++++++++++++++---------- src/Security.php | 6 ++- 2 files changed, 92 insertions(+), 28 deletions(-) diff --git a/src/Filter/Login.php b/src/Filter/Login.php index 4a993a1..64529d1 100644 --- a/src/Filter/Login.php +++ b/src/Filter/Login.php @@ -14,10 +14,40 @@ class Filter_Login extends Filter_Filter const SESSION_BROWSER_SIGN_KEYNAME = 'session.app.browser.sign'; public $mode = 'ajax'; public $user; + /* + * Проверка пары логин/пароль + */ + public function checkLoginPasswordPair($db, $login, $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; + }*/ + + // Извлечение пользователя из родительской CMS, для проверки пароля + if (md5($password) == $userPassword) { // password + $this->enter($db, $result); + return true; + } + } + return false; + } /** * Проверка авторизации - * @return Boolean Авторизовани пользователь или нет + * @return Boolean Авторизован пользователь или нет */ public function isLoggin(HttpRequest $request) { @@ -28,33 +58,12 @@ class Filter_Login extends Filter_Filter switch ($request->getAction()) { // Авторизация по постоянному паролю + case 'api_key': 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; - }*/ - - // Извлечнеие пользователя из родительской CMS, для проверки пароля - if (md5($password) == $userPassword) { // password - $this->enter($db, $result); - return true; - } + if($this->checkLoginPasswordPair($db,$login,$password)==true){ + return true; } $request->set('error', true); break; @@ -121,7 +130,8 @@ class Filter_Login extends Filter_Filter public function execute(HttpRequest $request) { - $logged = $this->isLoggin($request); + $logged = $this->isLoggin($request); +// return json_encode(["logged"=>$logged]); if ($request->get('action') == 'user_access') { if ($logged) { $result = array(); @@ -135,6 +145,11 @@ class Filter_Login extends Filter_Filter } } + if($logged && ($request->get('action') == 'api_key')) { + $result['key'] = Security::generateAPIKey(strval(time())); + return json_encode($result); + } + if ($request->get('action') == 'relogin') { if ($logged) { return json_encode(array('result' => 'ok', 'message' => "Авторизация успешна")); @@ -147,7 +162,7 @@ class Filter_Login extends Filter_Filter // Параметры при неправильной авторизации // Действия по умолчанию !! Возможно переход на форму регистрации if ($request->get('mode') == 'ajax') { - if (!$this->requestIsWhite($request)) { + if ((!$this->requestIsWhite($request))&&(!$this->APIKeyCheck($request))) { return json_encode(array('result' => 'fail', 'message' =>"NOT_AUTHORIZED")); } } else { @@ -186,4 +201,49 @@ class Filter_Login extends Filter_Filter return false; } + + /* --------------------- + * Проверка на попадание реквеста в API_key_allowed и проверка ключа API + */ + + public function APIKeyCheck(Collection $request) { + $key = $request->get('api_key'); + if(!is_string($key)) { + return false; + } + $module = $request->get('module'); + $action = $request->get('action'); + + $moduleDir = explode('_',$module)[0]; + $file = Path::join(CMS_PATH, 'modules', $moduleDir, 'filters', 'api_key.json'); + if (file_exists($file)) { + $whiteList = json_decode(file_get_contents($file), true); + + if (in_array($action, $whiteList)) { + if($this->isValidAPIKey($key)) { + return true; + } + } + } + + return false; + } + /** + * ключ API имеет вид [unixTime]_[hash(unixTime,WWW_PATH)] + */ + public function isValidAPIKey(String $key) { + $parts = explode('_',$key,2); + if(count($parts)!=2) { + return false; + } + $timestamp = intval($parts[0]); + $timediff = time()-$timestamp; + if(($timediff<0)||($timediff>60*60*24)) { // key is valid for 24 hours + return false; + } + if($key != Security::generateAPIKey($timestamp)){ + return false; + } + return true; + } } diff --git a/src/Security.php b/src/Security.php index a42af31..8eb7057 100644 --- a/src/Security.php +++ b/src/Security.php @@ -16,7 +16,7 @@ class Security { if ($strength & 8) { $consonants .= '@#$%'; } - + $password = ''; $alt = time() % 2; for ($i = 0; $i < $length; $i++) { @@ -30,4 +30,8 @@ class Security { } return $password; } + + public static function generateAPIKey($timestamp){ + return $timestamp."_".md5(WWW_PATH.$timestamp."asjfgkg0o123rkdsdfl1023kwaf012kj10asdld"); + } }