Использование ограничений доступа к данным для различных объектов 1С:Предприятия 8
Этот раздел содержит информацию об особенностях использования ограничений доступа к данным, определяемых поведением различных объектов 1С:Предприятия.
О принципах функционирования ограничений доступа к данным
Основные принципы функционирования и использования ограничений доступа к данным описаны в документации 1С:Предприятия 8 и в разделе «Ограничения доступа к данным. Сведения о принципах функционирования».
Для лучшего понимания механизма проверки ограничений доступа полезно иметь в виду следующие правила:
- Каждое ограничение доступа к данным представляет собой запрос, записанный на языке запросов (с некоторыми упрощениями).
- Проверка ограничений доступа к данным выполняется для каждой записи каждой таблицы базы данных, обращение к которым происходит при выполнении запроса или в процессе манипулирования любыми объектами 1С:Предприятия.
- Для конкретной записи конкретной таблицы базы данных проверка ограничения заключается в исполнении запроса, представляющего это ограничение. Если в результате исполнения этого запроса получается непустая выборка, то считается, что доступ к записи разрешен. Если же выборка пустая, то доступ к записи запрещен.
- Если обращение к данной записи требует проверки нескольких ограничений (из разных полей и/или из разных ролей текущего пользователя), то проверяется каждое из ограничений. Результаты проверки ограничений, наложенных на доступ к разным полям, объединяются логической операцией «И». Результаты проверки ограничений, относящихся к разным ролям текущего пользователя, объединяются логической операцией «ИЛИ». Если результат полученного логического выражения равен «Истина», то доступ к записи разрешен. Иначе — доступ запрещен.
- Обращение по ссылке в ограничении имеет тот же смысл, что и обращение по ссылке в запросе, а именно, если ссылка указывает на несуществующую запись или имеет значение NULL, то значением поля по ссылке будет NULL.
- Если в ограничении доступа к данным операция сравнения использует поле табличной части, то результат сравнения равен «Истина», если табличная часть содержит хотя бы одну запись, для которой результат этого сравнения — «Истина». При использовании в одном сравнении двух полей разных табличных частей значения сравнения будет «Истина», если в декартовом произведении этих табличных частей найдется запись, для которой сравнение имеет значение «Истина».
Приведем несколько примеров.
Например, в случае простейшего ограничения вида:
ГДЕ Реквизит = &ПравильноеЗначениеРеквизита
можно считать, что для каждой записи, для которой проверяется ограничение(проверяемой записи), выполняется запрос следующего вида:
ВЫБРАТЬ 1
ИЗ ТаблицаИзОднойПроверяемойЗаписи
ГДЕ Реквизит = &ПравильноеЗначениеРеквизита
В данной таблице доступ к записи, в которой значение реквизита «Реквизит» совпадает со значением параметра сеанса «ПравильноеЗначениеРеквизита», разрешен. К другим записям этой таблицы доступ запрещен.
Другой пример. Усложним ограничение. Допустим нужно разрешить доступ к записи таблицы «Справочник.Контрагенты» не только если ее «Реквизит» имеет «правильное значение», но и в том случае, если «правильное значение» имеет «Реквизит» родителя этой записи (1-го или 2-го уровня). В этом случае ограничение может иметь следующий вид:
Контрагенты
ИЗ Справочник.Контрагенты КАК Контрагенты
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагенты1
ПО Контрагенты.Родитель = Контрагенты1.Ссылка
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагенты2
ПО Контрагенты1.Родитель = Контрагенты2.Ссылка
ГДЕ Контрагенты.Реквизит = &ПравильноеЗначениеРеквизита ИЛИ Контрагенты1.Реквизит = &ПравильноеЗначениеРеквизита ИЛИ Контрагенты2.Реквизит = &ПравильноеЗначениеРеквизита
Тогда запрос, который будет выполнятся в процессе проверки этого ограничения для конкретной записи справочника «Контрагенты», будет иметь вид:
ВЫБРАТЬ 1
ИЗ ТаблицаИзОднойПроверяемойЗаписи КАК Контрагенты
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагенты1
ПО Контрагенты.Родитель = Контрагенты1.Ссылка
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагенты2
ПО Контрагенты1.Родитель = Контрагенты2.Ссылка
ГДЕ Контрагенты.Реквизит = &ПравильноеЗначениеРеквизита ИЛИ Контрагенты1.Реквизит = &ПравильноеЗначениеРеквизита ИЛИ Контрагенты2.Реквизит = &ПравильноеЗначениеРеквизита
Обращения по ссылкам в запросах и ограничения доступа к данным
При установке ограничений доступа к данным важно понимать, что ограничение проверяется при обращении к записи той таблицы базы данных, к которой относится ограничение. При этом если выполняется запрос к данным с ключевым словом РАЗРЕШЕННЫЕ , то запрет доступа к некоторой записи означает, что при выполнении этого запроса будет считаться, что эта запись таблицы базы данных (не результата запроса) отсутствует.
Пусть на справочник «Контрагенты» установлено следующее ограничение доступа:
ГДЕ Ответственный = &ТекущийПользователь
а сам справочник содержит такие записи:
Ответственный
(ссылка на Справочник.Пользователи)
Пусть регистр сведений «КонтактнаяИнформация» содержит следующие записи:
КонтактноеЛицо
(ссылка на Справочник.ФизЛица)
Организация
(ссылка на Справочник.Контрагенты)
Тогда если текущим пользователем является пользователь «Иванов», то результатом запроса:
ВЫБРАТЬ РАЗРЕШЕННЫЕ Имя, Ответственный
ИЗ Справочник.Контрагенты
Ответственный
(ссылка на Справочник.Пользователи)
Однако, результатом следующего запроса:
ВЫБРАТЬ РАЗРЕШЕННЫЕ КонтактноеЛицо, Организация
ИЗ РегистрСведений.КонтактнаяИнформация
Ответственный
(ссылка на Справочник.Пользователи)
противоречат ограничению, и поэтому считаются отсутствующими, а представление непустой ссылки на несуществующую запись равно » . «. В то же время, результатом запроса:
ВЫБРАТЬ РАЗРЕШЕННЫЕ КонтактноеЛицо, Организация.Имя КАК Имя, Организация.Ответственный КАК Ответственный
ИЗ РегистрСведений.КонтактнаяИнформация
поскольку противоречащие ограничению записи справочника «Контрагенты» считаются отсутствующими, а значениями полей «Имя» и «Ответственный» по ссылкам, указывающим на несуществующие записи, является значение NULL.
Если же необходимо по тому же признаку ограничить доступ к записям регистра сведений «КонтактнаяИнформация», то на этот регистр можно наложить ограничение вида:
ГДЕ Организация.Ответственный = &ТекущийПользователь
В этом случае результатом выполнения последнего запроса будет таблица:
Ограничения и табличные части
Ограничения доступа к данным действуют только на записи таблиц верхнего уровня и не могут ограничивать доступность записей табличных частей. С другой стороны, в тексте ограничения поля табличных частей использоваться могут. В этом случае в процессе проверки ограничения для некоторой записи будет исполнен запрос, в котором табличная часть будет соединена с таблицей из одной проверяемой записи левым внешнем соединением. Таким образом запись будет удовлетворять ограничению, если в ее табличной части найдется хотя бы одна запись, для которой условие в ограничении принимает значение «Истина».
Из соображений эффективности в ограничениях доступа к данным нельзя использовать агрегатные функции. Поэтому возможности участия в ограничениях доступа к данным каких-нибудь условий на совокупности записей табличных частей не предусмотрено. Подобная цель может быть достигнута посредством запросов, вложенных в ограничения, однако пользоваться этим необходимо с осторожностью из-за возможного снижения производительности.
Например, если документ «Накладная» содержит табличную часть «Состав», то ограничения доступа к этому документу проверяются при обращении к каждой накладной, как к единому целому и не могут разрешить доступ к какой-нибудь одной записи его табличной части «Состав», а к какой-нибудь другой запретить.
Пусть таблица «Документ.Накладная» содержит следующие записи:
Контрагент
(ссылка на Справочник.Контрагенты)
В этом случае запрос, исполняемый для каждой накладной в процессе проверки следующего ограничения:
ВЫБРАТЬ 1
ИЗ ТаблицаИзОднойПроверяемойЗаписи КАК Накладная
ЛЕВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ Документ.Накладная.Состав КАК Состав
ПО Накладная.Ссылка = Состав.Ссылка
ГДЕ Состав.Количество > 50
Следовательно доступ будет разрешен только для записи «Трикотажная фабрика». Поэтому запрос:
ВЫБРАТЬ РАЗРЕШЕННЫЕ Контрагент, Состав.(Номенклатура, Количество)
ИЗ Документ.Накладная
а запрос к вложенной таблице:
ВЫБРАТЬ РАЗРЕШЕННЫЕ Контрагент, Номенклатура, Количество
ИЗ Документ.Накладная.Состав
поскольку ограничение накладывается только на записи верхнего уровня, но не на записи табличных частей.
Если нужно разрешить доступ еще и к тем накладным, у которых состав пустой, то ограничение может быть модифицировано так:
ГДЕ Состав.Количество > 50 ИЛИ Состав.Количество ЕСТЬ NULL
Если же необходимо разрешить доступ только к тем накладным, у которых в табличной части «Состав» нет записей с «Количеством», превышающем 50, то в ограничении необходимо использовать вложенный запрос:
Накладная1
ИЗ Документ.Накладная КАК Накладная1
ГДЕ Накладная1.Ссылка В
(
ВЫБРАТЬ Состав1.Ссылка
ИЗ Документ.Накладная.Состав КАК Состав1
СГРУППИРОВАТЬ ПО Состав1.Ссылка
ИМЕЮЩИЕ МАКСИМУМ(Состав1.Количество) СправочникиМенеджер , СправочникМенеджер. , СправочникСсылка. , СправочникОбъект. , и другие.
Все операции над объектами встроенного языка 1С:Предприятия выполняются в режиме «ВСЕ» (без использования режима «РАЗРЕШЕННЫЕ»). Для успешного получения разрешенных объектов в соответствующих методах объектов необходимо указывать отборы, не противоречащие ограничениям. Например, если на чтение из регистра сведений «КонтактнаяИнформация» установлено ограничение вида:
ГДЕ Тип = &ТипКонтактнойИнформации»
то для успешного выполнения метода
необходимо установить отбор:
Если ограничение доступа сложное и не может быть сформулировано в терминах отборов, то использование выборки (метод Выбрать() ) и аналогичных оказывается невозможным. В этом случае следует использовать запросы. Проектирование разграничения доступа к данным таким образом, чтобы ограничения могли быть сформулированы в терминах отборов, позволит использовать объекты встроенного языка с максимальной гибкостью.
Виртуальные таблицы запросов
При использовании в запросах без ключевого слова РАЗРЕШЕННЫЕ виртуальных таблиц в условиях установленных ограничений доступа к данным необходимо указывать отборы, не противоречащие ограничениям не только для запроса в целом, но и для виртуальных таблиц. Например:
ВЫБРАТЬ
КонтактнаяИнформацияСрезПервых.Представление
ИЗ
РегистрСведений.КонтактнаяИнформация.СрезПоследних(, Тип = &Тип ) КАК КонтактнаяИнформацияСрезПервых
ГДЕ
КонтактнаяИнформацияСрезПервых.Тип = &Тип
Выделенный отбор по виртуальной таблице «СрезПоследних» может содержать произвольное логическое выражение, допустимое для раздела ГДЕ, использующее поля, которые присутствуют в виртуальной таблице.
источник