Добавление прав на чтение для ряда таблиц, завязанных на конкретном контрагенте
Нужно реализовать проставление прав доступа на чтение для указанного контакта для следущих сущностей вращающихся вокруг контрагента:
1. Задачи (у задачи есть связка с контрагентом - поле "Контрагент")
2. Договора (у договора есть связка с контрагентом - поле "Клиент")
3. Счета (у счета есть связка с контрагентом - поле "Клиент")
4. Расходные накладные (у расходной накладной есть связка с контрагентом - поле "Получатель")
Использоваться этот функционал будет в бизнес-процессе передачи контрагента другому ответственному. Я так понимаю, что выполнение раздачи прав на чтение ответственному нужно выполнять на стороне SQL-сервера. Помогите понять как это сделать. Нужно создать хранимую процедуру и вызывать ее? Как это делается правильно? Если можно, дайте пример.
Terrasoft XRM 3.3.1.146 MS SQL
Нравится
Хранимой процедуре может не хватить прав, лучше делать триггером.
Мы реализовывали специальное расширение, которое позволяет управлять такой раздачей прав на уровне пользователя (триггеры генерируются автоматически):
http://community.terrasoft.ua/catalog/4879
"Валерий Андрусик" написал:Хранимой процедуре может не хватить прав, лучше делать триггером.
Почему может не хватить? Можно же ее снабдить необходимыми правами. А триггеры сложнее отлаживать.
А пример можно какой-то? Или может в стандартной конфигурации есть что посмотреть по этому поводу?
Можно посмотреть, но у меня сейчас нет доступа, поищите по слову DBEngine глобальным поиском. что-то вроде:
Connector.DBEngine.ExecuteCustomSQL("<имя процедуры>", Parameters);
По умолчанию процедура вызывается от имени и имеет права создателя, если не указано явно, что она должна вызываться от имени пользователя.
"Раловец Ольга" написал:Почему может не хватить? Можно же ее снабдить необходимыми правами. А триггеры сложнее отлаживать.
Зависит от версии MSSQL у топик-стартера.
Для корректной раздачи прав доступа процедура должна выполняться с правами владельца базы. По-моему в MSSQL 2000 еще не было возможности указать процедуре выполняться AS OWNER.
"Валерий Андрусик" написал:Зависит от версии MSSQL у топик-стартера.
У меня версия MS SQL 2005. Думаю использовать хранимую процедуру, чтобы хоть какая-то наглядность была, когда читаешь код конфигурации.
Решил использовать вот такую процедуру:
set ANSI_NULLS ON set QUOTED_IDENTIFIER ON go CREATE procedure [dbo].[tsp_AddReadRightsToAccountHistory] @AccountID uniqueidentifier, @OwnerID uniqueidentifier as begin set nocount on declare @AuOwnerID uniqueidentifier declare @TaskID uniqueidentifier declare @ContractID uniqueidentifier declare @InvoiceID uniqueidentifier declare @OfferingMovementID uniqueidentifier if @AccountID is NULL OR @OwnerID is NULL return SET @AuOwnerID = (SELECT ID FROM tbl_AdminUnit WHERE UserContactID = @OwnerID) IF @AuOwnerID IS NULL return -- Проставление доступа на чтение для задачи привязанных к указанному контрагенту declare c_Task cursor FOR SELECT ID FROM tbl_Task WHERE AccountID = @AccountID OPEN c_Task FETCH NEXT FROM c_Task INTO @TaskID WHILE @@FETCH_STATUS=0 BEGIN INSERT INTO tbl_TaskRight (ID, RecordID, AdminUnitID, CanRead, CanWrite, CanDelete, CanChangeAccess) VALUES (NewID(), @TaskID, @AuOwnerID, 1, 0, 0, 0) FETCH NEXT FROM c_Task INTO @TaskID END CLOSE c_Task DEALLOCATE c_Task -- Проставление доступа на чтение для всех договоров контрагента declare c_Contract cursor FOR SELECT ID FROM tbl_Contract WHERE CustomerID = @AccountID OPEN c_Contract FETCH NEXT FROM c_Contract INTO @ContractID WHILE @@FETCH_STATUS=0 BEGIN INSERT INTO tbl_ContractRight (ID, RecordID, AdminUnitID, CanRead, CanWrite, CanDelete, CanChangeAccess) VALUES (NewID(), @ContractID, @AuOwnerID, 1, 0, 0, 0) FETCH NEXT FROM c_Contract INTO @ContractID END CLOSE c_Contract DEALLOCATE c_Contract -- Проставление доступа на чтение для всех счетов контрагента declare c_Invoice cursor FOR SELECT ID FROM tbl_Invoice WHERE CustomerID = @AccountID OPEN c_Invoice FETCH NEXT FROM c_Invoice INTO @InvoiceID WHILE @@FETCH_STATUS=0 BEGIN INSERT INTO tbl_InvoiceRight (ID, RecordID, AdminUnitID, CanRead, CanWrite, CanDelete, CanChangeAccess) VALUES (NewID(), @InvoiceID, @AuOwnerID, 1, 0, 0, 0) FETCH NEXT FROM c_Invoice INTO @InvoiceID END CLOSE c_Invoice DEALLOCATE c_Invoice -- Проставление доступа на чтение для всех расходных накладных контрагента declare c_OffMov cursor FOR SELECT ID FROM tbl_OfferingMovement WHERE RecipientID = @AccountID OPEN c_OffMov FETCH NEXT FROM c_OffMov INTO @OfferingMovementID WHILE @@FETCH_STATUS=0 BEGIN INSERT INTO tbl_OfferingMovementRight (ID, RecordID, AdminUnitID, CanRead, CanWrite, CanDelete, CanChangeAccess) VALUES (NewID(), @OfferingMovementID, @AuOwnerID, 1, 0, 0, 0) FETCH NEXT FROM c_OffMov INTO @OfferingMovementID END CLOSE c_OffMov DEALLOCATE c_OffMov end
Выполняю следующий код при изменении ответственного в карточке контрагента:
var Parameters = CreateSPParameters(); CreateSPParameter(Parameters, 'AccountID', pdtGUID, AccountID); CreateSPParameter(Parameters, 'OwnerID', pdtGUID, OwnerID); var SQLText = 'exec [tsp_AddReadRightsToAccountHistory] :AccountID, :OwnerID'; Connector.DBEngine.ExecuteCustomSQL(SQLText, Parameters);
Всем спасибо за советы :smile:
Проверьте, работает ли под обычным пользователем, не администратором.
Возможно после CREATE PROCEDURE надо добавить ключевые слова:
CREATE PROCEDURE .... WITH EXECUTE AS OWNER
AS
...
"Валерий Андрусик" написал:Проверьте, работает ли под обычным пользователем, не администратором.
Пока нареканий не было. Посмотрим.
"Валерий Андрусик" написал:Проверьте, работает ли под обычным пользователем, не администратором.
Возможно после CREATE PROCEDURE надо добавить ключевые слова:
CREATE PROCEDURE .... WITH EXECUTE AS OWNER
AS
...
Попробовал, почему-то все равно не хочет запускаться под другими пользователями. Сейчас ищу решение.
Нашел в чем проблема возникла. Нужно было дать доступ на выполнение хранимой процедуры для группы пользователей 'public':
Или так
grant execute on [dbo].tsp_AddReadRightsToAccountHistory to public
"Кулак Олег" написал:GRANT execute ON [dbo].tsp_AddReadRightsToAccountHistory TO public
Спасибо :) Так удобней