mirror of
https://github.com/keycloak/keycloak.git
synced 2026-05-02 21:21:10 -05:00
Ensure GroupMemberLeaveEvent has a reference to the user leaving the group
Closes #44400 Signed-off-by: Stefan Guilhen <sguilhen@redhat.com>
This commit is contained in:
committed by
Pedro Igor
parent
3e312d91d8
commit
be714d935d
@@ -474,7 +474,7 @@ public class UserAdapter implements UserModel, JpaModel<UserEntity> {
|
||||
em.remove(entity);
|
||||
}
|
||||
em.flush();
|
||||
GroupMemberLeaveEvent.fire(group, session);
|
||||
GroupMemberLeaveEvent.fire(group, this, session);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+8
-3
@@ -11,8 +11,10 @@ import org.keycloak.models.FederatedIdentityModel.FederatedIdentityCreatedEvent;
|
||||
import org.keycloak.models.FederatedIdentityModel.FederatedIdentityRemovedEvent;
|
||||
import org.keycloak.models.GroupModel;
|
||||
import org.keycloak.models.GroupModel.GroupMemberJoinEvent;
|
||||
import org.keycloak.models.GroupModel.GroupMemberLeaveEvent;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.RoleModel.RoleGrantedEvent;
|
||||
import org.keycloak.models.RoleModel.RoleRevokedEvent;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.provider.ProviderEvent;
|
||||
|
||||
@@ -70,7 +72,10 @@ public enum ResourceOperationType {
|
||||
}
|
||||
|
||||
public String getResourceId(ProviderEvent event) {
|
||||
if (event instanceof GroupMemberJoinEvent gme) {
|
||||
if (event instanceof GroupMemberJoinEvent gme) {
|
||||
return gme.getUser().getId();
|
||||
}
|
||||
if (event instanceof GroupMemberLeaveEvent gme) {
|
||||
return gme.getUser().getId();
|
||||
}
|
||||
if (event instanceof FederatedIdentityModel.FederatedIdentityCreatedEvent fie) {
|
||||
@@ -79,10 +84,10 @@ public enum ResourceOperationType {
|
||||
if (event instanceof FederatedIdentityModel.FederatedIdentityRemovedEvent fie) {
|
||||
return fie.getUser().getId();
|
||||
}
|
||||
if (event instanceof RoleModel.RoleGrantedEvent rge) {
|
||||
if (event instanceof RoleGrantedEvent rge) {
|
||||
return rge.getUser().getId();
|
||||
}
|
||||
if (event instanceof RoleModel.RoleRevokedEvent rre) {
|
||||
if (event instanceof RoleRevokedEvent rre) {
|
||||
return rre.getUser().getId();
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -138,7 +138,7 @@ public interface GroupModel extends RoleMapperModel {
|
||||
}
|
||||
|
||||
interface GroupMemberLeaveEvent extends GroupEvent {
|
||||
static void fire(GroupModel group, KeycloakSession session) {
|
||||
static void fire(GroupModel group, UserModel user, KeycloakSession session) {
|
||||
session.getKeycloakSessionFactory().publish(new GroupMemberLeaveEvent() {
|
||||
@Override
|
||||
public RealmModel getRealm() {
|
||||
@@ -150,12 +150,19 @@ public interface GroupModel extends RoleMapperModel {
|
||||
return group;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserModel getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeycloakSession getKeycloakSession() {
|
||||
return session;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
UserModel getUser();
|
||||
}
|
||||
|
||||
interface GroupPathChangeEvent extends GroupEvent {
|
||||
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
package org.keycloak.tests.admin.model.workflow;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import jakarta.ws.rs.core.Response;
|
||||
|
||||
import org.keycloak.admin.client.resource.UserResource;
|
||||
import org.keycloak.admin.client.resource.WorkflowsResource;
|
||||
import org.keycloak.models.workflow.ResourceOperationType;
|
||||
import org.keycloak.models.workflow.SetUserAttributeStepProviderFactory;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.representations.userprofile.config.UPConfig;
|
||||
import org.keycloak.representations.workflows.WorkflowRepresentation;
|
||||
import org.keycloak.representations.workflows.WorkflowStepRepresentation;
|
||||
import org.keycloak.testframework.annotations.KeycloakIntegrationTest;
|
||||
import org.keycloak.testframework.realm.GroupConfigBuilder;
|
||||
import org.keycloak.testframework.realm.UserConfigBuilder;
|
||||
import org.keycloak.testframework.util.ApiUtil;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
||||
@KeycloakIntegrationTest(config = WorkflowsBlockingServerConfig.class)
|
||||
public class GroupMembershipLeaveWorkflowTest extends AbstractWorkflowTest {
|
||||
|
||||
private static final String GROUP_NAME = "generic-group";
|
||||
|
||||
@Test
|
||||
public void testEventsOnGroupMembershipLeave() {
|
||||
UPConfig upConfig = managedRealm.admin().users().userProfile().getConfiguration();
|
||||
upConfig.setUnmanagedAttributePolicy(UPConfig.UnmanagedAttributePolicy.ENABLED);
|
||||
managedRealm.admin().users().userProfile().update(upConfig);
|
||||
String groupId;
|
||||
|
||||
// create a test group
|
||||
try (Response response = managedRealm.admin().groups().add(GroupConfigBuilder.create().name(GROUP_NAME).build())) {
|
||||
groupId = ApiUtil.getCreatedId(response);
|
||||
}
|
||||
|
||||
WorkflowRepresentation expectedWorkflow = WorkflowRepresentation.withName("myworkflow")
|
||||
.onEvent(ResourceOperationType.USER_GROUP_MEMBERSHIP_REMOVED.name() + "(" + GROUP_NAME + ")")
|
||||
.withSteps(
|
||||
WorkflowStepRepresentation.create()
|
||||
.of(SetUserAttributeStepProviderFactory.ID)
|
||||
.withConfig("attribute", "attr1")
|
||||
.after(Duration.ofDays(5))
|
||||
.build()
|
||||
).build();
|
||||
|
||||
// create the workflow that activates on group membership removal
|
||||
WorkflowsResource workflows = managedRealm.admin().workflows();
|
||||
try (Response response = workflows.create(expectedWorkflow)) {
|
||||
assertThat(response.getStatus(), is(Response.Status.CREATED.getStatusCode()));
|
||||
}
|
||||
|
||||
// now create a user and add them to the group
|
||||
String userId;
|
||||
try (Response response = managedRealm.admin().users().create(UserConfigBuilder.create()
|
||||
.username("generic-user").email("generic-user@example.com").build())) {
|
||||
userId = ApiUtil.getCreatedId(response);
|
||||
}
|
||||
UserResource userResource = managedRealm.admin().users().get(userId);
|
||||
userResource.joinGroup(groupId);
|
||||
|
||||
// set offset to 6 days - no steps should run as the workflow shouldn't have activated yet
|
||||
runScheduledSteps(Duration.ofDays(6));
|
||||
UserRepresentation rep = userResource.toRepresentation();
|
||||
assertNull(rep.getAttributes());
|
||||
|
||||
// now remove the user from the group - this should trigger the workflow
|
||||
userResource.leaveGroup(groupId);
|
||||
// set offset to 6 days - set attribute step should run now
|
||||
runScheduledSteps(Duration.ofDays(6));
|
||||
rep = userResource.toRepresentation();
|
||||
assertNotNull(rep.getAttributes());
|
||||
assertThat(rep.getAttributes().get("attribute").get(0), is("attr1"));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user