Skip to content

Commit cbf40d7

Browse files
committed
Add keycloak_role_mapping type and provider
This new type allows attaching client and realm roles into users and groups. Using the normal JSON payload approach ended up being overly complex as well as much less performant than this simplistic approach. Signed-off-by: Samuli Seppänen <samuli.seppanen@puppeteers.net>
1 parent 444cd66 commit cbf40d7

File tree

3 files changed

+97
-0
lines changed

3 files changed

+97
-0
lines changed

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
* [Keycloak](#keycloak)
1212
* [Deploy SPI](#deploy-spi)
1313
* [keycloak_realm](#keycloak_realm)
14+
* [keycloak_role_mapping](#keycloak_role_mapping)
1415
* [keycloak_ldap_user_provider](#keycloak_ldap_user_provider)
1516
* [keycloak_ldap_mapper](#keycloak_ldap_mapper)
1617
* [keycloak_sssd_user_provider](#keycloak_sssd_user_provider)
@@ -282,6 +283,23 @@ keycloak_realm { 'test':
282283

283284
**NOTE:** If the flow properties such as `browser_flow` are changed from their defaults then this value will not be set when a realm is first created. The value will also not be updated if the flow does not exist. For new realms you will have to run Puppet twice in order to create the flows then update the realm setting.
284285

286+
### keycloak\_role\_mapping
287+
288+
Manage realm role mappings for users and groups. Example:
289+
290+
keycloak_role_mapping { 'roles for john on master':
291+
realm => 'master',
292+
name => 'john',
293+
realm_roles => ['role1', 'role2'],
294+
}
295+
296+
keycloak_role_mapping { 'roles for mygroup on master':
297+
realm => 'master',
298+
name => 'mygroup',
299+
group => true,
300+
realm_roles => ['role1'],
301+
}
302+
285303
### keycloak\_ldap\_user_provider
286304

287305
Define a LDAP user provider so that authentication can be performed against LDAP. The example below uses two LDAP servers, disables importing of users and assumes the SSL certificates are trusted and do not require being in the truststore.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'keycloak_api'))
2+
3+
Puppet::Type.type(:keycloak_role_mapping).provide(:kcadm, parent: Puppet::Provider::KeycloakAPI) do
4+
desc ''
5+
6+
def opt
7+
(resource[:group] == :true) ? 'gname' : 'uusername'
8+
end
9+
10+
def realm_roles
11+
@active_realm_roles = []
12+
13+
output = kcadm('get-roles', nil, resource[:realm], nil, nil, false, opt => resource[:name])
14+
begin
15+
data = JSON.parse(output)
16+
rescue JSON::ParserError
17+
Puppet.debug('Unable to parse output from kcadm get-roles')
18+
end
19+
20+
data.each do |d|
21+
@active_realm_roles << d['name']
22+
end
23+
@active_realm_roles
24+
end
25+
26+
def realm_roles=(_value)
27+
removed_roles = @active_realm_roles.reject { |role| resource[:realm_roles].include?(role) }
28+
remove_roles(removed_roles)
29+
30+
new_roles = resource[:realm_roles].reject { |role| @active_realm_roles.include?(role) }
31+
add_roles(new_roles)
32+
end
33+
34+
def remove_roles(roles)
35+
return if roles.empty?
36+
kcadm('remove-roles', '', resource[:realm], nil, nil, false, opt => resource[:name], rolename: roles)
37+
end
38+
39+
def add_roles(roles)
40+
return if roles.empty?
41+
kcadm('add-roles', '', resource[:realm], nil, nil, false, opt => resource[:name], rolename: roles)
42+
end
43+
end
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
require_relative '../../puppet_x/keycloak/type'
2+
require_relative '../../puppet_x/keycloak/array_property'
3+
4+
Puppet::Type.newtype(:keycloak_role_mapping) do
5+
desc <<-DESC
6+
Attach realm roles to users and groups
7+
@example Ensure that a user has the defined realm roles
8+
keycloak_role_mapping { 'john-offline_access':
9+
realm => 'test',
10+
name => 'john',
11+
realm_roles => ['offline_access'],
12+
}
13+
DESC
14+
15+
extend PuppetX::Keycloak::Type
16+
add_autorequires
17+
18+
newparam(:name, namevar: true) do
19+
desc '--uusername/--gname'
20+
end
21+
22+
newparam(:group, boolean: true) do
23+
desc 'is this a group instead of a user'
24+
newvalues(:true, :false)
25+
defaultto :false
26+
end
27+
28+
newparam(:realm) do
29+
desc 'realm'
30+
end
31+
32+
newproperty(:realm_roles, array_matching: :all, parent: PuppetX::Keycloak::ArrayProperty) do
33+
desc 'realm roles'
34+
defaultto []
35+
end
36+
end

0 commit comments

Comments
 (0)