helpf.pro
Регистрация

v8: Разграничение прав доступа пользователя по организации

Ermak
12.02.2013 13:05Прочитано: 7070
Хочу разобраться как написать самому разграничение прав доступа пользователя по организации в документах, справочниках. Может у кого есть пример своей разработки, поделились бы.
Yandex
Возможно, вас также заинтересует
Реклама на портале
IKSparrow
12.02.2013 14:11Ответ № 1
Речь идёт про самописную конфигурацию или типовую?
E_Migachev
12.02.2013 14:15Ответ № 2
(0) Ermak, а чем не устраивает обычный способ настройки прав + rls?
или все же хочется программно это реализовать?
DJ_Serega
12.02.2013 14:45Ответ № 3
(2) E_Migachev, +rls это нужно учесть мощность сервера (на файловой не тестировал) и количество пользователей *09
Ermak
13.02.2013 09:44Ответ № 4
(1) IKSparrow, Самописная конфига
(2) E_Migachev, хотелось бы программно реализовать
E_Migachev
13.02.2013 10:02Ответ № 5
(4) Ermak, тогда смотри как в УТ устроен механизм дополнительных прав и делай аналогично
Ermak
13.02.2013 12:31Ответ № 6
хорошо, я просто думал может кто сам делал, посмотреть хотел пример
Ermak
26.03.2013 12:49Ответ № 7
В УТ можно у пользователя добавить к какой он будет относить организации, покажите как можно программно использовать это? Например: Пользователи относящиеся к организации "Рога" запрещается видеть "Реквизит"
E_Migachev
26.03.2013 13:05Ответ № 8
(7) Ermak, Посмотри как в УТ реализовано ДопПрава:

1. в Планы видов характеристик
title

2. Регистр сведений для хранения настроек
title


в коде проверяешь
Код 1C v 8.х
 	Если НЕ УправлениеДопПравамиПользователей.ЕстьДопПраво("ИспользоватьБПДокументооборота") Тогда
Предупреждение("У Вас НЕТ прав на ведение БП Документооборот! Обратитесь к Администратору!");
Возврат;
КонецЕсли;


Функции проверки
Код 1C v 8.х
 // Функция возвращает признак произвольного дополнительного права.
//
// Параметры:
// ИмяДопПрава - имя доп. права, как оно задано в предопределенных
//
// Возвращаемое значение:
// Истина - если можно менять цены, иначе Ложь.
//
Функция ЕстьДопПраво(ИмяДопПрава) Экспорт

СписокФильтров = УправлениеПользователями.ПолучитьЗначениеПраваДляТекущегоПользователя(ПланыВидовХарактеристик.ПраваПользователей[ИмяДопПрава], Ложь);

Если СписокФильтров.Количество() = 0 Тогда
Возврат Ложь;
ИначеЕсли СписокФильтров.Количество() > 1 Тогда
Возврат Истина;
Иначе
Возврат СписокФильтров[0].Значение;
КонецЕсли;

КонецФункции // ЕстьДопПраво()



// Функция возвращает список значений права, установленных для пользователя.
// Если количество значений меньше количество доступных ролей, то возвращается значение по умолчанию
//
// Параметры:
// Право - право, для которого определяются значения
// ЗначениеПоУмолчанию - значение по умолчанию для передаваемого права (возвращается в случае
// отсутствия значений в регистре сведений)
//
// Возвращаемое значение:
// Список всех значений, установленных наборам прав (ролям), доступных пользователю
//
Функция ПолучитьЗначениеПраваДляТекущегоПользователя(Право, ЗначениеПоУмолчанию = Неопределено) Экспорт

КэшДополнительныхПрав = глЗначениеПеременной("ЗначенияДополнительныхПравПользователя");
ЗначениеПрава = КэшДополнительныхПрав[Право];
Если ЗначениеПрава = Неопределено Тогда
ЗначениеПрава = ПрочитатьЗначениеПраваДляТекущегоПользователя(Право, ЗначениеПоУмолчанию);
КэшДополнительныхПрав[Право] = ЗначениеПрава;
#Если Сервер Тогда
глЗначениеПеременнойУстановить("ЗначенияДополнительныхПравПользователя", КэшДополнительныхПрав, Истина);
#КонецЕсли
КонецЕсли;
Возврат ЗначениеПрава;

КонецФункции // ПолучитьЗначениеПраваДляТекущегоПользователя()

Функция ПрочитатьЗначениеПраваДляТекущегоПользователя(Право, ЗначениеПоУмолчанию)

ВозвращаемыеЗначения = Новый СписокЗначений;

Запрос = Новый Запрос;

