Skip to content

Commit 4010ba2

Browse files
author
Travis Fields
committed
FM-2298 - User - Add permissions hash to allow user to pass all permissions in one define
1 parent 7130984 commit 4010ba2

File tree

4 files changed

+138
-25
lines changed

4 files changed

+138
-25
lines changed

manifests/user.pp

+41
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@
3434
# [password]
3535
# The password for the user, can only be used when the database is a contained database.
3636
#
37+
# [permissions]
38+
# A hash of permissions that should be managed for the user. Valid keys are 'GRANT', 'GRANT_WITH_OPTION', 'DENY' or 'REVOKE'. Valid values must be an array of Strings i.e. {'GRANT' => ['SELECT', 'INSERT'] }
39+
#
3740
##
3841
define sqlserver::user (
3942
$database,
@@ -43,6 +46,7 @@
4346
$instance = 'MSSQLSERVER',
4447
$login = undef,
4548
$password = undef,
49+
$permissions = { },
4650
)
4751
{
4852
sqlserver_validate_instance_name($instance)
@@ -69,4 +73,41 @@
6973
require => Sqlserver::Config[$instance]
7074
}
7175

76+
if $ensure == present {
77+
validate_hash($permissions)
78+
$_upermissions = sqlserver_upcase($permissions)
79+
sqlserver_validate_hash_uniq_values($_upermissions, "Duplicate permissions found for sqlserver::user[${title}]")
80+
81+
Sqlserver::User::Permissions{
82+
user => $user,
83+
database => $database,
84+
instance => $instance,
85+
require => Sqlserver_tsql["user-${instance}-${database}-${user}"]
86+
}
87+
if has_key($_upermissions, 'GRANT') and is_array($_upermissions['GRANT']) {
88+
sqlserver::user::permissions{ "Sqlserver::User[${title}]-GRANT-${user}":
89+
state => 'GRANT',
90+
permissions => $_upermissions['GRANT'],
91+
}
92+
}
93+
if has_key($_upermissions, 'DENY') and is_array($_upermissions['DENY']) {
94+
sqlserver::user::permissions{ "Sqlserver::User[${title}]-DENY-${user}":
95+
state => 'DENY',
96+
permissions => $_upermissions['DENY'],
97+
}
98+
}
99+
if has_key($_upermissions, 'REVOKE') and is_array($_upermissions['REVOKE']) {
100+
sqlserver::user::permissions{ "Sqlserver::User[${title}]-REVOKE-${user}":
101+
state => 'REVOKE',
102+
permissions => $_upermissions['REVOKE'],
103+
}
104+
}
105+
if has_key($_upermissions, 'GRANT_WITH_OPTION') and is_array($_upermissions['GRANT_WITH_OPTION']) {
106+
sqlserver::user::permissions{ "Sqlserver::User[${title}]-GRANT-WITH_GRANT_OPTION-${user}":
107+
state => 'GRANT',
108+
with_grant_option => true,
109+
permissions => $_upermissions['GRANT_WITH_OPTION'],
110+
}
111+
}
112+
}
72113
}

manifests/user/permission.pp renamed to manifests/user/permissions.pp

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
##
2-
# == Define Resource Type: sqlserver::user::permission#
2+
# == Define Resource Type: sqlserver::user::permissions
33
#
44
# === Requirement/Dependencies:
55
#
@@ -26,7 +26,7 @@
2626
# The name of the instance where the user and database exists. Defaults to 'MSSQLSERVER'
2727
#
2828
##
29-
define sqlserver::user::permission (
29+
define sqlserver::user::permissions (
3030
$user,
3131
$database,
3232
$permissions,

spec/defines/user/permission_spec.rb renamed to spec/defines/user/permissions_spec.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
require 'spec_helper'
22
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'manifest_shared_examples.rb'))
33

4-
describe 'sqlserver::user::permission' do
4+
describe 'sqlserver::user::permissions' do
55
let(:facts) { {:osfamily => 'windows'} }
66
context 'validation errors' do
77
include_context 'manifests' do
@@ -15,7 +15,7 @@
1515
} }
1616
let(:raise_error_check) { 'User must be between 1 and 128 characters' }
1717
describe 'missing' do
18-
let(:raise_error_check) { 'Must pass user to Sqlserver::User::Permission[myTitle]' }
18+
let(:raise_error_check) { 'Must pass user to Sqlserver::User::Permissions[myTitle]' }
1919
it_behaves_like 'validation error'
2020
end
2121
describe 'empty' do

spec/defines/user_spec.rb

+93-21
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,18 @@
2727

