-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathRowLevelSecurity.sql
106 lines (78 loc) · 2.43 KB
/
RowLevelSecurity.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
-- CLEAN UP
DROP USER ChatApp
DROP LOGIN ChatApp
DROP SECURITY POLICY Security.RoomsFilter
DROP SECURITY POLICY Security.MessagesFilter
DROP FUNCTION security.fn_CheckMessages
DROP FUNCTION security.fn_CheckMatchingCompany
DROP SCHEMA security
-- ChatApp Account
CREATE LOGIN ChatApp
WITH PASSWORD = 'Chat123!'
GO
CREATE USER ChatApp
FOR LOGIN ChatApp
WITH DEFAULT_SCHEMA = dbo
GO
GRANT SELECT, INSERT, UPDATE, DELETE ON SCHEMA :: dbo TO ChatApp;
GRANT SHOWPLAN TO ChatApp;
GO
-- Security policies
CREATE SCHEMA security;
GO
CREATE FUNCTION security.fn_CheckMatchingCompany(@CompanyId NVARCHAR(10))
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN SELECT 1 AS fn_CheckMatchingCompany_result
WHERE
IS_ROLEMEMBER (N'db_owner') = 1 OR
CAST(SESSION_CONTEXT(N'CompanyId') AS NVARCHAR(10)) = @CompanyId;
GO
CREATE FUNCTION security.fn_CheckMessages(@RoomId int)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN SELECT 1 AS fn_CheckMessages_result
FROM dbo.Rooms r
WHERE r.Id = @RoomId AND
EXISTS (SELECT fn_CheckMatchingCompany_result FROM security.fn_CheckMatchingCompany(r.CompanyId))
GO
CREATE SECURITY POLICY Security.RoomsFilter
ADD FILTER PREDICATE Security.fn_CheckMatchingCompany(CompanyId)
ON dbo.Rooms,
ADD BLOCK PREDICATE Security.fn_CheckMatchingCompany(CompanyId)
ON dbo.Rooms AFTER INSERT,
ADD BLOCK PREDICATE Security.fn_CheckMatchingCompany(CompanyId)
ON dbo.Rooms AFTER UPDATE
WITH (STATE = ON);
GO
CREATE SECURITY POLICY Security.MessagesFilter
ADD FILTER PREDICATE Security.fn_CheckMessages(RoomId)
ON dbo.Messages,
ADD BLOCK PREDICATE Security.fn_CheckMessages(RoomId)
ON dbo.Messages AFTER INSERT,
ADD BLOCK PREDICATE Security.fn_CheckMessages(RoomId)
ON dbo.Messages AFTER UPDATE
WITH (STATE = ON);
GO
-- Playground
SELECT IS_SRVROLEMEMBER(N'sysadmin')
SELECT IS_ROLEMEMBER ('db_owner', 'ChatApp')
EXECUTE AS USER = 'ChatApp';
REVERT
EXEC sp_set_session_context @key=N'CompanyId', @value='Acme'
SELECT * FROM rooms
SELECT * FROM messages
SELECT SESSION_CONTEXT(N'CompanyId')
INSERT INTO rooms (NAME, CompanyId) VALUES ('not in', 'Acme')
INSERT INTO [dbo].[Messages]
([TimeStamp]
,[Username]
,[Content]
,[RoomId])
VALUES
('2020-1-1'
,'test'
,'some message'
,1)