KEYCLOAK-18954 Refactor user consent list retrieval to avoid ConcurrentModificationException
This avoids a ConcurrentModificationException to be thrown in UserResource.getConsents()
calls that got introduced in 4e8b18f560
by filtering
the resulting stream explicitly instead of removing items from the collection
that we iterate over, which triggered the CME in the first place.
Signed-off-by: Thomas Darimont <thomas.darimont@googlemail.com>
This commit is contained in:
parent
6431afe360
commit
f16eb4d8b9
1 changed files with 12 additions and 5 deletions
|
@ -103,6 +103,7 @@ import java.text.MessageFormat;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -450,11 +451,18 @@ public class UserResource {
|
|||
|
||||
Set<ClientModel> offlineClients = new UserSessionManager(session).findClientsWithOfflineToken(realm, user);
|
||||
|
||||
return Stream.concat(
|
||||
session.users().getConsentsStream(realm, user.getId())
|
||||
.map(consent -> toConsent(consent, offlineClients)),
|
||||
Set<ClientModel> clientsWithUserConsents = new HashSet<>();
|
||||
List<UserConsentModel> userConsents = session.users().getConsentsStream(realm, user.getId())
|
||||
// collect clients with explicit user consents for later filtering
|
||||
.peek(ucm -> clientsWithUserConsents.add(ucm.getClient()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
offlineClients.stream().map(this::toConsent)
|
||||
return Stream.concat(
|
||||
userConsents.stream().map(consent -> toConsent(consent, offlineClients)),
|
||||
offlineClients.stream()
|
||||
// filter out clients with explicit user consents to avoid rendering them twice
|
||||
.filter(c -> !clientsWithUserConsents.contains(c))
|
||||
.map(this::toConsent)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -492,7 +500,6 @@ public class UserResource {
|
|||
offlineTokens.put("client", consent.getClient().getId());
|
||||
offlineTokens.put("key", "Offline Token");
|
||||
additionalGrants.add(offlineTokens);
|
||||
offlineClients.remove(consent.getClient());
|
||||
}
|
||||
currentRep.put("additionalGrants", additionalGrants);
|
||||
return currentRep;
|
||||
|
|
Loading…
Reference in a new issue