Как автоматически скорректировать права на все существующие записи при изменении прав по умолчанию?
Такое решение давно напрашивалось для ситуаций, когда требуется не только изменить настройки прав по умолчанию, но и актуализировать уже розданные права на существующие записи согласно новым настройкам прав.
Представьте, что сдали заказчику проект, он поработал и вдруг осознаёт: права по умолчанию надо поменять. И поменял. Система легко кастомизируется, о настройках прав в ТС тонны отличных руководств. Но на уже созданные по «старым» настройкам записи, понятное дело, эти изменения не повлияли. И вот тогда заказчик может обратиться к разработчику с пожеланием сделать так, чтобы на уже созданные записи права были розданы точно так же, как он настроил.
К сожалению далеко не всегда известно, что именно менялось и для каких таблиц. Выяснить это можно, но время, время…. Требовалось такое решение, которое позволило бы быстро, одним щелчком раздать права на все существующие записи всех таблиц в точности так, как настроены права по умолчанию сейчас.
В предлагаемом скрипте происходит перебор всех администрируемых по записям таблиц и перенастройка прав согласно существующим правам по-умолчанию. Подразумевается, что таблицы прав называются по схеме ‘имя администрируемой таблицы + ’Right’
.
[tbl_Service].[Code] + 'Right'
Права нарочно не перераздаются на записи в таблицах групп, так как по умолчанию права на группы имеют только авторы записей. Следовательно из выборки исключены все таблицы, оканчивающиеся на ‘Group’. Если такое ограничение не требуется – закомментируйте строку
NOT [tbl_Service].[Code] LIKE '%Group'
В выборке учитывается и тот момент, что [tbl_TableDefaultRight]
может содержать различный «мусор» от таблиц, у которых снят признак администрирования.
Предлагаемый скрипт в его нынешнем виде генерирует строки insert
и update
, которые можно проанализировать прежде чем выполнять. Но если требуется сразу выполнить – снимите комментарий в обоих строках
EXECUTE sp_executesql @InsertQueryExecutable
....
EXECUTE sp_executesql @UpdateQueryExecutable
Надеюсь, предлагаемое решение окажется полезным всем, кто в будущем столкнётся с похожей ситуацией.
/* ---------------------------------------------
Установка прав на все администрируемые таблицы
согласно текущим правам по умолчанию
==============================================*/
declare @Code nvarchar(250)
declare @AdminUnitID uniqueidentifier
declare @CanRead int
declare @CanWrite int
declare @CanDelete int
declare @CanChangeAccess int
declare @UpdateQueryExecutable nvarchar(4000)
declare @UpdateQuery nvarchar(4000)
SET @UpdateQuery =
'update [@CodeRight]
set [CanRead] = @CanRead
, [CanWrite] = @CanWrite
, [CanDelete] = @CanDelete
, [CanChangeAccess] = @CanChangeAccess
where [AdminUnitID] = ''@AdminUnitID'''
declare @InsertQueryExecutable nvarchar(4000)
declare @InsertQuery nvarchar(4000)
SET @InsertQuery =
'insert into [@CodeRight]
(
[RecordID]
, [AdminUnitID]
, [CanRead]
, [CanWrite]
, [CanDelete]
, [CanChangeAccess]
)
select [ID]
, ''@AdminUnitID''
, @CanRead
, @CanWrite
, @CanDelete
, @CanChangeAccess
from [@Code]
where
not exists
( select [a].[ID]
from [@CodeRight] as [a]
where [AdminUnitID] = ''@AdminUnitID''
and [a].[RecordID] = [@Code].[ID]
)'
declare DefaultRightCursor cursor FOR
SELECT
[tbl_Service].[Code]
, [tbl_TableDefaultRight].[SubjectAdminUnitID]
, MAX([tbl_TableDefaultRight].[CanRead])
, MAX([tbl_TableDefaultRight].[CanWrite])
, MAX([tbl_TableDefaultRight].[CanDelete])
, MAX([tbl_TableDefaultRight].[CanChangeAccess])
FROM [tbl_TableDefaultRight]
INNER JOIN [tbl_Service]
ON
[tbl_Service].[ID] = [tbl_TableDefaultRight].[TableServiceID]
INNER JOIN [tbl_AdminUnit]
ON
[tbl_AdminUnit].[ID] = [tbl_TableDefaultRight].[SubjectAdminUnitID]
WHERE
--Не использовать для групп - у них права по-умолчанию имеет только автор
NOT [tbl_Service].[Code] LIKE '%Group'
AND
--Учитывать только существующие таблицы прав
--(иногда бывает "мусор" от таблиц, на которые раньше раздавались права, а теперь нет)
EXISTS (
SELECT * FROM
INFORMATION_SCHEMA.TABLES
WHERE INFORMATION_SCHEMA.TABLES.TABLE_NAME = [tbl_Service].[Code] + 'Right'
)
GROUP BY [tbl_Service].[Code], [tbl_TableDefaultRight].[SubjectAdminUnitID]
ORDER BY [tbl_Service].[Code]
open DefaultRightCursor
fetch next FROM DefaultRightCursor INTO
@Code
, @AdminUnitID
, @CanRead
, @CanWrite
, @CanDelete
, @CanChangeAccess
while @@fetch_status = 0
begin
SET @InsertQueryExecutable = REPLACE(@InsertQuery, '@Code', @Code)
SET @InsertQueryExecutable = REPLACE(@InsertQueryExecutable, '@AdminUnitID', @AdminUnitID)
SET @InsertQueryExecutable = REPLACE(@InsertQueryExecutable, '@CanRead', @CanRead)
SET @InsertQueryExecutable = REPLACE(@InsertQueryExecutable, '@CanWrite', @CanWrite)
SET @InsertQueryExecutable = REPLACE(@InsertQueryExecutable, '@CanDelete', @CanDelete)
SET @InsertQueryExecutable = REPLACE(@InsertQueryExecutable, '@CanChangeAccess', @CanChangeAccess)
print @InsertQueryExecutable
--EXECUTE sp_executesql @InsertQueryExecutable
print '---------------------------------------'
SET @UpdateQueryExecutable = REPLACE(@UpdateQuery, '@Code', @Code)
SET @UpdateQueryExecutable = REPLACE(@UpdateQueryExecutable, '@AdminUnitID', @AdminUnitID)
SET @UpdateQueryExecutable = REPLACE(@UpdateQueryExecutable, '@CanRead', @CanRead)
SET @UpdateQueryExecutable = REPLACE(@UpdateQueryExecutable, '@CanWrite', @CanWrite)
SET @UpdateQueryExecutable = REPLACE(@UpdateQueryExecutable, '@CanDelete', @CanDelete)
SET @UpdateQueryExecutable = REPLACE(@UpdateQueryExecutable, '@CanChangeAccess', @CanChangeAccess)
print @UpdateQueryExecutable
--EXECUTE sp_executesql @UpdateQueryExecutable
print '--===================================--'
fetch next FROM DefaultRightCursor INTO
@Code
, @AdminUnitID
, @CanRead
, @CanWrite
, @CanDelete
, @CanChangeAccess
end
close DefaultRightCursor
deallocate DefaultRightCursor