2828
describe 'should contain correct sql syntax for check' do
2929
let(:should_contain_onlyif) { [
30-
"USE [myDatabase]",
31-
"\nIF NOT EXISTS(SELECT name FROM sys.database_principals WHERE type in ('U','S','G') AND name = 'loggingUser')\n",
32-
"THROW 51000, 'User [loggingUser] does not exist for database [myDatabase]', 10\n"
30+
"USE [myDatabase]",
31+
"\nIF NOT EXISTS(SELECT name FROM sys.database_principals WHERE type in ('U','S','G') AND name = 'loggingUser')\n",
32+
"THROW 51000, 'User [loggingUser] does not exist for database [myDatabase]', 10\n"
3333
] }
3434
let(:should_contain_command) { [
35-
"USE [myDatabase]",
36-
/CREATE USER \[loggingUser\]\n\s+FROM LOGIN \[mySysLogin\]/
35+
"USE [myDatabase]",
36+
/CREATE USER \[loggingUser\]\n\s+FROM LOGIN \[mySysLogin\]/
3737
] }
3838
let(:should_not_contain_command) { [
39-
'PASSWORD',
40-
'DEFAULT_SCHEMA',
41-
'WITH'
39+
'PASSWORD',
40+
'DEFAULT_SCHEMA',
41+
'WITH'
4242
] }
4343
let(:additional_params) { {:login => 'mySysLogin'} }
4444
it_should_behave_like 'sqlserver_tsql onlyif'
@@ -50,11 +50,11 @@
5050
password = 'Pupp3t1@'
5151
let(:additional_params) { {:password => password} }
5252
let(:should_contain_command) { [
53-
"USE [myDatabase];",
54-
/CREATE USER \[loggingUser\]\n\s+WITH PASSWORD = '#{password}'/
53+
"USE [myDatabase];",
54+
/CREATE USER \[loggingUser\]\n\s+WITH PASSWORD = '#{password}'/
5555
] }
5656
let(:should_not_contain_command) { [
57-
'DEFAULT_SCHEMA',
57+
'DEFAULT_SCHEMA',
5858
] }
5959
it_should_behave_like 'sqlserver_tsql onlyif'
6060
it_should_behave_like 'sqlserver_tsql command'
@@ -64,11 +64,11 @@
6464
describe 'when a default_schema is specified' do
6565
let(:additional_params) { {:default_schema => 'dbo'} }
6666
let(:should_contain_command) { [
67-
"USE [myDatabase]",
68-
/CREATE USER \[loggingUser\]\n\s+WITH\s+DEFAULT_SCHEMA = dbo/
67+
"USE [myDatabase]",
68+
/CREATE USER \[loggingUser\]\n\s+WITH\s+DEFAULT_SCHEMA = dbo/
6969
] }
7070
let(:should_not_contain_command) { [
71-
'PASSWORD',
71+
'PASSWORD',
7272
] }
7373
it_should_behave_like 'sqlserver_tsql command'
7474
it_should_behave_like 'sqlserver_tsql without_command'
@@ -78,8 +78,8 @@
7878
let(:additional_params) { {:user => 'myMachineName/myUser'} }
7979
let(:sqlserver_tsql_title) { 'user-MSSQLSERVER-myDatabase-myMachineName/myUser' }
8080
let(:should_contain_command) { [
81-
"USE [myDatabase];",
82-
'CREATE USER [myMachineName/myUser]'
81+
"USE [myDatabase];",
82+
'CREATE USER [myMachineName/myUser]'
8383
] }
8484
it_should_behave_like 'sqlserver_tsql command'
8585
end
@@ -88,8 +88,8 @@
8888
let(:additional_params) { {:user => 'myMachineName/myUser', :login => 'myMachineName/myUser'} }
8989
let(:sqlserver_tsql_title) { 'user-MSSQLSERVER-myDatabase-myMachineName/myUser' }
9090
let(:should_contain_command) { [
91-
"USE [myDatabase]",
92-
/CREATE USER \[myMachineName\/myUser\]\n\s+FROM LOGIN \[myMachineName\/myUser\]/
91+
"USE [myDatabase]",
92+
/CREATE USER \[myMachineName\/myUser\]\n\s+FROM LOGIN \[myMachineName\/myUser\]/
9393
] }
9494
it_should_behave_like 'sqlserver_tsql command'
9595
end
@@ -103,14 +103,86 @@
103103
describe 'when ensure => absent' do
104104
let(:additional_params) { {:ensure => 'absent'} }
105105
let(:sqlserver_contain_command) { [
106-
'USE [loggingDb];\nDROP [loggingUser]',
107-
"\nIF EXISTS(SELECT name FROM sys.database_principals WHERE name = 'loggingUser')\n THROW",
106+
'USE [loggingDb];\nDROP [loggingUser]',
107+
"\nIF EXISTS(SELECT name FROM sys.database_principals WHERE name = 'loggingUser')\n THROW",
108108
] }
109109
let(:sqlserver_contain_onlyif) { [
110-
"\nIF EXISTS(SELECT name FROM sys.database_principals WHERE type in ('U','S','G') AND name = 'loggingUser')\n",
110+
"\nIF EXISTS(SELECT name FROM sys.database_principals WHERE type in ('U','S','G') AND name = 'loggingUser')\n",
111111
] }
112112
it_should_behave_like 'sqlserver_tsql command'
113113
it_should_behave_like 'sqlserver_tsql onlyif'
114114
end
115+
context 'permissions =>' do
116+
let(:title) { 'myTitle' }
117+
let(:params) { {:user => 'loggingUser', :database => 'myDatabase'} }
118+
let(:permissions) { {} }
119+
shared_examples 'sqlserver_user_permissions exists' do |type|
120+
it {
121+
params[:permissions] = permissions
122+
type_title = (type =~ /GRANT_WITH_OPTION/i ? 'GRANT-WITH_GRANT_OPTION' : type.upcase)
123+
should contain_sqlserver__user__permissions("Sqlserver::User[#{title}]-#{type_title}-loggingUser").with(
124+
{
125+
'user' => 'loggingUser',
126+
'database' => 'myDatabase',
127+
'state' => type == 'GRANT_WITH_OPTION' ? 'GRANT' : type.upcase,
128+
'with_grant_option' => type == 'GRANT_WITH_OPTION',
129+
'permissions' => permissions[type],
130+
'require' => 'Sqlserver_tsql[user-MSSQLSERVER-myDatabase-loggingUser]'
131+
}
132+
)
133+
}
134+
end
135+
136+
shared_examples 'sqlserver_user_permissions absent' do |type|
137+
it {
138+
params[:permissions] = permissions
139+
type_title = (type =~ /GRANT_WITH_OPTION/i ? 'GRANT-WITH_GRANT_OPTION' : type.upcase)
140+
should_not contain_sqlserver__user__permissions("Sqlserver::User[#{title}]-#{type_title}-loggingUser")
141+
}
142+
end
143+
144+
describe 'GRANT permissions' do
145+
let(:permissions) { {'GRANT' => ['SELECT']} }
146+
it_behaves_like 'sqlserver_user_permissions exists', 'GRANT'
147+
it_behaves_like 'sqlserver_user_permissions absent', 'DENY'
148+
it_behaves_like 'sqlserver_user_permissions absent', 'REVOKE'
149+
it_behaves_like 'sqlserver_user_permissions absent', 'GRANT_WITH_OPTION'
150+
end
151+
152+
describe 'GRANT DENY' do
153+
let(:permissions) { {'GRANT' => ['CONNECT SQL'], 'DENY' => ['INSERT']} }
154+
it_behaves_like 'sqlserver_user_permissions exists', 'GRANT'
155+
it_behaves_like 'sqlserver_user_permissions exists', 'DENY'
156+
it_behaves_like 'sqlserver_user_permissions absent', 'REVOKE'
157+
it_behaves_like 'sqlserver_user_permissions absent', 'GRANT_WITH_OPTION'
158+
end
115159

