Урок 18. Права доступа

В прошлом уроке мы реализовали в программе механизм аутентификации пользователей. А также назначили права доступа группам "Администраторы" и "Пользователи". Точнее мы просто передали этим группам все права, которые были описаны для гостевой учетки, и не задали различие этих групп. Все пользователи могут смотреть и редактировать любые данные в программе.

В этом уроке мы рассмотрим статические прав доступа, а следующий урок будет посвящен динамическим правам доступа. Суть статических прав доступа заключается в том, что разработчик через серверный xml-файл настраивает разрешения для групп пользователей. Динамические права доступа позволяют пользователю через интерфейс программы самому настраивать права доступа.

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

При разворачивании проекта используйте backup базы данных, который можете найти в архиве из раздела Ответы прошлого урока. Скопируйте папки Forms, Workflow и Patterns в папку с развернутым проектом, например, в папку D:\WT\Projects\Template\Projects\1. Template.

Инструкция по подключению шаблонов находится по ссылке.

Настройка прав доступа

Есть два направления в организации прав доступа. Первое направление заключается в настройке группам пользователей разрешений на выполнение запросов на стороне сервера. Второе направление состоит в настройке доступа к графическим элементам интерфейса и выполнению команд на клиентской части.

Управлять доступом до графических объектов на формах можно через тэги <Visible> и <Enabled> этих объектов. А проверять права доступа будем через специальный элемент <AccessPoint>.

Точки доступа на форме

Перейдем в xml-файл стартовой формы (TemplateStart.xml) и на ее примере рассмотрим точки доступа.

Первым делом для каждого элемента формы в тэги <Visible> и <Enabled> необходимо прописать AccessPoint с именем, описывающем суть действия. Например, для AdminMenuItem (Администрирование) в <MainMenu> добавим следующие условия видимости пунктов меню:

TemplateStart.xml
<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, который будет с сервера получать информацию о правах доступа для текущего пользователя, и прописать в нем все точки доступа, которые расставили на объектах формы:

TemplateStart.xml
<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>:

Template.xml
<AccessPoints>
  <AccessPoint Name="UserViewAccessPoint" />
  <AccessPoint Name="SettingsViewAccessPoint" />
</AccessPoints>

Теперь необходимо эти AccessPoint распределить по Permission. Переделаем UserViewSqlQueryPermission в UserViewPermission:

Template.xml
<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:

Template.xml
<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, чтобы подсказывать пользователю, почему кнопка недоступна. Таким образом, полный синтаксис кнопки добавления заказа будет иметь вид:

TemplateStart.xml
<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>, который ограничит выполнение команды:

TemplateStart.xml
<Command Name="OrderDataConnectionRefreshCommand" Type="DataConnectionRefreshCommand" Assembly="Commands">
  <Condition Name="OrderViewAccessPointCondition" />
  <DataConnections>
    <DataConnection Name="OrderPrimaryGetDataConnection" />
  </DataConnections>
</Command>

Так как в команде нельзя указать AccessPoint напрямую, то мы должны обернуть его в условие проверки:

TemplateStart.xml
<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