generated from mirzaev/pot
	большая разработка аутентификации
This commit is contained in:
		
							
								
								
									
										149
									
								
								mirzaev/site/account/system/controllers/account.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										149
									
								
								mirzaev/site/account/system/controllers/account.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,149 @@ | ||||
| <?php | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace mirzaev\site\account\controllers; | ||||
|  | ||||
| // Файлы проекта | ||||
| use mirzaev\site\account\controllers\core, | ||||
|   mirzaev\site\account\models\account as model, | ||||
|   mirzaev\site\account\models\session, | ||||
|   mirzaev\site\account\models\vk; | ||||
|  | ||||
| // Фреймворк для ВКонтакте | ||||
| use mirzaev\vk\core as api; | ||||
|  | ||||
| // Библиотека для ArangoDB | ||||
| use ArangoDBClient\Document as _document; | ||||
|  | ||||
| // Встроенные библиотеки | ||||
| use stdClass; | ||||
|  | ||||
| /** | ||||
|  * Контроллер аккаунта | ||||
|  * | ||||
|  * @package mirzaev\site\account\controllers | ||||
|  * @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy> | ||||
|  */ | ||||
| final class account extends core | ||||
| { | ||||
|   /** | ||||
|    * Страница профиля | ||||
|    * | ||||
|    * @param array $parameters Параметры запроса | ||||
|    */ | ||||
|   public function index(array $parameters = []): ?string | ||||
|   { | ||||
|     return null; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Инициализация | ||||
|    * | ||||
|    * @param array $parameters Параметры запроса | ||||
|    */ | ||||
|   public function initialization(array $parameters = []): ?string | ||||
|   { | ||||
|     if ($this->variables['account'] instanceof _document) { | ||||
|       // Найден аккаунт | ||||
|  | ||||
|       if ($this->variables['vk'] instanceof _document) { | ||||
|         // Найден аккаунт ВКонтакте | ||||
|  | ||||
|         // Инициализация данных аккаунта ВКонтакте | ||||
|         vk::parse($this->variables['vk'], $this->variables['errors']['vk']); | ||||
|       } | ||||
|  | ||||
|       // Запись кода ответа | ||||
|       http_response_code(200); | ||||
|  | ||||
|       return null; | ||||
|     } else { | ||||
|       // Не найден аккаунт | ||||
|  | ||||
|       // Запись кода ответа | ||||
|       http_response_code(401); | ||||
|  | ||||
|       // Запись заголовка ответа с ключом аккаунта | ||||
|       header('session: ' . $this->variables['session']->hash); | ||||
|  | ||||
|       return null; | ||||
|     } | ||||
|  | ||||
|     // Запись кода ответа | ||||
|     http_response_code(500); | ||||
|  | ||||
|     return null; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Связь аккаунта с аккаунтом ВКонтакте | ||||
|    * | ||||
|    * @param array $parameters Параметры запроса | ||||
|    */ | ||||
|   public function connect(array $parameters = []): ?string | ||||
|   { | ||||
|     if ($this->variables['session']->hash === $parameters['state']) { | ||||
|       // Совпадает хеш сессии с полученным хешем из ответа ВКонтакте | ||||
|  | ||||
|       if (!empty($response = vk::key($parameters['code'], $this->variables['errors']['vk']))) { | ||||
|         // Получены данные аккаунта ВКонтакте | ||||
|  | ||||
|         if (($this->variables['vk'] = vk::initialization($response, $this->variables['errors']['vk'])) instanceof _document) { | ||||
|           // Инициализирован аккаунт ВКонтакте | ||||
|  | ||||
|           if (($this->variables['account'] = vk::account($this->variables['vk'])) instanceof _document) { | ||||
|             // Найден аккаунт (существующий) | ||||
|  | ||||
|             if (session::connect($this->variables['session'], $this->variables['account'], $this->variables['errors']['session'])) { | ||||
|               // Связана сессия с аккаунтом | ||||
|             } | ||||
|           } else if (($this->variables['account'] = model::create($this->variables['errors']['account'])) instanceof _document) { | ||||
|             // Найден аккаунт (создан новый) | ||||
|  | ||||
|             if (session::connect($this->variables['session'], $this->variables['account'], $this->variables['errors']['session'])) { | ||||
|               // Связана сессия с аккаунтом | ||||
|  | ||||
|               if (account::connect($this->variables['account'], $this->variables['vk'], $this->variables['errors']['account'])) { | ||||
|                 // Связан аккаунт с аккаунтом ВКонтакте | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|  | ||||
|           // Инициализация робота для аккаунта ВКонтакте | ||||
|           $this->vk = api::init()->user(key: $this->variables['vk']->access['key']); | ||||
|  | ||||
|           if ($this->variables['vk'] instanceof _document) { | ||||
|             // Инициализирован робот для аккаунта ВКонтакте | ||||
|  | ||||
|             // Инициализация данных аккаунта ВКонтакте | ||||
|             $data = vk::parse($this->vk, $this->variables['errors']['vk']); | ||||
|             var_dump($data); | ||||
|             die; | ||||
|  | ||||
|             if ($data instanceof stdClass) { | ||||
|               // Получены данные ВКонтакте | ||||
|  | ||||
|               // Запись в базу данных | ||||
|               vk::update($this->variables['vk'], $data, $this->variables['errors']['vk']); | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // Генерация представления | ||||
|     return $this->view->render(DIRECTORY_SEPARATOR . 'account' . DIRECTORY_SEPARATOR . 'vk.html', $this->variables); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Генерация панели аккаунта | ||||
|    * | ||||
|    * @param array $parameters Параметры запроса | ||||
|    */ | ||||
|   public function panel(array $parameters = []): ?string | ||||
|   { | ||||
|     // Генерация представления | ||||
|     return $this->view->render(DIRECTORY_SEPARATOR . 'account' . DIRECTORY_SEPARATOR . 'panel.html', $this->variables); | ||||
|   } | ||||
| } | ||||
| @@ -1,146 +0,0 @@ | ||||
| <?php | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace mirzaev\site\account\controllers; | ||||
|  | ||||
| // Файлы проекта | ||||
| use mirzaev\site\account\controllers\core; | ||||
| use mirzaev\site\account\models\account_model as account; | ||||
| use mirzaev\site\account\models\session_model as session; | ||||
| use mirzaev\site\account\models\vk_model as vk; | ||||
|  | ||||
| // Библиотека для ArangoDB | ||||
| use ArangoDBClient\Document as _document; | ||||
| use stdClass; | ||||
|  | ||||
| // Фреймворк для ВКонтакте | ||||
| use mirzaev\vk\core as api; | ||||
|  | ||||
| /** | ||||
|  * Контроллер аккаунтов | ||||
|  * | ||||
|  * @package mirzaev\site\account\controllers | ||||
|  * @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy> | ||||
|  */ | ||||
| final class account_controller extends core | ||||
| { | ||||
|     /** | ||||
|      * Страница профиля | ||||
|      * | ||||
|      * @param array $parameters Параметры запроса | ||||
|      */ | ||||
|     public function index(array $parameters = []): ?string | ||||
|     { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Инициализация | ||||
|      * | ||||
|      * @param array $parameters Параметры запроса | ||||
|      */ | ||||
|     public function initialization(array $parameters = []): ?string | ||||
|     { | ||||
|         if ($this->variables['account'] instanceof _document) { | ||||
|             // Найден аккаунт | ||||
|  | ||||
|             if ($this->variables['vk'] instanceof _document) { | ||||
|                 // Найден аккаунт ВКонтакте | ||||
|  | ||||
|                 // Инициализация данных аккаунта ВКонтакте | ||||
|                 vk::parse($this->variables['vk'], $this->variables['errors']['vk']); | ||||
|             } | ||||
|  | ||||
|             // Запись кода ответа | ||||
|             http_response_code(200); | ||||
|  | ||||
|             return null; | ||||
|         } else { | ||||
|             // Не найден аккаунт | ||||
|  | ||||
|             // Запись кода ответа | ||||
|             http_response_code(401); | ||||
|  | ||||
|             // Запись заголовка ответа с ключом аккаунта | ||||
|             header('session: ' . $this->variables['session']->hash); | ||||
|  | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         // Запись кода ответа | ||||
|         http_response_code(500); | ||||
|  | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Связь аккаунта с аккаунтом ВКонтакте | ||||
|      * | ||||
|      * @param array $parameters Параметры запроса | ||||
|      */ | ||||
|     public function connect(array $parameters = []): ?string | ||||
|     { | ||||
|         if ($this->variables['session']->hash === $parameters['state']) { | ||||
|             // Совпадает хеш сессии с полученным хешем из ответа ВКонтакте | ||||
|  | ||||
|             if (!empty($response = vk::key($parameters['code'], $this->variables['errors']['vk']))) { | ||||
|                 // Получены данные аккаунта ВКонтакте | ||||
|  | ||||
|                 if (($this->variables['vk'] = vk::initialization($response, $this->variables['errors']['vk'])) instanceof _document) { | ||||
|                     // Инициализирован аккаунт ВКонтакте | ||||
|  | ||||
|                     if (($this->variables['account'] = vk::account($this->variables['vk'])) instanceof _document) { | ||||
|                         // Найден аккаунт (существующий) | ||||
|  | ||||
|                         if (session::connect($this->variables['session'], $this->variables['account'], $this->variables['errors']['session'])) { | ||||
|                             // Связана сессия с аккаунтом | ||||
|                         } | ||||
|                     } else if (($this->variables['account'] = account::create($this->variables['errors']['account'])) instanceof _document) { | ||||
|                         // Найден аккаунт (создан новый) | ||||
|  | ||||
|                         if (session::connect($this->variables['session'], $this->variables['account'], $this->variables['errors']['session'])) { | ||||
|                             // Связана сессия с аккаунтом | ||||
|  | ||||
|                             if (account::connect($this->variables['account'], $this->variables['vk'], $this->variables['errors']['account'])) { | ||||
|                                 // Связан аккаунт с аккаунтом ВКонтакте | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|  | ||||
|                     // Инициализация робота для аккаунта ВКонтакте | ||||
|                     $this->vk = api::init()->user(key: $this->variables['vk']->access['key']); | ||||
|  | ||||
|                     if ($this->variables['vk'] instanceof _document) { | ||||
|                         // Инициализирован робот для аккаунта ВКонтакте | ||||
|  | ||||
|                         // Инициализация данных аккаунта ВКонтакте | ||||
|                         $data = vk::parse($this->vk, $this->variables['errors']['vk']); | ||||
|                         var_dump($data); die; | ||||
|  | ||||
|                         if ($data instanceof stdClass) { | ||||
|                             // Получены данные ВКонтакте | ||||
|  | ||||
|                             // Запись в базу данных | ||||
|                             vk::update($this->variables['vk'], $data, $this->variables['errors']['vk']); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Генерация представления | ||||
|         return $this->view->render(DIRECTORY_SEPARATOR . 'account' . DIRECTORY_SEPARATOR . 'vk.html', $this->variables); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Генерация панели аккаунта | ||||
|      * | ||||
|      * @param array $parameters Параметры запроса | ||||
|      */ | ||||
|     public function panel(array $parameters = []): ?string | ||||
|     { | ||||
|         // Генерация представления | ||||
|         return $this->view->render(DIRECTORY_SEPARATOR . 'account' . DIRECTORY_SEPARATOR . 'panel.html', $this->variables); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										73
									
								
								mirzaev/site/account/system/controllers/api.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								mirzaev/site/account/system/controllers/api.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | ||||
| <?php | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace mirzaev\site\account\controllers; | ||||
|  | ||||
| // Файлы проекта | ||||
| use mirzaev\site\account\controllers\core, | ||||
|   mirzaev\site\account\controllers\traits\errors, | ||||
|   mirzaev\site\account\models\generators\password; | ||||
|  | ||||
| // Встроенные библиотеки | ||||
| use exception; | ||||
|  | ||||
| /** | ||||
|  * Контроллер API | ||||
|  * | ||||
|  * @package mirzaev\site\account\controllers | ||||
|  * @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy> | ||||
|  */ | ||||
| final class api extends core | ||||
| { | ||||
|   use errors; | ||||
|  | ||||
|   /** | ||||
|    * Сгенерировать пароль | ||||
|    * | ||||
|    * @param array $parameters Параметры запроса | ||||
|    *  | ||||
|    * @return string JSON-документ с запрашиваемыми параметрами | ||||
|    */ | ||||
|   public function password(array $parameters = []): string | ||||
|   { | ||||
|     // Инициализация буфера ответа | ||||
|     $buffer = []; | ||||
|  | ||||
|     // Инициализация реестра возвращаемых параметров | ||||
|     $return = explode(',', $parameters['return'], 50); | ||||
|  | ||||
|     // Инициализация значений по умолчению | ||||
|     $parameters['length'] ??= 6; | ||||
|     $parameters['type'] ??= 'classic'; | ||||
|  | ||||
|     try { | ||||
|       // Проверка параметров на соответствие требованиям | ||||
|       if (($parameters['length'] = (int) $parameters['length']) === 0) throw new exception('Минимальная длина генерируемого пароля: 1 символ'); | ||||
|       if ($parameters['type'] !== 'classic' && $parameters['type'] !== 'mnemonic') throw new exception('Допустимые типы пароля: "mnemonic", "classic"'); | ||||
|  | ||||
|       // Генерация ответа по запрашиваемым параметрам | ||||
|       foreach ($return as $parameter) match ($parameter) { | ||||
|         'password' => $buffer['password'] = password::{$parameters['type'] ?? 'classic'}($parameters['length'], $this->errors), | ||||
|         'errors' => null, | ||||
|         default => throw new exception("Параметр не найден: $parameter") | ||||
|       }; | ||||
|     } catch (exception $e) { | ||||
|       // Запись в журнал ошибок | ||||
|       $this->errors[] = [ | ||||
|         'text' => $e->getMessage(), | ||||
|         'file' => $e->getFile(), | ||||
|         'line' => $e->getLine(), | ||||
|         'stack' => $e->getTrace() | ||||
|       ]; | ||||
|     } | ||||
|  | ||||
|     // Запись реестра ошибок в буфер ответа | ||||
|     if (in_array('errors', $return, true)) $buffer['errors'] = self::parse_only_text($this->errors); | ||||
|  | ||||
|     // Запись заголовка ответа | ||||
|     header('Content-Type: application/json'); | ||||
|  | ||||
|     return json_encode($buffer); | ||||
|   } | ||||
| } | ||||
| @@ -7,8 +7,8 @@ namespace mirzaev\site\account\controllers; | ||||
| // Файлы проекта | ||||
| use mirzaev\site\account\views\templater; | ||||
| use mirzaev\site\account\models\core as models; | ||||
| use mirzaev\site\account\models\account_model as account; | ||||
| use mirzaev\site\account\models\session_model as session; | ||||
| use mirzaev\site\account\models\account; | ||||
| use mirzaev\site\account\models\session; | ||||
|  | ||||
| // Библиотека для ArangoDB | ||||
| use ArangoDBClient\Document as _document; | ||||
| @@ -26,13 +26,36 @@ use mirzaev\vk\robots\user as robot; | ||||
|  * @package mirzaev\site\account\controllers | ||||
|  * @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy> | ||||
|  */ | ||||
| class core extends controller  | ||||
| class core extends controller | ||||
| { | ||||
|   /** | ||||
|    * Переменные окружения | ||||
|    */ | ||||
|   protected robot $vk; | ||||
|  | ||||
|   /** | ||||
|    * Инстанция сессии | ||||
|    */ | ||||
|   public session $session; | ||||
|  | ||||
|   /** | ||||
|    * Инстанция аккаунта | ||||
|    */ | ||||
|   public ?account $account; | ||||
|  | ||||
|   /** | ||||
|    * Постфикс | ||||
|    */ | ||||
|   public string $postfix = ''; | ||||
|  | ||||
|   /** | ||||
|    * Реестр ошибок | ||||
|    */ | ||||
|   public array $errors = [ | ||||
|     'session' => [], | ||||
|     'account' => [] | ||||
|   ]; | ||||
|  | ||||
|   /** | ||||
|    * Конструктор | ||||
|    * | ||||
| @@ -48,25 +71,18 @@ class core extends controller | ||||
|     // Инициализация шаблонизатора представлений | ||||
|     $this->view = new templater; | ||||
|  | ||||
|     // Инициализация журнала ошибок | ||||
|     $this->view->errors = [ | ||||
|       'session' => [], | ||||
|       'account' => [], | ||||
|       'vk' => [] | ||||
|     ]; | ||||
|  | ||||
|     // Инициализация даты до которой будет активна сессия | ||||
|     $expires = time() + 604800; | ||||
|  | ||||
|     // Инициализация сессии (без журналирования) | ||||
|     $this->view->session = new session($_COOKIE["session"] ?? null, $expires) ?? | ||||
|     $this->session = new session($_COOKIE["session"] ?? null, $expires) ?? | ||||
|       header('Location: https://mirzaev.sexy/error?code=500&text=Не+удалось+инициализировать+сессию'); | ||||
|  | ||||
|     if ($_COOKIE["session"] ?? null !== $this->view->session->hash) { | ||||
|     if ($_COOKIE["session"] ?? null !== $this->session->hash) { | ||||
|       // Изменился хеш сессии (подразумевается, что сессия устарела) | ||||
|  | ||||
|       // Запись хеша новой сессии | ||||
|       setcookie('session', $this->view->session->hash, [ | ||||
|       setcookie('session', $this->session->hash, [ | ||||
|         'expires' => $expires, | ||||
|         'domain' => 'mirzaev.sexy', | ||||
|         'path' => '/', | ||||
| @@ -77,20 +93,11 @@ class core extends controller | ||||
|     } | ||||
|  | ||||
|     // Инициализация аккаунта (без журналирования) | ||||
|     $this->view->account = $this->view->session->account(); | ||||
|     $this->account = $this->session->account(); | ||||
|  | ||||
|     if ($this->view->account instanceof _document) { | ||||
|     if ($this->account instanceof _document) { | ||||
|       // Инициализирован аккаунт | ||||
|  | ||||
|       // Инициализация аккаунта ВКонтакте (без журналирования) | ||||
|       $this->variables['vk'] = account::vk($this->variables['account']); | ||||
|  | ||||
|       if ($this->variables['vk'] instanceof _document) { | ||||
|         // Инициализирован аккаунт ВКонтакте | ||||
|  | ||||
|         // Инициализация робота для аккаунта ВКонтакте | ||||
|         $this->vk = vk::init()->user(key: $this->variables['vk']->access['key']); | ||||
|       } else unset($this->variables['account'], $this->variables['vk']); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -13,7 +13,7 @@ use mirzaev\site\account\controllers\core; | ||||
|  * @package mirzaev\site\account\controllers | ||||
|  * @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy> | ||||
|  */ | ||||
| final class error_controller extends core | ||||
| final class error extends core | ||||
| { | ||||
|     /** | ||||
|      * Страница с ошибкой | ||||
| @@ -23,22 +23,22 @@ final class error_controller extends core | ||||
|     public function index(array $parameters = []): ?string | ||||
|     { | ||||
|         // Запись текста ошибки в переменную окружения
 | ||||
|         $this->variables['text'] = $parameters['text'] ?? null; | ||||
|         $this->view->text = $parameters['text'] ?? null; | ||||
| 
 | ||||
|         if (isset($parameters['code'])) { | ||||
|             // Получен код ошибки
 | ||||
| 
 | ||||
|             // Запись кода ошибки в переменную окружения
 | ||||
|             $this->variables['code'] = $parameters['code']; | ||||
|             $this->view->code = $parameters['code']; | ||||
| 
 | ||||
|             // Запись кода ответа
 | ||||
|             http_response_code($parameters['code']); | ||||
| 
 | ||||
|             // Генерация представления
 | ||||
|             return $this->view->render(DIRECTORY_SEPARATOR . 'errors' . DIRECTORY_SEPARATOR . 'index.html', $this->variables); | ||||
|             return $this->view->render(DIRECTORY_SEPARATOR . 'errors' . DIRECTORY_SEPARATOR . 'index.html'); | ||||
|         } | ||||
| 
 | ||||
|         // Генерация представления
 | ||||
|         return $this->view->render(DIRECTORY_SEPARATOR . 'errors' . DIRECTORY_SEPARATOR . ($parameters['code'] ?? 'index') . '.html', $this->variables); | ||||
|         return $this->view->render(DIRECTORY_SEPARATOR . 'errors' . DIRECTORY_SEPARATOR . ($parameters['code'] ?? 'index') . '.html'); | ||||
|     } | ||||
| } | ||||
| @@ -13,7 +13,7 @@ use mirzaev\site\account\controllers\core; | ||||
|  * @package mirzaev\site\account\controllers | ||||
|  * @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy> | ||||
|  */ | ||||
| final class graph_controller extends core | ||||
| final class graph extends core | ||||
| { | ||||
|     /** | ||||
|      * Страница с графиком | ||||
| @@ -13,7 +13,7 @@ use mirzaev\site\account\controllers\core; | ||||
|  * @package mirzaev\site\account\controllers | ||||
|  * @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy> | ||||
|  */ | ||||
| final class hotline_controller extends core | ||||
| final class hotline extends core | ||||
| { | ||||
|     /** | ||||
|      * Страница с бегущей строкой | ||||
| @@ -13,7 +13,7 @@ use mirzaev\site\account\controllers\core; | ||||
|  * @package mirzaev\site\account\controllers | ||||
|  * @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy> | ||||
|  */ | ||||
| final class index_controller extends core | ||||
| final class index extends core | ||||
| { | ||||
|   /** | ||||
|    * Главная страница | ||||
| @@ -25,6 +25,7 @@ final class index_controller extends core | ||||
|     // Инициализация узлов
 | ||||
|     $this->view->nodes = [ | ||||
|       'account' => $this->view->render(DIRECTORY_SEPARATOR . 'nodes' . DIRECTORY_SEPARATOR . (isset($this->account) ? 'profile.html' : 'authentication.html')) | ||||
|       /* 'account' => $this->view->render(DIRECTORY_SEPARATOR . 'nodes' . DIRECTORY_SEPARATOR . (isset($this->account) ? 'profile.html' : 'connect.html')) */ | ||||
|     ]; | ||||
| 
 | ||||
|     // Генерация представления
 | ||||
							
								
								
									
										203
									
								
								mirzaev/site/account/system/controllers/session.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										203
									
								
								mirzaev/site/account/system/controllers/session.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,203 @@ | ||||
| <?php | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace mirzaev\site\account\controllers; | ||||
|  | ||||
| // Файлы проекта | ||||
| use mirzaev\site\account\controllers\core, | ||||
|   mirzaev\site\account\controllers\traits\errors, | ||||
|   mirzaev\site\account\models\invite, | ||||
|   mirzaev\site\account\models\account; | ||||
|  | ||||
| // Встроенные библиотеки | ||||
| use exception; | ||||
|  | ||||
| /** | ||||
|  * Контроллер сессии  | ||||
|  * | ||||
|  * @package mirzaev\site\account\controllers | ||||
|  * @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy> | ||||
|  */ | ||||
| final class session extends core | ||||
| { | ||||
|   use errors; | ||||
|  | ||||
|   /** | ||||
|    * Записать входной псевдоним  | ||||
|    * | ||||
|    * Проверяет существование аккаунта с этим входным псевдонимом | ||||
|    * и запоминает для использования в процессе аутентификации | ||||
|    * | ||||
|    * @param array $parameters Параметры запроса | ||||
|    *  | ||||
|    * @return string JSON-документ с запрашиваемыми параметрами | ||||
|    */ | ||||
|   public function login(array $parameters = []): string | ||||
|   { | ||||
|     // Инициализация буфера ответа | ||||
|     $buffer = []; | ||||
|  | ||||
|     // Инициализация реестра возвращаемых параметров | ||||
|     $return = explode(',', $parameters['return'], 50); | ||||
|  | ||||
|     try { | ||||
|       // Проверка наличия обязательных параметров | ||||
|       if (empty($parameters['login'])) throw new exception('Необходимо передать входной псевдоним'); | ||||
|  | ||||
|       // Вычисление длины | ||||
|       $length = strlen($parameters['login']); | ||||
|  | ||||
|       // Проверка параметров на соответствование требованиям | ||||
|       if ($length === 0) throw new exception('Входной псевдоним не может быть пустым'); | ||||
|       if ($length > 100) throw new exception('Входной псевдоним не может быть длиннее 100 символов'); | ||||
|  | ||||
|       // Поиск аккаунта | ||||
|       $account = account::read($parameters['login'], $this->errors['account']); | ||||
|  | ||||
|       // Генерация ответа по запрашиваемым параметрам | ||||
|       foreach ($return as $parameter) match ($parameter) { | ||||
|         'exist' => $buffer['exist'] = isset($account->instance), | ||||
|         'errors' => null, | ||||
|         default => throw new exception("Параметр не найден: $parameter") | ||||
|       }; | ||||
|  | ||||
|       if ($parameters['remember'] === '1') $this->session->remember('account.identification.login', $parameters['login']); | ||||
|     } catch (exception $e) { | ||||
|       // Запись в журнал ошибок | ||||
|       $this->errors['session'][] = [ | ||||
|         'text' => $e->getMessage(), | ||||
|         'file' => $e->getFile(), | ||||
|         'line' => $e->getLine(), | ||||
|         'stack' => $e->getTrace() | ||||
|       ]; | ||||
|     } | ||||
|  | ||||
|     // Запись реестра ошибок в буфер ответа | ||||
|     if (in_array('errors', $return, true)) $buffer['errors'] = self::parse_only_text($this->errors); | ||||
|  | ||||
|     // Запись заголовка ответа | ||||
|     header('Content-Type: application/json'); | ||||
|  | ||||
|     return json_encode($buffer); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Записать пароль | ||||
|    * | ||||
|    * Проверяет на соответствие требованиям  | ||||
|    * и запоминает для использования в процессе аутентификации | ||||
|    * | ||||
|    * @param array $parameters Параметры запроса | ||||
|    *  | ||||
|    * @return string JSON-документ с запрашиваемыми параметрами | ||||
|    */ | ||||
|   public function password(array $parameters = []): string | ||||
|   { | ||||
|     // Инициализация буфера ответа | ||||
|     $buffer = []; | ||||
|  | ||||
|     // Инициализация реестра возвращаемых параметров | ||||
|     $return = explode(',', $parameters['return'], 50); | ||||
|  | ||||
|     try { | ||||
|       // Проверка наличия обязательных параметров | ||||
|       if (empty($parameters['password'])) throw new exception('Необходимо передать пароль'); | ||||
|  | ||||
|       // Вычисление длины | ||||
|       $length = strlen($parameters['password']); | ||||
|  | ||||
|       // Проверка параметров на соответствование требованиям | ||||
|       if ($length === 0) throw new exception('Пароль не может быть пустым'); | ||||
|       if ($length > 300) throw new exception('Пароль не может быть длиннее 300 символов'); | ||||
|  | ||||
|       // Генерация ответа по запрашиваемым параметрам | ||||
|       foreach ($return as $parameter) match ($parameter) { | ||||
|         'verify' => $buffer['verify'] = true, | ||||
|         'errors' => null, | ||||
|         default => throw new exception("Параметр не найден: $parameter") | ||||
|       }; | ||||
|  | ||||
|       if ($parameters['remember'] === '1') throw new exception('Запоминать пароль не безопасно'); | ||||
|     } catch (exception $e) { | ||||
|       // Запись в журнал ошибок | ||||
|       $this->errors['session'][] = [ | ||||
|         'text' => $e->getMessage(), | ||||
|         'file' => $e->getFile(), | ||||
|         'line' => $e->getLine(), | ||||
|         'stack' => $e->getTrace() | ||||
|       ]; | ||||
|  | ||||
|       // Запись реестра ошибок в буфер ответа | ||||
|       if (in_array('verify', $return, true)) $buffer['verify'] = false; | ||||
|     } | ||||
|  | ||||
|     // Запись реестра ошибок в буфер ответа | ||||
|     if (in_array('errors', $return, true)) $buffer['errors'] = self::parse_only_text($this->errors); | ||||
|  | ||||
|     // Запись заголовка ответа | ||||
|     header('Content-Type: application/json'); | ||||
|  | ||||
|     return json_encode($buffer); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Записать код приглашения | ||||
|    * | ||||
|    * Проверяет существование приглашения с этим кодом | ||||
|    * и запоминает для использования в процессе регистрации | ||||
|    * | ||||
|    * @param array $parameters Параметры запроса | ||||
|    *  | ||||
|    * @return string JSON-документ с запрашиваемыми параметрами | ||||
|    */ | ||||
|   public function invite(array $parameters = []): string | ||||
|   { | ||||
|     // Инициализация буфера ответа | ||||
|     $buffer = []; | ||||
|  | ||||
|     // Инициализация реестра возвращаемых параметров | ||||
|     $return = explode(',', $parameters['return'], 50); | ||||
|  | ||||
|     try { | ||||
|       // Проверка наличия обязательных параметров | ||||
|       if (empty($parameters['invite'])) throw new exception('Необходимо передать ключ приглашения'); | ||||
|  | ||||
|       // Вычисление длины | ||||
|       $length = strlen($parameters['invite']); | ||||
|  | ||||
|       // Проверка параметров на соответствование требованиям | ||||
|       if ($length === 0) throw new exception('Получен пустой ключ приглашения'); | ||||
|  | ||||
|       // Поиск приглашения | ||||
|       $invite = invite::read($parameters['invite'], $this->errors['session']); | ||||
|  | ||||
|       // Генерация ответа по запрашиваемым параметрам | ||||
|       foreach ($return as $parameter) match ($parameter) { | ||||
|         'exist' => $buffer['exist'] = isset($invite->instance), | ||||
|         // from временное решение пока не будет разработана система сессий | ||||
|         'from' => $return['from'] = ['login' => 'mirzaev'] ?? $invite->from(), | ||||
|         'errors' => null, | ||||
|         default => throw new exception("Параметр не найден: $parameter") | ||||
|       }; | ||||
|  | ||||
|       if ($parameters['remember'] === '1') $this->session->remember('account.registration.invite', $parameters['invite']); | ||||
|     } catch (exception $e) { | ||||
|       // Запись в журнал ошибок | ||||
|       $this->errors['session'][] = [ | ||||
|         'text' => $e->getMessage(), | ||||
|         'file' => $e->getFile(), | ||||
|         'line' => $e->getLine(), | ||||
|         'stack' => $e->getTrace() | ||||
|       ]; | ||||
|     } | ||||
|  | ||||
|     // Запись реестра ошибок в буфер ответа | ||||
|     if (in_array('errors', $return, true)) $buffer['errors'] = self::parse_only_text($this->errors); | ||||
|  | ||||
|     // Запись заголовка ответа | ||||
|     header('Content-Type: application/json'); | ||||
|    | ||||
|     return json_encode($buffer); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										30
									
								
								mirzaev/site/account/system/controllers/traits/errors.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								mirzaev/site/account/system/controllers/traits/errors.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| <?php | ||||
|  | ||||
| declare(strict_types=1); | ||||
|  | ||||
| namespace mirzaev\site\account\controllers\traits; | ||||
|  | ||||
| /** | ||||
|  * Заготовка для обработки ошибок | ||||
|  * | ||||
|  * @package mirzaev\site\account\controllers\traits | ||||
|  * @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy> | ||||
|  */ | ||||
| trait errors | ||||
| { | ||||
|   private static function parse_only_text(array $errors): array | ||||
|   { | ||||
|     // Инициализация буфера вывода | ||||
|     $buffer = []; | ||||
|  | ||||
|     foreach ($errors as $offset => $error) { | ||||
|       // Перебор ошибок | ||||
|  | ||||
|       // Проверка на вложенность и запись в буфер вывода (вход в рекурсию) | ||||
|       if (isset($error['text'])) $buffer[] = $error['text']; | ||||
|       else if (is_array($error)) $buffer[$offset] = static::parse_only_text($error); | ||||
|     } | ||||
|  | ||||
|     return $buffer; | ||||
|   } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user