Fixing realm removal when removing groups and brokers associated with an organization
Closes #29495 Signed-off-by: Pedro Igor <pigor.craveiro@gmail.com>
This commit is contained in:
parent
b5a854b68e
commit
b4d231fd40
4 changed files with 80 additions and 6 deletions
|
@ -78,6 +78,7 @@ import org.keycloak.models.jpa.entities.RealmEntity;
|
|||
import org.keycloak.models.jpa.entities.RealmLocalizationTextsEntity;
|
||||
import org.keycloak.models.jpa.entities.RoleEntity;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.organization.utils.Organizations;
|
||||
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
||||
|
||||
|
||||
|
@ -190,7 +191,7 @@ public class JpaRealmProvider implements RealmProvider, ClientProvider, ClientSc
|
|||
session.clientScopes().removeClientScopes(adapter);
|
||||
session.roles().removeRoles(adapter);
|
||||
|
||||
session.groups().getTopLevelGroupsStream(adapter).forEach(adapter::removeGroup);
|
||||
session.groups().getTopLevelGroupsStream(adapter).forEach(Organizations.removeGroup(session, adapter));
|
||||
|
||||
num = em.createNamedQuery("removeClientInitialAccessByRealm")
|
||||
.setParameter("realm", realm).executeUpdate();
|
||||
|
|
|
@ -113,14 +113,21 @@ public class JpaOrganizationProvider implements OrganizationProvider {
|
|||
|
||||
try {
|
||||
session.setAttribute(OrganizationModel.class.getName(), organization);
|
||||
RealmModel realm = session.realms().getRealm(this.realm.getId());
|
||||
|
||||
// check if the realm is being removed so that we don't need to remove manually remove any other data but the org
|
||||
if (realm != null) {
|
||||
GroupModel group = getOrganizationGroup(entity);
|
||||
|
||||
if (group != null) {
|
||||
//TODO: won't scale, requires a better mechanism for bulk deleting users
|
||||
userProvider.getGroupMembersStream(realm, group).forEach(userModel -> removeMember(organization, userModel));
|
||||
groupProvider.removeGroup(realm, group);
|
||||
userProvider.getGroupMembersStream(this.realm, group).forEach(userModel -> removeMember(organization, userModel));
|
||||
groupProvider.removeGroup(this.realm, group);
|
||||
}
|
||||
|
||||
organization.getIdentityProviders().forEach((model) -> removeIdentityProvider(organization, model));
|
||||
}
|
||||
|
||||
em.remove(entity);
|
||||
} finally {
|
||||
session.removeAttribute(OrganizationModel.class.getName());
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.keycloak.organization.utils;
|
|||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.keycloak.common.Profile;
|
||||
import org.keycloak.common.Profile.Feature;
|
||||
|
@ -85,4 +86,32 @@ public class Organizations {
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Consumer<GroupModel> removeGroup(KeycloakSession session, RealmModel realm) {
|
||||
return group -> {
|
||||
if (!Profile.isFeatureEnabled(Feature.ORGANIZATION)) {
|
||||
realm.removeGroup(group);
|
||||
return;
|
||||
}
|
||||
|
||||
OrganizationModel current = (OrganizationModel) session.getAttribute(OrganizationModel.class.getName());
|
||||
|
||||
try {
|
||||
String orgId = group.getFirstAttribute(OrganizationModel.ORGANIZATION_ATTRIBUTE);
|
||||
OrganizationProvider provider = session.getProvider(OrganizationProvider.class);
|
||||
|
||||
if (orgId != null) {
|
||||
session.setAttribute(OrganizationModel.class.getName(), provider.getById(orgId));
|
||||
}
|
||||
|
||||
realm.removeGroup(group);
|
||||
} finally {
|
||||
if (current == null) {
|
||||
session.removeAttribute(OrganizationModel.class.getName());
|
||||
} else {
|
||||
session.setAttribute(OrganizationModel.class.getName(), current);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,10 +43,15 @@ import jakarta.ws.rs.core.Response;
|
|||
import jakarta.ws.rs.core.Response.Status;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.admin.client.resource.OrganizationResource;
|
||||
import org.keycloak.admin.client.resource.RealmResource;
|
||||
import org.keycloak.common.Profile.Feature;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.representations.idm.IdentityProviderRepresentation;
|
||||
import org.keycloak.representations.idm.OrganizationDomainRepresentation;
|
||||
import org.keycloak.representations.idm.OrganizationRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
|
||||
import org.keycloak.testsuite.util.RealmBuilder;
|
||||
|
||||
@EnableFeature(Feature.ORGANIZATION)
|
||||
public class OrganizationTest extends AbstractOrganizationTest {
|
||||
|
@ -367,4 +372,36 @@ public class OrganizationTest extends AbstractOrganizationTest {
|
|||
assertEquals(1, existing.getDomains().size());
|
||||
assertNotNull(existing.getDomain("acme.com"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteRealm() {
|
||||
RealmRepresentation realmRep = RealmBuilder.create().name(KeycloakModelUtils.generateId()).build();
|
||||
RealmResource realm = realmsResouce().realm(realmRep.getRealm());
|
||||
|
||||
try {
|
||||
realmRep.setEnabled(true);
|
||||
realmsResouce().create(realmRep);
|
||||
realm = realmsResouce().realm(realmRep.getRealm());
|
||||
realm.toRepresentation();
|
||||
OrganizationRepresentation org = new OrganizationRepresentation();
|
||||
org.setName("test-org");
|
||||
org.addDomain(new OrganizationDomainRepresentation("test.org"));
|
||||
org.setEnabled(true);
|
||||
Response response = realm.organizations().create(org);
|
||||
response.close();
|
||||
assertEquals(Status.CREATED.getStatusCode(), response.getStatus());
|
||||
List<OrganizationRepresentation> orgs = realm.organizations().getAll();
|
||||
assertEquals(1, orgs.size());
|
||||
IdentityProviderRepresentation broker = bc.setUpIdentityProvider();
|
||||
broker.setAlias(KeycloakModelUtils.generateId());
|
||||
response = realm.identityProviders().create(broker);
|
||||
response.close();
|
||||
assertEquals(Status.CREATED.getStatusCode(), response.getStatus());
|
||||
response = realm.organizations().get(orgs.get(0).getId()).identityProviders().addIdentityProvider(broker.getAlias());
|
||||
response.close();
|
||||
assertEquals(Status.NO_CONTENT.getStatusCode(), response.getStatus());
|
||||
} finally {
|
||||
realm.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue