Пересчет разрешений и экземпляров ключей

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

Пересчет разрешений доступа

Пересчет разрешений доступа требуется в следующих случаях:

  • Если вы изменили алгоритм вычисления разрешений для сущности в обработчиках следующих событий:
    • ВычислитьРазрешенияДоступа,
    • ВычислитьРазрешенияДоступаДляОбъектов,
    • ВычислитьКлючиДоступаДляЧтения,
    • ВычислитьКлючиДоступаДляИзменения.
    В этом случае необходимо выполнить пересчет разрешений доступа для этой сущности в обработчике обновления проекта. Например, при изменении алгоритма расчета разрешений доступа справочника КонтактныеЛица:
    @ОбновлениеПроекта(Ид = "ИзменениеСпособаРасчетаРазрешенийДоступаДляКонтактныхЛиц", Номер = 1)
    метод ИзменениеСпособаРасчетаРазрешенийДоступаДляКонтактныхЛиц()
        КонтактныеЛица.ПересчитатьРазрешенияДоступа()
        КонтактныеЛица.ПересчитатьРазрешенияДоступаДляОбъектов()
    ;
  • Если вы добавили в проект новые элементы, для которых поддерживается управление доступом (справочник, HTTP-сервис и т. д.). В этом случае необходимо выполнить пересчет разрешений доступа для этих сущностей в обработчике обновления проекта. Например, при добавлении в проект новых справочников Задачи и События:
    @ОбновлениеПроекта(Ид = "ДобавлениеПодсистемыМероприятий", Номер = 1)
    метод ДобавлениеПодсистемыМероприятий()
        Задачи.ПересчитатьРазрешенияДоступа()
        События.ПересчитатьРазрешенияДоступа()
    ;
  • Разрешения доступа объектов могут быть настроены таким образом, что будут зависеть от данных других объектов, используемых при вычислении разрешений. Если эти данные меняются, разрешения доступа следует явно пересчитывать.

    К примеру, разрешения доступа для объектов справочника Контактные лица зависят от значения реквизита Регион справочника Клиенты, который является владельцем справочника Контактных лиц. При изменении значения региона у некоторого клиента нужно явно пересчитывать разрешения доступа тех объектов справочника Контактные лица, которые связаны с измененным клиентом. Метод пересчета может быть вызван в обработчике ПослеЗаписи объекта справочника Клиенты. Для объектов, разрешения которых, в свою очередь, зависят от объектов справочника Контактные лица, также по цепочке необходимо выполнить пересчет разрешений.

    Например, после записи объекта справочника Клиенты, от данных которого зависят разрешения доступа объектов связанного справочника КонтактныеЛица, можно вызвать метод ПересчитатьРазрешенияДоступаСвязанныхОбъектов, чтобы выполнить пересчет разрешений:
    @Обработчик
    метод ПослеЗаписи(До: Клиенты.Данные, ПараметрыЗаписи: Клиенты.ПараметрыЗаписи)
        если Регион != До.Регион
            ПересчитатьРазрешенияДоступаСвязанныхОбъектов()
        ;
    ;
    
    метод ПересчитатьРазрешенияДоступаСвязанныхОбъектов()
        исп КонтекстДоступа.Привилегированный()
    
        // Разрешения Контактных лиц зависят от их Клиентов
        знч ДанныеРасчетаРазрешенийКонтактныхЛиц = новый КонтактныеЛица.ДанныеРасчетаРазрешений(Ссылка)
        КонтактныеЛица.ПересчитатьРазрешенияДоступаДляОбъектов([ДанныеРасчетаРазрешенийКонтактныхЛиц])
    
        // Пересчет разрешений доступа для объектов, разрешения которых зависят от Контактных лиц
        // (...)
    ;
Пересчет разрешений можно вызвать:
  • Для одного элемента проекта, например справочника Сотрудники:
    Сотрудники.ПересчитатьРазрешенияДоступа()
  • Для всех элементов проекта или для всех их элементов данных, например для всех справочников:
    для Справочник из Справочники
        Справочник.ПересчитатьРазрешенияДоступа()
    ;
  • Для всех или некоторых объектов одного элемента проекта, например для всех элементов справочника Сотрудники:
    Сотрудники.ПересчитатьРазрешенияДоступаДляОбъектов()
    Когда требуется выполнять пересчет разрешений доступа для конкретных объектов, в параметр метода имя-сущности.ПересчитатьРазрешенияДоступаДляОбъектов() следует передавать массив этих объектов или массив данных расчета разрешений. При вызове метода без параметра будет выполнен пересчет разрешений для всех объектов, что нужно делать, как правило, только при изменении алгоритма расчета разрешений доступа.

    При явном пересчете разрешений доступа объектов с помощью метода имя-сущности.ПересчитатьРазрешенияДоступаДляОбъектов() следует отдавать предпочтение его форме, принимающей в качестве параметра Обходимое<имя-сущности.ДанныеРасчетаРазрешений>, а не Обходимое<имя-сущности.Объект>.

    Предупреждение: Эта операция может занять длительное время, если, например, справочник содержит большое количество элементов. Рекомендуется придерживаться основных принципов построения собственной системы прав.
    Важно: У периодического регистра сведений вызов этого метода приведет к вызову двух событий: ВычислитьКлючиДоступаДляЧтения и ВычислитьКлючиДоступаДляИзменения.

