@@ -15,16 +15,18 @@ type Group struct {
15
15
path []string
16
16
17
17
Members []User
18
+
19
+ displayName string
18
20
}
19
21
20
22
// NewGroup creates a new group.
21
- func NewGroup (path ... string ) Group {
22
- return Group {path : path }
23
+ func NewGroup (displayName string , path ... string ) Group {
24
+ return Group {path : path , displayName : displayName }
23
25
}
24
26
25
27
// NewGroupFromPath creates a new group.
26
- func NewGroupFromPath (path string ) Group {
27
- return NewGroup (strings .Split (strings .TrimPrefix (path , "/" ), "/" )... )
28
+ func NewGroupFromPath (displayName string , path string ) Group {
29
+ return NewGroup (displayName , strings .Split (strings .TrimPrefix (path , "/" ), "/" )... )
28
30
}
29
31
30
32
// WithMemberNames returns a copy of the group with given members added.
@@ -119,6 +121,7 @@ type GoCloak interface {
119
121
CreateGroup (ctx context.Context , accessToken , realm string , group gocloak.Group ) (string , error )
120
122
CreateChildGroup (ctx context.Context , accessToken , realm , groupID string , group gocloak.Group ) (string , error )
121
123
GetGroups (ctx context.Context , accessToken , realm string , params gocloak.GetGroupsParams ) ([]* gocloak.Group , error )
124
+ UpdateGroup (ctx context.Context , accessToken , realm string , updatedGroup gocloak.Group ) error
122
125
DeleteGroup (ctx context.Context , accessToken , realm , groupID string ) error
123
126
124
127
GetGroupMembers (ctx context.Context , accessToken , realm , groupID string , params gocloak.GetGroupsParams ) ([]* gocloak.User , error )
@@ -157,7 +160,7 @@ func NewClient(host, realm, username, password string) Client {
157
160
// PutGroup creates the provided Keycloak group if it does not exist and adjusts the group members accordingly.
158
161
// The method is idempotent.
159
162
func (c Client ) PutGroup (ctx context.Context , group Group ) (Group , error ) {
160
- res := NewGroup (group .path ... )
163
+ res := NewGroup (group .displayName , group . path ... )
161
164
group = c .prependRoot (group )
162
165
163
166
token , err := c .login (ctx )
@@ -176,6 +179,14 @@ func (c Client) PutGroup(ctx context.Context, group Group) (Group, error) {
176
179
return res , err
177
180
}
178
181
found = & created
182
+ } else {
183
+ if getDisplayNameOfGroup (found ) != group .displayName {
184
+ found .Attributes = setDisplayName (found .Attributes , group .displayName )
185
+ err := c .updateGroup (ctx , token , * found )
186
+ if err != nil {
187
+ return res , err
188
+ }
189
+ }
179
190
}
180
191
181
192
membErr := MembershipSyncErrors {}
@@ -212,8 +223,9 @@ func (c Client) PutGroup(ctx context.Context, group Group) (Group, error) {
212
223
213
224
func (c Client ) createGroup (ctx context.Context , token * gocloak.JWT , group Group ) (gocloak.Group , error ) {
214
225
toCreate := gocloak.Group {
215
- Name : gocloak .StringP (group .BaseName ()),
216
- Path : gocloak .StringP (group .Path ()),
226
+ Name : gocloak .StringP (group .BaseName ()),
227
+ Path : gocloak .StringP (group .Path ()),
228
+ Attributes : setDisplayName (nil , group .displayName ),
217
229
}
218
230
219
231
if len (group .PathMembers ()) == 1 {
@@ -223,7 +235,7 @@ func (c Client) createGroup(ctx context.Context, token *gocloak.JWT, group Group
223
235
}
224
236
225
237
p := group .PathMembers ()
226
- parent , err := c .getGroup (ctx , token , NewGroup (p [0 :len (p )- 1 ]... ))
238
+ parent , err := c .getGroup (ctx , token , NewGroup (group . displayName , p [0 :len (p )- 1 ]... ))
227
239
if err != nil {
228
240
return toCreate , fmt .Errorf ("error finding parent group for %v: %w" , group , err )
229
241
}
@@ -236,6 +248,11 @@ func (c Client) createGroup(ctx context.Context, token *gocloak.JWT, group Group
236
248
return toCreate , err
237
249
}
238
250
251
+ func (c Client ) updateGroup (ctx context.Context , token * gocloak.JWT , group gocloak.Group ) error {
252
+ err := c .Client .UpdateGroup (ctx , token .AccessToken , c .Realm , group )
253
+ return err
254
+ }
255
+
239
256
// DeleteGroup deletes the Keycloak group by name.
240
257
// The method is idempotent and will not do anything if the group does not exits.
241
258
func (c Client ) DeleteGroup (ctx context.Context , path ... string ) error {
@@ -245,7 +262,7 @@ func (c Client) DeleteGroup(ctx context.Context, path ...string) error {
245
262
}
246
263
defer c .logout (ctx , token )
247
264
248
- found , err := c .getGroup (ctx , token , c .prependRoot (NewGroup (path ... )))
265
+ found , err := c .getGroup (ctx , token , c .prependRoot (NewGroup ("" , path ... )))
249
266
if err != nil {
250
267
return fmt .Errorf ("failed finding group: %w" , err )
251
268
}
@@ -488,7 +505,7 @@ func flatGroups(gcp []gocloak.Group) []Group {
488
505
var flatten func ([]gocloak.Group )
489
506
flatten = func (groups []gocloak.Group ) {
490
507
for _ , g := range groups {
491
- group := NewGroupFromPath (* g .Path )
508
+ group := NewGroupFromPath (getDisplayNameOfGroup ( & g ), * g .Path )
492
509
group .id = * g .ID
493
510
flat = append (flat , group )
494
511
if g .SubGroups != nil {
@@ -501,6 +518,30 @@ func flatGroups(gcp []gocloak.Group) []Group {
501
518
return flat
502
519
}
503
520
521
+ func getDisplayNameOfGroup (group * gocloak.Group ) string {
522
+ if group .Attributes != nil {
523
+ displayNames , ok := (* group .Attributes )["displayName" ]
524
+ if ok && len (displayNames ) > 0 {
525
+ return displayNames [0 ]
526
+ }
527
+ }
528
+ return ""
529
+ }
530
+
531
+ func setDisplayName (attributes * map [string ][]string , displayName string ) * map [string ][]string {
532
+ if attributes == nil {
533
+ attrMap := make (map [string ][]string )
534
+ attributes = & attrMap
535
+ }
536
+ if displayName == "" {
537
+ delete (* attributes , "displayName" )
538
+ } else {
539
+ (* attributes )["displayName" ] = []string {displayName }
540
+ }
541
+ return attributes
542
+ }
543
+
504
544
var defaultParams = gocloak.GetGroupsParams {
505
- Max : gocloak .IntP (- 1 ),
545
+ Max : gocloak .IntP (- 1 ),
546
+ BriefRepresentation : gocloak .BoolP (false ), // required in order to get attributes when listing groups
506
547
}
0 commit comments