Skip to content

Commit 969d33b

Browse files
committed
Support schema privileges in default_privileges
1 parent 80d95ff commit 969d33b

File tree

3 files changed

+200
-1
lines changed

3 files changed

+200
-1
lines changed

manifests/server/default_privileges.pp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
/(?i:^ROUTINES$)/,
2222
/(?i:^SEQUENCES$)/,
2323
/(?i:^TABLES$)/,
24-
/(?i:^TYPES$)/
24+
/(?i:^TYPES$)/,
25+
/(?i:^SCHEMAS$)/
2526
] $object_type,
2627
String $schema = 'public',
2728
String $psql_db = $postgresql::server::default_database,
@@ -129,6 +130,21 @@
129130
}
130131
$_check_type = 'T'
131132
}
133+
'SCHEMAS': {
134+
if (versioncmp($version, '10.0') == -1) {
135+
fail 'Default_privileges on schemas is only supported on PostgreSQL >= 10.0'
136+
}
137+
if $schema != '' {
138+
fail('Cannot alter default schema permissions within a schema')
139+
}
140+
case $_privilege {
141+
/^ALL$/: { $_check_privilege = 'UC' }
142+
/^USAGE$/: { $_check_privilege = 'U' }
143+
/^CREATE$/: { $_check_privilege = 'C' }
144+
default: { fail('Illegal value for $privilege parameter') }
145+
}
146+
$_check_type = 'n'
147+
}
132148
default: {
133149
fail("Missing privilege validation for object type ${_object_type}")
134150
}

spec/acceptance/server/default_privileges_spec.rb

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,67 @@ class { 'postgresql::server': }
6868
MANIFEST
6969
end
7070

71+
let(:schema_check_command) do
72+
"SELECT * FROM pg_default_acl WHERE '#{user}=UC' = ANY (defaclacl) AND defaclnamespace = 0 and defaclobjtype = 'n';"
73+
end
74+
75+
let(:pp_schema) do
76+
<<-MANIFEST.unindent
77+
$db = #{db}
78+
$user = #{user}
79+
$group = #{group}
80+
$password = #{password}
81+
82+
class { 'postgresql::server': }
83+
84+
postgresql::server::role { $user:
85+
password_hash => postgresql::postgresql_password($user, $password),
86+
}
87+
88+
postgresql::server::database { $db:
89+
require => Postgresql::Server::Role[$user],
90+
}
91+
92+
# Set default privileges on tables
93+
postgresql::server::default_privileges { "alter default privileges grant all on tables to ${user}":
94+
db => $db,
95+
role => $user,
96+
privilege => 'ALL',
97+
object_type => 'SCHEMAS',
98+
schema => '',
99+
require => Postgresql::Server::Database[$db],
100+
}
101+
MANIFEST
102+
end
103+
let(:pp_schema_revoke) do
104+
<<-MANIFEST
105+
$db = #{db}
106+
$user = #{user}
107+
$group = #{group}
108+
$password = #{password}
109+
110+
class { 'postgresql::server': }
111+
112+
postgresql::server::role { $user:
113+
password_hash => postgresql::postgresql_password($user, $password),
114+
}
115+
postgresql::server::database { $db:
116+
require => Postgresql::Server::Role[$user],
117+
}
118+
119+
# Removes default privileges on tables
120+
postgresql::server::default_privileges { "alter default privileges revoke all on tables for ${user}":
121+
db => $db,
122+
role => $user,
123+
privilege => 'ALL',
124+
object_type => 'SCHEMAS',
125+
schema => '',
126+
ensure => 'absent',
127+
require => Postgresql::Server::Database[$db],
128+
}
129+
MANIFEST
130+
end
131+
71132
let(:all_schemas_check_command) do
72133
"SELECT * FROM pg_default_acl a WHERE '#{user}=arwdDxt' = ANY (defaclacl) AND defaclnamespace = 0 and defaclobjtype = 'r';"
73134
end
@@ -152,6 +213,29 @@ class { 'postgresql::server': }
152213
end
153214
end
154215

