Skip to content

Commit ac1b7b4

Browse files
authored
Merge pull request #2460 from puppetlabs/CAT-1417-nested-require-for-authz-mod
(CAT-1417) Nested require support for authz_core mod
2 parents ab45655 + c9cc80d commit ac1b7b4

File tree

10 files changed

+500
-180
lines changed

10 files changed

+500
-180
lines changed

.rubocop_todo.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,3 +156,8 @@ RSpec/RepeatedExampleGroupDescription:
156156
RSpec/StubbedMock:
157157
Exclude:
158158
- 'spec/util/apache_mod_platform_compatibility_spec.rb'
159+
160+
# Offense count: 1
161+
Metrics/BlockLength:
162+
Exclude:
163+
- 'lib/puppet/functions/apache/authz_core_config.rb'

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
[`apache::mod::auth_mellon`]: https://forge.puppet.com/modules/puppetlabs/apache/reference#apachemodauth_mellon
4040
[`apache::mod::authn_dbd`]: https://forge.puppet.com/modules/puppetlabs/apache/reference#apachemodauthn_dbd
4141
[`apache::mod::authnz_ldap`]: https://forge.puppet.com/modules/puppetlabs/apache/reference#apachemodauthnz_ldap
42+
[`apache::mod::authz_core`]: https://forge.puppet.com/modules/puppetlabs/apache/reference#apachemodauthz_core
4243
[`apache::mod::cluster`]: https://forge.puppet.com/modules/puppetlabs/apache/reference#apachemodcluster
4344
[`apache::mod::data]: https://forge.puppet.com/modules/puppetlabs/apache/reference#apachemoddata
4445
[`apache::mod::disk_cache`]: https://forge.puppet.com/modules/puppetlabs/apache/reference#apachemoddisk_cache
@@ -157,6 +158,7 @@
157158
[`mod_authnz_external`]: https://github.com/phokz/mod-auth-external
158159
[`mod_auth_dbd`]: http://httpd.apache.org/docs/current/mod/mod_authn_dbd.html
159160
[`mod_auth_mellon`]: https://github.com/UNINETT/mod_auth_mellon
161+
[`mod_authz_core`]: https://httpd.apache.org/docs/current/mod/mod_authz_core.html
160162
[`mod_dbd`]: http://httpd.apache.org/docs/current/mod/mod_dbd.html
161163
[`mod_disk_cache`]: https://httpd.apache.org/docs/2.2/mod/mod_disk_cache.html
162164
[`mod_dumpio`]: https://httpd.apache.org/docs/2.4/mod/mod_dumpio.html

REFERENCE.md

Lines changed: 268 additions & 121 deletions
Large diffs are not rendered by default.
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# frozen_string_literal: true
2+
3+
# @summary
4+
# Function to generate the authz_core configuration directives.
5+
#
6+
Puppet::Functions.create_function(:'apache::authz_core_config') do
7+
# @param config
8+
# The input as JSON format.
9+
#
10+
# @return
11+
# Returns the authz_core config directives in array.
12+
#
13+
# @example
14+
#
15+
# arg = {
16+
# require_all => {
17+
# 'require_any' => {
18+
# 'require' => ['user superadmin'],
19+
# 'require_all' => {
20+
# 'require' => ['group admins'],
21+
# },
22+
# },
23+
# 'require_none' => {
24+
# 'require' => ['group temps']
25+
# }
26+
# }
27+
# }
28+
#
29+
# apache::bool2httpd(arg)
30+
# returns :
31+
# [
32+
# " <RequireAll>",
33+
# " <RequireAny>",
34+
# " Require user superadmin",
35+
# " <RequireAll>",
36+
# " Require group admins",
37+
# " Require ldap-group \"cn=Administrators,o=Airius\"",
38+
# " </RequireAll>",
39+
# " </RequireAny>",
40+
# " <RequireNone>",
41+
# " Require group temps",
42+
# " Require ldap-group \"cn=Temporary Employees,o=Airius\"",
43+
# " </RequireNone>",
44+
# " </RequireAll>"
45+
# ]
46+
#
47+
dispatch :authz_core_config do
48+
param 'Hash', :config
49+
return_type 'Array'
50+
end
51+
52+
private
53+
54+
def build_directive(value)
55+
value.split('_').map(&:capitalize).join
56+
end
57+
58+
def authz_core_config(config, count = 1)
59+
result_string = []
60+
config.map do |key, value|
61+
directive = build_directive(key)
62+
if value.is_a?(Hash)
63+
result_string << spacing("<#{directive}>", count)
64+
result_string << authz_core_config(value, count + 1)
65+
result_string << spacing("</#{directive}>", count)
66+
else
67+
value.map do |v|
68+
result_string << spacing("#{directive} #{v}", count)
69+
end
70+
end
71+
end
72+
result_string.flatten
73+
end
74+
75+
def spacing(string, count)
76+
(' ' * count) + string
77+
end
78+
end

manifests/default_mods.pp

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,7 @@
131131
include apache::mod::filter
132132

133133
# authz_core is needed for 'Require' directive
134-
::apache::mod { 'authz_core':
135-
id => 'authz_core_module',
136-
}
134+
include apache::mod::authz_core
137135

138136
# lots of stuff seems to break without access_compat
139137
::apache::mod { 'access_compat': }
@@ -145,17 +143,13 @@
145143
::apache::default_mods::load { $mods: }
146144

147145
# authz_core is needed for 'Require' directive
148-
::apache::mod { 'authz_core':
149-
id => 'authz_core_module',
150-
}
146+
include apache::mod::authz_core
151147

152148
# filter is needed by mod_deflate
153149
include apache::mod::filter
154150
} else {
155151
# authz_core is needed for 'Require' directive
156-
::apache::mod { 'authz_core':
157-
id => 'authz_core_module',
158-
}
152+
include apache::mod::authz_core
159153

160154
# filter is needed by mod_deflate
161155
include apache::mod::filter

manifests/mod/authz_core.pp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# @summary
2+
# Installs `mod_authz_core`.
3+
#
4+
# @see https://httpd.apache.org/docs/current/mod/mod_authz_core.html for additional documentation.
5+
#
6+
class apache::mod::authz_core {
7+
apache::mod { 'authz_core': }
8+
}

manifests/vhost.pp

Lines changed: 77 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1325,6 +1325,83 @@
13251325
# Any handlers you do not set in these hashes are considered `undefined` within Puppet and
13261326
# are not added to the virtual host, resulting in the module using their default values.
13271327
#
1328+
# The `directories` param can accepts the different authentication ways, including `gssapi`, `Basic (authz_core)`,
1329+
# and others.
1330+
#
1331+
# * `gssapi` - Specifies mod_auth_gssapi parameters for particular directories in a virtual host directory
1332+
# TODO: check, if this Documentation is obsolete
1333+
#
1334+
# ```puppet
1335+
# apache::vhost { 'sample.example.net':
1336+
# docroot => '/path/to/directory',
1337+
# directories => [
1338+
# { path => '/path/to/different/dir',
1339+
# gssapi => {
1340+
# acceptor_name => '{HOSTNAME}',
1341+
# allowed_mech => ['krb5', 'iakerb', 'ntlmssp'],
1342+
# authname => 'Kerberos 5',
1343+
# authtype => 'GSSAPI',
1344+
# basic_auth => true,
1345+
# basic_auth_mech => ['krb5', 'iakerb', 'ntlmssp'],
1346+
# basic_ticket_timeout => 300,
1347+
# connection_bound => true,
1348+
# cred_store => {
1349+
# ccache => ['/path/to/directory'],
1350+
# client_keytab => ['/path/to/example.keytab'],
1351+
# keytab => ['/path/to/example.keytab'],
1352+
# },
1353+
# deleg_ccache_dir => '/path/to/directory',
1354+
# deleg_ccache_env_var => 'KRB5CCNAME',
1355+
# deleg_ccache_perms => {
1356+
# mode => '0600',
1357+
# uid => 'example-user',
1358+
# gid => 'example-group',
1359+
# },
1360+
# deleg_ccache_unique => true,
1361+
# impersonate => true,
1362+
# local_name => true,
1363+
# name_attributes => 'json',
1364+
# negotiate_once => true,
1365+
# publish_errors => true,
1366+
# publish_mech => true,
1367+
# required_name_attributes => 'auth-indicators=high',
1368+
# session_key => 'file:/path/to/example.key',
1369+
# signal_persistent_auth => true,
1370+
# ssl_only => true,
1371+
# use_s4u2_proxy => true,
1372+
# use_sessions => true,
1373+
# }
1374+
# },
1375+
# ],
1376+
# }
1377+
# ```
1378+
#
1379+
# * `Basic` - Specifies mod_authz_core parameters for particular directories in a virtual host directory
1380+
# ```puppet
1381+
# apache::vhost { 'sample.example.net':
1382+
# docroot => '/path/to/directory',
1383+
# directories => [
1384+
# {
1385+
# path => '/path/to/different/dir',
1386+
# auth_type => 'Basic',
1387+
# authz_core => {
1388+
# require_all => {
1389+
# 'require_any' => {
1390+
# 'require' => ['user superadmin'],
1391+
# 'require_all' => {
1392+
# 'require' => ['group admins', 'ldap-group "cn=Administrators,o=Airius"'],
1393+
# },
1394+
# },
1395+
# 'require_none' => {
1396+
# 'require' => ['group temps', 'ldap-group "cn=Temporary Employees,o=Airius"']
1397+
# }
1398+
# }
1399+
# }
1400+
# },
1401+
# ],
1402+
# }
1403+
# ```
1404+
#
13281405
# @param custom_fragment
13291406
# Pass a string of custom configuration directives to be placed at the end of the directory
13301407
# configuration.
@@ -1405,56 +1482,6 @@
14051482
# }
14061483
# ```
14071484
#
1408-
# TODO: check, if this Documentation is obsolete
1409-
# lint:ignore:parameter_documentation
1410-
# @param gssapi
1411-
# lint:endignore
1412-
# Specfies mod_auth_gssapi parameters for particular directories in a virtual host directory
1413-
# ```puppet
1414-
# apache::vhost { 'sample.example.net':
1415-
# docroot => '/path/to/directory',
1416-
# directories => [
1417-
# { path => '/path/to/different/dir',
1418-
# gssapi => {
1419-
# acceptor_name => '{HOSTNAME}',
1420-
# allowed_mech => ['krb5', 'iakerb', 'ntlmssp'],
1421-
# authname => 'Kerberos 5',
1422-
# authtype => 'GSSAPI',
1423-
# basic_auth => true,
1424-
# basic_auth_mech => ['krb5', 'iakerb', 'ntlmssp'],
1425-
# basic_ticket_timeout => 300,
1426-
# connection_bound => true,
1427-
# cred_store => {
1428-
# ccache => ['/path/to/directory'],
1429-
# client_keytab => ['/path/to/example.keytab'],
1430-
# keytab => ['/path/to/example.keytab'],
1431-
# },
1432-
# deleg_ccache_dir => '/path/to/directory',
1433-
# deleg_ccache_env_var => 'KRB5CCNAME',
1434-
# deleg_ccache_perms => {
1435-
# mode => '0600',
1436-
# uid => 'example-user',
1437-
# gid => 'example-group',
1438-
# },
1439-
# deleg_ccache_unique => true,
1440-
# impersonate => true,
1441-
# local_name => true,
1442-
# name_attributes => 'json',
1443-
# negotiate_once => true,
1444-
# publish_errors => true,
1445-
# publish_mech => true,
1446-
# required_name_attributes => 'auth-indicators=high',
1447-
# session_key => 'file:/path/to/example.key',
1448-
# signal_persistent_auth => true,
1449-
# ssl_only => true,
1450-
# use_s4u2_proxy => true,
1451-
# use_sessions => true,
1452-
# }
1453-
# },
1454-
# ],
1455-
# }
1456-
# ```
1457-
#
14581485
# @param ssl
14591486
# Enables SSL for the virtual host. SSL virtual hosts only respond to HTTPS queries.
14601487
#
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# frozen_string_literal: true
2+
3+
require 'spec_helper'
4+
5+
describe 'apache::authz_core_config' do
6+
let(:input1) do
7+
{
8+
'Require' => [
9+
'user foo',
10+
'user bar',
11+
]
12+
}
13+
end
14+
15+
let(:input2) do
16+
{
17+
'require_all' => {
18+
'require_any' => {
19+
'require' => ['user superadmin'],
20+
'require_all' => {
21+
'require' => ['group admins', 'ldap-group "cn=Administrators,o=Airius"']
22+
}
23+
},
24+
'require_none' => {
25+
'require' => ['group temps', 'ldap-group "cn=Temporary Employees,o=Airius"']
26+
}
27+
}
28+
}
29+
end
30+
let(:output2) do
31+
[
32+
' <RequireAll>',
33+
' <RequireAny>',
34+
' Require user superadmin',
35+
' <RequireAll>',
36+
' Require group admins',
37+
' Require ldap-group "cn=Administrators,o=Airius"',
38+
' </RequireAll>',
39+
' </RequireAny>',
40+
' <RequireNone>',
41+
' Require group temps',
42+
' Require ldap-group "cn=Temporary Employees,o=Airius"',
43+
' </RequireNone>',
44+
' </RequireAll>',
45+
]
46+
end
47+
48+
it { is_expected.to run.with_params(nil).and_raise_error(StandardError) }
49+
it { is_expected.to run.with_params([]).and_raise_error(StandardError) }
50+
it { is_expected.to run.with_params({}).and_return([]) }
51+
it { is_expected.to run.with_params(input1).and_return([' Require user foo', ' Require user bar']) }
52+
it { is_expected.to run.with_params(input2).and_return(output2) }
53+
end

templates/vhost/_authz_core.epp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<% $authz_core_config.each |$line| { -%>
2+
<%= $line %>
3+
<%- } -%>

templates/vhost/_directories.erb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,9 @@
544544
<%- if directory['custom_fragment'] -%>
545545
<%= directory['custom_fragment'] %>
546546
<%- end -%>
547+
<%- if directory['authz_core'] -%>
548+
<%= scope.call_function('epp',["apache/vhost/_authz_core.epp", 'authz_core_config' => scope.call_function('apache::authz_core_config', directory['authz_core'])]) -%>
549+
<%- end -%>
547550
<%- if directory['gssapi'] -%>
548551
<%= scope.call_function('epp',["apache/vhost/_gssapi.epp", directory['gssapi']]) -%>
549552
<%- end -%>

0 commit comments

Comments
 (0)