From 43c1a169e4f2b1683eee7fd10d830a310eacf389 Mon Sep 17 00:00:00 2001 From: rmartinc Date: Thu, 4 Dec 2025 16:40:36 +0100 Subject: [PATCH] Manage service accounts when updating a client using registration Closes #44257 Signed-off-by: rmartinc --- .../AbstractClientRegistrationProvider.java | 2 ++ .../client/ClientRegistrationTest.java | 21 +++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/services/src/main/java/org/keycloak/services/clientregistration/AbstractClientRegistrationProvider.java b/services/src/main/java/org/keycloak/services/clientregistration/AbstractClientRegistrationProvider.java index b0b98055abd..f782af30c3c 100755 --- a/services/src/main/java/org/keycloak/services/clientregistration/AbstractClientRegistrationProvider.java +++ b/services/src/main/java/org/keycloak/services/clientregistration/AbstractClientRegistrationProvider.java @@ -55,6 +55,7 @@ import org.keycloak.services.clientregistration.policy.ClientRegistrationPolicyM import org.keycloak.services.clientregistration.policy.RegistrationAuth; import org.keycloak.services.managers.ClientManager; import org.keycloak.services.managers.RealmManager; +import org.keycloak.services.resources.admin.ClientResource; import org.keycloak.validation.ValidationUtil; /** @@ -171,6 +172,7 @@ public abstract class AbstractClientRegistrationProvider implements ClientRegist throw new ErrorResponseException(ErrorCodes.INVALID_CLIENT_METADATA, "Client Identifier modified", Response.Status.BAD_REQUEST); } + ClientResource.updateClientServiceAccount(session, client, rep.isServiceAccountsEnabled()); RepresentationToModel.updateClient(rep, client, session); RepresentationToModel.updateClientProtocolMappers(rep, client); RepresentationToModel.updateClientScopes(rep, client); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/ClientRegistrationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/ClientRegistrationTest.java index f2cd1cf0859..74ad94974be 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/ClientRegistrationTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/ClientRegistrationTest.java @@ -42,6 +42,7 @@ import org.keycloak.client.registration.Auth; import org.keycloak.client.registration.ClientRegistration; import org.keycloak.client.registration.ClientRegistrationException; import org.keycloak.client.registration.HttpErrorException; +import org.keycloak.common.constants.ServiceAccountConstants; import org.keycloak.common.util.CollectionUtil; import org.keycloak.events.Errors; import org.keycloak.models.Constants; @@ -154,6 +155,26 @@ public class ClientRegistrationTest extends AbstractClientRegistrationTest { } } + @Test + public void updateServiceAccount() throws Exception { + authManageClients(); + ClientRepresentation client = buildClient(); + final ClientRepresentation createdClient = registerClient(client); + + client = reg.get(CLIENT_ID); + assertFalse(client.isServiceAccountsEnabled()); + assertTrue(adminClient.realm(REALM_NAME).users().search(ServiceAccountConstants.SERVICE_ACCOUNT_USER_PREFIX + client.getClientId(), true).isEmpty()); + client.setServiceAccountsEnabled(true); + client = reg.update(client); + assertTrue(client.isServiceAccountsEnabled()); + assertFalse(adminClient.realm(REALM_NAME).users().search(ServiceAccountConstants.SERVICE_ACCOUNT_USER_PREFIX + client.getClientId(), true).isEmpty()); + + client.setServiceAccountsEnabled(false); + client = reg.update(client); + assertFalse(client.isServiceAccountsEnabled()); + assertTrue(adminClient.realm(REALM_NAME).users().search(ServiceAccountConstants.SERVICE_ACCOUNT_USER_PREFIX + client.getClientId(), true).isEmpty()); + } + @Test public void registerClientInMasterRealm() throws Exception { ClientRegistration masterReg = ClientRegistration.create().url(suiteContext.getAuthServerInfo().getContextRoot() + "/auth", "master").build();