Управление правами в 7.7 — "на лету" до каждой кнопочки!



Система управления правами доступа "на лету" для конфигураций на платформе 1С:Предприятие 7.7.
— Онлайн :: Не требует выхода пользователей.
— Умная :: Позволяет управлять доступом хоть к каждой кнопке на форме.
— Универсальная :: Встраивается в любую конфигурацию за 1 минуту!
— Преемственная :: Сохраняет настройки существующих наборов прав.

Происхождение Системы

В начале далекого уже сегодня 2007 года у меня возник проект, в котором стояла задача разработки системы контроля прав для конфигурации на платформе 1С:Предприятие 7.7. Стоял выбор — полностью перерабатывать конфигурацию заказчика или сделать что-то универсальное.

«Универсальное решение для любой конфигурации 7.7 ? Без подписок на события и т.п.? Не смешите меня — такое невозможно сделать!» — именно эти слова коллеги пробудили во мне спортивный интерес и практически «на спор» была разработана Система управления правами для 1С:Предприятие 7.7

Система построена на базе небезызвестного компонента 1С++, который в то время как раз «обзавелся» функциями перехвата событий. И по сегодняшний день в платформе 1С:Предприятие 8 нет подписок на события формы — а в 1С++ они работали уже тогда!

История разработки

Как и положено универсальному инструменту главным условием при разработке системы стало не трогать саму конфигурацию, в которой предполагалось управлять правами. Нужно было обойтись минимальными изменениями, скажем, одной строкой кода в глобальном модуле. И это получилось!

Конечно же, разработка не была простой. Потребовалось «разобрать на запчасти» все возможные события платформы, побороться с особенностями не только модальных, но и весьма специфических (как оказалось) окон. Таких как, например, выбор периода для журнала…

Желающим ознакомиться с ходом разработки можно заглянуть в файл whatsnew.txt — там описано много нетривиальных проблем, которые пришлось решать прямо по ходу проекта. Был задействован целый ряд инструментов — и DynamicWrapper для вызова WinAPI процедур, и компонента UsersDef.dll для управления пользователями прямо из пользовательского режима.

Возможности Системы

Достоинства этой Системы управления правами по сравнению с типовым механизмом такие.

  • Любое изменение прав применяется сразу же. Пользователь не только не обязан теперь выходить из программы, а даже может не закрывать форму, к кнопке которой у него забрали доступ! При нажатии на кнопку произойдет проверка прав и кнопка заблокируется еще до выполнения действия.
  • Пользователей можно объединять в группы. Один пользователь может принадлежать сразу нескольким группам (в типовой платформе пользователю можно дать только один набор прав). Права устанавливаются как на группы, так и на отдельных пользователей. Запрет на пользователя имеет больший приоритет, чем разрешение на группу. С точки зрения конфигуратора группа — это обычный пользователь, в имени которого идет 2 знака подчеркивания впереди, например «__Бухгалтерия». Вход в программу под такими пользователями программно блокируется.
  • Права доступа настраиваются не только для объектов метаданных, но и для форм и их элементов! Обязательное условие для управления доступом к элементам — наличие у элемента формы идентификатора — неименованные элементы Системой не обрабатываются.
  • Управлять пользователями можно полностью из-под пользовательского режима, не заходя в Конфигуратор.

Помимо «фич» есть и просто полезные инструменты, облегчающие труд по работе с правами.

  • Возможно сохранить права доступа, настроенные через наборы прав. Правда, для этого придется зайти в ИБ от имени каждого пользователя, для которого нужно сохранить права. При этом наборы прав станут группами пользователей, а права из наборов загрузятся в Систему управления
  • Есть даже режим отладки, когда каждая проверка прав записывается в файл лога и/или выводится в окно сообщений.

Порядок установки и запуска

Чтобы попробовать Систему самому, достаточно выполнить лишь несколько несложных действий. Работу можно производить на любой конфигурации. Перед тем, как выкладывать эту Систему сюда я проверял ее на первой попавшейся конфигурации — типовом «Бухучете для Украины» (релиз 281). На всякий случай уточню, что все действия по настройке производятся в Windows от имени администратора — я не проверял, как поведет себя Система при работе с ограниченными правами.

Итак по порядку.

Шаг 1. Подготовка файлов

Берем любую конфигурацию для платформы 7.7. Скачанный архив разворачиваем в папку ИБ с сохранением иерархии архива.

Шаг 2. Регистрация компонентов

