From 17748d5ba8a31c442a9845ba7151b3eb03dd0583 Mon Sep 17 00:00:00 2001 From: pedroigor Date: Wed, 29 Nov 2017 18:56:31 -0200 Subject: [PATCH] [KEYCLOAK-5660] - Adding UserQueryProvider.getUsersCount(realm, includeServiceAccount) method --- .../cache/infinispan/UserCacheSession.java | 7 ++++++- .../keycloak/models/jpa/JpaUserProvider.java | 15 +++++++++++++-- .../models/jpa/entities/UserEntity.java | 3 ++- .../storage/user/UserQueryProvider.java | 17 +++++++++++++++++ .../util/MultipleStepsExportProvider.java | 2 +- .../keycloak/storage/UserStorageManager.java | 9 +++++++-- .../keycloak/testsuite/model/UserModelTest.java | 3 +++ 7 files changed, 49 insertions(+), 7 deletions(-) diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheSession.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheSession.java index de726fc8a4..e100c298f7 100755 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheSession.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheSession.java @@ -597,9 +597,14 @@ public class UserCacheSession implements UserCache { return getDelegate().getUsers(realm, includeServiceAccounts); } + @Override + public int getUsersCount(RealmModel realm, boolean includeServiceAccount) { + return getDelegate().getUsersCount(realm, includeServiceAccount); + } + @Override public int getUsersCount(RealmModel realm) { - return getDelegate().getUsersCount(realm); + return getUsersCount(realm, false); } @Override diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java index d192a7d742..08f316425d 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java @@ -596,13 +596,24 @@ public class JpaUserProvider implements UserProvider, UserCredentialStore { } @Override - public int getUsersCount(RealmModel realm) { - Object count = em.createNamedQuery("getRealmUserCount") + public int getUsersCount(RealmModel realm, boolean includeServiceAccount) { + String namedQuery = "getRealmUserCountExcludeServiceAccount"; + + if (includeServiceAccount) { + namedQuery = "getRealmUserCount"; + } + + Object count = em.createNamedQuery(namedQuery) .setParameter("realmId", realm.getId()) .getSingleResult(); return ((Number)count).intValue(); } + @Override + public int getUsersCount(RealmModel realm) { + return getUsersCount(realm, false); + } + @Override public List getUsers(RealmModel realm) { return getUsers(realm, false); diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserEntity.java index b239a55cf9..d0662cb251 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/UserEntity.java @@ -48,7 +48,8 @@ import java.util.Collection; @NamedQuery(name="getRealmUserByLastName", query="select u from UserEntity u where u.lastName = :lastName and u.realmId = :realmId"), @NamedQuery(name="getRealmUserByFirstLastName", query="select u from UserEntity u where u.firstName = :first and u.lastName = :last and u.realmId = :realmId"), @NamedQuery(name="getRealmUserByServiceAccount", query="select u from UserEntity u where u.serviceAccountClientLink = :clientInternalId and u.realmId = :realmId"), - @NamedQuery(name="getRealmUserCount", query="select count(u) from UserEntity u where u.realmId = :realmId and (u.serviceAccountClientLink is null)"), + @NamedQuery(name="getRealmUserCount", query="select count(u) from UserEntity u where u.realmId = :realmId"), + @NamedQuery(name="getRealmUserCountExcludeServiceAccount", query="select count(u) from UserEntity u where u.realmId = :realmId and (u.serviceAccountClientLink is null)"), @NamedQuery(name="getRealmUsersByAttributeNameAndValue", query="select u from UserEntity u join u.attributes attr " + "where u.realmId = :realmId and attr.name = :name and attr.value = :value"), @NamedQuery(name="deleteUsersByRealm", query="delete from UserEntity u where u.realmId = :realmId"), diff --git a/server-spi/src/main/java/org/keycloak/storage/user/UserQueryProvider.java b/server-spi/src/main/java/org/keycloak/storage/user/UserQueryProvider.java index b1dab0b9d6..83c74f131b 100644 --- a/server-spi/src/main/java/org/keycloak/storage/user/UserQueryProvider.java +++ b/server-spi/src/main/java/org/keycloak/storage/user/UserQueryProvider.java @@ -35,8 +35,25 @@ import java.util.Map; */ public interface UserQueryProvider { + /** + * Returns the number of users, without consider any service account. + * + * @param realm the realm + * @return the number of users + */ int getUsersCount(RealmModel realm); + /** + * Returns the number of users. + * + * @param realm the realm + * @param includeServiceAccount if true, the number of users will also include service accounts. Otherwise, only the number of users. + * @return the number of users + */ + default int getUsersCount(RealmModel realm, boolean includeServiceAccount) { + throw new RuntimeException("Not implemented"); + } + List getUsers(RealmModel realm); List getUsers(RealmModel realm, int firstResult, int maxResults); diff --git a/services/src/main/java/org/keycloak/exportimport/util/MultipleStepsExportProvider.java b/services/src/main/java/org/keycloak/exportimport/util/MultipleStepsExportProvider.java index e1038c17e1..fa73f810a9 100755 --- a/services/src/main/java/org/keycloak/exportimport/util/MultipleStepsExportProvider.java +++ b/services/src/main/java/org/keycloak/exportimport/util/MultipleStepsExportProvider.java @@ -81,7 +81,7 @@ public abstract class MultipleStepsExportProvider implements ExportProvider { // Count total number of users if (!exportUsersIntoRealmFile) { - usersHolder.totalCount = session.users().getUsersCount(realm); + usersHolder.totalCount = session.users().getUsersCount(realm, true); federatedUsersHolder.totalCount = session.userFederatedStorage().getStoredUsersCount(realm); } } diff --git a/services/src/main/java/org/keycloak/storage/UserStorageManager.java b/services/src/main/java/org/keycloak/storage/UserStorageManager.java index dad7b83cd7..7cbe67c901 100755 --- a/services/src/main/java/org/keycloak/storage/UserStorageManager.java +++ b/services/src/main/java/org/keycloak/storage/UserStorageManager.java @@ -399,14 +399,19 @@ public class UserStorageManager implements UserProvider, OnUserCache, OnCreateCo } @Override - public int getUsersCount(RealmModel realm) { - int size = localStorage().getUsersCount(realm); + public int getUsersCount(RealmModel realm, boolean includeServiceAccount) { + int size = localStorage().getUsersCount(realm, includeServiceAccount); for (UserQueryProvider provider : getStorageProviders(session, realm, UserQueryProvider.class)) { size += provider.getUsersCount(realm); } return size; } + @Override + public int getUsersCount(RealmModel realm) { + return getUsersCount(realm, false); + } + @FunctionalInterface interface PaginatedQuery { List query(Object provider, int first, int max); diff --git a/testsuite/integration-deprecated/src/test/java/org/keycloak/testsuite/model/UserModelTest.java b/testsuite/integration-deprecated/src/test/java/org/keycloak/testsuite/model/UserModelTest.java index 08bd68865e..16e3b363b6 100755 --- a/testsuite/integration-deprecated/src/test/java/org/keycloak/testsuite/model/UserModelTest.java +++ b/testsuite/integration-deprecated/src/test/java/org/keycloak/testsuite/model/UserModelTest.java @@ -357,6 +357,9 @@ public class UserModelTest extends AbstractModelTest { Assert.assertTrue(users.contains(user1)); Assert.assertTrue(users.contains(user2)); + Assert.assertEquals(2, session.users().getUsersCount(realm, true)); + Assert.assertEquals(1, session.users().getUsersCount(realm, false)); + // Remove client new ClientManager(realmManager).removeClient(realm, client); commit();