Пересчет экземпляров ключей доступа

Пересчет экземпляров ключей доступа требуется в следующих случаях:
  • Если вы изменили алгоритм выдачи экземпляров ключей в обработчиках событий имя-ключа-доступа.ПроверитьНаличиеКлючейДоступа. В этом случае необходимо выполнить пересчет этого ключа для всех пользователей в обработчике обновления проекта.
    Например, при изменении алгоритма проверки наличия ключа доступа КлючДоступаМенеджера:
    @ОбновлениеПроекта(Ид = "ИзменениеСпособаПроверкиНаличияКлючаДоступаМенеджера", Номер = 1)
    метод ИзменениеСпособаПроверкиНаличияКлючаДоступаМенеджера()
        КлючДоступаМенеджера.ПересчитатьКлючи()
    ;
  • Если изменился набор параметров у какого-либо ключа доступа в проекте. В этом случае при обновлении приложения таблица ключей пользователя будет очищена. Соответственно, нужно пересчитать экземпляры этого ключа доступа и разрешения, которые могли содержать экземпляры этого класса ключа доступа.
  • Если изменились данные, на которых основывается выдача экземпляров ключей тем или иным пользователям: принадлежность к той или иной роли, к тому или иному подразделению и т. д. Эти данные могут храниться в структурах, создаваемых другими элементами проекта, или во внешней системе.
    • При изменении данных, от которых зависит наличие ключей доступа у пользователей, необходимо вызвать пересчет ключей пользователей. К примеру, в проекте существует справочник Сотрудники, который связывает пользователя с тем или иным подразделением. Если права сотрудника зависят от его подразделения, при записи объекта справочника Сотрудники необходимо вызвать пересчет ключей доступа соответствующего пользователя:
      @Обработчик
      метод ПослеЗаписи(До: Сотрудники.Данные, ПараметрыЗаписи: Сотрудники.ПараметрыЗаписи)
          // Пересчет ключей доступа пользователей
          знч ПользователиКПересчету = <Пользователи.Объект>[]
          если Пользователь != Неопределено
              ПользователиКПересчету.Добавить(Пользователь.ЗагрузитьОбъект())
          ;
          если До.Пользователь != Неопределено и Пользователь != До.Пользователь
              ПользователиКПересчету.Добавить(До.Пользователь.ЗагрузитьОбъект())
          ;
          если не ПользователиКПересчету.Пусто()
              исп КонтекстДоступа.Привилегированный()
              Пользователи.ПересчитатьКлючиДоступа(ПользователиКПересчету)
          ;
      ;

      При этом явный пересчет разрешений доступа каких-либо объектов не требуется.

    • При изменении данных, от которых зависит наличие у пользователей конкретного ключа доступа, следует выполнить пересчет этого ключа. К примеру, в приложении существует справочник Клиенты. Каждый из пользователей приложения относится к одному из клиентов. Клиенты могут иметь статус. Если некоторый ключ доступа выдается пользователям в зависимости от принадлежности к клиенту и от статуса этого клиента, то при изменении статуса клиента необходимо выполнить пересчет этого ключа доступа.
      метод УстановитьСтатусКлиента(Клиент: Клиенты.Ссылка, Статус: СтатусыКлиентов)
          //  (...)
           
          исп КонтекстДоступа.Привилегированный()
          КлючДоступаКлиента.ПересчитатьКлючи()
      ;
Пересчет экземпляров ключей можно вызвать:
  • Для некоторых или для всех пользователей:
    Пользователи.ПересчитатьКлючиДоступа()
  • Для экземпляров определенного ключа, например для всех экземпляров ключа КлючиГруппСотрудников:
    КлючиГруппСотрудников.ПересчитатьКлючи()
  • Для конкретного экземпляра ключа (пересчитать экземпляр ключа для некоторых или для всех пользователей):
    пер КлючМенеджеров = новый КлючиГруппСотрудников.Объект(ГруппыСотрудников.Менеджеры)
    КлючМенеджеров.Пересчитать()
  • Для всех ключей доступа:
    для КлючДоступа из КлючиДоступа
        КлючДоступа.ПересчитатьКлючи()
    ;