Файл dynwrap.dll из каталога ИБ переносим в папку WindowsSystem32 и регистрируем в системе командой

regsvr32.exe dynwrap.dll

Шаг 3. Доработка конфигурации

Доработка конфигурации выполняется за 1 минуту. Если у вас в конфигурации уже используется FormEx и 1C++, тогда действительно понадобится добавить всего одну строку в глобальный модуль. Если нет, то полный текст «вставки» будет выглядеть так:

// {секция объявления переменных} ...
Перем Сервис Экспорт;
 
Процедура ПриНачалеРаботыСистемы()
 
// ... {здесь ваш уже существующий текст, если есть} ...  
 
// (1) эти строки, если в конфигурации ранее не использовался FormEx и 1C++
    ЗагрузитьВнешнююКомпоненту("FormEx.dll");
    Сервис = СоздатьОбъект("Сервис");
    ЗагрузитьВнешнююКомпоненту("1CPP.dll");
// конец (1)
 
// (2) вызов Системы управления правами
    ОткрытьФорму(""Обработка"", ""фоновый"", КаталогИБ()+""SecurityУправлениеДоступами.ert"");
// конец (2)
 
КонецПроцедуры

Еще одна микродоработка связана с тем, что у некоторых объектов при проверке права открытия формы окно все же «мелькает» на экране. Во избежание этого был доработан механизм «подмены» формы на свою. Ему требуется, чтобы в метаданных была пустая обработка с именем «ОшибкаДоступа_Тихо» и модулем из 3-х строк:

Процедура ПриОткрытии()
СтатусВозврата(0);
КонецПроцедуры // ПриОткрытии

Благодаря подмене «проблемных» форм объектов на эту форму окна даже не мелькают (если нельзя открывать форму объекта).

Вот и все доработки. Теперь можно запускать 1С:Предприятие.

Шаг 4. Загрузка прав из существующих наборов

Вместе с предприятием сразу откроется обработка «Управление доступами». Она откроется только один раз — при первом запуске — и сформирует файл для хранения прав (файл Securitymdsec.mdb в каталоге ИБ). Если что-то пойдет не так — можно просто удалить этот файл — при следующем запуске Система создаст его снова и откроет форму обработки. Безусловно, открыть обработку можно и вручную.

В форме обработки «Управление доступами» нажмите кнопку [Импорт объектов и прав]. При этом

  • будет загружена структура метаданных вплоть до форм и именованных реквизитов на них
  • проанализированы права доступа текущего пользователя к объектам и такие же права будут загружены в Систему
  • набор прав будет превращен в группу пользователей, а текущий пользователь помещен в эту группу

С этого момента можно уже полноценно работать в системе.

Учтите, что права доступа к новым объектам по умолчанию не выдаются! Для реквизитов формы придется давать права вручную, ведь в классической платформе 7.7 не существует прав на формы и их реквизиты.

Заключение

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

Просьба не «бежать» устанавливать Систему сразу на боевой базе. Да, она уже достаточно отлажена, но падения платформы еще возможны.

Чтобы «проникнуться» результатами работы Системы сразу после установки сделайте вот что. Откройте любой документ/элемент справочника, найдите там какое-то поле ввода или кнопку (только обязательно с установленным идентификатором!). В обработке управления правами доступа попробуйте установить право и, не закрывая «подопытную» форму, нажать на объект для которого изменили права. Работает? Таки неправ был коллега — бывает и такое! 😉

