====== Этап разработки системы прав ======
[[start:|lss]]
===== Введение =====
На этом этапе мы разработаем экраны списка ролей и пользователей системы, наладим работу контроллера прав, проставим права в описатели таблиц, главное меню системы.
===== Развертывание этапа на площадке =====
  * Скачаем архив **LSS проекта** для текущего этапа.
  * Обновим проект из архива. Надо быть осторожным с конфигурационным файлом площадки **php/config/config-place.php**, он содержит текущие параметры соединения с базой данных, его обновлять не надо.
  * Выполним с помощью утилиты **pgAdmin** скрипт обновления содержимого системных таблиц, файл **export-import/backup/backup.sql**.
==== Описание ====
=== Экранная форма ролей formRole ===
Описание экранной формы ролей расположено в файле **php/perm/formRole.xml**. Это описание практически идентично описанию стандартной формы справочника.
=== Экранная форма пользователей formUser ===
Описание экранной формы ролей расположено в файле **php/perm/formUser.xml**. Это описание практически идентично описанию стандартной формы справочника.
=== Контроллер источника данных пользователей ===
Файл контроллера **php/datasources/user.php**:
class DataSource_User_Ext extends DataSource_User {
	protected function onRowAfter(&$row, $params=Array()) {
		if ($row['password']) $row['password']='***';
	}
	protected function onBeforeSave(&$params) {
		if ($params['password']) $params['password']=cryptPassword($params['password']);
	}
}
return new DataSource_User_Ext();
  * обработчик **onRowAfter** скрывает отображение паролей пользователей, заменяя их на звездочки.
  * обработчик **onBeforeSave** шифрует пароль пользователя перед сохранением в базе данных. Функция **cryptPassword** обеспечивает простейшее шифрование по **md5** с солью.
  * в описатель поля **password** таблицы **user** добавлен атрибут **save=1** (см экранную форму **Разработка/Структура базы**). В результате правка этого поля вызывает автоматическое сохранение изменений строки таблицы. А в ответе вместо значения поля пароля приходят звездочки.
=== Контроллер прав доступа ===
Контроллер прав доступа PermController размещен в файле **php/perm.php**:
execDisconnect();
		session_start();
		try {
			if ($login==getCfg('root.login','root') && cryptPassword($password)==getCfg('root.password')) {
				$_SESSION['connect_isconnected']=true;
				$_SESSION['connect_login']='root';
				if (getCfg('root.enabled', true)) {
					$_SESSION['connect_isroot']=true;
				}
				else {
					$_SESSION['connect_role']='АДМ';
				}
				return true;
			}
			
			$sql_login=$this->str2Sql($login);
			$sql_password=$this->str2Sql(cryptPassword($password));
			$sql=<<pdoFetch($sql);
			if ($rec['id']) {
				$_SESSION['connect_isconnected']=true;
				$_SESSION['connect_login']=$rec['fio'];
				$_SESSION['connect_role']=$rec['role_code'];
				return true;
			}
		}
		finally {
			// защита от CSRF уязвимости посредством токена
			if (getCfg('csrftoken.enabled')) $_SESSION['connect_csrftoken']=getGUID();
			session_write_close();
		}
		return false;
	}
}
return new PermControllerPrj();
  * метод **execConnect** вызывается диалогом аутентификации посредством запроса **connect**. Отдельно проверяется пользователь **root**, его параметры берутся из конфигурационного файла. Отдельно проверяются все остальные пользователи - на основе содержимого таблицы **user**. Если логин и пароль указаны правильно, то параметры пользователя сохраняются в сессии.
  * метод **getPerm** проверяет доступность по правам текущему пользователю режима работы системы. Используем следующие режимы:
    * **connected** - доступно всем авторизованным пользователям. Если проверка не прошла, то пользователя автоматически перенаправляют на экран аутентификации, посредством отправки ответа **disconnected**.
    * **root** - доступно только пользователю **root**, например пункт меню **Разработка** должен быть доступен только программисту.
    * **ref** - справочники, на чтение доступны всем авторизованным пользователям, правка только администратору
    * **rootref** - системные справочники, на чтение доступны всем авторизованным пользователям, правка только root
    * **machine** - работа с оборудованием и ремонтами, на чтение доступно всем авторизованным пользователям, правка доступна администратору и роли ПРВ
    * **report** - выполнение отчетов, доступно всем авторизированным пользователям
    * **perm** - пользователи и права, доступно только администратору
=== Права в описателях структуры данных ===
Экранная форма **Разработка/Структура базы** позволяет назначить режим прав каждой таблице (поле **Режим по правам**). Затем можно вызвать **Пересчет/Генерация классов DataSource** и перенести эти права в контроллеры источников данных **DataSource**.
Помимо режима прав (параметр **mode**) **DataSource** делит запросы на операции (параметр **operation**) **read** и **write**. Соответственно, контроллер прав **PermController** определяет доступность соответствующей операции текущему пользователю.
=== Права в главном меню системы ===
Проставим права в описании главного меню системы, файл **php/config/appmenu.xml**:
	
	
	
		
		
	
	
		
		
		
	
	
		
		
	
    
        
        
    
=== Права в контроллерах отчетов ===
Добавим проверку прав в контроллеры отчетов **plan** и **fact**:
class ReportPlan extends ReportController {
  public function getParams() {
    if (!getPerm('report','read')) throw new Exception('У Вас нет прав на выполнение этого отчета');
    ...
===== Демонстрационные примеры и ссылки =====
Демонстрационные примеры доступны в режиме "**только чтение**". Для входа используйте логин **root**, пароль **1**.
  * демонстрация работы **тестового примера** "Материальные активы" у нас на сайте: [[https://lss.m-cti.ru/storage/example/lss-exampl]]