Advertisement
PavloSerg

LabaNewMasking

Oct 21st, 2023 (edited)
1,729
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
T-SQL 9.45 KB | None | 0 0
  1. --Разработать свой метод маскирования символьных данных и применить его
  2. --для указанных пользователей. Инструменты: View, Триггеры, Функции
  3.  
  4.  
  5. --Необходимо создать свою систему маскирования (желательно условно автоматическую)
  6. --Для этого я предлагаю следующее:
  7. --Создать:
  8. --1) Таблицу с правами на столбцы(Пользователь, таблица, столбец)
  9. --2) Таблицу с указания функций маскирования столбцов(таблица, столбец, функция)
  10. --3) Тригер на создание таблиц, чтобы сразу регистрировать в 2)
  11. --4) Хранимая процедура для выборки определенной таблицы(таблица, колонки)
  12. --5) Тригер на выдачу прав для 4) для новых пользователей
  13. --6) Создать и зарегистрировать функции маскирования
  14. create SCHEMA MaskingTables;
  15. create SCHEMA MaskingFunctions;
  16. create SCHEMA ResultSchema;
  17. go;
  18. --1) Таблицу с правами на столбцы(Пользователь, таблица, столбец)
  19. create table MaskingTables.ColumnsRights(
  20.     userName nvarchar(40) not null,
  21.     tableName nvarchar(40) not null,
  22.     columnName nvarchar(40) not null,
  23.     primary key(userName, tableName, columnName)
  24. )
  25. go;
  26.  
  27.  
  28. --2) Таблицу с указания функций маскирования столбцов(таблица, столбец, функция)
  29. create table MaskingTables.ColumnsMaskFunctions(
  30.     tableName nvarchar(40) not null,
  31.     columnName nvarchar(40) not null,
  32.     maskDefinition nvarchar(255) not null,
  33.     primary key(tableName, columnName, maskDefinition)
  34. )
  35. go;
  36.  
  37.  
  38. --3) Тригер на создание таблиц, чтобы сразу регистрировать в 2)
  39. --Для начала создадим функцию-заглушку чтобы она возвращала переданное значение
  40. create function MaskingFunctions.DefaultFunction(@value as nvarchar(max))
  41. returns nvarchar(max)
  42. as
  43.     begin
  44.         return @value
  45.     end
  46. go;
  47. --Пишем сам тригер
  48. create or alter trigger RegisterNewTableColumnsTrigger
  49. on database
  50. after CREATE_TABLE
  51. as
  52.     begin
  53.          DECLARE @created_table NVARCHAR(200) = EVENTDATA()
  54.         .value('(/EVENT_INSTANCE/ObjectName)[1]', 'nvarchar(256)')
  55.  
  56.          insert into MaskingTables.ColumnsMaskFunctions
  57.          SELECT @created_table, sys.columns.name, 'MaskingFunctions.DefaultFunction(@value)'
  58.          FROM sys.columns
  59.          WHERE object_id = OBJECT_ID('dbo.' + @created_table);
  60.          --завязка только на dbo
  61.     end
  62. go;
  63. --Создадим таблицу для дальнейших тестов
  64. create table Users
  65. (
  66.     id          bigint identity (1,1) primary key,
  67.     name        nvarchar(20) not null,
  68.     phoneNumber char(12)     not null
  69. )
  70. go;
  71. insert into Users
  72. values (N'Сарожа', '+79998887766'),
  73.        (N'Егор', '+71112223344'),
  74.        (N'Лаврентий', '+70000000000')
  75. go;
  76.  
  77.  
  78. --4) Хранимая процедура для выборки определенной таблицы(таблица, колонки)
  79. --Костыль
  80. create view Result
  81. as
  82. select 'dasdas' as test
  83. where 2>1
  84.  
  85. --Сама процедура
  86. create or alter procedure MaskingTables.SelectColumns(
  87.     @tableName as nvarchar(200),
  88.     @columnsName as nvarchar(200)
  89. ) as
  90. begin
  91.     declare @currentColumn nvarchar(200);
  92.     declare columnsCursor cursor for
  93.         SELECT value
  94.         FROM STRING_SPLIT(@columnsName, ',')
  95.         WHERE TRIM(value) <> '';
  96.     open columnsCursor;
  97.     fetch next from columnsCursor into @currentColumn
  98.     while @@fetch_status=0
  99.     begin
  100.         set @currentColumn = TRIM(@currentColumn)
  101.         declare @currentColumnDefinition nvarchar(200);
  102.         if not exists(select *
  103.                       from MaskingTables.ColumnsRights cr
  104.                       where cr.userName = current_user and
  105.                             cr.tableName = @tableName and
  106.                             cr.columnName = @currentColumn)
  107.         begin
  108.              select @currentColumnDefinition = maskDefinition
  109.              from MaskingTables.ColumnsMaskFunctions
  110.              where tableName = @tableName and columnName = @currentColumn
  111.  
  112.              set @columnsName = replace(@columnsName, @currentColumn, @currentColumnDefinition+N' as '+@currentColumn)
  113.              set @columnsName = replace(@columnsName, '@value', @currentColumn)
  114.         end
  115.  
  116.         fetch next from columnsCursor into @currentColumn;
  117.     end
  118.     close columnsCursor;
  119.     deallocate columnsCursor;
  120.  
  121.     --if exists(select *
  122.     --    from sys.views
  123.     --    where object_id = object_id('ResultSchema.Result'))
  124.     --begin
  125.     --    drop view ResultSchema.Result
  126.     --end
  127.     DECLARE @SQLString NVARCHAR(500)
  128. --     К сожалению код ниже не работает
  129. --set @SQLString = N'create VIEW [dbo].[Result]
  130. --                                     AS
  131. --                                     select @columnsNamee
  132. --                                     from @tableNamee'
  133. --DECLARE @ParamDefinition NVARCHAR(500) = N'@tableNamee nvarchar(200), @columnsNamee nvarchar(200)';
  134. --exec sp_executesql @SQLString, @ParamDefinition, @tableNamee = @tableName, @columnsNamee = @columnsName;
  135.  
  136.     set @SQLString = N'create or alter VIEW ResultSchema.Result
  137.                                     AS
  138.                                     select '+@columnsName+'
  139.                                     from '+@tableName
  140.     print(@SQLString)
  141.     execute(@SQLString)
  142.  
  143.     --set @SQLString = N'grant select on ResultSchema.Result to ' + current_user
  144.     --execute(@SQLString)
  145. end
  146.  
  147.  
  148. --exec MaskingTables.SelectColumns N'Users', N'id, name, phoneNumber'
  149. --5) Тригер на выдачу прав для 4) для новых пользователей
  150. CREATE OR ALTER TRIGGER NewUserAdditionTrigger
  151.     ON DATABASE
  152.     after CREATE_USER
  153.     AS
  154. BEGIN
  155.     DECLARE @createdUser NVARCHAR(200) = EVENTDATA()
  156.         .value('(/EVENT_INSTANCE/ObjectName)[1]', 'nvarchar(256)')
  157.     declare @sqlCommand nvarchar(255)
  158.     set @sqlCommand = 'grant execute on MaskingTables.SelectColumns to ['+@createdUser+']'
  159.     --DECLARE @ParamDefinition NVARCHAR(500) = N'@createdUserr NVARCHAR(256)'
  160.     exec sp_executesql @sqlCommand--, @ParamDefinition, @createdUserr = @createdUser
  161.     set @sqlCommand = 'grant ALTER, CONTROL, SELECT on SCHEMA::ResultSchema to ['+@createdUser+']'
  162.     exec sp_executesql @sqlCommand
  163.     set @sqlCommand = 'GRANT CREATE VIEW TO ['+@createdUser+']'
  164.     exec sp_executesql @sqlCommand
  165. END;
  166. --6) Создать и зарегистрировать функции маскирования
  167. --Для имени
  168. create function MaskingFunctions.MaskName(@value as nvarchar(max))
  169. returns nvarchar(max)
  170. as
  171.     begin
  172.         return N'***MaskedName***'
  173.     end
  174. go;
  175. --Для номера телефона
  176. create function MaskingFunctions.MaskPhone(@value as char(12))
  177. returns char(12)
  178. as
  179.     begin
  180.         return '***' + substring(@value, 8, 4)
  181.     end
  182. go;
  183. --Регистрируем
  184. update MaskingTables.ColumnsMaskFunctions
  185. set MaskingTables.ColumnsMaskFunctions.maskDefinition = N'MaskingFunctions.MaskName(@value)'
  186. where tableName = 'Users' and columnName ='name'
  187.  
  188. update MaskingTables.ColumnsMaskFunctions
  189. set MaskingTables.ColumnsMaskFunctions.maskDefinition = N'MaskingFunctions.MaskPhone(@value)'
  190. where tableName = 'Users' and columnName ='phoneNumber'
  191.  
  192. grant create view to [ПровидецВсего]
  193. ------------------ТЕСТИРОВАНИЕ-------------------------
  194. --1) Создадим пользователей и выдадим им разные права
  195. -- drop user [ПровидецИмени]
  196. -- drop user [ПровидецНомераТелефона]
  197. -- drop user [ПровидецВсего]
  198. -- create user [ПровидецИмени] without login;
  199. -- go;
  200. -- create user [ПровидецНомераТелефона] without login;
  201. -- go;
  202. -- create user [ПровидецВсего] without login;
  203. -- go;
  204. -- select current_user
  205. create user [ПровидецИмени] without login;
  206. insert into MaskingTables.ColumnsRights values
  207. (N'ПровидецИмени', N'Users', N'name')
  208. go;
  209. create user [ПровидецНомераТелефона] without login;
  210. insert into MaskingTables.ColumnsRights values
  211. (N'ПровидецНомераТелефона', N'Users', N'phoneNumber')
  212. go;
  213. create user [ПровидецВсего] without login;
  214. insert into MaskingTables.ColumnsRights values
  215. (N'ПровидецВсего', N'Users', N'name'),
  216. (N'ПровидецВсего', N'Users', N'phoneNumber')
  217. go;
  218.  
  219. --Проверяем
  220. execute as user = N'ПровидецИмени'
  221. exec MaskingTables.SelectColumns N'Users', N'id, name, phoneNumber'
  222. select *
  223. from ResultSchema.Result
  224. revert
  225.  
  226. execute as user = N'ПровидецНомераТелефона'
  227. exec MaskingTables.SelectColumns N'Users', N'id, name, phoneNumber'
  228. select *
  229. from ResultSchema.Result
  230. revert
  231.  
  232. execute as user = N'ПровидецВсего'
  233. exec MaskingTables.SelectColumns N'Users', N'id, name, phoneNumber'
  234. select *
  235. from ResultSchema.Result
  236. revert
  237.  
  238.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement