Skip to content

Commit ad53b2f

Browse files
committed
feat: Add KeycloakClient ClientRolesV2 field (#152)
Introduced the new ClientRolesV2 field for KeycloakClient for more advanced client setup. ClientRolesV2 supports role descriptions and composite roles, unlike ClientRoles. ClientRoles marked as deprecated.
1 parent f50e574 commit ad53b2f

25 files changed

+1872
-403
lines changed

api/v1/keycloakclient_types.go

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,16 @@ type KeycloakClientSpec struct {
7272
AdvancedProtocolMappers bool `json:"advancedProtocolMappers,omitempty"`
7373

7474
// ClientRoles is a list of client roles names assigned to client.
75+
// Deprecated: Use ClientRolesV2 instead.
7576
// +nullable
7677
// +optional
7778
ClientRoles []string `json:"clientRoles,omitempty"`
7879

80+
// ClientRolesV2 is a list of client roles assigned to client.
81+
// +nullable
82+
// +optional
83+
ClientRolesV2 []ClientRole `json:"clientRolesV2,omitempty"`
84+
7985
// ProtocolMappers is a list of protocol mappers assigned to client.
8086
// +nullable
8187
// +optional
@@ -204,7 +210,7 @@ type ServiceAccount struct {
204210
// ClientRoles is a list of client roles assigned to service account.
205211
// +nullable
206212
// +optional
207-
ClientRoles []ClientRole `json:"clientRoles,omitempty"`
213+
ClientRoles []UserClientRole `json:"clientRoles,omitempty"`
208214

209215
// Attributes is a map of service account attributes.
210216
// +nullable
@@ -217,7 +223,7 @@ type ServiceAccount struct {
217223
Groups []string `json:"groups,omitempty"`
218224
}
219225

220-
type ClientRole struct {
226+
type UserClientRole struct {
221227
// ClientID is a client ID.
222228
ClientID string `json:"clientId"`
223229

@@ -227,6 +233,22 @@ type ClientRole struct {
227233
Roles []string `json:"roles,omitempty"`
228234
}
229235

236+
type ClientRole struct {
237+
// Name is a client role name.
238+
// +required
239+
Name string `json:"name,omitempty"`
240+
241+
// Description is a client role description.
242+
// +optional
243+
Description string `json:"description,omitempty"`
244+
245+
// AssociatedClientRoles is a list of client roles names associated with the current role.
246+
// These roles won't be created automatically, user should specify them separately in clientRolesV2.
247+
// +nullable
248+
// +optional
249+
AssociatedClientRoles []string `json:"associatedClientRoles,omitempty"`
250+
}
251+
230252
type ProtocolMapper struct {
231253
// Name is a protocol mapper name.
232254
// +optional

api/v1/keycloakrealmgroup_types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ type KeycloakRealmGroupSpec struct {
4242
// ClientRoles is a list of client roles assigned to group.
4343
// +nullable
4444
// +optional
45-
ClientRoles []ClientRole `json:"clientRoles,omitempty"`
45+
ClientRoles []UserClientRole `json:"clientRoles,omitempty"`
4646
}
4747

4848
// KeycloakRealmGroupStatus defines the observed state of KeycloakRealmGroup.

api/v1/keycloakrealmuser_types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ type KeycloakRealmUserSpec struct {
4848
// ClientRoles is a list of client roles assigned to user.
4949
// +nullable
5050
// +optional
51-
ClientRoles []ClientRole `json:"clientRoles,omitempty"`
51+
ClientRoles []UserClientRole `json:"clientRoles,omitempty"`
5252

5353
// Groups is a list of groups assigned to user.
5454
// +nullable

api/v1/zz_generated.deepcopy.go

Lines changed: 32 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/v1.edp.epam.com_keycloakclients.yaml

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -423,12 +423,36 @@ spec:
423423
URI and tokens.
424424
type: string
425425
clientRoles:
426-
description: ClientRoles is a list of client roles names assigned
427-
to client.
426+
description: |-
427+
ClientRoles is a list of client roles names assigned to client.
428+
Deprecated: Use ClientRolesV2 instead.
428429
items:
429430
type: string
430431
nullable: true
431432
type: array
433+
clientRolesV2:
434+
description: ClientRolesV2 is a list of client roles assigned to client.
435+
items:
436+
properties:
437+
associatedClientRoles:
438+
description: |-
439+
AssociatedClientRoles is a list of client roles names associated with the current role.
440+
These roles won't be created automatically, user should specify them separately in clientRolesV2.
441+
items:
442+
type: string
443+
nullable: true
444+
type: array
445+
description:
446+
description: Description is a client role description.
447+
type: string
448+
name:
449+
description: Name is a client role name.
450+
type: string
451+
required:
452+
- name
453+
type: object
454+
nullable: true
455+
type: array
432456
consentRequired:
433457
description: ConsentRequired is a flag to enable consent.
434458
type: boolean

deploy-templates/_crd_examples/keycloakclient.yaml

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,34 @@
11
apiVersion: v1.edp.epam.com/v1
22
kind: KeycloakClient
33
metadata:
4-
name: keycloakclient-sample
4+
name: keycloakclient-sample2
55
spec:
66
realmRef:
77
name: keycloakrealm-sample
88
kind: KeycloakRealm
99
advancedProtocolMappers: true
10-
clientId: agocd
10+
clientId: agocd2
1111
directAccess: true
1212
public: false
1313
secret: $client-secret-name:client-secret-key
1414
webUrl: https://argocd.example.com
1515
adminUrl: https://admin.example.com
1616
homeUrl: /home/
17-
defaultClientScopes:
18-
- groups
17+
# defaultClientScopes:
18+
# - groups
1919
redirectUris:
2020
- /url1/*
2121
- /url2/*
22+
clientRoles:
23+
- administrator
24+
- developer
25+
# clientRolesV2:
26+
# - name: roleA
27+
# description: "Role A"
28+
# associatedClientRoles:
29+
# - roleB
30+
# - name: roleB
31+
# description: "Role B"
2232

2333
---
2434

deploy-templates/crds/v1.edp.epam.com_keycloakclients.yaml

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -423,12 +423,36 @@ spec:
423423
URI and tokens.
424424
type: string
425425
clientRoles:
426-
description: ClientRoles is a list of client roles names assigned
427-
to client.
426+
description: |-
427+
ClientRoles is a list of client roles names assigned to client.
428+
Deprecated: Use ClientRolesV2 instead.
428429
items:
429430
type: string
430431
nullable: true
431432
type: array
433+
clientRolesV2:
434+
description: ClientRolesV2 is a list of client roles assigned to client.
435+
items:
436+
properties:
437+
associatedClientRoles:
438+
description: |-
439+
AssociatedClientRoles is a list of client roles names associated with the current role.
440+
These roles won't be created automatically, user should specify them separately in clientRolesV2.
441+
items:
442+
type: string
443+
nullable: true
444+
type: array
445+
description:
446+
description: Description is a client role description.
447+
type: string
448+
name:
449+
description: Name is a client role name.
450+
type: string
451+
required:
452+
- name
453+
type: object
454+
nullable: true
455+
type: array
432456
consentRequired:
433457
description: ConsentRequired is a flag to enable consent.
434458
type: boolean

docs/api.md

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2287,7 +2287,15 @@ If empty - WebUrl will be used.<br/>
22872287
<td><b>clientRoles</b></td>
22882288
<td>[]string</td>
22892289
<td>
2290-
ClientRoles is a list of client roles names assigned to client.<br/>
2290+
ClientRoles is a list of client roles names assigned to client.
2291+
Deprecated: Use ClientRolesV2 instead.<br/>
2292+
</td>
2293+
<td>false</td>
2294+
</tr><tr>
2295+
<td><b><a href="#keycloakclientspecclientrolesv2index">clientRolesV2</a></b></td>
2296+
<td>[]object</td>
2297+
<td>
2298+
ClientRolesV2 is a list of client roles assigned to client.<br/>
22912299
</td>
22922300
<td>false</td>
22932301
</tr><tr>
@@ -3181,6 +3189,48 @@ Condition is evaluated during OpenID Connect authorization request and/or token
31813189
</table>
31823190

31833191

3192+
### KeycloakClient.spec.clientRolesV2[index]
3193+
<sup><sup>[↩ Parent](#keycloakclientspec)</sup></sup>
3194+
3195+
3196+
3197+
3198+
3199+
<table>
3200+
<thead>
3201+
<tr>
3202+
<th>Name</th>
3203+
<th>Type</th>
3204+
<th>Description</th>
3205+
<th>Required</th>
3206+
</tr>
3207+
</thead>
3208+
<tbody><tr>
3209+
<td><b>name</b></td>
3210+
<td>string</td>
3211+
<td>
3212+
Name is a client role name.<br/>
3213+
</td>
3214+
<td>true</td>
3215+
</tr><tr>
3216+
<td><b>associatedClientRoles</b></td>
3217+
<td>[]string</td>
3218+
<td>
3219+
AssociatedClientRoles is a list of client roles names associated with the current role.
3220+
These roles won't be created automatically, user should specify them separately in clientRolesV2.<br/>
3221+
</td>
3222+
<td>false</td>
3223+
</tr><tr>
3224+
<td><b>description</b></td>
3225+
<td>string</td>
3226+
<td>
3227+
Description is a client role description.<br/>
3228+
</td>
3229+
<td>false</td>
3230+
</tr></tbody>
3231+
</table>
3232+
3233+
31843234
### KeycloakClient.spec.permission
31853235
<sup><sup>[↩ Parent](#keycloakclientspec)</sup></sup>
31863236

internal/controller/keycloakclient/chain/put_client_role.go

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,8 @@ func (el *PutClientRole) putKeycloakClientRole(ctx context.Context, keycloakClie
3333

3434
clientDto := dto.ConvertSpecToClient(&keycloakClient.Spec, "", realmName, nil)
3535

36-
for _, role := range clientDto.Roles {
37-
exist, err := el.keycloakApiClient.ExistClientRole(clientDto, role)
38-
if err != nil {
39-
return errors.Wrap(err, "error during ExistClientRole")
40-
}
41-
42-
if exist {
43-
reqLog.Info("Client role already exists", "role", role)
44-
continue
45-
}
46-
47-
if err := el.keycloakApiClient.CreateClientRole(clientDto, role); err != nil {
48-
return errors.Wrap(err, "unable to create client role")
49-
}
36+
if err := el.keycloakApiClient.SyncClientRoles(ctx, realmName, clientDto); err != nil {
37+
return errors.Wrap(err, "unable to sync client roles")
5038
}
5139

5240
reqLog.Info("End put keycloak client role")

internal/controller/keycloakclient/chain/service_account_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ func TestServiceAccount_Serve(t *testing.T) {
2323
Attributes: map[string]string{
2424
"foo": "bar",
2525
},
26-
ClientRoles: []keycloakApi.ClientRole{
26+
ClientRoles: []keycloakApi.UserClientRole{
2727
{
2828
ClientID: "clid2",
2929
Roles: []string{"foo", "bar"},

0 commit comments

Comments
 (0)