Skip to content

Commit

Permalink
added unlink method. cleaned up authz for link/unlink (#206)
Browse files Browse the repository at this point in the history
Signed-off-by: Garth <[email protected]>
  • Loading branch information
xgp committed Mar 15, 2024
1 parent 77666cf commit 5316171
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import jakarta.ws.rs.core.Response;
import java.util.stream.Stream;
import lombok.extern.jbosslog.JBossLog;
import org.keycloak.models.IdentityProviderModel;
import org.keycloak.representations.idm.IdentityProviderMapperRepresentation;
import org.keycloak.representations.idm.IdentityProviderRepresentation;

Expand Down Expand Up @@ -44,6 +45,27 @@ public Response delete() {
return kcResource.delete();
}

@POST
@Path("unlink")
public Response unlinkIdp() {
// authz
if (!auth.hasManageOrgs()) {
throw new NotAuthorizedException(
String.format(
"Insufficient permission to unlink identity provider for %s", organization.getId()));
}

// get an idp with the same alias
IdentityProviderModel idp = realm.getIdentityProviderByAlias(alias);
if (idp == null) {
throw new NotFoundException(String.format("No IdP found with alias %s", alias));
}

idp.getConfig().remove(ORG_OWNER_CONFIG_KEY);
realm.updateIdentityProvider(idp);
return Response.noContent().build();
}

@PUT
@Consumes(MediaType.APPLICATION_JSON)
public Response update(IdentityProviderRepresentation providerRep) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,16 @@ protected void idpDefaults(
representation.setPostBrokerLoginFlowAlias(postBrokerFlow);
}

private void deactivateOtherIdps(IdentityProviderRepresentation representation) {
// Organization can have only one active idp
// Activating an idp deactivates all others
private void deactivateOtherIdps(
IdentityProviderRepresentation representation, boolean unlink, boolean disable) {
if (representation.isEnabled()) {
realm
.getIdentityProvidersStream()
.filter(provider -> idpInOrg(provider))
.forEach(
provider -> {
provider.setEnabled(false);
if (disable) provider.setEnabled(false);
if (unlink) provider.getConfig().remove(ORG_OWNER_CONFIG_KEY);
realm.updateIdentityProvider(provider); // weird that this is necessary
});
}
Expand Down Expand Up @@ -129,7 +129,7 @@ public Response createIdentityProvider(IdentityProviderRepresentation representa
}

idpDefaults(representation, Optional.of(linkFromRep(representation)));
deactivateOtherIdps(representation);
deactivateOtherIdps(representation, false, true);

Response resp = getIdpResource().create(representation);
if (resp.getStatus() == Response.Status.CREATED.getStatusCode()) {
Expand All @@ -145,10 +145,10 @@ public Response createIdentityProvider(IdentityProviderRepresentation representa
@Produces(MediaType.APPLICATION_JSON)
public Response linkIdp(LinkIdp linkIdp) {
// authz
if (!auth.hasManageOrgs() && !auth.hasOrgManageIdentityProviders(organization)) {
if (!auth.hasManageOrgs()) {
throw new NotAuthorizedException(
String.format(
"Insufficient permission to create identity providers for %s", organization.getId()));
"Insufficient permission to link identity providers for %s", organization.getId()));
}

// get an idp with the same alias
Expand All @@ -161,14 +161,6 @@ public Response linkIdp(LinkIdp linkIdp) {
String.format("Cannot link disabled IdP %s", linkIdp.getAlias()));
}

// does it already contain an orgId for a different org?
String orgId = idp.getConfig().get(ORG_OWNER_CONFIG_KEY);
if (orgId != null && !organization.getId().equals(orgId)) {
throw new ClientErrorException(
String.format("IdP with alias %s unavailable for linking.", linkIdp.getAlias()),
Response.Status.CONFLICT);
}

IdentityProviderRepresentation representation =
ModelToRepresentation.toRepresentation(realm, idp);
idpDefaults(representation, Optional.of(linkIdp));
Expand All @@ -179,7 +171,7 @@ public Response linkIdp(LinkIdp linkIdp) {
representation.setPostBrokerLoginFlowAlias(linkIdp.getPostBrokerFlow());
}

deactivateOtherIdps(representation);
deactivateOtherIdps(representation, true, false);

try {
IdentityProviderModel updated = RepresentationToModel.toModel(realm, representation, session);
Expand Down

0 comments on commit 5316171

Please sign in to comment.