Урок 18. Права доступа
В прошлом уроке мы реализовали в программе механизм аутентификации пользователей. А также назначили права доступа группам "Администраторы" и "Пользователи". Точнее мы просто передали этим группам все права, которые были описаны для гостевой учетки, и не задали различие этих групп. Все пользователи могут смотреть и редактировать любые данные в программе.
В этом уроке мы рассмотрим статические прав доступа, а следующий урок будет посвящен динамическим правам доступа. Суть статических прав доступа заключается в том, что разработчик через серверный xml-файл настраивает разрешения для групп пользователей. Динамические права доступа позволяют пользователю через интерфейс программы самому настраивать права доступа.
Если хотите начать практику с этого урока, то вам необходимо развернуть учебный проект по инструкции в статье Разворачивание проекта.
При разворачивании проекта используйте backup базы данных, который можете найти в архиве из раздела Ответы прошлого урока. Скопируйте папки Forms, Workflow и Patterns в папку с развернутым проектом, например, в папку D:\WT\Projects\Template\Projects\1. Template.
Инструкция по подключению шаблонов находится по ссылке.
Настройка прав доступа
Есть два направления в организации прав доступа. Первое направление заключается в настройке группам пользователей разрешений на выполнение запросов на стороне сервера. Второе направление состоит в настройке доступа к графическим элементам интерфейса и выполнению команд на клиентской части.
Управлять доступом до графических объектов на формах можно через тэги <Visible>
и <Enabled>
этих объектов. А проверять права доступа будем через специальный элемент <AccessPoint>
.
Точки доступа на форме
Перейдем в xml-файл стартовой формы (TemplateStart.xml) и на ее примере рассмотрим точки доступа.
Первым делом для каждого элемента формы в тэги <Visible>
и <Enabled>
необходимо прописать AccessPoint с именем, описывающем суть действия. Например, для AdminMenuItem (Администрирование) в <MainMenu>
добавим следующие условия видимости пунктов меню:
<MenuItem Name="AdminMenuItem" Type="MenuItem">
<Title>Администрирование</Title>
<Visible>
<Or>
<AccessPoint Name="UserViewAccessPoint" />
<AccessPoint Name="SettingsViewAccessPoint" />
</Or>
</Visible>
<Items>
<MenuItem Name="UserListMenuItem" Type="MenuItem">
<Title>Пользователи...</Title>
<Commands>
<Command Name="UserListFormShowCommand" />
</Commands>
<Visible>
<AccessPoint Name="UserViewAccessPoint" />
</Visible>
</MenuItem>
<MenuItem Name="AdministrationSeparator" Type="Separator">
<Visible>
<And>
<AccessPoint Name="UserViewAccessPoint" />
<AccessPoint Name="SettingsViewAccessPoint" />
</And>
</Visible>
</MenuItem>
<MenuItem Name="SettingsMenuItem" Type="MenuItem">
<Title>Настройки...</Title>
<Command Name="SettingsFormShowCommand" />
<Visible>
<AccessPoint Name="SettingsViewAccessPoint" />
</Visible>
</MenuItem>
</Items>
</MenuItem>
Здесь UserViewAccessPoint будет отвечать за доступ к форме списка пользователей, а SettingsViewAccessPoint - за доступ к форме настроек.
Таким образом, мы формируем набор точек доступа, необходимых для совершения действий на форме.
Теперь необходимо создать AccessPointDataConnection, который будет с сервера получать информацию о правах доступа для текущего пользователя, и прописать в нем все точки доступа, которые расставили на объектах формы:
<DataConnection Name="AccessPointDataConnection" Type="AccessPointDataConnection" Assembly="DataConnections">
<Workflow Name="Template" />
<AccessPoints>
<AccessPoint Name="UserViewAccessPoint" />
<AccessPoint Name="SettingsViewAccessPoint" />
</AccessPoints>
</DataConnection>
Создайте команду типа DataConnectionRefreshCommand для обновления этого DataConnection. Добавьте вызов этой команды в Execution на команды LoginFormShowCommand и ReloginFormShowCommand, чтобы стартовая форма после аутентификации пользователя обновила информацию о его правах доступа.
Точки доступа на сервере
Перейдем в Template.xml. Здесь необходимо объявить все AccessPoint, которые используются на формах. Создадим <AccessPoints>
на одном уровне с <SqlQueries>
и <Permissions>
:
<AccessPoints>
<AccessPoint Name="UserViewAccessPoint" />
<AccessPoint Name="SettingsViewAccessPoint" />
</AccessPoints>
Теперь необходимо эти AccessPoint распределить по Permission. Переделаем UserViewSqlQueryPermission в UserViewPermission:
<Permission Name="UserViewPermission">
<AccessPoint Name="UserViewAccessPoint" />
<SqlQuery Name="UserSelectSqlQuery" />
<SqlQuery Name="UserByIdSelectSqlQuery" />
<SqlQuery Name="GroupSelectSqlQuery" />
<SqlQuery Name="UserExistsSelectSqlQuery" />
</Permission>
Мы удалили атрибут Type
, чтобы перевести Permission в универсальный вид и иметь возможность объявлять AccessPoint вместе с SqlQuery.
Аналогично переделаем SettingsViewSqlQueryPermission в SettingsViewPermission:
<Permission Name="SettingsViewPermission">
<AccessPoint Name="SettingsViewAccessPoint" />
<SqlQuery Name="SettingsSelectSqlQuery" />
<SqlQuery Name="LoadModeSelectSqlQuery" />
</Permission>
Теперь оставим SettingsEditRole и UserEditRole только в описании AdministratorGroup.
Переименуем BaseViewSqlQueryPermission в BaseViewPermission и добавим в него запрос SettingsSelectSqlQuery. Этот запрос предоставляет настройки, необходимые в карточке заказа для отправки счета на электронную почту клиента.
Запустите приложение и проверьте отображение пунктов меню для пользователя из группы "Администраторы" и для пользователя из группы "Пользователи".
Как это работает
При старте формы AccessPointDataConnection отправляет запрос на сервер, движок проверяет, в какой группе находится пользователь и какие Permission доступны этой группе. В ответ на запрос сервер возвращает таблицу с одной строкой, в которой для каждого AccessPoint в DataConnection будет стоять значение True или False, в зависимости от наличия соответствующего Permission у группы текущего пользователя.
Права доступа на просмотр и редактирование сущности
Давайте настроим права доступа к заказам. Для этого на все кнопки редактирования таблицы заказов добавим AccessPoint с соответствующими именами.
Например, на кнопку OrderAddButton добавим тэг <Enabled>
с OrderAddAccessPoint. Теперь необходимо для этой кнопки включить режим DisabledMode, чтобы подсказывать пользователю, почему кнопка недоступна. Таким образом, полный синтаксис кнопки добавления заказа будет иметь вид:
<MyObject Name="OrderAddButton" Type="Button" Assembly="BaseControls">
<Top>
<Object Name="OrderDatabaseTable">
<Property Name="Top" />
</Object>
</Top>
<Left>
<Calculate>
<Expression>{0} + 5</Expression>
<Items>
<Item>
<Object Name="OrderDatabaseTable">
<Property Name="Right" />
</Object>
</Item>
</Items>
</Calculate>
</Left>
<Width>40</Width>
<Height>40</Height>
<TabIndex>3</TabIndex>
<Hint>Добавить запись</Hint>
<BackgroundImage>Images\24x24\plus.png</BackgroundImage>
<BackgroundImageLayout>Center</BackgroundImageLayout>
<FlatStyle>Flat</FlatStyle>
<FlatBorderSize>1</FlatBorderSize>
<FlatBorderColor>ButtonFlatBorderColor</FlatBorderColor>
<FlatMouseDownBackColor>ButtonFlatMouseDownBackColor</FlatMouseDownBackColor>
<FlatMouseOverBackColor>ButtonFlatMouseOverBackColor</FlatMouseOverBackColor>
<Commands>
<Command Name="EmptyOrderInsertSaveCommand" />
<Command Name="OrderAddFormShowCommand" />
</Commands>
<Enabled>
<AccessPoint Name="OrderAddAccessPoint" />
</Enabled>
<DisabledMode>True</DisabledMode>
<DisabledText>У вас недостаточно прав для выполнения команды.</DisabledText>
</MyObject>
Аналогично добавим AccessPoint для кнопок OrderEditButton и OrderDeleteButton. Все AccessPoint добавим в AccessPointDataConnection и в серверный xml-файл.
Не забудьте про Execution по условию OrderCellDoubleClickCondition, в него тоже следует добавить проверку OrderEditAccessPoint.
Добавим OrderViewAccessPoint, с его помощью будем ограничивать доступ к просмотру списка заказов на главной форме.
Ограничить доступ к списку заказов мы можем через управление видимостью панели ContentPanel, так как на ней расположена таблица заказов, кнопки редактирования таблицы и фильтры отображения заказов.
Раз мы прячем таблицу от пользователей, то должны ограничить выполнение команды OrderDataConnectionRefreshCommand на обновление данных по заказам, чтобы не происходило лишнего запроса на сервер. Для этого в описание команды добавим тэг <Condition>
, который ограничит выполнение команды:
<Command Name="OrderDataConnectionRefreshCommand" Type="DataConnectionRefreshCommand" Assembly="Commands">
<Condition Name="OrderViewAccessPointCondition" />
<DataConnections>
<DataConnection Name="OrderPrimaryGetDataConnection" />
</DataConnections>
</Command>
Так как в команде нельзя указать AccessPoint напрямую, то мы должны обернуть его в условие проверки:
<Condition Name="OrderViewAccessPointCondition" Type="EqualCondition" Assembly="Conditions">
<Items>
<Item>
<AccessPoint Name="OrderViewAccessPoint" />
</Item>
<Item>True</Item>
</Items>
<DataType Type="BooleanDataType" />
</Condition>
В серверном xml-файле добавим OrderViewAccessPoint в <AccessPoints>
и в OrderViewSqlQueryPermission.
Самостоятельно
Добавьте AccessPoint на остальные пункты меню на главной форме. На всех остальных формах так же расставьте необходимые AccessPoint. Ограничьте доступ группы "Пользователи" к отчету по бюджету и списку удаленных заказов.
Обратите внимание:
При настройке доступа к кнопке AddEditButton, управляющей ComboBox, проверка AccessPoint должна учитывать, в каком режиме активна кнопка - добавление или редактирование.
На форме кассы проверка прав на редактирование кассовой операции (по кнопке и по двойному клику) должна учитывать, что при выборе оплаты заказа открывается форма заказа.
Итоги
В этом уроке мы настроили права доступа для групп "Администраторы" и "Пользователи", чтобы определить их возможности в программе. Настроили разрешения не только к запросам на стороне сервера, но так же определили точки доступа (AccessPoint) к элементам графического интерфейса на формах.
В следующем уроке познакомимся с динамическими правами доступа.
Ответы
В архиве присутствуют xml-файлы форм и серверный xml-файл, а также бэкап базы данных - с помощью файлов можете проверить себя.
Last updated