keycloak-memoizeit

Details

diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java
index 02063fa..a61dd05 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientResource.java
@@ -32,8 +32,8 @@ import org.keycloak.models.Constants;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.ModelDuplicateException;
 import org.keycloak.models.RealmModel;
-import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserCredentialModel;
+import org.keycloak.models.UserManager;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserSessionModel;
 import org.keycloak.models.utils.KeycloakModelUtils;
@@ -573,13 +573,17 @@ public class ClientResource {
 
 
     private void updateClientFromRep(ClientRepresentation rep, ClientModel client, KeycloakSession session) throws ModelDuplicateException {
+        UserModel serviceAccount = this.session.users().getServiceAccount(client);
         if (TRUE.equals(rep.isServiceAccountsEnabled())) {
-            UserModel serviceAccount = this.session.users().getServiceAccount(client);
-
             if (serviceAccount == null) {
                 new ClientManager(new RealmManager(session)).enableServiceAccount(client);
             }
         }
+        else {
+            if (serviceAccount != null) {
+                new UserManager(session).removeUser(realm, serviceAccount);
+            }
+        }
 
         if (!rep.getClientId().equals(client.getClientId())) {
             new ClientManager(new RealmManager(session)).clientIdChanged(client, rep.getClientId());
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/ServiceAccountTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/ServiceAccountTest.java
index cfd7907..3775e38 100755
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/ServiceAccountTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/ServiceAccountTest.java
@@ -30,6 +30,7 @@ import org.keycloak.representations.AccessToken;
 import org.keycloak.representations.RefreshToken;
 import org.keycloak.representations.idm.ClientRepresentation;
 import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.representations.idm.UserRepresentation;
 import org.keycloak.testsuite.AbstractKeycloakTest;
 import org.keycloak.testsuite.AssertEvents;
 import org.keycloak.testsuite.util.ClientBuilder;
@@ -48,6 +49,7 @@ import static org.junit.Assert.assertEquals;
 public class ServiceAccountTest extends AbstractKeycloakTest {
 
     private static String userId;
+    private static String userName;
 
     @Rule
     public AssertEvents events = new AssertEvents(this);
@@ -89,10 +91,11 @@ public class ServiceAccountTest extends AbstractKeycloakTest {
         realm.user(defaultUser);
 
         userId = KeycloakModelUtils.generateId();
+        userName = ServiceAccountConstants.SERVICE_ACCOUNT_USER_PREFIX + enabledApp.getClientId();
 
         UserBuilder serviceAccountUser = UserBuilder.create()
                 .id(userId)
-                .username(ServiceAccountConstants.SERVICE_ACCOUNT_USER_PREFIX + enabledApp.getClientId())
+                .username(userName)
                 .serviceAccountId(enabledApp.getClientId());
         realm.user(serviceAccountUser);
 
@@ -116,7 +119,7 @@ public class ServiceAccountTest extends AbstractKeycloakTest {
                 .session(accessToken.getSessionState())
                 .detail(Details.TOKEN_ID, accessToken.getId())
                 .detail(Details.REFRESH_TOKEN_ID, refreshToken.getId())
-                .detail(Details.USERNAME, ServiceAccountConstants.SERVICE_ACCOUNT_USER_PREFIX + "service-account-cl")
+                .detail(Details.USERNAME, userName)
                 .assertEvent();
 
         assertEquals(accessToken.getSessionState(), refreshToken.getSessionState());
@@ -153,7 +156,7 @@ public class ServiceAccountTest extends AbstractKeycloakTest {
                 .session(accessToken.getSessionState())
                 .detail(Details.TOKEN_ID, accessToken.getId())
                 .detail(Details.REFRESH_TOKEN_ID, refreshToken.getId())
-                .detail(Details.USERNAME, ServiceAccountConstants.SERVICE_ACCOUNT_USER_PREFIX + "service-account-cl")
+                .detail(Details.USERNAME, userName)
                 .detail(Details.CLIENT_AUTH_METHOD, ClientIdAndSecretAuthenticator.PROVIDER_ID)
                 .assertEvent();
 
@@ -246,4 +249,24 @@ public class ServiceAccountTest extends AbstractKeycloakTest {
         ClientManager.realm(adminClient.realm("test")).clientId("updated-client").renameTo("service-account-cl");
 
     }
+
+    @Test
+    public void refreshTokenRefreshForDisabledServiceAccount() throws Exception {
+        try {
+            oauth.clientId("service-account-cl");
+            OAuthClient.AccessTokenResponse response = oauth.doClientCredentialsGrantAccessTokenRequest("secret1");
+            assertEquals(200, response.getStatusCode());
+
+            ClientManager.realm(adminClient.realm("test")).clientId("service-account-cl").setServiceAccountsEnabled(false);
+
+            response = oauth.doRefreshTokenRequest(response.getRefreshToken(), "secret1");
+            assertEquals(400, response.getStatusCode());
+        }
+        finally {
+            ClientManager.realm(adminClient.realm("test")).clientId("service-account-cl").setServiceAccountsEnabled(true);
+            UserRepresentation user = ClientManager.realm(adminClient.realm("test")).clientId("service-account-cl").getServiceAccountUser();
+            userId = user.getId();
+            userName = user.getUsername();
+        }
+    }
 }
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ClientManager.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ClientManager.java
index 6bc7151..eb50949 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ClientManager.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ClientManager.java
@@ -5,6 +5,7 @@ import org.keycloak.admin.client.resource.RealmResource;
 import org.keycloak.representations.idm.ClientRepresentation;
 import org.keycloak.representations.idm.ProtocolMapperRepresentation;
 import org.keycloak.representations.idm.RoleRepresentation;
+import org.keycloak.representations.idm.UserRepresentation;
 
 import java.util.Collections;
 import java.util.LinkedHashMap;
@@ -52,6 +53,12 @@ public class ClientManager {
             clientResource.update(app);
         }
 
+        public void setServiceAccountsEnabled(Boolean enabled) {
+            ClientRepresentation app = clientResource.toRepresentation();
+            app.setServiceAccountsEnabled(enabled);
+            clientResource.update(app);
+        }
+
         public void updateAttribute(String attribute, String value) {
             ClientRepresentation app = clientResource.toRepresentation();
             if (app.getAttributes() == null) {
@@ -132,5 +139,9 @@ public class ClientManager {
             }
             clientResource.update(app);
         }
+
+        public UserRepresentation getServiceAccountUser() {
+            return clientResource.getServiceAccountUser();
+        }
     }
 }
\ No newline at end of file