keycloak-aplcache

Details

diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientsResource.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientsResource.java
index 8c1ae9f..47b4db4 100755
--- a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientsResource.java
+++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ClientsResource.java
@@ -25,6 +25,7 @@ import javax.ws.rs.POST;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import java.util.List;
@@ -45,6 +46,10 @@ public interface ClientsResource {
     @Produces(MediaType.APPLICATION_JSON)
     public List<ClientRepresentation> findAll();
 
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    public List<ClientRepresentation> findByClientId(@QueryParam("clientId") String clientId);
+
 
 
 }
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
index adde0e4..6c081cb 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
@@ -17,7 +17,6 @@
 
 package org.keycloak.models.jpa;
 
-import org.keycloak.connections.jpa.util.JpaUtils;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.ClientTemplateModel;
 import org.keycloak.models.KeycloakSession;
@@ -627,26 +626,7 @@ public class ClientAdapter implements ClientModel, JpaModel<ClientEntity> {
 
     @Override
     public boolean removeRole(RoleModel roleModel) {
-        if (roleModel == null) {
-            return false;
-        }
-        if (!roleModel.getContainer().equals(this)) return false;
-
-        session.users().preRemove(getRealm(), roleModel);
-        RoleEntity role = RoleAdapter.toRoleEntity(roleModel, em);
-        if (!role.isClientRole()) return false;
-
-        entity.getDefaultRoles().remove(role);
-        String compositeRoleTable = JpaUtils.getTableNameForNativeQuery("COMPOSITE_ROLE", em);
-        em.createNativeQuery("delete from " + compositeRoleTable + " where CHILD_ROLE = :role").setParameter("role", role).executeUpdate();
-        em.createNamedQuery("deleteScopeMappingByRole").setParameter("role", role).executeUpdate();
-        em.createNamedQuery("deleteTemplateScopeMappingByRole").setParameter("role", role).executeUpdate();
-        role.setClient(null);
-        em.flush();
-        em.remove(role);
-        em.flush();
-
-        return true;
+        return session.realms().removeRole(realm, roleModel);
     }
 
     @Override
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaRealmProvider.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaRealmProvider.java
index 8ed10be..5da9b4e 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaRealmProvider.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaRealmProvider.java
@@ -39,11 +39,9 @@ import javax.persistence.EntityManager;
 import javax.persistence.TypedQuery;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 
 /**
@@ -261,7 +259,7 @@ public class JpaRealmProvider implements RealmProvider {
         em.createNativeQuery("delete from " + compositeRoleTable + " where CHILD_ROLE = :role").setParameter("role", roleEntity).executeUpdate();
         em.createNamedQuery("deleteScopeMappingByRole").setParameter("role", roleEntity).executeUpdate();
         em.createNamedQuery("deleteTemplateScopeMappingByRole").setParameter("role", roleEntity).executeUpdate();
-        em.createNamedQuery("deleteGroupRoleMappingsByRole").setParameter("roleId", roleEntity.getId()).executeUpdate();
+        int val = em.createNamedQuery("deleteGroupRoleMappingsByRole").setParameter("roleId", roleEntity.getId()).executeUpdate();
 
         em.remove(roleEntity);
         em.flush();
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java
index ff18fdf..69635e2 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java
@@ -17,8 +17,6 @@
 
 package org.keycloak.models.mongo.keycloak.adapters;
 
-import com.mongodb.DBObject;
-import com.mongodb.QueryBuilder;
 import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.ClientTemplateModel;
@@ -48,7 +46,7 @@ public class ClientAdapter extends AbstractMongoAdapter<MongoClientEntity> imple
 
     protected final MongoClientEntity clientEntity;
     private final RealmModel realm;
-    protected  KeycloakSession session;
+    protected KeycloakSession session;
 
     public ClientAdapter(KeycloakSession session, RealmModel realm, MongoClientEntity clientEntity, MongoStoreInvocationContext invContext) {
         super(invContext);
@@ -583,8 +581,7 @@ public class ClientAdapter extends AbstractMongoAdapter<MongoClientEntity> imple
 
     @Override
     public boolean removeRole(RoleModel role) {
-        session.users().preRemove(getRealm(), role);
-        return getMongoStore().removeEntity(MongoRoleEntity.class, role.getId(), invocationContext);
+        return session.realms().removeRole(realm, role);
     }
 
     @Override
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ClientsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ClientsResource.java
index 6dd5046..a96b7a0 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ClientsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ClientsResource.java
@@ -36,11 +36,11 @@ import javax.ws.rs.POST;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
-
 import java.util.ArrayList;
 import java.util.List;
 
@@ -71,26 +71,36 @@ public class ClientsResource {
      * Get clients belonging to the realm
      *
      * Returns a list of clients belonging to the realm
+     *
+     * @param clientId filter by clientId
      */
     @GET
     @Produces(MediaType.APPLICATION_JSON)
     @NoCache
-    public List<ClientRepresentation> getClients() {
+    public List<ClientRepresentation> getClients(@QueryParam("clientId") String clientId) {
         auth.requireAny();
 
         List<ClientRepresentation> rep = new ArrayList<>();
-        List<ClientModel> clientModels = realm.getClients();
-
-        boolean view = auth.hasView();
-        for (ClientModel clientModel : clientModels) {
-            if (view) {
-                rep.add(ModelToRepresentation.toRepresentation(clientModel));
-            } else {
-                ClientRepresentation client = new ClientRepresentation();
-                client.setId(clientModel.getId());
-                client.setClientId(clientModel.getClientId());
-                client.setDescription(clientModel.getDescription());
-                rep.add(client);
+
+        if (clientId == null) {
+            List<ClientModel> clientModels = realm.getClients();
+
+            boolean view = auth.hasView();
+            for (ClientModel clientModel : clientModels) {
+                if (view) {
+                    rep.add(ModelToRepresentation.toRepresentation(clientModel));
+                } else {
+                    ClientRepresentation client = new ClientRepresentation();
+                    client.setId(clientModel.getId());
+                    client.setClientId(clientModel.getClientId());
+                    client.setDescription(clientModel.getDescription());
+                    rep.add(client);
+                }
+            }
+        } else {
+            ClientModel client = realm.getClientByClientId(clientId);
+            if (client != null) {
+                rep.add(ModelToRepresentation.toRepresentation(client));
             }
         }
         return rep;
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupTest.java
old mode 100644
new mode 100755
index e369859..ad3793e
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupTest.java
@@ -74,6 +74,36 @@ public class GroupTest extends AbstractGroupTest {
         clients.add(client);
     }
 
+    /**
+     * KEYCLOAK-2716
+     * @throws Exception
+     */
+    @Test
+    public void testClientRemoveWithClientRoleGroupMapping() throws Exception {
+        RealmResource realm = adminClient.realms().realm("test");
+        ClientRepresentation client = new ClientRepresentation();
+        client.setClientId("foo");
+        client.setRootUrl("http://foo");
+        client.setProtocol("openid-connect");
+        Response response = realm.clients().create(client);
+        response.close();
+        client = realm.clients().findByClientId("foo").get(0);
+        RoleRepresentation role = new RoleRepresentation();
+        role.setName("foo-role");
+        realm.clients().get(client.getId()).roles().create(role);
+        role = realm.clients().get(client.getId()).roles().get("foo-role").toRepresentation();
+        GroupRepresentation group = new GroupRepresentation();
+        group.setName("2716");
+        realm.groups().add(group).close();
+        group = realm.getGroupByPath("/2716");
+        List<RoleRepresentation> list = new LinkedList<>();
+        list.add(role);
+        realm.groups().group(group.getId()).roles().clientLevel(client.getId()).add(list);
+        realm.clients().get(client.getId()).remove();
+
+    }
+
+
     @Test
     public void createAndTestGroups() throws Exception {
         RealmResource realm = adminClient.realms().realm("test");