160+
describe 'GRANT_WITH_OPTION' do
161+
let(:permissions) { {'GRANT_WITH_OPTION' => ['CONNECT SQL']} }
162+
it_behaves_like 'sqlserver_user_permissions exists', 'GRANT_WITH_OPTION'
163+
end
164+
165+
describe 'REVOKE' do
166+
let(:permissions) { {'revoke' => ['CREATE ANY DATABASE']} }
167+
it_behaves_like 'sqlserver_user_permissions exists', 'revoke'
168+
it_behaves_like 'sqlserver_user_permissions absent', 'GRANT'
169+
it_behaves_like 'sqlserver_user_permissions absent', 'DENY'
170+
it_behaves_like 'sqlserver_user_permissions absent', 'GRANT_WITH_OPTION'
171+
end
172+
173+
describe 'empty' do
174+
%w(GRANT DENY REVOKE GRANT-WITH_GRANT_OPTION).each do |type|
175+
it_behaves_like 'sqlserver_user_permissions absent', type
176+
end
177+
end
178+
179+
describe 'duplicate permissions' do
180+
let(:additional_params) { {
181+
:permissions => {'GRANT' => ['CONNECT SQL'], 'REVOKE' => ['CONNECT SQL']}
182+
} }
183+
let(:raise_error_check) { "Duplicate permissions found for sqlserver::user[#{title}" }
184+
let(:raise_error_check) { "Duplicate permissions found for sqlserver::user[#{title}" }
185+
it_behaves_like 'validation error'
186+
end
187+
end
116188
end

0 commit comments

Comments
 (0)