Avoid iterating over user policies when removing users
Closes #19358 Signed-off-by: Pedro Igor <pigor.craveiro@gmail.com>
This commit is contained in:
parent
42251b3a13
commit
b76f4f9c1b
3 changed files with 31 additions and 59 deletions
|
@ -78,7 +78,9 @@ public class UserPolicyProviderFactory implements PolicyProviderFactory<UserPoli
|
||||||
if (users == null) {
|
if (users == null) {
|
||||||
representation.setUsers(Collections.emptySet());
|
representation.setUsers(Collections.emptySet());
|
||||||
} else {
|
} else {
|
||||||
representation.setUsers(JsonSerialization.readValue(users, Set.class));
|
representation.setUsers((Set<String>) JsonSerialization.readValue(users, Set.class).stream()
|
||||||
|
.filter(id -> getUser((String) id, authorization) != null)
|
||||||
|
.collect(Collectors.toSet()));
|
||||||
}
|
}
|
||||||
} catch (IOException cause) {
|
} catch (IOException cause) {
|
||||||
throw new RuntimeException("Failed to deserialize roles", cause);
|
throw new RuntimeException("Failed to deserialize roles", cause);
|
||||||
|
@ -94,12 +96,12 @@ public class UserPolicyProviderFactory implements PolicyProviderFactory<UserPoli
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Policy policy, UserPolicyRepresentation representation, AuthorizationProvider authorization) {
|
public void onCreate(Policy policy, UserPolicyRepresentation representation, AuthorizationProvider authorization) {
|
||||||
updateUsers(policy, representation, authorization);
|
updateUsers(policy, authorization, representation.getUsers());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUpdate(Policy policy, UserPolicyRepresentation representation, AuthorizationProvider authorization) {
|
public void onUpdate(Policy policy, UserPolicyRepresentation representation, AuthorizationProvider authorization) {
|
||||||
updateUsers(policy, representation, authorization);
|
updateUsers(policy, authorization, representation.getUsers());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -133,28 +135,12 @@ public class UserPolicyProviderFactory implements PolicyProviderFactory<UserPoli
|
||||||
representation.setConfig(config);
|
representation.setConfig(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateUsers(Policy policy, UserPolicyRepresentation representation, AuthorizationProvider authorization) {
|
|
||||||
updateUsers(policy, authorization, representation.getUsers());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateUsers(Policy policy, AuthorizationProvider authorization, Set<String> users) {
|
private void updateUsers(Policy policy, AuthorizationProvider authorization, Set<String> users) {
|
||||||
KeycloakSession session = authorization.getKeycloakSession();
|
|
||||||
RealmModel realm = authorization.getRealm();
|
|
||||||
UserProvider userProvider = session.users();
|
|
||||||
Set<String> updatedUsers = new HashSet<>();
|
Set<String> updatedUsers = new HashSet<>();
|
||||||
|
|
||||||
if (users != null) {
|
if (users != null) {
|
||||||
for (String userId : users) {
|
for (String userId : users) {
|
||||||
UserModel user = null;
|
UserModel user = getUser(userId, authorization);
|
||||||
|
|
||||||
try {
|
|
||||||
user = userProvider.getUserByUsername(realm, userId);
|
|
||||||
} catch (Exception ignore) {
|
|
||||||
}
|
|
||||||
|
|
||||||
if (user == null) {
|
|
||||||
user = userProvider.getUserById(realm, userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
throw new RuntimeException("Error while updating policy [" + policy.getName() + "]. User [" + userId + "] could not be found.");
|
throw new RuntimeException("Error while updating policy [" + policy.getName() + "]. User [" + userId + "] could not be found.");
|
||||||
|
@ -172,6 +158,23 @@ public class UserPolicyProviderFactory implements PolicyProviderFactory<UserPoli
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static UserModel getUser(String userId, AuthorizationProvider authorization) {
|
||||||
|
if (userId == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
KeycloakSession session = authorization.getKeycloakSession();
|
||||||
|
RealmModel realm = authorization.getRealm();
|
||||||
|
UserProvider userProvider = session.users();
|
||||||
|
UserModel user = userProvider.getUserByUsername(realm, userId);
|
||||||
|
|
||||||
|
if (user == null) {
|
||||||
|
user = userProvider.getUserById(realm, userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(Config.Scope config) {
|
public void init(Config.Scope config) {
|
||||||
|
|
||||||
|
@ -191,18 +194,4 @@ public class UserPolicyProviderFactory implements PolicyProviderFactory<UserPoli
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return "user";
|
return "user";
|
||||||
}
|
}
|
||||||
|
|
||||||
static String[] getUsers(Policy policy) {
|
|
||||||
String users = policy.getConfig().get("users");
|
|
||||||
|
|
||||||
if (users != null) {
|
|
||||||
try {
|
|
||||||
return JsonSerialization.readValue(users.getBytes(), String[].class);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException("Could not parse users [" + users + "] from policy config [" + policy.getName() + ".", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new String[0];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,30 +48,6 @@ public class UserSynchronizer implements Synchronizer<UserRemovedEvent> {
|
||||||
|
|
||||||
removeFromUserPermissionTickets(event, authorizationProvider);
|
removeFromUserPermissionTickets(event, authorizationProvider);
|
||||||
removeUserResources(event, authorizationProvider);
|
removeUserResources(event, authorizationProvider);
|
||||||
removeFromUserPolicies(event, authorizationProvider);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void removeFromUserPolicies(UserRemovedEvent event, AuthorizationProvider authorizationProvider) {
|
|
||||||
StoreFactory storeFactory = authorizationProvider.getStoreFactory();
|
|
||||||
PolicyStore policyStore = storeFactory.getPolicyStore();
|
|
||||||
UserModel userModel = event.getUser();
|
|
||||||
Map<Policy.FilterOption, String[]> attributes = new EnumMap<>(Policy.FilterOption.class);
|
|
||||||
|
|
||||||
attributes.put(Policy.FilterOption.TYPE, new String[] {"user"});
|
|
||||||
attributes.put(Policy.FilterOption.CONFIG, new String[] {"users", userModel.getId()});
|
|
||||||
attributes.put(Policy.FilterOption.ANY_OWNER, new String[] {Boolean.TRUE.toString()});
|
|
||||||
|
|
||||||
List<Policy> search = policyStore.find(null, attributes, null, null);
|
|
||||||
|
|
||||||
for (Policy policy : search) {
|
|
||||||
PolicyProviderFactory policyFactory = authorizationProvider.getProviderFactory(policy.getType());
|
|
||||||
UserPolicyRepresentation representation = UserPolicyRepresentation.class.cast(policyFactory.toRepresentation(policy, authorizationProvider));
|
|
||||||
Set<String> users = representation.getUsers();
|
|
||||||
|
|
||||||
users.remove(userModel.getId());
|
|
||||||
|
|
||||||
policyFactory.onUpdate(policy, representation, authorizationProvider);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeUserResources(UserRemovedEvent event, AuthorizationProvider authorizationProvider) {
|
private void removeUserResources(UserRemovedEvent event, AuthorizationProvider authorizationProvider) {
|
||||||
|
@ -106,7 +82,7 @@ public class UserSynchronizer implements Synchronizer<UserRemovedEvent> {
|
||||||
}
|
}
|
||||||
|
|
||||||
attributes.clear();
|
attributes.clear();
|
||||||
|
|
||||||
attributes.put(PermissionTicket.FilterOption.REQUESTER, userModel.getId());
|
attributes.put(PermissionTicket.FilterOption.REQUESTER, userModel.getId());
|
||||||
|
|
||||||
for (PermissionTicket ticket : ticketStore.find(null, attributes, null, null)) {
|
for (PermissionTicket ticket : ticketStore.find(null, attributes, null, null)) {
|
||||||
|
|
|
@ -107,6 +107,13 @@ public class UserPolicyManagementTest extends AbstractPolicyManagementTest {
|
||||||
|
|
||||||
permission.update(representation);
|
permission.update(representation);
|
||||||
assertRepresentation(representation, permission);
|
assertRepresentation(representation, permission);
|
||||||
|
|
||||||
|
String userName = representation.getUsers().iterator().next();
|
||||||
|
UserRepresentation user = getRealm().users().search(userName).get(0);
|
||||||
|
getRealm().users().delete(user.getId()).close();
|
||||||
|
|
||||||
|
representation.getUsers().clear();
|
||||||
|
assertRepresentation(representation, permission);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Loading…
Reference in a new issue