47 Comments

  1. Il

    действительно гигантская работа была проведена. пораньше бы такой механизм… но + однозначно!

    Reply
  2. gavlexx

    Еще один момент добавлю.

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

    Reply
  3. Ёпрст

    1cpp должен быть всегда загружен первым.

    Reply
  4. Ёпрст

    На скриншотах не видно, где управление доступом к реквизитам формы.

    Reply
  5. Ёпрст

    + в поделке используется допотопный формекс и 1cpp

    + свой класс лучше подключить и создать в самой обработке, раз уж её в ПриНачалеРаботы запускаешь (у многих уже давно есть свои классы, в том числе, основанные на перехватчике)

    И твоя ра

    Reply
  6. Ёпрст

    Ну и.. не работает на типовой тис — всё время

    rs=db.OpenRecordset(query);

    {Глобальный модуль(244)}: DAO.Database: Указан недопустимый объект, или объект более не задан.

    rs=db.OpenRecordset(query);

    {Глобальный модуль(244)}: DAO.Database: Указан недопустимый объект, или объект более не задан.

    rs=db.OpenRecordset(query);

    {Глобальный модуль(244)}: DAO.Database: Указан недопустимый объект, или объект более не задан.

    Reply
  7. gavlexx

    (3) Ёпрст,

    Принято, будет исправлено. Честно говоря, почему должен быть первым — не встречал.

    Reply
  8. gavlexx

    (5) Ёпрст,

    Да, выложил тот формекс и 1С++, которые использовал во время своей разработки. Не было времени проверять, как работает с текущими. Если не работает — дайте знать, буду исправлять.

    Reply
  9. gavlexx

    (5) Ёпрст,

    > И твоя работа.. не взлетит.

    Не понял связи между «не взлетит» и предыдущими утверждениями

    Reply
  10. gavlexx

    (6) Ёпрст,

    Очень странно. Объект доступа к базе был создан успешно, а вот запрос не выполняется… Вручную ничего в созданной базе прав (файл mdsec.mdb) не делали? Дадите на него взглянуть?

    Еще попробуйте совсем удалить файл базы прав и запустить конфигурацию.

    Можно получить файл лога, который при этом получается? Из-за исключительной ситуации, правда, туда может ничего не записаться, но все же.

    Reply
  11. Ёпрст

    Права никакие не назначаются, файл лога ниже:

    Reply
  12. Ёпрст

    >>>Не понял связи между «не взлетит» и предыдущими утверждениями

    Несколько перехватчиков и их взаимодействие придётся реализовывать в еще одном обзем классе , который будет посылать события в остальные классы-перехватчики.

    Reply
  13. Ёпрст

    + Не нашел в классе, где перехват обработкиПроведения.

    Reply
  14. Ёпрст

    + судя по коду, настройка прав на атрибуты не корректна — любая штатная «УправлениеВидимостью()» «забьёт» все потуги в ПриВыбореЗакладки()..

    Reply
  15. gavlexx

    (14) Ёпрст,

    А вы пробовали? Попробуйте. Даже несмотря на то, что в какой-то момент времени недоступный атрибут формы может оказаться доступным, при нажатии на него все равно произойдет проверка.

    Reply
  16. gavlexx

    (13) Ёпрст,

    В функции «ПриЗаписи()» для документа проверяется право ввода нового, перепроведения старого и т.п.

    Само проведение не перехватывается, перехватывается запись и при записи происходит проверка прав на проведение, если нужно.

    Reply
  17. Ёпрст

    (15) конечно не пробовал — твоя поделка же не работает, причина в (6)

    Reply
  18. Ёпрст

    (16) дык какое отношение проведение и перепроведение имеет к записи ?

    И к ПриЗаписи() ??????

    Т.е все документы, в которых есть Провести()/#Провести запросто проводятся у вас ?

    Reply
  19. Ёпрст

    я к чему это всё — у меня есть свой класс и свое решение для управления правами доступа, только права хранятся в справочнике, а не во внешней базе (ну мну лень было делать, взял готовое решение и переделал под себя + всё переделал на классы).

    Вот и хотел посмотреть, что еще есть нового в этом роде.

    Reply
  20. gavlexx

    (18) Ёпрст,

    Похоже, действительно «косяк», исправлю. Спасибо за обратную связь.

    (17) Ёпрст,

    Буду разбираться с этой штукой. У меня на 2-х разных компьютерах дома работает, не могу пока понять, в чем может быть проблема.

    (19) Ёпрст,

    Позвольте полюбопытствовать, что за «готовое решение»? Интересно.

    Reply
  21. Ёпрст

    на основе вот этого

    http://infostart.ru/public/20129/

    Только все переделано — настройка прав в штатном справочнике Пользователи, всё переделано на классы +

    доп «фенички», типа хранения списка элементов справочника для отборов у определенных пользователей, это чтоб им принудительно фильтр ставился во всех отчетах (сам пользователь этот фильтр нигде не видит, но он есть 🙂 )..

    и еще чего, не помню.

    На хранение настроек прав во внешней базе, например sqllite (или в табличках скуля), мне лениво было.

    Reply
  22. Fenicss

    Удобно. Жалко только то нет возможности менять пароль пользователей. Так бы очень удобно было по РИб вводить новых пользователей и закрывать старые пароли. А то приходится на каждую точку ехать и менять настройки. плюс технику безопасности можно бы сделать при входе смена пароля раз в месяц

    Reply
  23. Ёпрст

    (22) это все легко реализуется.

    Есть вк для настройки списка пользователей из предприятия.

    Reply
  24. gavlexx

    (22) Fenicss,

    > Жалко только то нет возможности менять пароль пользователей.

    Где нет? Здесь же прямо в форме вместе со всем параметрами можно поменять пароль. И компонента (файл UsersDef.dll), о которой говорит Ёпрст, с этой разработкой идет «в комплекте».

    Reply
  25. apatyukov

    При нажатии обновить массово открываются формы и остаются открытыми. Это так и должно быть?

    Reply
  26. Ёпрст

    (24) не только через UsersDef.dll можно..

    Есть и другие, в том числе, эта, к примеру:

    http://infostart.ru/public/16930/

    есть еще и admin1c.dll

    Reply
  27. gavlexx

    (25) apatyukov,

    Только что проверил, не открываются. Возможно, Вы не добавили в конфигурацию отчет «ОшибкаДоступа_Тихо», который должен заменять вызовы форм, чтобы те не открывались при инициализации?

    Reply
  28. olo_lo4

    Попробовал вашу обработку , не работает, у меня типовая ТИС

    Выставил в файле ГлобМодуль1.тхт свои метки и вот что обнаружил — почему то не срабатывает метод СтатусВозврата(0)

    Например при записи константы идет возврат 0 (нет прав на корректировку) но ничего не происходит и значение меняется…непонятно в чем тут подвох.

    еще такой вопрос — может вместо компиляции еще одного глоб.модуля имеет смысл все из этого файла засунуть в глобальный конфигурации ?

    Reply
  29. olo_lo4

    судя по ссылке http://www.1cpp.ru/forum/YaBB.pl?num=1172047061

    действительно есть такая проблема и ее как-то уже решили. но где почитать не нашел. подскажите пож

    Reply
  30. gavlexx

    (28) olo_lo4,

    > Например при записи константы идет возврат 0 (нет прав на корректировку) но ничего не происходит и значение меняется…непонятно в чем тут подвох.

    а Вы использовали ту библиотеку 1cpp.dll, что в комплекте с обработкой шла? У меня работало нормально.

    > еще такой вопрос — может вместо компиляции еще одного глоб.модуля имеет смысл все из этого файла засунуть в глобальный конфигурации ?

    Не подскажу, это у разработчиков 1cpp.dll лучше спросить, в чем будет разница. Код выносил в отдельный модуль из-за того, чтобы обойтись как можно меньшими изменениями типовой. Вы думаете проблема описанная Вами решится включением кода в основной ГМ?

    Reply
  31. gavlexx

    (29) olo_lo4,

    В ближайшее время посмотрю. На первый взгляд, там сообщение еще 2007-го года. И даже в ответе #6 есть решение. Вы это пробовали?

    Перехватчик.УстановитьСтатусВозвратаГК(КонтФормы, НовыйСтатус);

    Должно работать, судя по сообщению http://www.1cpp.ru/forum/YaBB.pl?num=1173778761/9#9

    Reply
  32. olo_lo4

    Подскажите пож с чем могут быть связаны след ошибки

    1 ОбъектПерехватчикГК = СоздатьОбъект(«ПерехватСобытий»);

    {Глобальный модуль(506)}: Неудачная попытка создания объекта (ПерехватСобытий)

    2 ИмяНастройкиВыгрузки = СписокПараметров.Получить(«ИмяНастройкиВыгрузки»);

    {Обработка.УниверсальныйОбменВформатеХМЛ.Форма.Модуль(6061)}: Значение не представляет агрегатный объект (Получить)

    3 гРежимРедактирования = Форма.Параметр.Получить(«РежимРедактирования»);

    {Обработка.СвойстваОбъектов.Форма.Модуль(607)}: Значение не представляет агрегатный объект (Получить)

    4 гИмяОткрывшейФормы = гПараметрыВызова.Получить(«ИмяВызвавшейФормы»);

    {Обработка.ПодборОбъектов.Форма.Модуль(4089)}: Значение не представляет агрегатный объект (Получить)

    Reply
  33. gavlexx

    (32) olo_lo4,

    1 — Скорее всего система не находит файл класса «Перехват событий».

    Нужно, чтобы в папке с базой находился файл «defcls.prm» с таким содержимым:

    class ПерехватСобытий = .SecurityПерехватСобытий.ert
    {}

    Точка в пути означает текущую папку (по идее, в которой лежит этот файл определения класса). И важно, чтобы файл самого класса (ert) действительно лежал по тому пути, что указан.

    Я выкладывал набор файлов, которые нужно скопировать в папку с базой. Так и сделали? Нет ли в пути в папке с базой пробелов?

    2, 3, 4 — это ошибки 1С, не касающиеся системы прав.

    Или они появляются только после внедрения системы прав в конфигурацию? В любом случае, сначала нужно решить вопрос 1!

    Reply
  34. olo_lo4

    Да, с п1 все получилось

    Подскажите пож, как можно пользователю поставить сразу все права на объект и все подчиненные подобъекты, скажем если мы ставим галочку на отчет но не поставим на все его реквизиты то все равно пользователь с отчетом работать не сможет. Это конечно жутко неудобно ставить миллион галочек.

    Reply
  35. gavlexx

    (34) olo_lo4,

    Да, пока так. Спасибо за замечание.

    Но ведь код открытый, никто не мешает доработать обработку по своему усмотрению. Или Вы не кодируете на 1С? Там нужно лишь добавить на форму кнопку «Отметить у всех подчиненных» и «Снять отметки у подчиненных» с обработчиком, который пройдет по дереву ниже текущей ветки и проставит отметки…

    Reply
  36. olo_lo4

    можете пример кода кинуть (хотя бы кусок начала) , я больше по восьмерке, с семеркой на вы..как обходить дерево в 7.7 вообще не в курсе, заранее спасибо!

    Reply
  37. Jkey

    ТиС 970 под юзером «Администратор» Нажал кнопку «Обновить» в «Доступы».

    гРежимРедактирования = Форма.Параметр.Получить(«РежимРедактирования»);

    {Обработка.СвойстваОбъектов.Форма.Модуль(608)}: Значение не представляет агрегатный объект (Получить)

    гИмяОткрывшейФормы = гПараметрыВызова.Получить(«ИмяВызвавшейФормы»);

    {Обработка.ПодборОбъектов.Форма.Модуль(4095)}: Значение не представляет агрегатный объект (Получить)

    Поиск новых занял 0.076сек.

    Поиск удаленных занял 0.092сек.

    Reply
  38. gavlexx

    (37) Jkey,

    Странно, ошибки в коде обработок, не касающиеся этого механизма управления правами. Все настройки выполнили по инструкции? Обработку, подавляющую вывод форм на экран, в конфигурацию загрузили?

    Здесь, насколько я понимаю, уже были участники, которые этот механизм под ТиС запускали…

    Reply
  39. Jkey

    (38)gavlexx, делал, как по инструкции. Дабы с 1с7 с 97года дружу.

    Reply
  40. laduk

    Вопрос, есть в этой обработке возможность вывести отчет по правам доступа в разрезе пользователей ?

    Reply
  41. gavlexx

    (40) laduk,

    Нет, такого не делал.

    Но можно «докрутить» сам файл прав, который формирует система 1С. Это ведь обычный файл Access, а он умеет на основании своих таблиц делать чудесные отчеты конструктором.

    Reply
  42. gavlexx

    (39) Jkey,

    Могу лишь предложить попробовать подключиться к Вам удаленно и посмотреть, что же происходит.

    P.S. У меня опыт 7.7 с 98-го. 0:1 в Вашу пользу 🙂

    Reply
  43. Bukaska

    За статью однозначно плюс. Жаль что не знала раньше))))

    Reply
  44. vadimlp77

    Подскажите плиз что делать на 64 битний винде ?

    regsvr32.exe dynwrap.dll

    Пишет, что не хочет на 64 …

    Reply
  45. vadimlp77

    C:WindowsSysWOW64
    egsvr32 C:WindowsSysWOW64dynwrap.dll

    вроде вот так помогло

    Reply
  46. vadimlp77

    Подскажите пожалуйста!

    Валится 1с-ка на выполнении строчки:

    СтрИнтерфейсыИБ = UserCtrl.ПолучитьИнтерфейсыБазы(КаталогИБ());

    Куда бежать, на что смотреть ?

    UsersDef.dll — 2.1.1.1

    FormEx.dll — 2.0.5.0

    1CPP.dll — 2.5.0.2

    1С 7.7 27 релиз с телепатом

    Reply
  47. gavlexx
    СтрИнтерфейсыИБ = UserCtrl.ПолучитьИнтерфейсыБазы(КаталогИБ());

    В выполнении этой строки вижу потенциальную проблему в пути к базе. Предложение стандартное — проверить путь к ИБ на пробелы, спец.символы и т.п. И убрать по возможности.

    Во-вторых, попробовать запустить под правами админа.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *