Публикация

Перераздача прав на существующие записи согласно настройки прав доступа по умолчанию

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

Здесь я опишу как я сделал функционал перераздачи прав на существующие записи в таблицах с использованием интерфеса Террасофт, отображением прогресса выполнения и логированием с учетом ошибок, поскольку не всегда удобно, да и возможно запускать чистый sql-код на сервере.

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

В разделе "Администрировние" было добавлено действие "Обновление прав на записи согласно правам по умолчанию", которое выполняет обновление прав для всех таблиц, по которым установлен признак "Администрируется по записям".
действие

Также была добавлена кнопка "Обновить права на записи таблицы согласно правам по умолчанию" на вкладке "Права доступа по умолчанию" для обновления прав у выделенной в реестре таблицы.
кнопка

Для проставления прав используется хранимая процедура usp_UpdateRecordRights (прикрепил см. файл usp_updaterecordrights.sql_.txt):

CREATE PROCEDURE usp_UpdateRecordRights
        @RightsTableCode nvarchar(100),
        @TableCode nvarchar(100),
        @Result nvarchar(1000) OUT
WITH EXECUTE AS OWNER
AS
SET NOCOUNT ON

SET @Result = 'OK';

DECLARE @DeleteQuery nvarchar(4000);
DECLARE @DeleteQueryExec nvarchar(4000);

DECLARE @InsertQuery nvarchar(max);
DECLARE @InsertQueryExec nvarchar(max);

DECLARE @ServiceTableID uniqueidentifier;

SET @DeleteQuery = 'DELETE FROM @RightsTableCode
        WHERE EXISTS (SELECT ID FROM tbl_AdminUnit AS AU WHERE AU.IsGroup = 1 AND AU.ID = @RightsTableCode.AdminUnitID)'
;
       
