Do not manage brokers through the Organization API

Closes #29268

Signed-off-by: Pedro Igor <pigor.craveiro@gmail.com>
This commit is contained in:
Pedro Igor 2024-05-03 10:09:08 -03:00
parent 2172741eb6
commit c0325c9fdb
10 changed files with 323 additions and 149 deletions

View file

@ -17,10 +17,8 @@
package org.keycloak.admin.client.resource; package org.keycloak.admin.client.resource;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.DELETE; import jakarta.ws.rs.DELETE;
import jakarta.ws.rs.GET; import jakarta.ws.rs.GET;
import jakarta.ws.rs.PUT;
import jakarta.ws.rs.Produces; import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
@ -32,10 +30,6 @@ public interface OrganizationIdentityProviderResource {
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
IdentityProviderRepresentation toRepresentation(); IdentityProviderRepresentation toRepresentation();
@PUT
@Consumes(MediaType.APPLICATION_JSON)
Response update(IdentityProviderRepresentation idpRepresentation);
@DELETE @DELETE
Response delete(); Response delete();
} }

View file

@ -33,7 +33,7 @@ public interface OrganizationIdentityProvidersResource {
@POST @POST
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
Response create(IdentityProviderRepresentation idpRepresentation); Response addIdentityProvider(String id);
@GET @GET
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)

View file

@ -100,7 +100,7 @@ public class JpaOrganizationProvider implements OrganizationProvider {
//TODO: won't scale, requires a better mechanism for bulk deleting users //TODO: won't scale, requires a better mechanism for bulk deleting users
userProvider.getGroupMembersStream(realm, group).forEach(userModel -> removeMember(organization, userModel)); userProvider.getGroupMembersStream(realm, group).forEach(userModel -> removeMember(organization, userModel));
groupProvider.removeGroup(realm, group); groupProvider.removeGroup(realm, group);
organization.getIdentityProviders().forEach((model) -> realm.removeIdentityProviderByAlias(model.getAlias())); organization.getIdentityProviders().forEach((model) -> removeIdentityProvider(organization, model));
em.remove(entity); em.remove(entity);
@ -216,6 +216,13 @@ public class JpaOrganizationProvider implements OrganizationProvider {
throwExceptionIfObjectIsNull(identityProvider, "Identity provider"); throwExceptionIfObjectIsNull(identityProvider, "Identity provider");
OrganizationEntity organizationEntity = getEntity(organization.getId()); OrganizationEntity organizationEntity = getEntity(organization.getId());
String orgId = identityProvider.getOrganizationId();
if (organizationEntity.getId().equals(orgId)) {
return false;
} else if (orgId != null) {
throw new ModelValidationException("Identity provider already associated with a different organization");
}
identityProvider.setOrganizationId(organizationEntity.getId()); identityProvider.setOrganizationId(organizationEntity.getId());
realm.updateIdentityProvider(identityProvider); realm.updateIdentityProvider(identityProvider);
@ -243,7 +250,8 @@ public class JpaOrganizationProvider implements OrganizationProvider {
return false; return false;
} }
realm.removeIdentityProviderByAlias(identityProvider.getAlias()); identityProvider.setOrganizationId(null);
realm.updateIdentityProvider(identityProvider);
return true; return true;
} }

View file