216+
it 'grants default privileges to an user on schemas' do
217+
if Gem::Version.new(postgresql_version) >= Gem::Version.new('10.0')
218+
idempotent_apply(pp_schema)
219+
220+
psql("--command=\"SET client_min_messages = 'error';#{schema_check_command}\" --db=#{db}") do |r|
221+
expect(r.stdout).to match(%r{\(1 row\)})
222+
expect(r.stderr).to eq('')
223+
end
224+
end
225+
end
226+
227+
it 'revokes default privileges for an user on schemas' do
228+
if Gem::Version.new(postgresql_version) >= Gem::Version.new('10.0')
229+
apply_manifest(pp_schema, catch_failures: true)
230+
apply_manifest(pp_schema_revoke, expect_changes: true)
231+
232+
psql("--command=\"SET client_min_messages = 'error';#{schema_check_command}\" --db=#{db}") do |r|
233+
expect(r.stdout).to match(%r{\(0 rows\)})
234+
expect(r.stderr).to eq('')
235+
end
236+
end
237+
end
238+
155239
it 'grants default privileges on all schemas to a user' do
156240
if Gem::Version.new(postgresql_version) >= Gem::Version.new('9.6')
157241
idempotent_apply(pp_unset_schema)

spec/unit/defines/server/default_privileges_spec.rb

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,105 @@
133133

134134
it { is_expected.to compile.and_raise_error(%r{Illegal value for \$privilege parameter}) }
135135
end
136+
137+
context 'schemas on postgres < 10.0' do
138+
let(:facts) do
139+
{
140+
os: {
141+
family: 'Debian',
142+
name: 'Debian',
143+
release: { 'full' => '9.0', 'major' => '9' },
144+
},
145+
kernel: 'Linux',
146+
id: 'root',
147+
path: '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin',
148+
}
149+
end
150+
151+
let :params do
152+
{
153+
db: 'test',
154+
role: 'test',
155+
privilege: 'all',
156+
object_type: 'schemas',
157+
schema: '',
158+
}
159+
end
160+
161+
let :pre_condition do
162+
"class {'postgresql::server':}"
163+
end
164+
165+
it { is_expected.to compile.and_raise_error(%r{Default_privileges on schemas is only supported on PostgreSQL >= 10.0}m) }
166+
end
167+
168+
context 'schemas on postgres >= 10.0' do
169+
let :facts do
170+
{
171+
os: {
172+
family: 'Debian',
173+
name: 'Debian',
174+
release: { 'full' => '10.0', 'major' => '10' },
175+
},
176+
kernel: 'Linux',
177+
id: 'root',
178+
path: '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin',
179+
}
180+
end
181+
182+
let :params do
183+
{
184+
db: 'test',
185+
role: 'test',
186+
privilege: 'all',
187+
object_type: 'schemas',
188+
schema: '',
189+
}
190+
end
191+
192+
let :pre_condition do
193+
"class {'postgresql::server':}"
194+
end
195+
196+
it { is_expected.to compile.with_all_deps }
197+
it { is_expected.to contain_postgresql__server__default_privileges('test') }
198+
it do
199+
is_expected.to contain_postgresql_psql('default_privileges:test')
200+
.with_command('ALTER DEFAULT PRIVILEGES GRANT ALL ON SCHEMAS TO "test"')
201+
.with_unless("SELECT 1 WHERE EXISTS (SELECT * FROM pg_default_acl AS da LEFT JOIN pg_namespace AS n ON da.defaclnamespace = n.oid WHERE 'test=UC' = ANY (defaclacl) AND nspname IS NULL and defaclobjtype = 'n')")
202+
end
203+
end
204+
205+
context 'nested schemas are invalid' do
206+
let :facts do
207+
{
208+
os: {
209+
family: 'Debian',
210+
name: 'Debian',
211+
release: { 'full' => '10.0', 'major' => '10' },
212+
},
213+
kernel: 'Linux',
214+
id: 'root',
215+
path: '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin',
216+
}
217+
end
218+
219+
let :params do
220+
{
221+
db: 'test',
222+
role: 'test',
223+
privilege: 'all',
224+
object_type: 'schemas',
225+
schema: 'public',
226+
}
227+
end
228+
229+
let :pre_condition do
230+
"class {'postgresql::server':}"
231+
end
232+
233+
it { is_expected.to compile.and_raise_error(%r{Cannot alter default schema permissions within a schema}) }
234+
end
136235
end
137236

138237
context 'with specific db connection settings - default port' do

0 commit comments

Comments
 (0)