Skip to content

Commit 0a99b81

Browse files
author
Travis Fields
committed
FM-2236 Change to permissions and allow user to pass an array instead of single permission
1 parent 461ba1b commit 0a99b81

File tree

6 files changed

+52
-39
lines changed

6 files changed

+52
-39
lines changed

manifests/user/permission.pp

+9-7
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
# [database]
1414
# The databaser you would like the permission managed on.
1515
#
16-
# [permission]
17-
# The permission you would like managed. i.e. 'SELECT', 'INSERT', 'UPDATE', 'DELETE'
16+
# [permissions]
17+
# An array of permissions you would like managed. i.e. ['SELECT', 'INSERT', 'UPDATE', 'DELETE']
1818
#
1919
# [state]
2020
# The state you would like the permission in. Accepts 'GRANT', 'DENY', 'REVOKE' Please note that REVOKE equates to absent and will default to database and system level permissions.
@@ -29,17 +29,16 @@
2929
define sqlserver::user::permission (
3030
$user,
3131
$database,
32-
$permission = $title,
32+
$permissions,
3333
$state = 'GRANT',
3434
$with_grant_option = false,
3535
$instance = 'MSSQLSERVER',
3636
){
3737
sqlserver_validate_instance_name($instance)
3838

3939
## Validate Permissions
40-
$_permission = upcase($permission)
41-
sqlserver_validate_range($_permission, 4, 128, 'Permission must be between 4 and 128 characters')
42-
validate_re($_permission, '^([A-Z]|\s)+$','Permissions must be alphabetic only')
40+
sqlserver_validate_range($permissions, 4, 128, 'Permission must be between 4 and 128 characters')
41+
validate_array($permissions)
4342

4443
## Validate state
4544
$_state = upcase($state)
@@ -54,8 +53,11 @@
5453

5554
sqlserver_validate_range($user, 1, 128, 'User must be between 1 and 128 characters')
5655

56+
if $with_grant_option {
57+
$grant_option = "-WITH_GRANT_OPTION"
58+
}
5759
sqlserver_tsql{
58-
"user-permissions-${instance}-${database}-${user}-${_permission}":
60+
"user-permissions-${instance}-${database}-${user}-${_state}${grant_option}":
5961
instance => $instance,
6062
command => template("sqlserver/create/user/permission.sql.erb"),
6163
onlyif => template('sqlserver/query/user/permission_exists.sql.erb'),

spec/defines/user/permission_spec.rb

+22-21
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
context 'validation errors' do
77
include_context 'manifests' do
88
let(:title) { 'myTitle' }
9-
let(:sqlserver_tsql_title) { 'user-permissions-MSSQLSERVER-loggingDb-loggingUser-SELECT' }
9+
let(:sqlserver_tsql_title) { 'user-permissions-MSSQLSERVER-loggingDb-loggingUser-GRANT' }
1010
end
1111
context 'user =>' do
1212
let(:params) { {
13-
:permission => 'SELECT',
13+
:permissions => ['SELECT'],
1414
:database => 'loggingDb',
1515
} }
1616
let(:raise_error_check) { 'User must be between 1 and 128 characters' }
@@ -27,28 +27,28 @@
2727
it_behaves_like 'validation error'
2828
end
2929
end
30-
context 'permission' do
30+
context 'permissions' do
3131
let(:params) { {
3232
:user => 'loggingUser',
3333
:database => 'loggingDb',
3434
} }
3535
let(:raise_error_check) { 'Permission must be between 4 and 128 characters' }
3636
describe 'empty' do
37-
let(:additional_params) { {:permission => ''} }
37+
let(:additional_params) { {:permissions => ''} }
3838
it_behaves_like 'validation error'
3939
end
4040
describe 'under limit' do
41-
let(:additional_params) { {:permission => random_string_of_size(3, false)} }
41+
let(:additional_params) { {:permissions => [random_string_of_size(3, false)]} }
4242
it_behaves_like 'validation error'
4343
end
4444
describe 'over limit' do
45-
let(:additional_params) { {:permission => random_string_of_size(129, false)} }
45+
let(:additional_params) { {:permissions => [random_string_of_size(129, false)]} }
4646
it_behaves_like 'validation error'
4747
end
4848
end
4949
context 'state =>' do
5050
let(:params) { {
51-
:permission => 'SELECT',
51+
:permissions => ['SELECT'],
5252
:database => 'loggingDb',
5353
:user => 'loggingUser'
5454
} }
@@ -60,7 +60,7 @@
6060
end
6161
context 'with_grant_option => ' do
6262
let(:params) { {
63-
:permission => 'SELECT',
63+
:permissions => ['SELECT'],
6464
:database => 'loggingDb',
6565
:user => 'loggingUser',
6666

@@ -80,16 +80,16 @@
8080
context 'successfully' do
8181
include_context 'manifests' do
8282
let(:title) { 'myTitle' }
83-
let(:sqlserver_tsql_title) { 'user-permissions-MSSQLSERVER-loggingDb-loggingUser-SELECT' }
83+
let(:sqlserver_tsql_title) { 'user-permissions-MSSQLSERVER-loggingDb-loggingUser-GRANT' }
8484
let(:params) { {
8585
:user => 'loggingUser',
86-
:permission => 'SELECT',
86+
:permissions => ['SELECT'],
8787
:database => 'loggingDb',
8888
} }
8989
end
9090
%w(revoke grant deny).each do |state|
9191
context "state => '#{state}'" do
92-
let(:sqlserver_tsql_title) { 'user-permissions-MSSQLSERVER-loggingDb-loggingUser-SELECT' }
92+
let(:sqlserver_tsql_title) { "user-permissions-MSSQLSERVER-loggingDb-loggingUser-#{state.upcase}" }
9393
let(:should_contain_command) { ["#{state.upcase} SELECT TO [loggingUser];", 'USE [loggingDb];'] }
9494
describe "lowercase #{state}" do
9595
let(:additional_params) { {:state => state} }
@@ -106,15 +106,15 @@
106106
context 'permission' do
107107
describe 'upper limit' do
108108
permission =random_string_of_size(128, false)
109-
let(:additional_params) { {:permission => permission} }
110-
let(:sqlserver_tsql_title) { "user-permissions-MSSQLSERVER-loggingDb-loggingUser-#{permission.upcase}" }
109+
let(:additional_params) { {:permissions => [permission]} }
110+
let(:sqlserver_tsql_title) { "user-permissions-MSSQLSERVER-loggingDb-loggingUser-GRANT" }
111111
let(:should_contain_command) { ['USE [loggingDb];'] }
112112
it_behaves_like 'sqlserver_tsql command'
113113
end
114114
describe 'alter' do
115-
let(:additional_params) { {:permission => 'ALTER'} }
115+
let(:additional_params) { {:permissions => ['ALTER']} }
116116
let(:should_contain_command) { ['USE [loggingDb];', 'GRANT ALTER TO [loggingUser];'] }
117-
let(:sqlserver_tsql_title) { 'user-permissions-MSSQLSERVER-loggingDb-loggingUser-ALTER' }
117+
let(:sqlserver_tsql_title) { 'user-permissions-MSSQLSERVER-loggingDb-loggingUser-GRANT' }
118118
it_behaves_like 'sqlserver_tsql command'
119119
end
120120
end
@@ -131,6 +131,7 @@
131131

132132
context 'with_grant_option =>' do
133133
describe 'true' do
134+
let(:sqlserver_tsql_title) { 'user-permissions-MSSQLSERVER-loggingDb-loggingUser-GRANT-WITH_GRANT_OPTION' }
134135
let(:additional_params) { {:with_grant_option => true} }
135136
let(:should_contain_command) { [
136137
"IF @perm_state != 'GRANT_WITH_GRANT_OPTION'",
@@ -150,7 +151,6 @@
150151
'REVOKE GRANT OPTION FOR SELECT TO [loggingUser] CASCADE;',
151152
"IF 'GRANT_WITH_GRANT_OPTION' = ISNULL(",
152153
] }
153-
154154
let(:should_contain_onlyif) { ["IF @perm_state != 'GRANT'",] }
155155
it_behaves_like 'sqlserver_tsql command'
156156
it_behaves_like 'sqlserver_tsql onlyif'
@@ -161,21 +161,22 @@
161161
context 'command syntax' do
162162
include_context 'manifests' do
163163
let(:title) { 'myTitle' }
164-
let(:sqlserver_tsql_title) { 'user-permissions-MSSQLSERVER-loggingDb-loggingUser-SELECT' }
164+
let(:sqlserver_tsql_title) { 'user-permissions-MSSQLSERVER-loggingDb-loggingUser-GRANT' }
165165
let(:params) { {
166166
:user => 'loggingUser',
167-
:permission => 'SELECT',
167+
:permissions => ['SELECT'],
168168
:database => 'loggingDb',
169169
} }
170170
describe '' do
171171
let(:should_contain_command) { [
172172
'USE [loggingDb];',
173173
'GRANT SELECT TO [loggingUser];',
174-
/DECLARE @perm_state varchar\(250\)/,
174+
/DECLARE @perm_state varchar\(250\), @error_msg varchar\(250\)/,
175+
/SET @permission = 'SELECT'/,
175176
/SET @perm_state = ISNULL\(\n\s+\(SELECT perm.state_desc FROM sys\.database_principals princ\n\s+JOIN sys\./,
176177
/JOIN sys\.database_permissions perm ON perm\.grantee_principal_id = princ.principal_id\n\s+WHERE/,
177-
/WHERE princ\.type in \('U','S','G'\) AND name = 'loggingUser' AND permission_name = 'SELECT'\),\n\s+'REVOKE'\)\s+;/,
178-
/DECLARE @error_msg varchar\(250\);\nSET @error_msg = 'EXPECTED user \[loggingUser\] to have permission \[SELECT\] with GRANT but got ' \+ @perm_state;/,
178+
/WHERE princ\.type in \('U','S','G'\) AND name = 'loggingUser' AND permission_name = @permission\),\n\s+'REVOKE'\)\s+;/,
179+
/SET @error_msg = 'EXPECTED user \[loggingUser\] to have permission \[' \+ @permission \+ '\] with GRANT but got ' \+ @perm_state;/,
179180
/IF @perm_state != 'GRANT'\n\s+THROW 51000, @error_msg, 10/
180181
] }
181182
it_behaves_like 'sqlserver_tsql command'
+10-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
1+
USE [<%= @database %>];
2+
DECLARE @perm_state varchar(250), @error_msg varchar(250), @permission varchar(250);
3+
<% @permissions.each do |permission|
4+
permission.upcase!
5+
%>
6+
SET @permission = '<%= permission %>'
17
BEGIN
2-
USE [<%= @database %>];
38
<% if @with_grant_option == false %>
49
IF 'GRANT_WITH_GRANT_OPTION' = <%= scope.function_template(['sqlserver/snippets/user/permission/get_perm_state.sql.erb']) %>
5-
REVOKE GRANT OPTION FOR <%= @_permission %> TO [<%= @user %>] CASCADE;
10+
REVOKE GRANT OPTION FOR <%= permission %> TO [<%= @user %>] CASCADE;
611
<% end %>
7-
<%= @_state %> <%= @_permission %> TO [<%= @user %>]<% if @with_grant_option == true %> WITH GRANT OPTION<% end %>;
12+
<%= @_state %> <%= permission %> TO [<%= @user %>]<% if @with_grant_option == true %> WITH GRANT OPTION<% end %>;
813
END
914
BEGIN
10-
<%= scope.function_template(['sqlserver/query/user/permission_exists.sql.erb']) %>
15+
<%= scope.function_template(['sqlserver/snippets/user/permission/exists.sql.erb']) %>
1116
END
17+
<% end %>
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
USE [<%= @database %>];
2-
DECLARE @perm_state varchar(250);
3-
SET @perm_state = <%= scope.function_template(['sqlserver/snippets/user/permission/get_perm_state.sql.erb']) %>;
4-
DECLARE @error_msg varchar(250);
5-
SET @error_msg = 'EXPECTED user [<%= @user %>] to have permission [<%= @_permission %>] with <%= @_state %> but got ' + @perm_state;
62

7-
IF @perm_state != '<% if @with_grant_option == true %>GRANT_WITH_GRANT_OPTION<% else %><%= @_state %><% end %>'
8-
THROW 51000, @error_msg, 10
3+
DECLARE @perm_state varchar(250), @error_msg varchar(250), @permission varchar(250);
4+
<% @permissions.each do |permission|
5+
permission.upcase! %>
6+
SET @permission = '<%= permission %>'
7+
<%= scope.function_template(['sqlserver/snippets/user/permission/exists.sql.erb']) %>
8+
<% end %>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
SET @perm_state = <%= scope.function_template(['sqlserver/snippets/user/permission/get_perm_state.sql.erb']) %>;
2+
SET @error_msg = 'EXPECTED user [<%= @user %>] to have permission [' + @permission + '] with <%= @_state %> but got ' + @perm_state;
3+
IF @perm_state != '<% if @with_grant_option == true %>GRANT_WITH_GRANT_OPTION<% else %><%= @_state %><% end %>'
4+
THROW 51000, @error_msg, 10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
ISNULL(
22
(SELECT perm.state_desc FROM sys.database_principals princ
33
JOIN sys.database_permissions perm ON perm.grantee_principal_id = princ.principal_id
4-
WHERE princ.type in ('U','S','G') AND name = '<%= @user %>' AND permission_name = '<%= @_permission %>'),
4+
WHERE princ.type in ('U','S','G') AND name = '<%= @user %>' AND permission_name = @permission),
55
'REVOKE')

0 commit comments

Comments
 (0)