@ -60,6 +60,7 @@ import org.keycloak.client.clienttype.ClientType;
import org.keycloak.client.clienttype.ClientTypeException; import org.keycloak.client.clienttype.ClientTypeException;
import org.keycloak.client.clienttype.ClientTypeManager; import org.keycloak.client.clienttype.ClientTypeManager;
import org.keycloak.common.Profile; import org.keycloak.common.Profile;
import org.keycloak.common.Profile.Feature;
import org.keycloak.common.util.MultivaluedHashMap; import org.keycloak.common.util.MultivaluedHashMap;
import org.keycloak.common.util.ObjectUtil; import org.keycloak.common.util.ObjectUtil;
import org.keycloak.common.util.UriUtils; import org.keycloak.common.util.UriUtils;
@ -80,6 +81,8 @@ import org.keycloak.models.IdentityProviderModel;
import org.keycloak.models.KeycloakContext; import org.keycloak.models.KeycloakContext;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ModelException; import org.keycloak.models.ModelException;
import org.keycloak.models.OrganizationDomainModel;
import org.keycloak.models.OrganizationModel;
import org.keycloak.models.ProtocolMapperModel; import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel; import org.keycloak.models.RoleModel;
@ -92,6 +95,7 @@ import org.keycloak.models.credential.PasswordCredentialModel;
import org.keycloak.models.credential.dto.OTPCredentialData; import org.keycloak.models.credential.dto.OTPCredentialData;
import org.keycloak.models.credential.dto.OTPSecretData; import org.keycloak.models.credential.dto.OTPSecretData;
import org.keycloak.models.credential.dto.PasswordCredentialData; import org.keycloak.models.credential.dto.PasswordCredentialData;
import org.keycloak.organization.OrganizationProvider;
import org.keycloak.policy.PasswordPolicyNotMetException; import org.keycloak.policy.PasswordPolicyNotMetException;
import org.keycloak.provider.ProviderConfigProperty; import org.keycloak.provider.ProviderConfigProperty;
import org.keycloak.representations.idm.AuthenticationExecutionRepresentation; import org.keycloak.representations.idm.AuthenticationExecutionRepresentation;
@ -875,6 +879,7 @@ public class RepresentationToModel {
identityProviderModel.setAuthenticateByDefault(representation.isAuthenticateByDefault()); identityProviderModel.setAuthenticateByDefault(representation.isAuthenticateByDefault());
identityProviderModel.setStoreToken(representation.isStoreToken()); identityProviderModel.setStoreToken(representation.isStoreToken());
identityProviderModel.setAddReadTokenRoleOnCreate(representation.isAddReadTokenRoleOnCreate()); identityProviderModel.setAddReadTokenRoleOnCreate(representation.isAddReadTokenRoleOnCreate());
updateOrganizationBroker(realm, representation, session);
identityProviderModel.setConfig(removeEmptyString(representation.getConfig())); identityProviderModel.setConfig(removeEmptyString(representation.getConfig()));
String flowAlias = representation.getFirstBrokerLoginFlowAlias(); String flowAlias = representation.getFirstBrokerLoginFlowAlias();
@ -898,7 +903,7 @@ public class RepresentationToModel {
} }
identityProviderModel.setPostBrokerLoginFlowId(flowModel.getId()); identityProviderModel.setPostBrokerLoginFlowId(flowModel.getId());
} }
identityProviderModel.validate(realm); identityProviderModel.validate(realm);
return identityProviderModel; return identityProviderModel;
@ -1121,11 +1126,11 @@ public class RepresentationToModel {
resourceServer.setAllowRemoteResourceManagement(rep.isAllowRemoteResourceManagement()); resourceServer.setAllowRemoteResourceManagement(rep.isAllowRemoteResourceManagement());
DecisionStrategy decisionStrategy = rep.getDecisionStrategy(); DecisionStrategy decisionStrategy = rep.getDecisionStrategy();
if (decisionStrategy == null) { if (decisionStrategy == null) {
decisionStrategy = DecisionStrategy.UNANIMOUS; decisionStrategy = DecisionStrategy.UNANIMOUS;
} }
resourceServer.setDecisionStrategy(decisionStrategy); resourceServer.setDecisionStrategy(decisionStrategy);
for (ScopeRepresentation scope : rep.getScopes()) { for (ScopeRepresentation scope : rep.getScopes()) {
@ -1548,7 +1553,7 @@ public class RepresentationToModel {
public static Scope toModel(ScopeRepresentation scope, ResourceServer resourceServer, AuthorizationProvider authorization) { public static Scope toModel(ScopeRepresentation scope, ResourceServer resourceServer, AuthorizationProvider authorization) {
return toModel(scope, resourceServer, authorization, true); return toModel(scope, resourceServer, authorization, true);
} }
public static Scope toModel(ScopeRepresentation scope, ResourceServer resourceServer, AuthorizationProvider authorization, boolean updateIfExists) { public static Scope toModel(ScopeRepresentation scope, ResourceServer resourceServer, AuthorizationProvider authorization, boolean updateIfExists) {
StoreFactory storeFactory = authorization.getStoreFactory(); StoreFactory storeFactory = authorization.getStoreFactory();
ScopeStore scopeStore = storeFactory.getScopeStore(); ScopeStore scopeStore = storeFactory.getScopeStore();
@ -1645,4 +1650,34 @@ public class RepresentationToModel {
.map(HashSet::new) .map(HashSet::new)
.orElse(null); .orElse(null);
} }
private static void updateOrganizationBroker(RealmModel realm, IdentityProviderRepresentation representation, KeycloakSession session) {
if (!Profile.isFeatureEnabled(Feature.ORGANIZATION)) {
return;
}
IdentityProviderModel existing = realm.getIdentityProvidersStream()
.filter(p -> Objects.equals(p.getAlias(), representation.getAlias()) || Objects.equals(p.getInternalId(), representation.getInternalId()))
.findFirst().orElse(null);
String orgId = existing == null ? representation.getConfig().get(OrganizationModel.ORGANIZATION_ATTRIBUTE) : existing.getOrganizationId();
if (orgId != null) {
OrganizationProvider provider = session.getProvider(OrganizationProvider.class);
OrganizationModel org = provider.getById(orgId);
String newOrgId = representation.getConfig().get(OrganizationModel.ORGANIZATION_ATTRIBUTE);
if (org == null || (newOrgId != null && provider.getById(newOrgId) == null)) {
throw new IllegalArgumentException("Organization associated with broker does not exist");
}
String domain = representation.getConfig().get(OrganizationModel.ORGANIZATION_DOMAIN_ATTRIBUTE);
if (domain != null && org.getDomains().map(OrganizationDomainModel::getName).noneMatch(domain::equals)) {
throw new IllegalArgumentException("Domain does not match any domain from the organization");
}
// make sure the link to an organization does not change
representation.getConfig().put(OrganizationModel.ORGANIZATION_ATTRIBUTE, orgId);
}
}
} }

View file

@ -18,6 +18,7 @@
package org.keycloak.organization.admin.resource; package org.keycloak.organization.admin.resource;
import jakarta.ws.rs.Consumes; import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.DELETE;
import jakarta.ws.rs.GET; import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST; import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path; import jakarta.ws.rs.Path;
@ -28,13 +29,12 @@ import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.Status; import jakarta.ws.rs.core.Response.Status;
import jakarta.ws.rs.ext.Provider; import jakarta.ws.rs.ext.Provider;
import java.util.List; import java.util.Objects;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.keycloak.models.IdentityProviderModel; import org.keycloak.models.IdentityProviderModel;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ModelException; import org.keycloak.models.ModelException;
import org.keycloak.models.OrganizationDomainModel;
import org.keycloak.models.OrganizationModel; import org.keycloak.models.OrganizationModel;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.utils.ModelToRepresentation; import org.keycloak.models.utils.ModelToRepresentation;
@ -42,19 +42,15 @@ import org.keycloak.organization.OrganizationProvider;
import org.keycloak.representations.idm.IdentityProviderRepresentation; import org.keycloak.representations.idm.IdentityProviderRepresentation;
import org.keycloak.services.ErrorResponse; import org.keycloak.services.ErrorResponse;
import org.keycloak.services.resources.admin.AdminEventBuilder; import org.keycloak.services.resources.admin.AdminEventBuilder;
import org.keycloak.services.resources.admin.IdentityProviderResource;
import org.keycloak.services.resources.admin.IdentityProvidersResource;
import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator; import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
@Provider @Provider
public class OrganizationIdentityProvidersResource { public class OrganizationIdentityProvidersResource {
private final KeycloakSession session;
private final RealmModel realm; private final RealmModel realm;
private final OrganizationProvider organizationProvider; private final OrganizationProvider organizationProvider;
private final OrganizationModel organization; private final OrganizationModel organization;
private final AdminPermissionEvaluator auth; private final AdminPermissionEvaluator auth;
private final AdminEventBuilder adminEvent;
public OrganizationIdentityProvidersResource() { public OrganizationIdentityProvidersResource() {
// needed for registering to the JAX-RS stack // needed for registering to the JAX-RS stack
@ -62,36 +58,34 @@ public class OrganizationIdentityProvidersResource {
} }
public OrganizationIdentityProvidersResource(KeycloakSession session, OrganizationModel organization, AdminPermissionEvaluator auth, AdminEventBuilder adminEvent) { public OrganizationIdentityProvidersResource(KeycloakSession session, OrganizationModel organization, AdminPermissionEvaluator auth, AdminEventBuilder adminEvent) {
this.session = session;
this.realm = session == null ? null : session.getContext().getRealm(); this.realm = session == null ? null : session.getContext().getRealm();
this.organizationProvider = session == null ? null : session.getProvider(OrganizationProvider.class); this.organizationProvider = session == null ? null : session.getProvider(OrganizationProvider.class);
this.organization = organization; this.organization = organization;
this.auth = auth; this.auth = auth;
this.adminEvent = adminEvent;
} }
@POST @POST
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
public Response addIdentityProvider(IdentityProviderRepresentation providerRep) { public Response addIdentityProvider(String id) {
auth.realm().requireManageRealm(); auth.realm().requireManageRealm();
Response response = new IdentityProvidersResource(realm, session, auth, adminEvent).create(providerRep); try {
IdentityProviderModel identityProvider = this.realm.getIdentityProvidersStream()
.filter(p -> Objects.equals(p.getAlias(), id) || Objects.equals(p.getInternalId(), id))
.findFirst().orElse(null);
if (Status.CREATED.getStatusCode() == response.getStatus()) { if (identityProvider == null) {
try { throw ErrorResponse.error("Identity provider not found with the given alias", Status.BAD_REQUEST);
IdentityProviderModel identityProvider = realm.getIdentityProviderByAlias(providerRep.getAlias());
if (organizationProvider.addIdentityProvider(organization, identityProvider)) {
return response;
}
throw ErrorResponse.error("Identity provider already associated to the organization", Status.BAD_REQUEST);
} catch (ModelException me) {
throw ErrorResponse.error(me.getMessage(), Status.BAD_REQUEST);
} }
}
return response; if (organizationProvider.addIdentityProvider(organization, identityProvider)) {
return Response.noContent().build();
}
throw ErrorResponse.error("Identity provider already associated to the organization", Status.CONFLICT);
} catch (ModelException me) {
throw ErrorResponse.error(me.getMessage(), Status.BAD_REQUEST);
}
} }
@GET @GET
@ -102,37 +96,40 @@ public class OrganizationIdentityProvidersResource {
} }
@Path("{alias}") @Path("{alias}")
public IdentityProviderResource getIdentityProvider(@PathParam("alias") String alias) { @GET
@Produces(MediaType.APPLICATION_JSON)
public IdentityProviderRepresentation getIdentityProvider(@PathParam("alias") String alias) {
IdentityProviderModel broker = realm.getIdentityProviderByAlias(alias); IdentityProviderModel broker = realm.getIdentityProviderByAlias(alias);
return new IdentityProviderResource(auth, realm, session, broker, adminEvent) {
@Override
public Response delete() {
Response response = super.delete();
if (organizationProvider.removeIdentityProvider(organization, broker)) { if (!isOrganizationBroker(broker)) {
return response; throw ErrorResponse.error("Identity provider not associated with the organization", Status.NOT_FOUND);
} }
throw ErrorResponse.error("Identity provider not associated with the organization", Status.BAD_REQUEST); return ModelToRepresentation.toRepresentation(realm, broker);
} }
@Override @Path("{alias}")
public Response update(IdentityProviderRepresentation providerRep) { @DELETE
if (organization.getIdentityProviders().noneMatch(model -> model.getInternalId().equals(providerRep.getInternalId()) || model.getAlias().equals(providerRep.getAlias()))) { @Produces(MediaType.APPLICATION_JSON)
return Response.status(Status.NOT_FOUND).build(); public Response delete(@PathParam("alias") String alias) {
} IdentityProviderModel broker = realm.getIdentityProviderByAlias(alias);
String domain = providerRep.getConfig().get(OrganizationModel.ORGANIZATION_DOMAIN_ATTRIBUTE);
if (domain != null && organization.getDomains().map(OrganizationDomainModel::getName).noneMatch(domain::equals)) { if (!isOrganizationBroker(broker)) {
return Response.status(Status.BAD_REQUEST).build(); throw ErrorResponse.error("Identity provider not found with the given alias", Status.NOT_FOUND);
} }
return super.update(providerRep); if (organizationProvider.removeIdentityProvider(organization, broker)) {
} return Response.noContent().build();
}; }
throw ErrorResponse.error("Identity provider not associated with the organization", Status.BAD_REQUEST);
} }
private IdentityProviderRepresentation toRepresentation(IdentityProviderModel idp) { private IdentityProviderRepresentation toRepresentation(IdentityProviderModel idp) {
return ModelToRepresentation.toRepresentation(realm, idp); return ModelToRepresentation.toRepresentation(realm, idp);
} }
private boolean isOrganizationBroker(IdentityProviderModel broker) {
return broker != null && organization.getId().equals(broker.getOrganizationId());
}
} }

View file

@ -30,6 +30,7 @@ import org.jboss.arquillian.graphene.page.Page;
import org.keycloak.admin.client.resource.OrganizationResource; import org.keycloak.admin.client.resource.OrganizationResource;
import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.admin.client.resource.UsersResource; import org.keycloak.admin.client.resource.UsersResource;
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.representations.idm.RealmRepresentation;
@ -144,8 +145,10 @@ public abstract class AbstractOrganizationTest extends AbstractAdminTest {
assertEquals(Status.CREATED.getStatusCode(), response.getStatus()); assertEquals(Status.CREATED.getStatusCode(), response.getStatus());
id = ApiUtil.getCreatedId(response); id = ApiUtil.getCreatedId(response);
} }
IdentityProviderRepresentation broker = brokerConfigFunction.apply(name).setUpIdentityProvider();
testRealm().organizations().get(id).identityProviders().create(brokerConfigFunction.apply(name).setUpIdentityProvider()).close(); testRealm().identityProviders().create(broker).close();
getCleanup().addCleanup(testRealm().identityProviders().get(broker.getAlias())::remove);
testRealm().organizations().get(id).identityProviders().addIdentityProvider(broker.getAlias()).close();
org = testRealm().organizations().get(id).toRepresentation(); org = testRealm().organizations().get(id).toRepresentation();
getCleanup().addCleanup(() -> testRealm().organizations().get(id).delete().close()); getCleanup().addCleanup(() -> testRealm().organizations().get(id).delete().close());

View file

@ -0,0 +1,130 @@
/*
* Copyright 2024 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.organization.admin;
import static org.keycloak.testsuite.AbstractTestRealmKeycloakTest.TEST_REALM_NAME;
import java.util.List;
import org.keycloak.models.IdentityProviderSyncMode;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.IdentityProviderRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.testsuite.broker.BrokerConfiguration;
import org.keycloak.testsuite.util.UserBuilder;
public class BrokerConfigurationWrapper implements BrokerConfiguration {
private final String orgName;
private final BrokerConfiguration delegate;
public BrokerConfigurationWrapper(String orgName, BrokerConfiguration delegate) {
this.orgName = orgName;
this.delegate = delegate;
}
@Override
public String consumerRealmName() {
return TEST_REALM_NAME;
}
@Override
public RealmRepresentation createProviderRealm() {
RealmRepresentation providerRealm = delegate.createProviderRealm();
providerRealm.setClients(createProviderClients());
providerRealm.setUsers(List.of(
UserBuilder.create()
.username(getUserLogin())
.email(getUserEmail())
.password(getUserPassword())
.enabled(true)
.build(),
UserBuilder.create()
.username("external")
.email("external@user.org")
.password("password")
.enabled(true)
.build()
)
);
return providerRealm;
}
@Override
public String getUserEmail() {
return getUserLogin() + "@" + orgName + ".org";
}
@Override
public String getIDPAlias() {
return orgName + "-identity-provider";
}
@Override
public IdentityProviderRepresentation setUpIdentityProvider() {
IdentityProviderRepresentation broker = delegate.setUpIdentityProvider();
broker.setAlias(getIDPAlias());
return broker;
}
@Override
public List<ClientRepresentation> createProviderClients() {
List<ClientRepresentation> clients = delegate.createProviderClients();
clients.get(0).setRedirectUris(List.of("*"));
return clients;
}
@Override
public RealmRepresentation createConsumerRealm() {
return delegate.createConsumerRealm();
}
@Override
public List<ClientRepresentation> createConsumerClients() {
return delegate.createConsumerClients();
}
@Override
public IdentityProviderRepresentation setUpIdentityProvider(IdentityProviderSyncMode force) {
IdentityProviderRepresentation broker = delegate.setUpIdentityProvider(force);
broker.setAlias(getIDPAlias());
return broker;
}
@Override
public String providerRealmName() {
return delegate.providerRealmName();
}
@Override
public String getIDPClientIdInProviderRealm() {
return delegate.getIDPClientIdInProviderRealm();
}
@Override
public String getUserLogin() {
return delegate.getUserLogin();
}
@Override
public String getUserPassword() {
return delegate.getUserPassword();
}
}

View file

@ -105,13 +105,15 @@ public class OrganizationAdminPermissionsTest extends AbstractOrganizationTest {
IdentityProviderRepresentation idpRep = new IdentityProviderRepresentation(); IdentityProviderRepresentation idpRep = new IdentityProviderRepresentation();
idpRep.setAlias("dummy"); idpRep.setAlias("dummy");
idpRep.setProviderId("oidc"); idpRep.setProviderId("oidc");
realmAdminResource.identityProviders().create(idpRep).close();
//create IdP //create IdP
try ( try (
Response userResponse = realmUserResource.organizations().get(orgId).identityProviders().create(idpRep); Response userResponse = realmUserResource.organizations().get(orgId).identityProviders().addIdentityProvider(idpRep.getAlias());
Response adminResponse = realmAdminResource.organizations().get(orgId).identityProviders().create(idpRep) Response adminResponse = realmAdminResource.organizations().get(orgId).identityProviders().addIdentityProvider(idpRep.getAlias())
) { ) {
assertThat(userResponse.getStatus(), equalTo(Status.FORBIDDEN.getStatusCode())); assertThat(userResponse.getStatus(), equalTo(Status.FORBIDDEN.getStatusCode()));
assertThat(adminResponse.getStatus(), equalTo(Status.CREATED.getStatusCode())); assertThat(adminResponse.getStatus(), equalTo(Status.NO_CONTENT.getStatusCode()));
getCleanup().addCleanup(() -> testRealm().organizations().get(orgId).identityProviders().get(idpRep.getAlias()).delete().close()); getCleanup().addCleanup(() -> testRealm().organizations().get(orgId).identityProviders().get(idpRep.getAlias()).delete().close());
} }
@ -127,11 +129,6 @@ public class OrganizationAdminPermissionsTest extends AbstractOrganizationTest {
} catch (ForbiddenException expected) {} } catch (ForbiddenException expected) {}
assertThat(realmAdminResource.organizations().get(orgId).identityProviders().get(idpRep.getAlias()).toRepresentation(), Matchers.notNullValue()); assertThat(realmAdminResource.organizations().get(orgId).identityProviders().get(idpRep.getAlias()).toRepresentation(), Matchers.notNullValue());
//update IdP
try (Response userResponse = realmUserResource.organizations().get(orgId).identityProviders().get(idpRep.getAlias()).update(idpRep)) {
assertThat(userResponse.getStatus(), equalTo(Status.FORBIDDEN.getStatusCode()));
}
//delete IdP //delete IdP
try (Response userResponse = realmUserResource.organizations().get(orgId).identityProviders().get(idpRep.getAlias()).delete()) { try (Response userResponse = realmUserResource.organizations().get(orgId).identityProviders().get(idpRep.getAlias()).delete()) {
assertThat(userResponse.getStatus(), equalTo(Status.FORBIDDEN.getStatusCode())); assertThat(userResponse.getStatus(), equalTo(Status.FORBIDDEN.getStatusCode()));

View file

@ -61,7 +61,7 @@ public class OrganizationBrokerSelfRegistrationTest extends AbstractOrganization
OrganizationResource organization = testRealm().organizations().get(createOrganization().getId()); OrganizationResource organization = testRealm().organizations().get(createOrganization().getId());
IdentityProviderRepresentation idp = organization.identityProviders().get(bc.getIDPAlias()).toRepresentation(); IdentityProviderRepresentation idp = organization.identityProviders().get(bc.getIDPAlias()).toRepresentation();
idp.getConfig().put(IdentityProviderModel.LOGIN_HINT, "true"); idp.getConfig().put(IdentityProviderModel.LOGIN_HINT, "true");
organization.identityProviders().get(bc.getIDPAlias()).update(idp).close(); testRealm().identityProviders().get(bc.getIDPAlias()).update(idp);
oauth.clientId("broker-app"); oauth.clientId("broker-app");
loginPage.open(bc.consumerRealmName()); loginPage.open(bc.consumerRealmName());
@ -127,10 +127,10 @@ public class OrganizationBrokerSelfRegistrationTest extends AbstractOrganization
// create a realm user in the consumer realm // create a realm user in the consumer realm
realmsResouce().realm(bc.consumerRealmName()).users() realmsResouce().realm(bc.consumerRealmName()).users()
.create(UserBuilder.create() .create(UserBuilder.create()
.username(bc.getUserLogin()) .username(bc.getUserLogin())
.email(bc.getUserEmail()) .email(bc.getUserEmail())
.password(bc.getUserPassword()) .password(bc.getUserPassword())
.enabled(true).build() .enabled(true).build()
).close(); ).close();
OrganizationResource organization = testRealm().organizations().get(createOrganization().getId()); OrganizationResource organization = testRealm().organizations().get(createOrganization().getId());
@ -174,6 +174,7 @@ public class OrganizationBrokerSelfRegistrationTest extends AbstractOrganization
// logout to force the user to authenticate again // logout to force the user to authenticate again
UserRepresentation account = getUserRepresentation(bc.getUserEmail()); UserRepresentation account = getUserRepresentation(bc.getUserEmail());
realmsResouce().realm(bc.consumerRealmName()).users().get(account.getId()).logout(); realmsResouce().realm(bc.consumerRealmName()).users().get(account.getId()).logout();
realmsResouce().realm(bc.providerRealmName()).logoutAll();
// login with email only // login with email only
loginPage.open(bc.consumerRealmName()); loginPage.open(bc.consumerRealmName());
@ -197,7 +198,7 @@ public class OrganizationBrokerSelfRegistrationTest extends AbstractOrganization
OrganizationIdentityProviderResource idp = organization.identityProviders().get(bc.getIDPAlias()); OrganizationIdentityProviderResource idp = organization.identityProviders().get(bc.getIDPAlias());
IdentityProviderRepresentation idpRep = idp.toRepresentation(); IdentityProviderRepresentation idpRep = idp.toRepresentation();
idpRep.getConfig().put(OrganizationModel.ORGANIZATION_DOMAIN_ATTRIBUTE, "neworg.org"); idpRep.getConfig().put(OrganizationModel.ORGANIZATION_DOMAIN_ATTRIBUTE, "neworg.org");
idp.update(idpRep).close(); testRealm().identityProviders().get(idpRep.getAlias()).update(idpRep);
// add the member for the first time // add the member for the first time
assertBrokerRegistration(organization, bc.getUserEmail()); assertBrokerRegistration(organization, bc.getUserEmail());
@ -248,11 +249,13 @@ public class OrganizationBrokerSelfRegistrationTest extends AbstractOrganization
OrganizationResource organization = testRealm().organizations().get(createOrganization().getId()); OrganizationResource organization = testRealm().organizations().get(createOrganization().getId());
IdentityProviderRepresentation idp = organization.identityProviders().get(bc.getIDPAlias()).toRepresentation(); IdentityProviderRepresentation idp = organization.identityProviders().get(bc.getIDPAlias()).toRepresentation();
idp.getConfig().put(OrganizationModel.ORGANIZATION_DOMAIN_ATTRIBUTE, "neworg.org"); idp.getConfig().put(OrganizationModel.ORGANIZATION_DOMAIN_ATTRIBUTE, "neworg.org");
organization.identityProviders().get(bc.getIDPAlias()).update(idp).close(); testRealm().identityProviders().get(bc.getIDPAlias()).update(idp);
idp.setAlias("second-idp"); idp.setAlias("second-idp");
idp.setInternalId(null); idp.setInternalId(null);
idp.getConfig().remove(OrganizationModel.ORGANIZATION_DOMAIN_ATTRIBUTE); idp.getConfig().remove(OrganizationModel.ORGANIZATION_DOMAIN_ATTRIBUTE);
organization.identityProviders().create(idp).close(); testRealm().identityProviders().create(idp).close();
getCleanup().addCleanup(testRealm().identityProviders().get("second-idp")::remove);
organization.identityProviders().addIdentityProvider(idp.getAlias()).close();
oauth.clientId("broker-app"); oauth.clientId("broker-app");
loginPage.open(bc.consumerRealmName()); loginPage.open(bc.consumerRealmName());
@ -290,7 +293,7 @@ public class OrganizationBrokerSelfRegistrationTest extends AbstractOrganization
IdentityProviderRepresentation idp = organization.identityProviders().get(bc.getIDPAlias()).toRepresentation(); IdentityProviderRepresentation idp = organization.identityProviders().get(bc.getIDPAlias()).toRepresentation();
idp.getConfig().put(OrganizationModel.ORGANIZATION_DOMAIN_ATTRIBUTE, "neworg.org"); idp.getConfig().put(OrganizationModel.ORGANIZATION_DOMAIN_ATTRIBUTE, "neworg.org");
// set a domain to the existing broker // set a domain to the existing broker
organization.identityProviders().get(bc.getIDPAlias()).update(idp).close(); testRealm().identityProviders().get(bc.getIDPAlias()).update(idp);
idp = bc.setUpIdentityProvider(); idp = bc.setUpIdentityProvider();
idp.setAlias("second-idp"); idp.setAlias("second-idp");
@ -298,7 +301,9 @@ public class OrganizationBrokerSelfRegistrationTest extends AbstractOrganization
idp.getConfig().remove(OrganizationModel.ORGANIZATION_DOMAIN_ATTRIBUTE); idp.getConfig().remove(OrganizationModel.ORGANIZATION_DOMAIN_ATTRIBUTE);
idp.getConfig().put(OrganizationModel.BROKER_PUBLIC, Boolean.TRUE.toString()); idp.getConfig().put(OrganizationModel.BROKER_PUBLIC, Boolean.TRUE.toString());
// create a second broker without a domain set // create a second broker without a domain set
organization.identityProviders().create(idp).close(); testRealm().identityProviders().create(idp).close();
getCleanup().addCleanup(testRealm().identityProviders().get("second-idp")::remove);
organization.identityProviders().addIdentityProvider(idp.getAlias()).close();
idp = organization.identityProviders().get(idp.getAlias()).toRepresentation(); idp = organization.identityProviders().get(idp.getAlias()).toRepresentation();
oauth.clientId("broker-app"); oauth.clientId("broker-app");
@ -313,7 +318,7 @@ public class OrganizationBrokerSelfRegistrationTest extends AbstractOrganization
Assert.assertTrue(loginPage.isSocialButtonPresent(idp.getAlias())); Assert.assertTrue(loginPage.isSocialButtonPresent(idp.getAlias()));
idp.getConfig().put(OrganizationModel.BROKER_PUBLIC, Boolean.FALSE.toString()); idp.getConfig().put(OrganizationModel.BROKER_PUBLIC, Boolean.FALSE.toString());
organization.identityProviders().get(idp.getAlias()).update(idp).close(); testRealm().identityProviders().get(idp.getAlias()).update(idp);
driver.navigate().refresh(); driver.navigate().refresh();
Assert.assertTrue(loginPage.isPasswordInputPresent()); Assert.assertTrue(loginPage.isPasswordInputPresent());
Assert.assertFalse(loginPage.isSocialButtonPresent(bc.getIDPAlias())); Assert.assertFalse(loginPage.isSocialButtonPresent(bc.getIDPAlias()));
@ -326,7 +331,7 @@ public class OrganizationBrokerSelfRegistrationTest extends AbstractOrganization
IdentityProviderRepresentation idp = organization.identityProviders().get(bc.getIDPAlias()).toRepresentation(); IdentityProviderRepresentation idp = organization.identityProviders().get(bc.getIDPAlias()).toRepresentation();
idp.getConfig().put(OrganizationModel.ORGANIZATION_DOMAIN_ATTRIBUTE, "neworg.org"); idp.getConfig().put(OrganizationModel.ORGANIZATION_DOMAIN_ATTRIBUTE, "neworg.org");
// set a domain to the existing broker // set a domain to the existing broker
organization.identityProviders().get(bc.getIDPAlias()).update(idp).close(); testRealm().identityProviders().get(bc.getIDPAlias()).update(idp);
idp = bc.setUpIdentityProvider(); idp = bc.setUpIdentityProvider();
idp.setAlias("second-idp"); idp.setAlias("second-idp");
@ -334,7 +339,9 @@ public class OrganizationBrokerSelfRegistrationTest extends AbstractOrganization
idp.getConfig().remove(OrganizationModel.ORGANIZATION_DOMAIN_ATTRIBUTE); idp.getConfig().remove(OrganizationModel.ORGANIZATION_DOMAIN_ATTRIBUTE);
idp.getConfig().put(OrganizationModel.BROKER_PUBLIC, Boolean.TRUE.toString()); idp.getConfig().put(OrganizationModel.BROKER_PUBLIC, Boolean.TRUE.toString());
// create a second broker without a domain set // create a second broker without a domain set
organization.identityProviders().create(idp).close(); testRealm().identityProviders().create(idp).close();
getCleanup().addCleanup(testRealm().identityProviders().get("second-idp")::remove);
organization.identityProviders().addIdentityProvider(idp.getAlias()).close();
oauth.clientId("broker-app"); oauth.clientId("broker-app");
loginPage.open(bc.consumerRealmName()); loginPage.open(bc.consumerRealmName());
@ -375,7 +382,7 @@ public class OrganizationBrokerSelfRegistrationTest extends AbstractOrganization
IdentityProviderRepresentation idp = organization.identityProviders().get(bc.getIDPAlias()).toRepresentation(); IdentityProviderRepresentation idp = organization.identityProviders().get(bc.getIDPAlias()).toRepresentation();
idp.getConfig().put(OrganizationModel.ORGANIZATION_DOMAIN_ATTRIBUTE, "neworg.org"); idp.getConfig().put(OrganizationModel.ORGANIZATION_DOMAIN_ATTRIBUTE, "neworg.org");
// set a domain to the existing broker // set a domain to the existing broker
organization.identityProviders().get(bc.getIDPAlias()).update(idp).close(); testRealm().identityProviders().get(bc.getIDPAlias()).update(idp);
idp = bc.setUpIdentityProvider(); idp = bc.setUpIdentityProvider();
idp.setAlias("second-idp"); idp.setAlias("second-idp");
@ -383,7 +390,9 @@ public class OrganizationBrokerSelfRegistrationTest extends AbstractOrganization
idp.getConfig().put(OrganizationModel.ORGANIZATION_DOMAIN_ATTRIBUTE, "other.org"); idp.getConfig().put(OrganizationModel.ORGANIZATION_DOMAIN_ATTRIBUTE, "other.org");
idp.getConfig().put(OrganizationModel.BROKER_PUBLIC, Boolean.TRUE.toString()); idp.getConfig().put(OrganizationModel.BROKER_PUBLIC, Boolean.TRUE.toString());
// create a second broker without a domain set // create a second broker without a domain set
organization.identityProviders().create(idp).close(); testRealm().identityProviders().create(idp).close();
getCleanup().addCleanup(testRealm().identityProviders().get("second-idp")::remove);
organization.identityProviders().addIdentityProvider(idp.getAlias()).close();
oauth.clientId("broker-app"); oauth.clientId("broker-app");
loginPage.open(bc.consumerRealmName()); loginPage.open(bc.consumerRealmName());
@ -421,14 +430,16 @@ public class OrganizationBrokerSelfRegistrationTest extends AbstractOrganization
IdentityProviderRepresentation idp = organization.identityProviders().get(bc.getIDPAlias()).toRepresentation(); IdentityProviderRepresentation idp = organization.identityProviders().get(bc.getIDPAlias()).toRepresentation();
idp.getConfig().put(OrganizationModel.ORGANIZATION_DOMAIN_ATTRIBUTE, "neworg.org"); idp.getConfig().put(OrganizationModel.ORGANIZATION_DOMAIN_ATTRIBUTE, "neworg.org");
// set a domain to the existing broker // set a domain to the existing broker
organization.identityProviders().get(bc.getIDPAlias()).update(idp).close(); testRealm().identityProviders().get(bc.getIDPAlias()).update(idp);
idp = bc.setUpIdentityProvider(); idp = bc.setUpIdentityProvider();
idp.setAlias("second-idp"); idp.setAlias("second-idp");
idp.setInternalId(null); idp.setInternalId(null);
idp.getConfig().put(OrganizationModel.BROKER_PUBLIC, Boolean.TRUE.toString()); idp.getConfig().put(OrganizationModel.BROKER_PUBLIC, Boolean.TRUE.toString());
// create a second broker without a domain set // create a second broker without a domain set
organization.identityProviders().create(idp).close(); testRealm().identityProviders().create(idp).close();
getCleanup().addCleanup(testRealm().identityProviders().get("second-idp")::remove);
organization.identityProviders().addIdentityProvider(idp.getAlias()).close();
oauth.clientId("broker-app"); oauth.clientId("broker-app");
loginPage.open(bc.consumerRealmName()); loginPage.open(bc.consumerRealmName());
@ -498,7 +509,7 @@ public class OrganizationBrokerSelfRegistrationTest extends AbstractOrganization
// make sure the user can select this idp from the organization when authenticating // make sure the user can select this idp from the organization when authenticating
idpRep.getConfig().put(OrganizationModel.BROKER_PUBLIC, Boolean.TRUE.toString()); idpRep.getConfig().put(OrganizationModel.BROKER_PUBLIC, Boolean.TRUE.toString());
organization.identityProviders().get(idpRep.getAlias()).update(idpRep).close(); testRealm().identityProviders().get(idpRep.getAlias()).update(idpRep);
// create a user to the provider realm using a email that does not share the same domain as the org // create a user to the provider realm using a email that does not share the same domain as the org
UserRepresentation user = UserBuilder.create() UserRepresentation user = UserBuilder.create()
@ -536,7 +547,7 @@ public class OrganizationBrokerSelfRegistrationTest extends AbstractOrganization
// make sure the user can select this idp from the organization when authenticating // make sure the user can select this idp from the organization when authenticating
idpRep.getConfig().put(OrganizationModel.BROKER_PUBLIC, Boolean.TRUE.toString()); idpRep.getConfig().put(OrganizationModel.BROKER_PUBLIC, Boolean.TRUE.toString());
organization.identityProviders().get(idpRep.getAlias()).update(idpRep).close(); testRealm().identityProviders().get(idpRep.getAlias()).update(idpRep);
// create a user to the provider realm using a email that does not share the same domain as the org // create a user to the provider realm using a email that does not share the same domain as the org
UserRepresentation user = UserBuilder.create() UserRepresentation user = UserBuilder.create()
@ -571,6 +582,7 @@ public class OrganizationBrokerSelfRegistrationTest extends AbstractOrganization
updateAccountInformationPage.updateAccountInformation(user.getUsername(), user.getEmail(), "Firstname", "Lastname"); updateAccountInformationPage.updateAccountInformation(user.getUsername(), user.getEmail(), "Firstname", "Lastname");
UserRepresentation account = getUserRepresentation(user.getEmail()); UserRepresentation account = getUserRepresentation(user.getEmail());
realmsResouce().realm(bc.consumerRealmName()).users().get(account.getId()).logout(); realmsResouce().realm(bc.consumerRealmName()).users().get(account.getId()).logout();
realmsResouce().realm(bc.providerRealmName()).logoutAll();
// the flow now changed and the user should be automatically redirected to the origin broker // the flow now changed and the user should be automatically redirected to the origin broker
loginPage.open(bc.consumerRealmName()); loginPage.open(bc.consumerRealmName());

View file

@ -20,11 +20,13 @@ package org.keycloak.testsuite.organization.admin;
import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import jakarta.ws.rs.BadRequestException;
import jakarta.ws.rs.NotFoundException; import jakarta.ws.rs.NotFoundException;
import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.Status; import jakarta.ws.rs.core.Response.Status;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.keycloak.admin.client.resource.IdentityProviderResource;
import org.keycloak.admin.client.resource.OrganizationIdentityProviderResource; import org.keycloak.admin.client.resource.OrganizationIdentityProviderResource;
import org.keycloak.admin.client.resource.OrganizationResource; import org.keycloak.admin.client.resource.OrganizationResource;
import org.keycloak.common.Profile.Feature; import org.keycloak.common.Profile.Feature;
@ -41,28 +43,35 @@ public class OrganizationIdentityProviderTest extends AbstractOrganizationTest {
OrganizationRepresentation organization = createOrganization(); OrganizationRepresentation organization = createOrganization();
OrganizationIdentityProviderResource orgIdPResource = testRealm().organizations().get(organization.getId()) OrganizationIdentityProviderResource orgIdPResource = testRealm().organizations().get(organization.getId())
.identityProviders().get(bc.getIDPAlias()); .identityProviders().get(bc.getIDPAlias());
IdentityProviderRepresentation actual = orgIdPResource.toRepresentation(); IdentityProviderRepresentation expected = orgIdPResource.toRepresentation();
IdentityProviderRepresentation expected = actual;
assertThat(expected.getAlias(), equalTo(bc.getIDPAlias()));
//update // organization link set
expected.setAlias("changed-alias"); Assert.assertEquals(expected.getConfig().get(OrganizationModel.ORGANIZATION_ATTRIBUTE), organization.getId());
expected.setDisplayName("My Org Broker");
expected.getConfig().put("test", "value"); IdentityProviderResource idpResource = testRealm().identityProviders().get(expected.getAlias());
try (Response response = orgIdPResource.update(expected)) { IdentityProviderRepresentation actual = idpResource.toRepresentation();
assertThat(response.getStatus(), equalTo(Response.Status.NO_CONTENT.getStatusCode())); Assert.assertEquals(actual.getConfig().get(OrganizationModel.ORGANIZATION_ATTRIBUTE), organization.getId());
} actual.getConfig().put(OrganizationModel.ORGANIZATION_ATTRIBUTE, "somethingelse");
try { try {
orgIdPResource.toRepresentation(); idpResource.update(actual);
Assert.fail("should fail because the alias changed"); Assert.fail("Should fail because it maps to an invalid org");
} catch (NotFoundException ignore) { } catch (BadRequestException ignore) {
} }
orgIdPResource = testRealm().organizations().get(organization.getId()).identityProviders().get(expected.getAlias());
actual = orgIdPResource.toRepresentation(); OrganizationRepresentation secondOrg = createOrganization("secondorg");
assertThat(expected.getAlias(), equalTo(actual.getAlias())); actual.getConfig().put(OrganizationModel.ORGANIZATION_ATTRIBUTE, secondOrg.getId());
assertThat(expected.getDisplayName(), equalTo(actual.getDisplayName())); idpResource.update(actual);
Assert.assertEquals(expected.getConfig().get("test"), actual.getConfig().get("test")); actual = idpResource.toRepresentation();
Assert.assertEquals(actual.getConfig().get(OrganizationModel.ORGANIZATION_ATTRIBUTE), organization.getId());
actual = idpResource.toRepresentation();
// the link to the organization should not change
Assert.assertEquals(actual.getConfig().get(OrganizationModel.ORGANIZATION_ATTRIBUTE), organization.getId());
actual.getConfig().remove(OrganizationModel.ORGANIZATION_ATTRIBUTE);
idpResource.update(actual);
actual = idpResource.toRepresentation();
// the link to the organization should not change
Assert.assertEquals(actual.getConfig().get(OrganizationModel.ORGANIZATION_ATTRIBUTE), organization.getId());
} }
@Test @Test
@ -74,13 +83,15 @@ public class OrganizationIdentityProviderTest extends AbstractOrganizationTest {
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
idpTemplate.setAlias("idp-" + i); idpTemplate.setAlias("idp-" + i);
idpTemplate.setInternalId(null); idpTemplate.setInternalId(null);
organization.identityProviders().create(idpTemplate).close(); testRealm().identityProviders().create(idpTemplate).close();
organization.identityProviders().addIdentityProvider(idpTemplate.getAlias()).close();
} }
Assert.assertEquals(6, organization.identityProviders().getIdentityProviders().size()); Assert.assertEquals(6, organization.identityProviders().getIdentityProviders().size());
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
OrganizationIdentityProviderResource idpResource = organization.identityProviders().get("idp-" + i); String alias = "idp-" + i;
OrganizationIdentityProviderResource idpResource = organization.identityProviders().get(alias);
try (Response response = idpResource.delete()) { try (Response response = idpResource.delete()) {
assertThat(response.getStatus(), equalTo(Response.Status.NO_CONTENT.getStatusCode())); assertThat(response.getStatus(), equalTo(Response.Status.NO_CONTENT.getStatusCode()));
@ -91,11 +102,13 @@ public class OrganizationIdentityProviderTest extends AbstractOrganizationTest {
Assert.fail("should be removed"); Assert.fail("should be removed");
} catch (NotFoundException expected) { } catch (NotFoundException expected) {
} }
// not removed from the realm
testRealm().identityProviders().get(alias).toRepresentation();
} }
organization.identityProviders().get(bc.getIDPAlias()).delete().close(); organization.identityProviders().get(bc.getIDPAlias()).delete().close();
Assert.assertFalse(testRealm().identityProviders().findAll().isEmpty());
Assert.assertTrue(testRealm().identityProviders().findAll().isEmpty());
} }
@Test @Test
@ -108,20 +121,25 @@ public class OrganizationIdentityProviderTest extends AbstractOrganizationTest {
String alias = idpRepresentation.getAlias(); String alias = idpRepresentation.getAlias();
idpRepresentation.setAlias("another-idp"); idpRepresentation.setAlias("another-idp");
testRealm().identityProviders().create(idpRepresentation).close();
try (Response response = organization.identityProviders().create(idpRepresentation)) { try (Response response = organization.identityProviders().addIdentityProvider(alias)) {
// already associated with the org
assertThat(response.getStatus(), equalTo(Status.CONFLICT.getStatusCode())); assertThat(response.getStatus(), equalTo(Status.CONFLICT.getStatusCode()));
} }
idpRepresentation.setAlias(alias); idpRepresentation.setAlias(alias);
idpRepresentation.setInternalId(null); idpRepresentation.setInternalId(null);
try (Response response = organization.identityProviders().create(idpRepresentation)) { OrganizationResource secondOrg = testRealm().organizations().get(createOrganization("secondorg").getId());
assertThat(response.getStatus(), equalTo(Status.CONFLICT.getStatusCode()));
try (Response response = secondOrg.identityProviders().addIdentityProvider(alias)) {
// associated with another org
assertThat(response.getStatus(), equalTo(Status.BAD_REQUEST.getStatusCode()));
} }
} }
@Test(expected = jakarta.ws.rs.NotFoundException.class) @Test
public void testRemovingOrgShouldRemoveIdP() { public void testRemovingOrgShouldRemoveIdP() {
OrganizationRepresentation orgRep = createOrganization(); OrganizationRepresentation orgRep = createOrganization();
OrganizationResource orgResource = testRealm().organizations().get(orgRep.getId()); OrganizationResource orgResource = testRealm().organizations().get(orgRep.getId());
@ -130,8 +148,10 @@ public class OrganizationIdentityProviderTest extends AbstractOrganizationTest {
assertThat(response.getStatus(), equalTo(Response.Status.NO_CONTENT.getStatusCode())); assertThat(response.getStatus(), equalTo(Response.Status.NO_CONTENT.getStatusCode()));
} }
testRealm().identityProviders().get(bc.getIDPAlias()).toRepresentation(); // broker not removed from realm
Assert.assertTrue(testRealm().identityProviders().findAll().isEmpty()); IdentityProviderRepresentation idpRep = testRealm().identityProviders().get(bc.getIDPAlias()).toRepresentation();
// broker no longer linked to the org
Assert.assertNull(idpRep.getConfig().get(OrganizationModel.ORGANIZATION_ATTRIBUTE));
} }
@Test @Test
@ -144,10 +164,6 @@ public class OrganizationIdentityProviderTest extends AbstractOrganizationTest {
//create IdP in realm not bound to Org //create IdP in realm not bound to Org
testRealm().identityProviders().create(idpRepresentation).close(); testRealm().identityProviders().create(idpRepresentation).close();
try (Response response = orgIdPResource.update(idpRepresentation)) {
assertThat(response.getStatus(), equalTo(Response.Status.NOT_FOUND.getStatusCode()));
}
try (Response response = orgIdPResource.delete()) { try (Response response = orgIdPResource.delete()) {
assertThat(response.getStatus(), equalTo(Status.NO_CONTENT.getStatusCode())); assertThat(response.getStatus(), equalTo(Status.NO_CONTENT.getStatusCode()));
} }
@ -157,33 +173,6 @@ public class OrganizationIdentityProviderTest extends AbstractOrganizationTest {
} }
} }
@Test
public void tryUpdateIdPWithValidAliasInvalidInternalId() {
OrganizationRepresentation orgRep = createOrganization();
OrganizationResource orgResource = testRealm().organizations().get(orgRep.getId());
OrganizationIdentityProviderResource orgIdPResource = orgResource.identityProviders().get(bc.getIDPAlias());
IdentityProviderRepresentation idpRepresentation = createRep("some-broker", "oidc");
//create IdP in realm not bound to Org and get created internalId
testRealm().identityProviders().create(idpRepresentation).close();
getCleanup().addCleanup(() -> testRealm().identityProviders().get(idpRepresentation.getAlias()).remove());
String internalId = testRealm().identityProviders().get("some-broker").toRepresentation().getInternalId();
IdentityProviderRepresentation orgIdPRep = orgIdPResource.toRepresentation();
orgIdPRep.setInternalId(internalId);
try (Response response = orgIdPResource.update(orgIdPRep)) {
assertThat(response.getStatus(), equalTo(Status.CONFLICT.getStatusCode()));
}
orgIdPRep.setAlias("some-broker-alias");
try (Response response = orgIdPResource.update(orgIdPRep)) {
assertThat(response.getStatus(), equalTo(Response.Status.NOT_FOUND.getStatusCode()));
}
}
@Test @Test
public void testAssignDomainNotBoundToOrganization() { public void testAssignDomainNotBoundToOrganization() {
OrganizationRepresentation orgRep = createOrganization(); OrganizationRepresentation orgRep = createOrganization();
@ -192,8 +181,17 @@ public class OrganizationIdentityProviderTest extends AbstractOrganizationTest {
IdentityProviderRepresentation idpRep = orgIdPResource.toRepresentation(); IdentityProviderRepresentation idpRep = orgIdPResource.toRepresentation();
idpRep.getConfig().put(OrganizationModel.ORGANIZATION_DOMAIN_ATTRIBUTE, "unknown.org"); idpRep.getConfig().put(OrganizationModel.ORGANIZATION_DOMAIN_ATTRIBUTE, "unknown.org");
try (Response response = orgIdPResource.update(idpRep)) { try {
assertThat(response.getStatus(), equalTo(Status.BAD_REQUEST.getStatusCode())); testRealm().identityProviders().get(idpRep.getAlias()).update(idpRep);
Assert.fail("Domain set to broker is invalid");
} catch (BadRequestException ignore) {
}
idpRep.setAlias("newbroker");
idpRep.setInternalId(null);
try (Response response = testRealm().identityProviders().create(idpRep)) {
Assert.assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
} }
} }