Skip to content

Commit 2049f86

Browse files
fix: support additional default client scopes
1 parent 7e82831 commit 2049f86

4 files changed

Lines changed: 72 additions & 2 deletions

File tree

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Build the manager binary
2-
FROM golang:1.20.13 as builder
2+
FROM golang:1.21.11 as builder
33

44
WORKDIR /workspace
55
# Copy the Go Modules manifests

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ A basic configuration for the keycloakcontroller consists of
1616

1717
* optional secret credential-keycloak-client-secret-seed in namespace des controllers
1818
* SECRET_SEED if the secret for each client should be created via a sha code of (secret-seed + client-name). This is sometimes necessary if a controller should be running in twho separate k8s clusters.
19+
* optional defaultClientScope for public KeycloakClients. For KeycloakClients, the defaultClientScopes are configured in the KeycloakClient CustomResource.
20+
If a certain defaultClientScope is needed in every KeycloakClient, e.g. the Scope "Nonce" for alle the public KeycloakClients, then this can be configured with the environment Variable ADDITIONAL_DEFAULT_CLIENT_SCOPE and in the case the value "Nonce".
21+
22+
1923

2024

2125

controllers/keycloakclient_reconciler.go

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ package controllers
33
import (
44
"bytes"
55
"fmt"
6+
"os"
67

78
kc "github.com/movewp3/keycloakclient-controller/api/v1alpha1"
89
"github.com/movewp3/keycloakclient-controller/pkg/common"
910
"github.com/movewp3/keycloakclient-controller/pkg/model"
1011
"github.com/movewp3/keycloakclient-controller/pkg/util"
12+
"k8s.io/utils/strings/slices"
1113
)
1214

1315
const (
@@ -169,8 +171,36 @@ func (i *DedicatedKeycloakClientReconciler) ReconcileScopeMappings(state *common
169171
}
170172
}
171173

174+
func getAdditionalDefaultClientScope() string {
175+
additionalDefaultClientScope, found := os.LookupEnv("ADDITIONAL_DEFAULT_CLIENT_SCOPE")
176+
if !found {
177+
return ""
178+
}
179+
return additionalDefaultClientScope
180+
}
181+
172182
func (i *DedicatedKeycloakClientReconciler) ReconcileClientScopes(state *common.ClientState, cr *kc.KeycloakClient, desired *common.DesiredClusterState) {
173-
defaultClientScopes := model.FilterClientScopesByNames(state.AvailableClientScopes, cr.Spec.Client.DefaultClientScopes)
183+
184+
logKcc.Info(fmt.Sprintf("ReconcileClientScopes %s", cr.Spec.Client.Name))
185+
186+
oldClientScopes := []string{}
187+
//addedDefaultClientScope := false
188+
189+
additionalDefaultClientScopes := cr.Spec.Client.DefaultClientScopes
190+
if getAdditionalDefaultClientScope() != "" && !slices.Contains(cr.Spec.Client.DefaultClientScopes, getAdditionalDefaultClientScope()) && cr.Spec.Client.PublicClient {
191+
logKcc.Info(fmt.Sprintf("Add default client scope %v",
192+
getAdditionalDefaultClientScope()))
193+
194+
oldClientScopes = cr.Spec.Client.DefaultClientScopes
195+
//addedDefaultClientScope = true
196+
additionalDefaultClientScopes = append(cr.Spec.Client.DefaultClientScopes, getAdditionalDefaultClientScope())
197+
198+
defer func() {
199+
cr.Spec.Client.DefaultClientScopes = oldClientScopes
200+
}()
201+
}
202+
203+
defaultClientScopes := model.FilterClientScopesByNames(state.AvailableClientScopes, additionalDefaultClientScopes)
174204

175205
defaultClientScopesNew, _ := model.ClientScopeDifferenceIntersection(defaultClientScopes, state.DefaultClientScopes)
176206
for _, clientScope := range defaultClientScopesNew {
@@ -449,6 +479,7 @@ func (i *DedicatedKeycloakClientReconciler) getDeletedClientClientScopeMappingsS
449479
}
450480

451481
func (i *DedicatedKeycloakClientReconciler) getCreatedClientDefaultClientScopeState(state *common.ClientState, cr *kc.KeycloakClient, clientScope *kc.KeycloakClientScope) common.ClusterAction {
482+
452483
return common.UpdateClientDefaultClientScopeAction{
453484
ClientScope: clientScope,
454485
Ref: cr,

pkg/common/cluster_actions.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package common
33
import (
44
"context"
55
"fmt"
6+
"os"
7+
"slices"
68

79
"github.com/movewp3/keycloakclient-controller/api/v1alpha1"
810
"github.com/movewp3/keycloakclient-controller/pkg/util"
@@ -133,11 +135,38 @@ func (i *ClusterActionRunner) CreateRealm(obj *v1alpha1.KeycloakRealm) error {
133135
return err
134136
}
135137

138+
func getAdditionalDefaultClientScope() string {
139+
140+
additionalDefaultClientScope, found := os.LookupEnv("ADDITIONAL_DEFAULT_CLIENT_SCOPE")
141+
if !found {
142+
return ""
143+
}
144+
return additionalDefaultClientScope
145+
}
146+
136147
func (i *ClusterActionRunner) CreateClient(obj *v1alpha1.KeycloakClient, realm string) error {
148+
137149
if i.keycloakClient == nil {
138150
return errors.Errorf("cannot perform client create when client is nil")
139151
}
140152

153+
oldClientScopes := []string{}
154+
addedDefaultClientScope := false
155+
156+
if getAdditionalDefaultClientScope() != "" && !slices.Contains(obj.Spec.Client.DefaultClientScopes, getAdditionalDefaultClientScope()) && obj.Spec.Client.PublicClient {
157+
log.Info(fmt.Sprintf("Add default client scope %v",
158+
getAdditionalDefaultClientScope()))
159+
160+
oldClientScopes = obj.Spec.Client.DefaultClientScopes
161+
addedDefaultClientScope = true
162+
obj.Spec.Client.DefaultClientScopes = append(obj.Spec.Client.DefaultClientScopes, getAdditionalDefaultClientScope())
163+
164+
defer func() {
165+
obj.Spec.Client.DefaultClientScopes = oldClientScopes
166+
}()
167+
168+
}
169+
141170
uid, err := i.keycloakClient.CreateClient(obj.Spec.Client, realm)
142171

143172
if err == nil {
@@ -153,6 +182,11 @@ func (i *ClusterActionRunner) CreateClient(obj *v1alpha1.KeycloakClient, realm s
153182
log.Info(fmt.Sprintf("Removed secret (generated from secretSeed) from keycloak client %v",
154183
obj.Name))
155184
}
185+
if addedDefaultClientScope {
186+
obj.Spec.Client.DefaultClientScopes = oldClientScopes
187+
log.Info(fmt.Sprintf("Removed additional client scope (%s) from keycloak client %v",
188+
getAdditionalDefaultClientScope(), obj.Name))
189+
}
156190

157191
return i.client.Update(i.context, obj)
158192
}
@@ -182,6 +216,7 @@ func (i *ClusterActionRunner) CreateClient(obj *v1alpha1.KeycloakClient, realm s
182216
}
183217

184218
return err
219+
185220
}
186221

187222
func (i *ClusterActionRunner) UpdateClient(obj *v1alpha1.KeycloakClient, realm string) error {

0 commit comments

Comments
 (0)