Добавление прав на чтение для ряда таблиц, завязанных на конкретном контрагенте

Нужно реализовать проставление прав доступа на чтение для указанного контакта для следущих сущностей вращающихся вокруг контрагента:
1. Задачи (у задачи есть связка с контрагентом - поле "Контрагент")
2. Договора (у договора есть связка с контрагентом - поле "Клиент")
3. Счета (у счета есть связка с контрагентом - поле "Клиент")
4. Расходные накладные (у расходной накладной есть связка с контрагентом - поле "Получатель")

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

Terrasoft XRM 3.3.1.146 MS SQL

Нравится

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

Хранимой процедуре может не хватить прав, лучше делать триггером.
Мы реализовывали специальное расширение, которое позволяет управлять такой раздачей прав на уровне пользователя (триггеры генерируются автоматически):
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
...

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

CREATE PROCEDURE .... WITH EXECUTE AS 'dbo'

Нашел в чем проблема возникла. Нужно было дать доступ на выполнение хранимой процедуры для группы пользователей 'public':

Или так

grant execute on [dbo].tsp_AddReadRightsToAccountHistory to public

"Кулак Олег" написал:GRANT execute ON [dbo].tsp_AddReadRightsToAccountHistory TO public

Спасибо :) Так удобней

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