Skip to content

Commit 361e448

Browse files
committed
Support schema privileges in default_privileges
1 parent 16166d3 commit 361e448

File tree

3 files changed

+212
-1
lines changed

3 files changed

+212
-1
lines changed

manifests/server/default_privileges.pp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
/(?i:^ROUTINES$)/,
2424
/(?i:^SEQUENCES$)/,
2525
/(?i:^TABLES$)/,
26-
/(?i:^TYPES$)/
26+
/(?i:^TYPES$)/,
27+
/(?i:^SCHEMAS$)/
2728
] $object_type,
2829
String $schema = 'public',
2930
String $psql_db = $postgresql::server::default_database,
@@ -140,6 +141,21 @@
140141
}
141142
$_check_type = 'T'
142143
}
144+
'SCHEMAS': {
145+
if (versioncmp($version, '10') == -1) {
146+
fail 'Default_privileges on schemas is only supported on PostgreSQL >= 10.0'
147+
}
148+
if $schema != '' {
149+
fail('Cannot alter default schema permissions within a schema')
150+
}
151+
case $_privilege {
152+
/^ALL$/: { $_check_privilege = 'UC' }
153+
/^USAGE$/: { $_check_privilege = 'U' }
154+
/^CREATE$/: { $_check_privilege = 'C' }
155+
default: { fail('Illegal value for $privilege parameter') }
156+
}
157+
$_check_type = 'n'
158+
}
143159
default: {
144160
fail("Missing privilege validation for object type ${_object_type}")
145161
}

spec/acceptance/server/default_privileges_spec.rb

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,67 @@ class { 'postgresql::server': }
167167
MANIFEST
168168
end
169169

170+
let(:schema_check_command) do
171+
"SELECT * FROM pg_default_acl WHERE '#{user}=UC' = ANY (defaclacl) AND defaclnamespace = 0 and defaclobjtype = 'n';"
172+
end
173+
174+
let(:pp_schema) do
175+
<<-MANIFEST.unindent
176+
$db = #{db}
177+
$user = #{user}
178+
$group = #{group}
179+
$password = #{password}
180+
181+
class { 'postgresql::server': }
182+
183+
postgresql::server::role { $user:
184+
password_hash => postgresql::postgresql_password($user, $password),
185+
}
186+
187+
postgresql::server::database { $db:
188+
require => Postgresql::Server::Role[$user],
189+
}
190+
191+
# Set default privileges on tables
192+
postgresql::server::default_privileges { "alter default privileges grant all on tables to ${user}":
193+
db => $db,
194+
role => $user,
195+
privilege => 'ALL',
196+
object_type => 'SCHEMAS',
197+
schema => '',
198+
require => Postgresql::Server::Database[$db],
199+
}
200+
MANIFEST
201+
end
202+
let(:pp_schema_revoke) do
203+
<<-MANIFEST
204+
$db = #{db}
205+
$user = #{user}
206+
$group = #{group}
207+
$password = #{password}
208+
209+
class { 'postgresql::server': }
210+
211+
postgresql::server::role { $user:
212+
password_hash => postgresql::postgresql_password($user, $password),
213+
}
214+
postgresql::server::database { $db:
215+
require => Postgresql::Server::Role[$user],
216+
}
217+
218+
# Removes default privileges on tables
219+
postgresql::server::default_privileges { "alter default privileges revoke all on tables for ${user}":
220+
db => $db,
221+
role => $user,
222+
privilege => 'ALL',
223+
object_type => 'SCHEMAS',
224+
schema => '',
225+
ensure => 'absent',
226+
require => Postgresql::Server::Database[$db],
227+
}
228+
MANIFEST
229+
end
230+
170231
let(:all_schemas_check_command) do
171232
"SELECT * FROM pg_default_acl a WHERE '#{user}=arwdDxt' = ANY (defaclacl) AND defaclnamespace = 0 and defaclobjtype = 'r';"
172233
end
@@ -274,6 +335,29 @@ class { 'postgresql::server': }
274335
end
275336
end
276337

338+
it 'grants default privileges to an user on schemas' do
339+
if Gem::Version.new(postgresql_version) >= Gem::Version.new('10.0')
340+
idempotent_apply(pp_schema)
341+
342+
psql("--command=\"SET client_min_messages = 'error';#{schema_check_command}\" --db=#{db}") do |r|
343+
expect(r.stdout).to match(%r{\(1 row\)})
344+
expect(r.stderr).to eq('')
345+
end
346+
end
347+
end
348+
349+
it 'revokes default privileges for an user on schemas' do
350+
if Gem::Version.new(postgresql_version) >= Gem::Version.new('10.0')
351+
apply_manifest(pp_schema, catch_failures: true)
352+
apply_manifest(pp_schema_revoke, expect_changes: true)
353+
354+
psql("--command=\"SET client_min_messages = 'error';#{schema_check_command}\" --db=#{db}") do |r|
355+
expect(r.stdout).to match(%r{\(0 rows\)})
356+
expect(r.stderr).to eq('')
357+
end
358+
end
359+
end
360+
277361
it 'grants default privileges on all schemas to a user' do
278362
if Gem::Version.new(postgresql_version) >= Gem::Version.new('9.6')
279363
idempotent_apply(pp_unset_schema)

spec/unit/defines/server/default_privileges_spec.rb

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,117 @@
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+
<<-MANIFEST
194+
class { 'postgresql::globals':
195+
version => '10.0',
196+
}
197+
class { 'postgresql::server': }
198+
MANIFEST
199+
end
200+
201+
it { is_expected.to compile.with_all_deps }
202+
it { is_expected.to contain_postgresql__server__default_privileges('test') }
203+
it do
204+
# rubocop:disable Layout/LineLength
205+
is_expected.to contain_postgresql_psql('default_privileges:test')
206+
.with_command('ALTER DEFAULT PRIVILEGES GRANT ALL ON SCHEMAS TO "test"')
207+
.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')")
208+
# rubocop:enable Layout/LineLength
209+
end
210+
end
211+
212+
context 'nested schemas are invalid' do
213+
let :facts do
214+
{
215+
os: {
216+
family: 'Debian',
217+
name: 'Debian',
218+
release: { 'full' => '10.0', 'major' => '10' },
219+
},
220+
kernel: 'Linux',
221+
id: 'root',
222+
path: '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin',
223+
}
224+
end
225+
226+
let :params do
227+
{
228+
db: 'test',
229+
role: 'test',
230+
privilege: 'all',
231+
object_type: 'schemas',
232+
schema: 'public',
233+
}
234+
end
235+
236+
let :pre_condition do
237+
<<-MANIFEST
238+
class { 'postgresql::globals':
239+
version => '10.0',
240+
}
241+
class { 'postgresql::server': }
242+
MANIFEST
243+
end
244+
245+
it { is_expected.to compile.and_raise_error(%r{Cannot alter default schema permissions within a schema}) }
246+
end
136247
end
137248

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

0 commit comments

Comments
 (0)