Skip to content

Commit

Permalink
Add properties to keycloak_client_protocol_mapper (#300)
Browse files Browse the repository at this point in the history
* usermodel_client_role_mapping_client_id
* multivalued
Fixes #234
  • Loading branch information
treydock authored Jul 16, 2023
1 parent fe8f6a6 commit dc2360a
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 0 deletions.
16 changes: 16 additions & 0 deletions lib/puppet/provider/keycloak_client_protocol_mapper/kcadm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ def self.instances
protocol_mapper[:claim_name] = d['config']['claim.name']
protocol_mapper[:json_type_label] = d['config']['jsonType.label']
end
if protocol_mapper[:type] == 'oidc-usermodel-client-role-mapper'
protocol_mapper[:usermodel_client_role_mapping_client_id] = d['config']['usermodel.clientRoleMapping.clientId']
end
if protocol_mapper[:type] == 'oidc-group-membership-mapper'
protocol_mapper[:full_path] = d['config']['full.path']
end
Expand All @@ -71,6 +74,7 @@ def self.instances
if ['saml-role-list-mapper'].include?(protocol_mapper[:type]) || protocol_mapper[:type] =~ %r{script-.+}
protocol_mapper[:single] = d['config']['single'].to_s.to_sym
end
protocol_mapper[:multivalued] = d['config']['multivalued'].to_s.to_sym if d['config']['multivalued']
protocol_mappers << new(protocol_mapper)
end
end
Expand Down Expand Up @@ -112,6 +116,9 @@ def create
if resource[:type] == 'oidc-group-membership-mapper' && resource[:full_path]
data[:config][:'full.path'] = resource[:full_path]
end
if resource[:type] == 'oidc-usermodel-client-role-mapper' && resource[:usermodel_client_role_mapping_client_id]
data[:config][:'usermodel.clientRoleMapping.clientId'] = resource[:usermodel_client_role_mapping_client_id]
end
if (['saml-user-property-mapper'].include?(resource[:type]) || (resource[:protocol] == 'saml' && resource[:type] =~ %r{script-.+})) && resource[:friendly_name]
data[:config][:'friendly.name'] = resource[:friendly_name]
end
Expand All @@ -132,6 +139,9 @@ def create
if (['saml-role-list-mapper'].include?(resource[:type]) || (resource[:protocol] == 'saml' && resource[:type] =~ %r{script-.+})) && resource[:single]
data[:config][:single] = resource[:single].to_s
end
if resource[:multivalued]
data[:config][:multivalued] = resource[:multivalued].to_s
end

t = Tempfile.new('keycloak_protocol_mapper')
t.write(JSON.pretty_generate(data))
Expand Down Expand Up @@ -194,6 +204,9 @@ def flush
if resource[:type] == 'oidc-group-membership-mapper' && resource[:full_path]
config[:'full.path'] = resource[:full_path]
end
if resource[:type] == 'oidc-usermodel-client-role-mapper' && resource[:usermodel_client_role_mapping_client_id]
config[:'usermodel.clientRoleMapping.clientId'] = resource[:usermodel_client_role_mapping_client_id]
end
if (['saml-user-property-mapper'].include?(resource[:type]) || (resource[:protocol] == 'saml' && resource[:type] =~ %r{script-.+})) && resource[:friendly_name]
config[:'friendly.name'] = resource[:friendly_name]
end
Expand All @@ -214,6 +227,9 @@ def flush
if (['saml-role-list-mapper'].include?(resource[:type]) || (resource[:protocol] == 'saml' && resource[:type] =~ %r{script-.+})) && resource[:single]
config[:single] = resource[:single].to_s
end
if resource[:multivalued]
config[:multivalued] = resource[:multivalued].to_s
end
data[:config] = config unless config.empty?

t = Tempfile.new('keycloak_protocol_mapper')
Expand Down
12 changes: 12 additions & 0 deletions lib/puppet/type/keycloak_client_protocol_mapper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,10 @@
end
end

newproperty(:usermodel_client_role_mapping_client_id) do
desc 'usermodel.clientRoleMapping.clientId for `type` `oidc-usermodel-client-role-mapper`'
end

newproperty(:single, boolean: true) do
desc 'single. Default to `false` for `type` `saml-role-list-mapper`.'
newvalues(:true, :false)
Expand All @@ -199,6 +203,11 @@
end
end

newproperty(:multivalued, boolean: true) do
desc 'multivalued'
newvalues(:true, :false)
end

newproperty(:included_client_audience) do
desc 'included.client.audience Required for `type` of `oidc-audience-mapper`'
end
Expand Down Expand Up @@ -264,5 +273,8 @@ def self.title_patterns
if self[:type] == 'oidc-audience-mapper' && self[:included_client_audience].nil?
raise Puppet::Error, 'included_client_audience is required for oidc-audience-mapper'
end
if self[:usermodel_client_role_mapping_client_id] && self[:type] != 'oidc-usermodel-client-role-mapper'
raise Puppet::Error, 'usermodel_client_role_mapping_client_id is only valid for type=oidc-usermodel-client-role-mapper'
end
end
end
34 changes: 34 additions & 0 deletions spec/acceptance/7_client_protocol_mapper_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ class { 'keycloak': }
type => 'oidc-audience-mapper',
included_client_audience => 'foo',
}
keycloak_client_protocol_mapper { 'role mapper for test.foo.bar on test':
type => 'oidc-usermodel-client-role-mapper',
claim_name => 'permissions',
multivalued => true,
usermodel_client_role_mapping_client_id => 'test.foo.bar',
}
PUPPET_PP

apply_manifest(pp, catch_failures: true)
Expand Down Expand Up @@ -77,6 +83,17 @@ class { 'keycloak': }
expect(mapper['config']['included.client.audience']).to eq('foo')
end
end

it 'has created protocol mapper type=oidc-usermodel-client-role-mapper' do
on hosts, '/opt/keycloak/bin/kcadm-wrapper.sh get clients/test.foo.bar/protocol-mappers/models -r test' do
data = JSON.parse(stdout)
mapper = data.select { |d| d['name'] == 'role mapper' }[0]
expect(mapper['protocolMapper']).to eq('oidc-usermodel-client-role-mapper')
expect(mapper['config']['claim.name']).to eq('permissions')
expect(mapper['config']['multivalued']).to eq('true')
expect(mapper['config']['usermodel.clientRoleMapping.clientId']).to eq('test.foo.bar')
end
end
end

context 'when updates protocol_mapper' do
Expand Down Expand Up @@ -108,6 +125,12 @@ class { 'keycloak': }
included_client_audience => 'foo',
id_token_claim => false,
}
keycloak_client_protocol_mapper { 'role mapper for test.foo.bar on test':
type => 'oidc-usermodel-client-role-mapper',
claim_name => 'permissions',
multivalued => false,
usermodel_client_role_mapping_client_id => 'test.foo',
}
PUPPET_PP

apply_manifest(pp, catch_failures: true)
Expand Down Expand Up @@ -156,5 +179,16 @@ class { 'keycloak': }
expect(mapper['config']['included.client.audience']).to eq('foo')
end
end

it 'has updated protocol mapper type=oidc-usermodel-client-role-mapper' do
on hosts, '/opt/keycloak/bin/kcadm-wrapper.sh get clients/test.foo.bar/protocol-mappers/models -r test' do
data = JSON.parse(stdout)
mapper = data.select { |d| d['name'] == 'role mapper' }[0]
expect(mapper['protocolMapper']).to eq('oidc-usermodel-client-role-mapper')
expect(mapper['config']['claim.name']).to eq('permissions')
expect(mapper['config']['multivalued']).to eq('false')
expect(mapper['config']['usermodel.clientRoleMapping.clientId']).to eq('test.foo')
end
end
end
end
35 changes: 35 additions & 0 deletions spec/unit/puppet/type/keycloak_client_protocol_mapper_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,20 @@
}.to raise_error(%r{foo})
end

it 'accepts usermodel_client_role_mapping_client_id' do
config[:usermodel_client_role_mapping_client_id] = 'foo'
config[:type] = 'oidc-usermodel-client-role-mapper'
expect(resource[:usermodel_client_role_mapping_client_id]).to eq('foo')
end

it 'errors when usermodel_client_role_mapping_client_id used with wrong type' do
config[:usermodel_client_role_mapping_client_id] = 'foo'
config[:type] = 'saml-role-list-mapper'
expect {
resource
}.to raise_error(Puppet::Error)
end

it 'accepts value for single' do
config[:protocol] = 'saml'
config[:type] = 'saml-role-list-mapper'
Expand Down Expand Up @@ -335,6 +349,27 @@
}.to raise_error(%r{foo})
end

it 'accepts value for multivalued' do
config[:multivalued] = false
expect(resource[:multivalued]).to eq(:false)
end

it 'accepts value for multivalued string' do
config[:multivalued] = 'false'
expect(resource[:multivalued]).to eq(:false)
end

it 'has default for multivalued' do
expect(resource[:multivalued]).to be_nil
end

it 'does not accept invalid value for multivalued' do
config[:single] = 'foo'
expect {
resource
}.to raise_error(%r{foo})
end

it 'accepts script' do
config[:protocol] = 'saml'
config[:type] = 'script-foo.js'
Expand Down

0 comments on commit dc2360a

Please sign in to comment.