From f3cc7cca12b3e0aba4692d8ba2457647e3172632 Mon Sep 17 00:00:00 2001 From: Pavel Belyaev Date: Sun, 6 Jun 2021 01:31:19 +0500 Subject: [PATCH] Add access level control --- CLASSES/core/LE_ALC.php | 88 ++++++++++++++++++++++++++++++++++++++ DOC/README.md | 1 + DOC/core_classes/LE_ALC.md | 40 +++++++++++++++++ TPL/main/sys/auth.tpl | 68 +++++++++++++++++++++++++++++ init.php | 1 + 5 files changed, 198 insertions(+) create mode 100644 CLASSES/core/LE_ALC.php create mode 100644 DOC/core_classes/LE_ALC.md create mode 100644 TPL/main/sys/auth.tpl diff --git a/CLASSES/core/LE_ALC.php b/CLASSES/core/LE_ALC.php new file mode 100644 index 0000000..06b1f21 --- /dev/null +++ b/CLASSES/core/LE_ALC.php @@ -0,0 +1,88 @@ +lev_control($need_lev); + } + + + + public function lev_control($need_lev) + { + if (!$need_lev>0) return true; + $lev = (isset($_SESSION['user']['level'])) ? $_SESSION['user']['level'] : 0; + + if (!$lev>0) return $this->auth($need_lev); + + if ($lev<$need_lev) + { + http_response_code(403); + exit ('ACCESS DENIED!!!'); + } + return $lev; + } + + public function auth($need_lev) + { + $vars = ['act_url'=>LE::$FULL_URL]; + + if(isset($_POST['login_ok'])) + { + $res = $this->login($_POST); + if ($res===200) return $this->lev_control($need_lev); + + if ($res===2) $vars['err']='Необходимо заполнить поля!'; + if ($res===3) $vars['err']='Пользователя с таким логином и паролем не существует!'; + } + + return $this->auth_form($vars); + } + + private function auth_form($vars) + { + LE::$TPL->mod_cont .= LE::$TPL->fetch('sys/auth',$vars,'main'); + http_response_code(401); + LE::$TPL->display(); + + exit(); + } + + public function login($in) + { + if (!is_array($in)) return 2; + $login = arr_v($in,'login'); + $password = arr_v($in,'password'); + + $login = PRE::F($in['login'],'DRL@_-.'); + if (empty($login) || empty($password)) return 2; + + + $sql = "SELECT * FROM `".$this->table."` WHERE `login`='".$login."'"; + $res = LE::$DB->query_single($sql); + + if (is_null($res) || $res['password']!==md5($password)) return 3; + + $_SESSION['user'] = ['uid'=>$res['id'],'level'=>$res['level']]; + + return 200; + + } + + + public function logout() + { + unset($_SESSION['user']); + } +} \ No newline at end of file diff --git a/DOC/README.md b/DOC/README.md index 219709a..d8b4458 100644 --- a/DOC/README.md +++ b/DOC/README.md @@ -31,3 +31,4 @@ * LE_TPL - шаблонизатор * [LE_СURL](core_classes/LE_CURL.md) - класс для выполнения HTTP запросов, работы с API и др, обертка над cURL * [LE_TIME](core_classes/LE_TIME.md) - класс для работы с датами и временем +* [LE_ALC](core_classes/LE_ALC.md) - класс для аутентификации пользователей и контроля доступом (Access Level Control) diff --git a/DOC/core_classes/LE_ALC.md b/DOC/core_classes/LE_ALC.md new file mode 100644 index 0000000..b08e0e2 --- /dev/null +++ b/DOC/core_classes/LE_ALC.md @@ -0,0 +1,40 @@ +# LE ALС - access level control +В системе LE предусмотрены уровни доступа, эти уровни могут задаваться на уровне всего пространства (например админка или личный кабинет) и на уровне кокнкретных модулей, например простой менеджер не может добавлять администраторов сайта, а директор может. + +## Хранение +Все аккаунты хранятся в таблице `sys_accounts` + + +Поле | Тип | Описание +----- | ----- | --------- +id | int 12 | +login | varchar 200| Логин для авторизации +level | int 2 | уровень привелегий +password | varchar 32 | пароль в формате md5, позже вероятно можно перейти на sha-256 +name | varchar 250 |Имя для отображения на сайте| +data | JSON |Любые произвольные, обычно анкетные данные, например адрес, этаж, код от домофона, ссылка на соц сеть... + +## Уровни доступа +В конкретном приложении можно придумать свои уровни, но на стандартном решени будут вот такие уровни + +Уровень | Роль | Описание +----- | ----- | --------- +0 | Гость | Обычный посетитель сайта, который не авторизовался +1 | Обычный пользователь | Это или покупатель или читатель, может например заходить в свой кабинет, менять свои данные, но в основном ограниченный, с нулевой кармой +2 | Привилигированный пользователь | Это человек имеющий например право писать комментарии и как-то модифицировать наполнение внешней части сайта +3 | Модератор | +4 | Менеджер | +5 | Директор | +6 | Администратор | + +## Включение контроля доступа +Контроль доступа можно включить как на уровне всего пространства (например админка), так и на уровне конкретного модуля, для этого в начале файла достаточно добавить + +```php +$user_lev = LE::$ALC->set_lev(2); +``` +Где 2 - это минимальный уровень доступа для данного функционала, даже если посетитель авторизовался, но у него уровень 1, то он не будет иметь доступа к данному функционалу и получит 403 ошибку + +Помимо этого, указанная функция возвращает уровень доступа текущего пользователя, что позволяет кастомизировать меню, скрывать запрещенные пункты итд... + +Если пользователь не авторизован, то он получит форму для ввода логина и пароля, дальнейшее выполнение скрипта остановится. \ No newline at end of file diff --git a/TPL/main/sys/auth.tpl b/TPL/main/sys/auth.tpl new file mode 100644 index 0000000..2ed8b48 --- /dev/null +++ b/TPL/main/sys/auth.tpl @@ -0,0 +1,68 @@ +
+
+ + + + + + + +
+
+ + + + + \ No newline at end of file diff --git a/init.php b/init.php index a02bab6..441e235 100644 --- a/init.php +++ b/init.php @@ -36,6 +36,7 @@ include I."db_init.php"; //mysql if (ISWEB): include I."session.php"; LE::$TPL = new LE_TPL; //шаблонизатор + LE::$ALC = new LE_ALC; //контроль доступа include I."load_mod.php"; //load module LE::$TPL->display(); exit();