Добавление прав на чтение для ряда таблиц, завязанных на конкретном контрагенте
Нужно реализовать проставление прав доступа на чтение для указанного контакта для следущих сущностей вращающихся вокруг контрагента:
1. Задачи (у задачи есть связка с контрагентом - поле "Контрагент")
2. Договора (у договора есть связка с контрагентом - поле "Клиент")
3. Счета (у счета есть связка с контрагентом - поле "Клиент")
4. Расходные накладные (у расходной накладной есть связка с контрагентом - поле "Получатель")
Использоваться этот функционал будет в бизнес-процессе передачи контрагента другому ответственному. Я так понимаю, что выполнение раздачи прав на чтение ответственному нужно выполнять на стороне SQL-сервера. Помогите понять как это сделать. Нужно создать хранимую процедуру и вызывать ее? Как это делается правильно? Если можно, дайте пример.
Terrasoft XRM 3.3.1.146 MS SQL
Нравится
Хранимой процедуре может не хватить прав, лучше делать триггером.
Мы реализовывали специальное расширение, которое позволяет управлять такой раздачей прав на уровне пользователя (триггеры генерируются автоматически):
http://community.terrasoft.ua/catalog/4879
"Валерий Андрусик" написал:Хранимой процедуре может не хватить прав, лучше делать триггером.
Почему может не хватить? Можно же ее снабдить необходимыми правами. А триггеры сложнее отлаживать.
А пример можно какой-то? Или может в стандартной конфигурации есть что посмотреть по этому поводу?
Можно посмотреть, но у меня сейчас нет доступа, поищите по слову DBEngine глобальным поиском. что-то вроде:
[javascript]
Connector.DBEngine.ExecuteCustomSQL("<имя процедуры>", Parameters);
[/javascript]
По умолчанию процедура вызывается от имени и имеет права создателя, если не указано явно, что она должна вызываться от имени пользователя.
"Раловец Ольга" написал:Почему может не хватить? Можно же ее снабдить необходимыми правами. А триггеры сложнее отлаживать.
Зависит от версии MSSQL у топик-стартера.
Для корректной раздачи прав доступа процедура должна выполняться с правами владельца базы. По-моему в MSSQL 2000 еще не было возможности указать процедуре выполняться AS OWNER.
"Валерий Андрусик" написал:Зависит от версии MSSQL у топик-стартера.
У меня версия MS SQL 2005. Думаю использовать хранимую процедуру, чтобы хоть какая-то наглядность была, когда читаешь код конфигурации.
Решил использовать вот такую процедуру:
[sql]
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
[/sql]
Выполняю следующий код при изменении ответственного в карточке контрагента:
[javascript]
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);
[/javascript]
Всем спасибо за советы :smile:
Проверьте, работает ли под обычным пользователем, не администратором.
Возможно после CREATE PROCEDURE надо добавить ключевые слова:
[sql]
CREATE PROCEDURE .... WITH EXECUTE AS OWNER
AS
...
[/sql]
"Валерий Андрусик" написал:Проверьте, работает ли под обычным пользователем, не администратором.
Пока нареканий не было. Посмотрим.
"Валерий Андрусик" написал:Проверьте, работает ли под обычным пользователем, не администратором.
Возможно после CREATE PROCEDURE надо добавить ключевые слова:
CREATE PROCEDURE .... WITH EXECUTE AS OWNER
AS
...
Попробовал, почему-то все равно не хочет запускаться под другими пользователями. Сейчас ищу решение.
Нашел в чем проблема возникла. Нужно было дать доступ на выполнение хранимой процедуры для группы пользователей 'public':

Или так
[sql]
grant execute on [dbo].tsp_AddReadRightsToAccountHistory to public
[/sql]
"Кулак Олег" написал:GRANT execute ON [dbo].tsp_AddReadRightsToAccountHistory TO public
Спасибо :) Так удобней