5
5
6
6
import java .util .ArrayList ;
7
7
import java .util .HashMap ;
8
+ import java .util .HashSet ;
8
9
import java .util .List ;
9
10
import java .util .Map ;
11
+ import java .util .Optional ;
10
12
import java .util .Set ;
11
13
12
14
import jakarta .enterprise .context .ApplicationScoped ;
@@ -76,8 +78,35 @@ public List<UserService.UserData> searchUsers(String query) {
76
78
77
79
@ Override
78
80
public List <String > getRoles (String username ) {
79
- return keycloak .realm (realm ).users ().get (findMatchingUser (username ).getId ()).roles ().realmLevel ().listAll ().stream ()
80
- .map (RoleRepresentation ::getName ).toList ();
81
+ List <RoleRepresentation > representations = keycloak .realm (realm ).users ().get (findMatchingUserId (username )).roles ()
82
+ .realmLevel ().listAll ();
83
+
84
+ Set <String > roles = new HashSet <>(representations .stream ().map (RoleRepresentation ::getName ).toList ());
85
+
86
+ // the realm level roles only include the composite roles, not the base ones. add them manually.
87
+ for (String r : List .of (Roles .MANAGER , Roles .TESTER , Roles .UPLOADER , Roles .VIEWER )) {
88
+ Optional <String > composite = roles .stream ().filter (role -> role .endsWith (r )).findAny ();
89
+ if (composite .isPresent ()) {
90
+ roles .add (r );
91
+ roles .add (composite .get ().substring (0 , composite .get ().length () - r .length () - 1 ) + "-team" );
92
+ }
93
+ }
94
+
95
+ // the right way to do this would be something like this (does call keycloak a bunch of times)
96
+ // Set<String> roles = new HashSet<>();
97
+ // representations.forEach(representation -> roles.addAll(getRoleAndComposites(representation)))
98
+
99
+ return new ArrayList <>(roles );
100
+ }
101
+
102
+ private Set <String > getRoleAndComposites (RoleRepresentation representation ) {
103
+ Set <String > roles = new HashSet <>();
104
+ if (representation .isComposite ()) {
105
+ keycloak .realm (realm ).rolesById ().getRealmRoleComposites (representation .getId ()).stream ()
106
+ .map (this ::getRoleAndComposites ).forEach (roles ::addAll );
107
+ }
108
+ roles .add (representation .getName ());
109
+ return roles ;
81
110
}
82
111
83
112
@ Override
@@ -119,7 +148,7 @@ public void createUser(UserService.NewUser user) {
119
148
120
149
try { // assign the provided roles to the realm
121
150
UsersResource usersResource = keycloak .realm (realm ).users ();
122
- String userId = findMatchingUser (rep .getUsername ()). getId ( );
151
+ String userId = findMatchingUserId (rep .getUsername ());
123
152
124
153
if (user .team != null ) {
125
154
String prefix = getTeamPrefix (user .team );
@@ -148,7 +177,7 @@ public void createUser(UserService.NewUser user) {
148
177
149
178
@ Override
150
179
public void removeUser (String username ) {
151
- try (Response response = keycloak .realm (realm ).users ().delete (findMatchingUser (username ). getId ( ))) {
180
+ try (Response response = keycloak .realm (realm ).users ().delete (findMatchingUserId (username ))) {
152
181
if (response .getStatusInfo ().getFamily () != Response .Status .Family .SUCCESSFUL ) {
153
182
LOG .warnv ("Got {0} response for removing user {0}" , response .getStatusInfo (), username );
154
183
throw ServiceException .serverError (format ("Unable to remove user {0}" , username ));
@@ -187,7 +216,7 @@ public List<String> getTeams() { // get the "team roles" in the realm
187
216
}
188
217
}
189
218
190
- private UserRepresentation findMatchingUser (String username ) { // find the clientID of a single user
219
+ private String findMatchingUserId (String username ) { // find the clientID of a single user
191
220
List <UserRepresentation > matchingUsers = keycloak .realm (realm ).users ().search (username , true );
192
221
if (matchingUsers == null || matchingUsers .isEmpty ()) {
193
222
LOG .warnv ("Cannot find user with username {0}" , username );
@@ -197,7 +226,7 @@ private UserRepresentation findMatchingUser(String username) { // find the clien
197
226
matchingUsers .stream ().map (UserRepresentation ::getId ).collect (joining (" " )));
198
227
throw ServiceException .serverError (format ("More than one user with username {0}" , username ));
199
228
}
200
- return matchingUsers .get (0 );
229
+ return matchingUsers .get (0 ). getId () ;
201
230
}
202
231
203
232
@ Override
@@ -227,10 +256,9 @@ public void updateTeamMembers(String team, Map<String, List<String>> roles) { //
227
256
RoleMappingResource rolesMappingResource ;
228
257
229
258
try { // fetch the current roles for the user
230
- String userId = findMatchingUser (entry .getKey ()). getId ( );
259
+ String userId = findMatchingUserId (entry .getKey ());
231
260
rolesMappingResource = keycloak .realm (realm ).users ().get (userId ).roles ();
232
- existingRoles = rolesMappingResource .getAll ().getRealmMappings ().stream ().map (RoleRepresentation ::getName )
233
- .toList ();
261
+ existingRoles = rolesMappingResource .realmLevel ().listAll ().stream ().map (RoleRepresentation ::getName ).toList ();
234
262
} catch (Throwable t ) {
235
263
LOG .warnv (t , "Failed to retrieve current roles of user {0} from Keycloak" , entry .getKey ());
236
264
throw ServiceException
@@ -267,6 +295,8 @@ public void updateTeamMembers(String team, Map<String, List<String>> roles) { //
267
295
}
268
296
}
269
297
}
298
+ } catch (NotFoundException e ) {
299
+ throw ServiceException .serverError (format ("The team {0} does not exist" , team ));
270
300
} catch (Throwable t ) {
271
301
LOG .warnv (t , "Failed to remove all roles of team {0}" , team );
272
302
throw ServiceException .serverError (format ("Failed to remove all roles of team {0}" , team ));
@@ -376,7 +406,7 @@ public void updateAdministrators(List<String> newAdmins) { // update the list of
376
406
for (String username : newAdmins ) { // add admin role for `newAdmins` not in `oldAdmins`
377
407
if (oldAdmins .stream ().noneMatch (old -> username .equals (old .getUsername ()))) {
378
408
try {
379
- usersResource .get (findMatchingUser (username ). getId ( )).roles ().realmLevel ().add (List .of (adminRole ));
409
+ usersResource .get (findMatchingUserId (username )).roles ().realmLevel ().add (List .of (adminRole ));
380
410
LOG .infov ("Added administrator role to user {0}" , username );
381
411
} catch (Throwable t ) {
382
412
LOG .warnv ("Could not add admin role to user {0} due to {1}" , username , t .getMessage ());
@@ -398,7 +428,7 @@ public void setPassword(String username, String password) {
398
428
credentials .setType (CredentialRepresentation .PASSWORD );
399
429
credentials .setValue (password );
400
430
401
- keycloak .realm (realm ).users ().get (findMatchingUser (username ). getId ( )).resetPassword (credentials );
431
+ keycloak .realm (realm ).users ().get (findMatchingUserId (username )).resetPassword (credentials );
402
432
} catch (Throwable t ) {
403
433
LOG .warnv (t , "Failed to retrieve current representation of user {0} from Keycloak" , username );
404
434
throw ServiceException
0 commit comments