8000 Organization isolation bypass - nested organization groups can be re-… by vramik · Pull Request #54957 · keycloak/keycloak · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
< 8000 label>
Split Diff View
Split
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import org.keycloak.models.RealmModel;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.organization.utils.Organizations;
import org.keycloak.representations.idm.GroupRepresentation;
import org.keycloak.representations.idm.ManagementPermissionReference;
import org.keycloak.representations.idm.UserRepresentation;
Expand Down Expand Up @@ -254,6 +255,9 @@ public Response addChild(GroupRepresentation rep) {
if (child == null) {
throw new NotFoundException("Could not find child by id");
}
if (Organizations.isOrganizationGroup(child)) {
throw ErrorResponse.error("Cannot manage organization related group via non Organization API.", Response.Status.BAD_REQUEST);
}
auth.groups().requireManage(child);
if (!Objects.equals(child.getParentId(), group.getId())) {
GroupUtils.checkAdminGroupRoles(group, auth);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,74 @@ public void testSearchOrgGroupsDoesNotReturnRealmGroups() {
assertThat(results.get(0).getName(), is("Engineering"));
}

@Test
public void testCannotMoveNestedOrgGroupViaChildrenEndpoint() {
OrganizationRepresentation orgRep = createOrganization();
OrganizationResource orgResource = realm.admin().organizations().get(orgRep.getId());

GroupRepresentation engineeringRep = new GroupRepresentation();
engineeringRep.setName("engineering");
String engineeringId;
try (Response response = orgResource.groups().addTopLevelGroup(engineeringRep)) {
assertThat(response.getStatus(), is(Status.CREATED.getStatusCode()));
engineeringId = ApiUtil.getCreatedId(response);
}

GroupRepresentation approversRep = new GroupRepresentation();
approversRep.setName("approvers");
String approversId;
try (Response response = orgResource.groups().group(engineeringId).addSubGroup(approversRep)) {
assertThat(response.getStatus(), is(Status.CREATED.getStatusCode()));
approversId = ApiUtil.getCreatedId(response);
}

GroupRepresentation targetRep = new GroupRepresentation();
targetRep.setName("target_realm_group");
String targetId;
try (Response response = realm.admin().groups().add(targetRep)) {
assertThat(response.getStatus(), is(Status.CREATED.getStatusCode()));
targetId = ApiUtil.getCreatedId(response);
}
realm.cleanup().add(r -> r.groups().group(targetId).remove());

GroupRepresentation moveRep = new GroupRepresentation();
moveRep.setId(approversId);
moveRep.setName("approvers");
try (Response response = realm.admin().groups().group(targetId).subGroup(moveRep)) {
assertThat(response.getStatus(), is(Status.BAD_REQUEST.getStatusCode()));
}
}

@Test
public void testCannotMoveTopLevelOrgGroupViaChildrenEndpoint() {
OrganizationRepresentation orgRep = createOrganization();
OrganizationResource orgResource = realm.admin().organizations().get(orgRep.getId());

GroupRepresentation engineeringRep = new GroupRepresentation();
engineeringRep.setName("engineering");
String engineeringId;
try (Response response = orgResource.groups().addTopLevelGroup(engineeringRep)) {
assertThat(response.getStatus(), is(Status.CREATED.getStatusCode()));
engineeringId = ApiUtil.getCreatedId(response);
}

GroupRepresentation targetRep = new GroupRepresentation();
targetRep.setName("target_realm_group");
String targetId;
try (Response response = realm.admin().groups().add(targetRep)) {
assertThat(response.getStatus(), is(Status.CREATED.getStatusCode()));
targetId = ApiUtil.getCreatedId(response);
}
realm.cleanup().add(r -> r.groups().group(targetId).remove());

GroupRepresentation moveRep = new GroupRepresentation();
moveRep.setId(engineeringId);
moveRep.setName("engineering");
try (Response response = realm.admin().groups().group(targetId).subGroup(moveRep)) {
assertThat(response.getStatus(), is(Status.BAD_REQUEST.getStatusCode()));
}
}

@Test
public void testCannotUseOrgGroupInAuthorizationPolicy() {
// Organization groups cannot be used in authorization policies - only realm groups are allowed
Expand Down
Loading
0