Запрос.УстановитьПараметр("Пользователь" , ПараметрыСеанса.ТекущийПользователь);
Запрос.УстановитьПараметр("ПравоПользователя", Право);

Запрос.Текст = "ВЫБРАТЬ РАЗРЕШЕННЫЕ РАЗЛИЧНЫЕ
| РегистрЗначениеПрав.Значение
|ИЗ
| РегистрСведений.ЗначенияДополнительныхПравПользователя КАК РегистрЗначениеПрав
|ГДЕ
| РегистрЗначениеПрав.Право = &ПравоПользователя
| И РегистрЗначениеПрав.Пользователь В
| (ВЫБРАТЬ
| ПользователиГруппы.Ссылка КАК Ссылка
| ИЗ
| Справочник.ГруппыПользователей.ПользователиГруппы КАК ПользователиГруппы
| ГДЕ
| ПользователиГруппы.Пользователь = &Пользователь
|
| ОБЪЕДИНИТЬ ВСЕ
|
| ВЫБРАТЬ
| ЗНАЧЕНИЕ(Справочник.ГруппыПользователей.ВсеПользователи)
|
| ОБЪЕДИНИТЬ ВСЕ
|
| ВЫБРАТЬ
| &Пользователь)";

Выборка = Запрос.Выполнить().Выбрать();

Если Выборка.Количество() = 0 Тогда
ВозвращаемыеЗначения.Добавить(ЗначениеПоУмолчанию);
Иначе
Пока Выборка.Следующий() Цикл
ВозвращаемыеЗначения.Добавить(Выборка.Значение);
КонецЦикла;
КонецЕсли;

Возврат ВозвращаемыеЗначения;

КонецФункции // ПолучитьЗначениеПраваДляТекущегоПользователя()
Ermak
26.03.2013 13:17Ответ № 9
Мне не реализовать надо, а условие сделать в документе. Например: Если пользователи относятся к организации "Рога" Тогда имеют доступ к реквизиту "Копыта"
E_Migachev
26.03.2013 13:52Ответ № 10
(9) Ermak, а как у тебя связаны пользователи и организация?
Ermak
26.03.2013 14:12Ответ № 11
У каждого пользователя в дополнительный настройках в разделе Основные значения ... - Прочие значения - Основная организация стоит "Рога". Вот я и хотел бы узнать как программно обратиться к этому
DJ_Serega
26.03.2013 20:58Ответ № 12
(11) Ermak, Значения данных настроек хранятся в регистре сведений НастройкиПользователей.
Ermak
27.03.2013 09:18Ответ № 13
А как программно условие прописать?
DJ_Serega
27.03.2013 10:22Ответ № 14
(13) Ermak, Запросиком *17
Вот недавно нужно было вытащить значения свойств номенклатуры. А смысл такой же. Единственное что параметры будут другими )
https://help1c.com/faq/view/1369.html
Ermak
27.03.2013 18:36Ответ № 15
Вот как я начал

Код 1C v 8.х
 ЗапросДоступа = Новый Запрос (
"ВЫБРАТЬ
| НастройкиПользователей.Пользователь.Наименование КАК Фио,
| НастройкиПользователей.Настройка.Наименование КАК Имя,
| НастройкиПользователей.Настройка.ТипЗначения КАК Знач
|ИЗ
| РегистрСведений.НастройкиПользователей КАК НастройкиПользователей");

Результат = Запрос.Выполнить().Выбрать();


Как потом условие сделать если текущий пользователь принадлежит организации "Рога" тогда ....
DJ_Serega
27.03.2013 21:08Ответ № 16
Код 1C v 8.х
 
|ГДЕ
| Пользователь = &Пользователь
| И Настройка = Значение(ПланыВидовХарактеристики.НастройкиПользователей.ОсновнаяОрганизация)

Где-то так.
Таким образом вы получите основную организацию.
Если есть "под рукой" типовая конфигурация, посмотрите как работает код:
Код 1C v 8.х
 УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(глЗначениеПеременной("глТекущийПользователь"), "ОсновнаяОрганизация");   

Изменено 27.03.13 21:09:20
Ermak
27.03.2013 21:39Ответ № 17
Вот код

Код 1C v 8.х
 Функция ПолучитьЗначениеПоУмолчанию(Пользователь, Настройка) Экспорт

Если Пользователь = глЗначениеПеременной("глТекущийПользователь") Тогда
НастройкаСсылка = ПланыВидовХарактеристик.НастройкиПользователей[Настройка];
КэшНастроекПользователей = глЗначениеПеременной("ЗначенияНастроекПользователей");
ЗначениеНастройки = КэшНастроекПользователей[НастройкаСсылка];
Если ЗначениеНастройки = Неопределено Тогда
ЗначениеНастройки = ПолучитьЗначениеПоУмолчаниюПользователя(Пользователь, Настройка);
КэшНастроекПользователей[НастройкаСсылка] = ЗначениеНастройки;
#Если Сервер Тогда
глЗначениеПеременнойУстановить("ЗначенияНастроекПользователей", КэшНастроекПользователей, Истина);
#КонецЕсли
КонецЕсли;
Возврат ЗначениеНастройки;
КонецЕсли;

Возврат ПолучитьЗначениеПоУмолчаниюПользователя(Пользователь, Настройка);

КонецФункции


И Тогда так получается?

Код 1C v 8.х
 
ЗапросДоступа = Новый Запрос (
"ВЫБРАТЬ
| НастройкиПользователей.Пользователь.Наименование КАК Фио,
| НастройкиПользователей.Настройка.Наименование КАК Имя,
| НастройкиПользователей.Настройка.ТипЗначения КАК Знач
|ИЗ
| РегистрСведений.НастройкиПользователей КАК НастройкиПользователей
|ГДЕ
| Пользователь = &Пользователь
| И Настройка = Значение(ПланыВидовХарактеристики.НастройкиПользователей.ОсновнаяОрганизация)");

Результат = Запрос.Выполнить().Выбрать();

Если УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(глЗначениеПеременной("глТекущийПользователь"), "Рога") Тогда
.....
КонецЕсли;
DJ_Serega
27.03.2013 22:19Ответ № 18
В функцию нужно передать
- Пользователь. Если не ошибаюсь Справочник.Пользователи.
- Настройка. Имя предопределенного элемента ПланаВидовХарактеристики.

Вот в этой функции строится запрос, который ищет нужное значение:
Код 1C v 8.х
 ЗначениеНастройки = ПолучитьЗначениеПоУмолчаниюПользователя(Пользователь, Настройка);   


Это есть типовая функция. Для того что бы узнать какая основная организация у конкретного пользователя, достаточно написать так:
Код 1C v 8.х
 ОсновнаяОрганизацияТекущегоПользователя = УправлениеПользователями.ПолучитьЗначениеПоУмолчанию(глЗначениеПеременной("глТекущийПользователь"), "ОсновнаяОрганизация");   


Если вы хотите понять как оно ищется (или написать самому), тогда советую посмотреть на текст итогового запроса в "ПолучитьЗначениеПоУмолчаниюПользователя()".
Текст не сильно будет отличаться от (15) Ermak (если добавить параметры запроса).
Ermak
27.03.2013 22:32Ответ № 19
я посмотрел

Код 1C v 8.х
 Функция ПолучитьЗначениеПоУмолчаниюПользователя(Пользователь, Настройка, СписокПолей = Неопределено)

НастройкаТипЗнч = ПланыВидовХарактеристик.НастройкиПользователей[Настройка].ТипЗначения;
НастройкаТипЗнчСправочник = Справочники.ТипВсеСсылки().СодержитТип(НастройкаТипЗнч.Типы()[0]);
Если НастройкаТипЗнчСправочник Тогда
МетаданныеТипаНастройки = Метаданные.НайтиПоТипу(НастройкаТипЗнч.Типы()[0]);
КонецЕсли;

Запрос = Новый Запрос;
Запрос.УстановитьПараметр("Пользователь", Пользователь);
Запрос.УстановитьПараметр("Настройка" , ПланыВидовХарактеристик.НастройкиПользователей[Настройка]);


Запрос.Текст = "
|ВЫБРАТЬ РАЗРЕШЕННЫЕ
| Значение КАК Значение";

Если СписокПолей <> Неопределено И НастройкаТипЗнчСправочник Тогда

СправочникИмя = МетаданныеТипаНастройки.Имя;

Для каждого Элемент из СписокПолей цикл

ИмяРеквизита = Элемент.Значение;
Представление = Элемент.Представление;
Если ПустаяСтрока(Представление) Тогда
Представление = ИмяРеквизита;
КонецЕсли;

Запрос.Текст = Запрос.Текст + ",
|ВЫРАЗИТЬ(Значение КАК Справочник." + СправочникИмя + ")." + ИмяРеквизита + " КАК " + Представление;

КонецЦикла;

КонецЕсли;

Запрос.Текст = Запрос.Текст + "
|ИЗ
| РегистрСведений.НастройкиПользователей КАК РегистрЗначениеПрав
|
|ГДЕ
| Пользователь = &Пользователь
| И Настройка = &Настройка
|";


Выборка = Запрос.Выполнить().Выбрать();

Если СписокПолей = Неопределено Тогда
ПустоеЗначение = НастройкаТипЗнч.ПривестиЗначение();
Иначе
ПустоеЗначение = новый Структура("Значение", НастройкаТипЗнч.ПривестиЗначение());
Для каждого ЭлементСписка из СписокПолей цикл
ПустоеЗначение.Вставить(?(ПустаяСтрока(ЭлементСписка.Представление), ЭлементСписка.Значение, ЭлементСписка.Представление));
КонецЦикла;
КонецЕсли;

Если Выборка.Следующий() Тогда

Если НЕ ЗначениеЗаполнено(Выборка.Значение) Тогда
Возврат ПустоеЗначение;
КонецЕсли;

Если НастройкаТипЗнчСправочник И ПараметрыДоступа("Чтение", МетаданныеТипаНастройки, "Ссылка").ОграничениеУсловием Тогда
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ РАЗРЕШЕННЫЕ 1 ИЗ Справочник." + МетаданныеТипаНастройки.Имя + " ГДЕ Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", Выборка.Значение);
РезультатЗапроса = Запрос.Выполнить();
Если РезультатЗапроса.Пустой() Тогда
Возврат ПустоеЗначение;
КонецЕсли;
КонецЕсли;

Если СписокПолей = Неопределено Тогда
Возврат Выборка.Значение;
Иначе
ЗаполнитьЗначенияСвойств(ПустоеЗначение, Выборка);
Возврат ПустоеЗначение;
КонецЕсли;

Иначе
Возврат ПустоеЗначение;
КонецЕсли;


КонецФункции


Но для меня это темный лес, трудно понять что тут. можете подсказать
DJ_Serega
28.03.2013 02:08Ответ № 20
так вот тут вы и получаете организацию, которая установленая в настройках пользователя:
Код 1C v 8.х
 ЗапросДоступа = Новый Запрос (
"ВЫБРАТЬ
| НастройкиПользователей.Пользователь.Наименование КАК Фио,
| НастройкиПользователей.Настройка.Наименование КАК Имя,
| НастройкиПользователей.Настройка.ТипЗначения КАК Знач
|ИЗ
| РегистрСведений.НастройкиПользователей КАК НастройкиПользователей
|ГДЕ
| Пользователь = &Пользователь
| И Настройка = Значение(ПланыВидовХарактеристики.НастройкиПользователей.ОсновнаяОрганизация)")[b]


А текст запроса (уже готовый) тут:
Код 1C v 8.х
 Выборка = Запрос.Выполнить().Выбрать();   

Завтра (тоестьсегодня) напишу текст.
Ermak
28.03.2013 08:29Ответ № 21
Спасибо буду ждать )
DJ_Serega
28.03.2013 12:34Ответ № 22
(21) Ermak, А что именно вам написать? *17
Ermak
28.03.2013 12:59Ответ № 23
Если текущий пользователь относится к организации Рога тогда ...
Ermak
01.04.2013 19:37Ответ № 24
*03
DJ_Serega
01.04.2013 19:44Ответ № 25
(24) Ermak, та дома не нашел пока времени ) а на работе только простенькое могу подсказать *03
Ermak
01.04.2013 22:30Ответ № 26
обидно *11
DJ_Serega
02.04.2013 10:57Ответ № 27
(26) Ermak, а где остановка произошла? на чем стопор получился?
Ermak
18.04.2013 12:54Ответ № 28
Сделал такой запрос

Код 1C v 8.х
 ЗапросДоступа = Новый Запрос (
"ВЫБРАТЬ
| НастройкиПользователей.Пользователь.Наименование КАК ФИО,
| НастройкиПользователей.Настройка.ТипЗначения КАК Знач
|ИЗ
| РегистрСведений.НастройкиПользователей КАК НастройкиПользователей
|ГДЕ
| НастройкиПользователей.Пользователь = &Ответственный
| И НастройкиПользователей.Настройка = Значение(ПланыВидовХарактеристики.НастройкиПользователей.ОсновнаяОрганизация)");
Выборка = Запрос.Выполнить().Выбрать();

Не могу понять как написать дальше условие если пользователь Пупкин имеет основную организация "Рога" тогда ...
Изменено 18.04.13 13:03:20
Ermak
19.04.2013 12:59Ответ № 29
Сделал не много по другому. Всем спасибо! )
Ermak
19.04.2013 12:59Ответ № 30
Вопрос закрыт!
Ermak
23.04.2013 16:04Ответ № 31
как прописать, если текущий пользователь принадлежит организации "Рога" тогда ...
Ermak
24.04.2013 11:52Ответ № 32
?
Подсказка: Для редактирования своего ответа щелкните по значку (справа)
Вы не можете отправить комментарий анонимно, пожалуйста войдите или зарегистрируйтесь.