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.RealmLocalizationTextsEntity;
|
||||||
import org.keycloak.models.jpa.entities.RoleEntity;
|
import org.keycloak.models.jpa.entities.RoleEntity;
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
|
import org.keycloak.organization.utils.Organizations;
|
||||||
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
||||||
|
|
||||||
|
|
||||||
|
@ -190,7 +191,7 @@ public class JpaRealmProvider implements RealmProvider, ClientProvider, ClientSc
|
||||||
session.clientScopes().removeClientScopes(adapter);
|
session.clientScopes().removeClientScopes(adapter);
|
||||||
session.roles().removeRoles(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")
|
num = em.createNamedQuery("removeClientInitialAccessByRealm")
|
||||||
.setParameter("realm", realm).executeUpdate();
|
.setParameter("realm", realm).executeUpdate();
|
||||||
|
|
|
@ -113,14 +113,21 @@ public class JpaOrganizationProvider implements OrganizationProvider {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
session.setAttribute(OrganizationModel.class.getName(), organization);
|
session.setAttribute(OrganizationModel.class.getName(), organization);
|
||||||
GroupModel group = getOrganizationGroup(entity);
|
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(this.realm, group).forEach(userModel -> removeMember(organization, userModel));
|
||||||
|
groupProvider.removeGroup(this.realm, group);
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
organization.getIdentityProviders().forEach((model) -> removeIdentityProvider(organization, model));
|
organization.getIdentityProviders().forEach((model) -> removeIdentityProvider(organization, model));
|
||||||
}
|
}
|
||||||
|
|
||||||
em.remove(entity);
|
em.remove(entity);
|
||||||
} finally {
|
} finally {
|
||||||
session.removeAttribute(OrganizationModel.class.getName());
|
session.removeAttribute(OrganizationModel.class.getName());
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.keycloak.organization.utils;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.keycloak.common.Profile;
|
import org.keycloak.common.Profile;
|
||||||
import org.keycloak.common.Profile.Feature;
|
import org.keycloak.common.Profile.Feature;
|
||||||
|
@ -85,4 +86,32 @@ public class Organizations {
|
||||||
|
|
||||||
return null;
|
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 jakarta.ws.rs.core.Response.Status;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.keycloak.admin.client.resource.OrganizationResource;
|
import org.keycloak.admin.client.resource.OrganizationResource;
|
||||||
|
import org.keycloak.admin.client.resource.RealmResource;
|
||||||
import org.keycloak.common.Profile.Feature;
|
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.OrganizationDomainRepresentation;
|
||||||
import org.keycloak.representations.idm.OrganizationRepresentation;
|
import org.keycloak.representations.idm.OrganizationRepresentation;
|
||||||
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
|
import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
|
||||||
|
import org.keycloak.testsuite.util.RealmBuilder;
|
||||||
|
|
||||||
@EnableFeature(Feature.ORGANIZATION)
|
@EnableFeature(Feature.ORGANIZATION)
|
||||||
public class OrganizationTest extends AbstractOrganizationTest {
|
public class OrganizationTest extends AbstractOrganizationTest {
|
||||||
|
@ -367,4 +372,36 @@ public class OrganizationTest extends AbstractOrganizationTest {
|
||||||
assertEquals(1, existing.getDomains().size());
|
assertEquals(1, existing.getDomains().size());
|
||||||
assertNotNull(existing.getDomain("acme.com"));
|
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