SET @InsertQuery = 'INSERT INTO @RightsTableCode(
    ID
    ,RecordID
    ,AdminUnitID
    ,CanRead
    ,CanWrite
    ,CanDelete
    ,CanChangeAccess)
  SELECT
    newid()
    ,I.ID
    ,D.SubjectAdminUnitID
    ,D.CanRead
    ,D.CanWrite
    ,D.CanDelete
    ,D.CanChangeAccess
  FROM (
    SELECT
      D.SubjectAdminUnitID
      ,MAX(D.CanRead) AS CanRead
      ,MAX(D.CanWrite) AS CanWrite
      ,MAX(D.CanDelete) AS CanDelete
      ,MAX(D.CanChangeAccess) AS CanChangeAccess
    FROM tbl_TableDefaultRight AS D
    LEFT OUTER JOIN tbl_AdminUnit AS AU ON AU.ID = D.SubjectAdminUnitID
    WHERE (D.TableServiceID = '
'@ServiceTableID'')
                AND (AU.IsGroup = 1)
  GROUP BY D.SubjectAdminUnitID)
        AS D, @TableCode I'
;

        --PRINT @RightsTableCode;
        --PRINT @TableCode;
       
        SET @ServiceTableID = (SELECT ID FROM tbl_Service WHERE Code = @TableCode AND ServiceTypeCode = N'Table');

        IF (@ServiceTableID IS NOT NULL)
                BEGIN
                BEGIN TRAN
                BEGIN TRY
                       
                        -- delete group rights
                        SET @DeleteQueryExec = REPLACE(@DeleteQuery, '@RightsTableCode', @RightsTableCode);
                        --PRINT @DeleteQueryExec;
                        EXECUTE sp_executesql @DeleteQueryExec;
                       
                        -- insert group rights
                        SET @InsertQueryExec = REPLACE(@InsertQuery, '@RightsTableCode', @RightsTableCode);
                        SET @InsertQueryExec = REPLACE(@InsertQueryExec, '@TableCode', @TableCode);
                        SET @InsertQueryExec = REPLACE(@InsertQueryExec, '@ServiceTableID', @ServiceTableID);
                        --PRINT @InsertQueryExec;
                        EXECUTE sp_executesql @InsertQueryExec;
                       
                COMMIT TRAN
                END TRY
                BEGIN CATCH
                        SET @Result =
                                        N'Message: ' + ISNULL(ERROR_MESSAGE(),'') +
                                        N' Number ' + CONVERT(nvarchar(100), ISNULL(ERROR_NUMBER(),'')) +
                                        N'. Severity ' + CONVERT(nvarchar(100), ISNULL(ERROR_SEVERITY(),'')) +
                                        N'. State ' + CONVERT(nvarchar(100), ISNULL(ERROR_STATE(),'')) +
                                        N'. Procedure ' + CONVERT(nvarchar(100), ISNULL(ERROR_PROCEDURE(),N'')) +
                                        N'. Line ' + CONVERT(nvarchar(10), ISNULL(ERROR_LINE(),''));
                       
                        ROLLBACK TRAN
                END CATCH
                END;

GO

Основная функия описана в скрипте scr_UserAction1 (все скрипты и саму хранимую процедуру прилагаю).
Также используется написанная мной функция CatchError для регистрации ошибок, которую я у себя расположил в скрипте scr_Utils (см. файл function_catcherror.js_.txt).

Пример вызова функции обновления записей по всем таблицам (нужно подключить скрипт scr_UserAction1):

UpdateRecordRights(Self);

используется при выполнении действия.

На нажатие кнопки выполняется следующий код (кнопку я разместил в окне wnd_TableGridArea, нужно подключить скрипт scr_UserAction1):

UpdateRecordRightsSingle(dlData.Dataset.ValAsStr('USI'), dlData.Dataset.ValAsStr('TableCaption'));

Внешний вид прогресса выполнения (видно какая по счету таблица из общего количество таблиц, ее название и количество записей в ней):
прогресс

Кусочек лога:
лог

Все файлы прикрепил (необходимые сервисы в архиве Services.zip).

Сервисы написаны на TS 3.4.1.
MS SQL

Нравится

Поделиться

7 комментариев

рекомендую исключать из этой процедуры контакты пользователей и их контрагентов, группы записей (фильтры)
а также учесть, что некоторые записи созданы Supervisor'ом

альтернативный вариант процедуры http://www.community.terrasoft.ru/blogs/9611#comment-40937
если надо выложу доработанную версию и примеры использования

Группы записей я исключил с самого начала, используются только таблицы записей.
А по поводу контактов пользователей и их контрагентов, и что некоторые записи созданы Supervisor-ом - не понимаю в чем тут проблема?

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

по опыту говорю :confused:
часть пользователей создана от имени учредителя (персонал не видит их контакты по-умолчанию), а часть от имени супервайзера и админа, для которых не настроены права по-умолчанию. После процедуры пересоздания права не сразу сообразил, что затер права на контакты пользователей, которые с утра не смогли зайти.

даже если у вас конкретно подобные недочеты исключены, увы, не факт, что и у остальных дела обстоят также :wink:

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

такую штуку хорошо иметь для себя, но на рынок я бы не рискнул ее выкладывать

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

Как я понял, корректная работа доступов на записи упирается в правильное распределение пользователей по группам пользователей и настройку прав по умолчанию для этих груп.

"Кошкаров Андрей" написал:Как я понял, корректная работа доступов на записи упирается в правильное распределение пользователей по группам пользователей и настройку прав по умолчанию для этих груп.

Конечно :lol:
Но дело-то не в том, как настроены права на данный момент. Дело в истории конкретных записей. Даже если не учитывать, что записи могут создаваться вне компетенции пользователей и, как следствие, права по-умолчанию для этой записи не будут соответствовать правам, какие должны быть у этой записи (например - контакт пользователя создал тот (учредитель), чьи контакты этот пользователь (менеджер) видеть не может).
Кроме того представим, что организационных недоразумений нет, но возникает вполне штатная ситуация: сегодня человек Менеджер по персоналу - заводит пользователей в терре, завтра становится Зам. директора по персоналу - и персонал уже не видит его контактов, но ответственным и создателем для уже заведенных он остается. После пересоздания прав пользователи не могут зайти в систему.

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

Видимо, при переезде все прикрепленные файлы пропали. Можно попросить добавить их снова?

Показать все комментарии