diff --git a/REFERENCE.md b/REFERENCE.md index b41cb73a..68918020 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -3159,6 +3159,8 @@ The following parameters are available in the `keycloak_protocol_mapper` type. * [`realm`](#-keycloak_protocol_mapper--realm) * [`resource_name`](#-keycloak_protocol_mapper--resource_name) * [`type`](#-keycloak_protocol_mapper--type) +* [`custom_type`](#-keycloak_protocol_mapper--custom_type) +* [`custom_config`](#-keycloak_protocol_mapper--custom_config) ##### `client_scope` @@ -3189,13 +3191,21 @@ The protocol mapper name. Defaults to `name`. ##### `type` -Valid values: `oidc-usermodel-property-mapper`, `oidc-usermodel-attribute-mapper`, `oidc-full-name-mapper`, `oidc-group-membership-mapper`, `oidc-audience-mapper`, `saml-group-membership-mapper`, `saml-user-property-mapper`, `saml-user-attribute-mapper`, `saml-role-list-mapper` +Valid values: `oidc-usermodel-property-mapper`, `oidc-usermodel-attribute-mapper`, `oidc-full-name-mapper`, `oidc-group-membership-mapper`, `oidc-audience-mapper`, `saml-group-membership-mapper`, `saml-user-property-mapper`, `saml-user-attribute-mapper`, `saml-role-list-mapper`, `custom` protocolMapper. Default is `oidc-usermodel-property-mapper` for `protocol` `openid-connect` and `saml-user-property-mapper` for `protocol` `saml`. +##### `custom_type` + +Custom mapper type if `type` is set to `custom`. + +##### `custom_config` + +Custom mapper config for custom type. Simple hash with key-value pair, which will be converted to JSON. + ### `keycloak_realm` Manage Keycloak realms diff --git a/lib/puppet/provider/keycloak_protocol_mapper/kcadm.rb b/lib/puppet/provider/keycloak_protocol_mapper/kcadm.rb index ee033c9a..915705c8 100644 --- a/lib/puppet/provider/keycloak_protocol_mapper/kcadm.rb +++ b/lib/puppet/provider/keycloak_protocol_mapper/kcadm.rb @@ -74,6 +74,12 @@ def self.instances 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'] + unless ['oidc-usermodel-property-mapper', 'oidc-usermodel-attribute-mapper', 'oidc-full-name-mapper', 'oidc-group-membership-mapper', 'oidc-audience-mapper', + 'saml-group-membership-mapper', 'saml-user-property-mapper', 'saml-user-attribute-mapper', 'saml-role-list-mapper', 'saml-javascript-mapper'].include?(d['protocolMapper']) + protocol_mapper[:type] = 'custom' + protocol_mapper[:custom_type] = d['protocolMapper'] + protocol_mapper[:custom_config] = d['config'] + end protocol_mappers << new(protocol_mapper) end end @@ -105,6 +111,10 @@ def create data[:protocol] = resource[:protocol] data[:protocolMapper] = resource[:type] data[:config] = {} + if resource[:type] == 'custom' + data[:protocolMapper] = resource[:custom_type] + data[:config] = resource[:custom_config] + end if ['oidc-usermodel-property-mapper', 'saml-user-property-mapper', 'saml-user-attribute-mapper', 'oidc-usermodel-attribute-mapper'].include?(resource[:type]) && resource[:user_attribute] data[:config][:'user.attribute'] = resource[:user_attribute] end @@ -192,6 +202,10 @@ def flush data[:protocol] = resource[:protocol] data[:protocolMapper] = resource[:type] config = {} + if resource[:type] == 'custom' + data[:protocolMapper] = resource[:custom_type] + config = resource[:custom_config] + end if ['oidc-usermodel-property-mapper', 'saml-user-property-mapper', 'saml-user-attribute-mapper', 'oidc-usermodel-attribute-mapper'].include?(resource[:type]) && resource[:user_attribute] config[:'user.attribute'] = resource[:user_attribute] end diff --git a/lib/puppet/type/keycloak_protocol_mapper.rb b/lib/puppet/type/keycloak_protocol_mapper.rb index b06dfd71..2e248bfb 100644 --- a/lib/puppet/type/keycloak_protocol_mapper.rb +++ b/lib/puppet/type/keycloak_protocol_mapper.rb @@ -67,6 +67,7 @@ 'saml-user-attribute-mapper', 'saml-role-list-mapper', %r{script-.+}, + 'custom', ) defaultto do case @resource[:protocol] @@ -210,6 +211,14 @@ desc 'included.client.audience Required for `type` of `oidc-audience-mapper`' end + newproperty(:custom_config) do + desc 'custom configuration data for `custom` protocolMapper type' + end + + newproperty(:custom_type) do + desc 'custom protocolMapper type' + end + autorequire(:keycloak_client_scope) do requires = [] catalog.resources.each do |resource| @@ -248,7 +257,8 @@ def self.title_patterns 'oidc-full-name-mapper', 'oidc-group-membership-mapper', 'oidc-audience-mapper', - 'oidc-usermodel-attribute-mapper' + 'oidc-usermodel-attribute-mapper', + 'custom' ] if self[:protocol] == 'openid-connect' && !openid_connect_types.include?(self[:type]) && self[:type] !~ %r{script-.+} raise Puppet::Error, "type #{self[:type]} is not valid for protocol openid-connect" @@ -273,5 +283,11 @@ 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[:type] == 'custom' && !self[:custom_type] + raise Puppet::Error, 'custom_type is required for `custom` protocol mapper type' + end + if self[:type] == 'custom' && !self[:custom_config] + raise Puppet::Error, 'custom_config is required for `custom` protocol mapper type' + end end end