Содержание

Этап разработки системы прав

lss

Введение

На этом этапе мы разработаем экраны списка ролей и пользователей системы, наладим работу контроллера прав, проставим права в описатели таблиц, главное меню системы.

Развертывание этапа на площадке

Описание

Экранная форма ролей 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();

Контроллер прав доступа

Контроллер прав доступа PermController размещен в файле php/perm.php:

<?php
class PermControllerPrj extends PermController {
	public function getPerm($mode, $operation) {
		// Если пользователь не авторизован, то ничего нельзя
		if (!getPP('isconnected')) return false;
		if ($mode=='connected') return true;

		// Если у пользователя права isroot, то все можно. Тут разрешаем и дальше уже проверять не будем
		if (getPP('isroot')) return true;
		// Режим root доступен только пользователю с правами isroot
		if ($mode=='root') return false;

		// Права доступны только АДМ
		if ($mode=='perm') {
			if (getPP('role')=='АДМ') return true;
			return false;
		}
		// Справочники на чтение доступны всем, а на правку только АДМ
		if ($mode=='ref') {
			if ($operation=='read') return true;
			if ($operation=='write' && getPP('role')=='АДМ') return true;
			return false;
		}
		// Системные справочники на чтение доступны всем, а на правку только isroot
		if ($mode=='rootref') {
			if ($operation=='read') return true;
			return false;
		}
		// Оборудование на чтение всем, на правку АДМ и ПРВ
		if ($mode=='machine') {
			if ($operation=='read') return true;
			if ($operation=='write' && (getPP('role')=='АДМ' || getPP('role')=='ПРВ')) return true;
			return false;
		}
		// Отчеты доступны всем - АДМ, ПРВ, ОТЧ
		if ($mode=='report') {
			if (getPP('role')=='АДМ' || getPP('role')=='ПРВ' || getPP('role')=='ОТЧ') return true;
			return false;
		}
		return false;
	}
	public function execConnect($login, $password) {
		$this->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=<<<SQL
select
	"user".*,
	"role".code as role_code
from
	"user"
		left join "role" on "role".id="user".roleid
where
	"user".login='{$sql_login}' and
	"user".password='{$sql_password}'
SQL;
			$rec=$this->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();

Права в описателях структуры данных

Экранная форма Разработка/Структура базы позволяет назначить режим прав каждой таблице (поле Режим по правам). Затем можно вызвать Пересчет/Генерация классов DataSource и перенести эти права в контроллеры источников данных DataSource.

Помимо режима прав (параметр mode) DataSource делит запросы на операции (параметр operation) read и write. Соответственно, контроллер прав PermController определяет доступность соответствующей операции текущему пользователю.

Права в главном меню системы

Проставим права в описании главного меню системы, файл php/config/appmenu.xml:

<root>
	<node name="Паспорта оборудования и ремонты" icon="box" form="formMachine" permmode="machine" permoper="read"/>
	<node name="Типы оборудования и нормативы ремонтов" icon="ref" form="ref.formMachineType" permmode="machine" permoper="read"/>
	<node name="Отчеты" icon="print" permmode="report" permoper="read">
		<node name="Отчет по плану ремонтов" icon="print" form="reports.formReportPlan" permmode="report" permoper="read"/>
		<node name="Отчет по выполненным ремонтам" icon="print" form="reports.formReportFact" permmode="report" permoper="read"/>
	</node>
	<node name="Справочники" icon="reffolder" permmode="ref" permoper="read">
		<node name="Структура предприятия" icon="ref" form="ref.formDepartment" permmode="ref" permoper="read"/>
		<node name="Виды ремонта" icon="ref" form="ref.formRepair" permmode="ref" permoper="read"/>
		<node name="Состояния оборудования" icon="ref" form="ref.formMachineStatus" permmode="ref" permoper="read"/>
	</node>
	<node name="Доступ" icon="perm" permmode="perm" permoper="read">
		<node name="Пользователи" icon="user" form="perm.formUser" permmode="perm" permoper="read"/>
		<node name="Роли" icon="usergroup" form="perm.formRole" permmode="rootref" permoper="read"/>
	</node>
    <node name="Разработка" icon="root" permmode="root" permoper="read">
        <node name="Структура базы" icon="tree" form="formSysTreeDataModel"/>
        <node name="Иконки" icon="icon" form="formSysIcons"/>
    </node>
</root>

Права в контроллерах отчетов

Добавим проверку прав в контроллеры отчетов plan и fact:

class ReportPlan extends ReportController {
  public function getParams() {
    if (!getPerm('report','read')) throw new Exception('У Вас нет прав на выполнение этого отчета');
    ...

Демонстрационные примеры и ссылки

Демонстрационные примеры доступны в режиме «только чтение». Для входа используйте логин root, пароль 1.