From 9c287aff1f776bb580f603ffc66a2a06cbae21dc Mon Sep 17 00:00:00 2001 From: Martin Kanis Date: Tue, 2 Nov 2021 09:14:02 +0100 Subject: [PATCH] KEYCLOAK-19709 Remove MapStorage.createCriteriaBuilder --- .../MapRootAuthenticationSessionProvider.java | 11 +-- .../MapPermissionTicketStore.java | 23 ++--- .../map/authorization/MapPolicyStore.java | 20 ++-- .../map/authorization/MapResourceStore.java | 20 ++-- .../map/authorization/MapScopeStore.java | 5 +- .../models/map/client/MapClientProvider.java | 44 ++++----- .../clientscope/MapClientScopeProvider.java | 11 +-- .../models/map/group/MapGroupProvider.java | 39 ++++---- .../MapUserLoginFailureProvider.java | 19 ++-- .../models/map/realm/MapRealmProvider.java | 17 ++-- .../models/map/role/MapRoleProvider.java | 58 +++++------ .../models/map/storage/MapStorage.java | 16 --- .../map/storage/ModelCriteriaBuilder.java | 14 --- .../ConcurrentHashMapKeycloakTransaction.java | 17 ++-- .../storage/chm/ConcurrentHashMapStorage.java | 40 +++----- ...ncurrentHashMapStorageProviderFactory.java | 3 +- .../storage/chm/MapModelCriteriaBuilder.java | 5 +- .../UserSessionConcurrentHashMapStorage.java | 7 +- .../criteria/DefaultModelCriteria.java | 17 ++-- .../models/map/user/MapUserProvider.java | 97 +++++++++---------- .../userSession/MapUserSessionProvider.java | 20 ++-- 21 files changed, 221 insertions(+), 282 deletions(-) diff --git a/model/map/src/main/java/org/keycloak/models/map/authSession/MapRootAuthenticationSessionProvider.java b/model/map/src/main/java/org/keycloak/models/map/authSession/MapRootAuthenticationSessionProvider.java index f6b8d873f1..2097529614 100644 --- a/model/map/src/main/java/org/keycloak/models/map/authSession/MapRootAuthenticationSessionProvider.java +++ b/model/map/src/main/java/org/keycloak/models/map/authSession/MapRootAuthenticationSessionProvider.java @@ -40,6 +40,7 @@ import java.util.function.Predicate; import static org.keycloak.common.util.StackUtil.getShortStackTrace; import static org.keycloak.models.map.storage.QueryParameters.withCriteria; +import static org.keycloak.models.map.storage.criteria.DefaultModelCriteria.criteria; /** * @author Martin Kanis @@ -49,13 +50,11 @@ public class MapRootAuthenticationSessionProvider implements AuthenticationSessi private static final Logger LOG = Logger.getLogger(MapRootAuthenticationSessionProvider.class); private final KeycloakSession session; protected final MapKeycloakTransaction tx; - private final MapStorage sessionStore; private static final String AUTHENTICATION_SESSION_EVENTS = "AUTHENTICATION_SESSION_EVENTS"; public MapRootAuthenticationSessionProvider(KeycloakSession session, MapStorage sessionStore) { this.session = session; - this.sessionStore = sessionStore; this.tx = sessionStore.createTransaction(session); session.getTransactionManager().enlistAfterCompletion(tx); @@ -132,8 +131,8 @@ public class MapRootAuthenticationSessionProvider implements AuthenticationSessi int expired = Time.currentTime() - RealmInfoUtil.getDettachedClientSessionLifespan(realm); - ModelCriteriaBuilder mcb = sessionStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) .compare(SearchableFields.TIMESTAMP, Operator.LT, expired); long deletedCount = tx.delete(withCriteria(mcb)); @@ -144,8 +143,8 @@ public class MapRootAuthenticationSessionProvider implements AuthenticationSessi @Override public void onRealmRemoved(RealmModel realm) { Objects.requireNonNull(realm, "The provided realm can't be null!"); - ModelCriteriaBuilder mcb = sessionStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()); + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()); tx.delete(withCriteria(mcb)); } diff --git a/model/map/src/main/java/org/keycloak/models/map/authorization/MapPermissionTicketStore.java b/model/map/src/main/java/org/keycloak/models/map/authorization/MapPermissionTicketStore.java index c12ef73691..2f71c8a63d 100644 --- a/model/map/src/main/java/org/keycloak/models/map/authorization/MapPermissionTicketStore.java +++ b/model/map/src/main/java/org/keycloak/models/map/authorization/MapPermissionTicketStore.java @@ -45,6 +45,7 @@ import java.util.stream.Collectors; import static org.keycloak.common.util.StackUtil.getShortStackTrace; import static org.keycloak.models.map.storage.QueryParameters.Order.ASCENDING; import static org.keycloak.models.map.storage.QueryParameters.withCriteria; +import static org.keycloak.models.map.storage.criteria.DefaultModelCriteria.criteria; import static org.keycloak.utils.StreamsUtil.distinctByKey; import static org.keycloak.utils.StreamsUtil.paginatedStream; @@ -53,11 +54,9 @@ public class MapPermissionTicketStore implements PermissionTicketStore { private static final Logger LOG = Logger.getLogger(MapPermissionTicketStore.class); private final AuthorizationProvider authorizationProvider; final MapKeycloakTransaction tx; - private final MapStorage permissionTicketStore; public MapPermissionTicketStore(KeycloakSession session, MapStorage permissionTicketStore, AuthorizationProvider provider) { this.authorizationProvider = provider; - this.permissionTicketStore = permissionTicketStore; this.tx = permissionTicketStore.createTransaction(session); session.getTransactionManager().enlist(tx); } @@ -69,7 +68,7 @@ public class MapPermissionTicketStore implements PermissionTicketStore { } private ModelCriteriaBuilder forResourceServer(String resourceServerId) { - ModelCriteriaBuilder mcb = permissionTicketStore.createCriteriaBuilder(); + ModelCriteriaBuilder mcb = criteria(); return resourceServerId == null ? mcb @@ -215,6 +214,7 @@ public class MapPermissionTicketStore implements PermissionTicketStore { PermissionTicket.FilterOption name = entry.getKey(); String value = entry.getValue(); + ModelCriteriaBuilder mcb = criteria(); switch (name) { case ID: case SCOPE_ID: @@ -222,8 +222,7 @@ public class MapPermissionTicketStore implements PermissionTicketStore { case OWNER: case REQUESTER: case POLICY_ID: - return permissionTicketStore.createCriteriaBuilder() - .compare(name.getSearchableModelField(), Operator.EQ, value); + return mcb.compare(name.getSearchableModelField(), Operator.EQ, value); case SCOPE_IS_NULL: case GRANTED: case REQUESTER_IS_NULL: { @@ -231,12 +230,10 @@ public class MapPermissionTicketStore implements PermissionTicketStore { if (Boolean.parseBoolean(value)) { op = Operator.EXISTS; } - return permissionTicketStore.createCriteriaBuilder() - .compare(name.getSearchableModelField(), op); + return mcb.compare(name.getSearchableModelField(), op); } case POLICY_IS_NOT_NULL: - return permissionTicketStore.createCriteriaBuilder() - .compare(SearchableFields.REQUESTER, Operator.NOT_EXISTS); + return mcb.compare(SearchableFields.REQUESTER, Operator.NOT_EXISTS); default: throw new IllegalArgumentException("Unsupported filter [" + name + "]"); @@ -266,8 +263,8 @@ public class MapPermissionTicketStore implements PermissionTicketStore { @Override public List findGrantedResources(String requester, String name, int first, int max) { - ModelCriteriaBuilder mcb = permissionTicketStore.createCriteriaBuilder() - .compare(SearchableFields.REQUESTER, Operator.EQ, requester) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REQUESTER, Operator.EQ, requester) .compare(SearchableFields.GRANTED_TIMESTAMP, Operator.EXISTS); Function ticketResourceMapper; @@ -298,8 +295,8 @@ public class MapPermissionTicketStore implements PermissionTicketStore { @Override public List findGrantedOwnerResources(String owner, int first, int max) { - ModelCriteriaBuilder mcb = permissionTicketStore.createCriteriaBuilder() - .compare(SearchableFields.OWNER, Operator.EQ, owner); + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.OWNER, Operator.EQ, owner); return paginatedStream(tx.read(withCriteria(mcb).orderBy(SearchableFields.RESOURCE_ID, ASCENDING)) .filter(distinctByKey(MapPermissionTicketEntity::getResourceId)), first, max) diff --git a/model/map/src/main/java/org/keycloak/models/map/authorization/MapPolicyStore.java b/model/map/src/main/java/org/keycloak/models/map/authorization/MapPolicyStore.java index 1bdba4ad2a..b5f6b3df5f 100644 --- a/model/map/src/main/java/org/keycloak/models/map/authorization/MapPolicyStore.java +++ b/model/map/src/main/java/org/keycloak/models/map/authorization/MapPolicyStore.java @@ -31,6 +31,7 @@ import org.keycloak.models.map.storage.MapKeycloakTransaction; import org.keycloak.models.map.storage.MapStorage; import org.keycloak.models.map.storage.ModelCriteriaBuilder; import org.keycloak.models.map.storage.ModelCriteriaBuilder.Operator; +import org.keycloak.models.map.storage.criteria.DefaultModelCriteria; import org.keycloak.representations.idm.authorization.AbstractPolicyRepresentation; import java.util.Arrays; @@ -42,17 +43,16 @@ import java.util.stream.Collectors; import static org.keycloak.common.util.StackUtil.getShortStackTrace; import static org.keycloak.models.map.storage.QueryParameters.withCriteria; +import static org.keycloak.models.map.storage.criteria.DefaultModelCriteria.criteria; public class MapPolicyStore implements PolicyStore { private static final Logger LOG = Logger.getLogger(MapPolicyStore.class); private final AuthorizationProvider authorizationProvider; final MapKeycloakTransaction tx; - private final MapStorage policyStore; public MapPolicyStore(KeycloakSession session, MapStorage policyStore, AuthorizationProvider provider) { this.authorizationProvider = provider; - this.policyStore = policyStore; this.tx = policyStore.createTransaction(session); session.getTransactionManager().enlist(tx); } @@ -64,7 +64,7 @@ public class MapPolicyStore implements PolicyStore { } private ModelCriteriaBuilder forResourceServer(String resourceServerId) { - ModelCriteriaBuilder mcb = policyStore.createCriteriaBuilder(); + ModelCriteriaBuilder mcb = criteria(); return resourceServerId == null ? mcb @@ -158,19 +158,18 @@ public class MapPolicyStore implements PolicyStore { Policy.FilterOption name = entry.getKey(); String[] value = entry.getValue(); + ModelCriteriaBuilder mcb = criteria(); switch (name) { case ID: case SCOPE_ID: case RESOURCE_ID: case OWNER: - return policyStore.createCriteriaBuilder() - .compare(name.getSearchableModelField(), Operator.IN, Arrays.asList(value)); + return mcb.compare(name.getSearchableModelField(), Operator.IN, Arrays.asList(value)); case PERMISSION: { - ModelCriteriaBuilder mcb = policyStore.createCriteriaBuilder() - .compare(SearchableFields.TYPE, Operator.IN, Arrays.asList("resource", "scope", "uma")); + mcb = mcb.compare(SearchableFields.TYPE, Operator.IN, Arrays.asList("resource", "scope", "uma")); if (!Boolean.parseBoolean(value[0])) { - mcb = policyStore.createCriteriaBuilder().not(mcb); // TODO: create NOT_IN operator + mcb = DefaultModelCriteria.criteria().not(mcb); // TODO: create NOT_IN operator } return mcb; @@ -183,11 +182,10 @@ public class MapPolicyStore implements PolicyStore { } value[1] = "%" + value[1] + "%"; - return policyStore.createCriteriaBuilder() - .compare(SearchableFields.CONFIG, Operator.LIKE, (Object[]) value); + return mcb.compare(SearchableFields.CONFIG, Operator.LIKE, (Object[]) value); case TYPE: case NAME: - return policyStore.createCriteriaBuilder().compare(name.getSearchableModelField(), Operator.ILIKE, "%" + value[0] + "%"); + return mcb.compare(name.getSearchableModelField(), Operator.ILIKE, "%" + value[0] + "%"); default: throw new IllegalArgumentException("Unsupported filter [" + name + "]"); diff --git a/model/map/src/main/java/org/keycloak/models/map/authorization/MapResourceStore.java b/model/map/src/main/java/org/keycloak/models/map/authorization/MapResourceStore.java index 8e53caab57..6b9d3d55a7 100644 --- a/model/map/src/main/java/org/keycloak/models/map/authorization/MapResourceStore.java +++ b/model/map/src/main/java/org/keycloak/models/map/authorization/MapResourceStore.java @@ -41,16 +41,15 @@ import java.util.stream.Collectors; import static org.keycloak.common.util.StackUtil.getShortStackTrace; import static org.keycloak.models.map.storage.QueryParameters.withCriteria; +import static org.keycloak.models.map.storage.criteria.DefaultModelCriteria.criteria; public class MapResourceStore implements ResourceStore { private static final Logger LOG = Logger.getLogger(MapResourceStore.class); private final AuthorizationProvider authorizationProvider; final MapKeycloakTransaction tx; - private final MapStorage resourceStore; public MapResourceStore(KeycloakSession session, MapStorage resourceStore, AuthorizationProvider provider) { - this.resourceStore = resourceStore; this.tx = resourceStore.createTransaction(session); session.getTransactionManager().enlist(tx); authorizationProvider = provider; @@ -63,7 +62,7 @@ public class MapResourceStore implements ResourceStore { } private ModelCriteriaBuilder forResourceServer(String resourceServerId) { - ModelCriteriaBuilder mcb = resourceStore.createCriteriaBuilder(); + ModelCriteriaBuilder mcb = criteria(); return resourceServerId == null ? mcb @@ -172,24 +171,21 @@ public class MapResourceStore implements ResourceStore { Resource.FilterOption name = entry.getKey(); String[] value = entry.getValue(); + ModelCriteriaBuilder mcb = criteria(); switch (name) { case ID: case SCOPE_ID: case OWNER: case URI: - return resourceStore.createCriteriaBuilder() - .compare(name.getSearchableModelField(), Operator.IN, Arrays.asList(value)); + return mcb.compare(name.getSearchableModelField(), Operator.IN, Arrays.asList(value)); case URI_NOT_NULL: - return resourceStore.createCriteriaBuilder().compare(SearchableFields.URI, Operator.EXISTS); + return mcb.compare(SearchableFields.URI, Operator.EXISTS); case OWNER_MANAGED_ACCESS: - return resourceStore.createCriteriaBuilder() - .compare(SearchableFields.OWNER_MANAGED_ACCESS, Operator.EQ, Boolean.valueOf(value[0])); + return mcb.compare(SearchableFields.OWNER_MANAGED_ACCESS, Operator.EQ, Boolean.valueOf(value[0])); case EXACT_NAME: - return resourceStore.createCriteriaBuilder() - .compare(SearchableFields.NAME, Operator.EQ, value[0]); + return mcb.compare(SearchableFields.NAME, Operator.EQ, value[0]); case NAME: - return resourceStore.createCriteriaBuilder() - .compare(SearchableFields.NAME, Operator.ILIKE, "%" + value[0] + "%"); + return mcb.compare(SearchableFields.NAME, Operator.ILIKE, "%" + value[0] + "%"); default: throw new IllegalArgumentException("Unsupported filter [" + name + "]"); diff --git a/model/map/src/main/java/org/keycloak/models/map/authorization/MapScopeStore.java b/model/map/src/main/java/org/keycloak/models/map/authorization/MapScopeStore.java index b81d3d4cff..f357301137 100644 --- a/model/map/src/main/java/org/keycloak/models/map/authorization/MapScopeStore.java +++ b/model/map/src/main/java/org/keycloak/models/map/authorization/MapScopeStore.java @@ -39,17 +39,16 @@ import java.util.stream.Collectors; import static org.keycloak.common.util.StackUtil.getShortStackTrace; import static org.keycloak.models.map.storage.QueryParameters.withCriteria; +import static org.keycloak.models.map.storage.criteria.DefaultModelCriteria.criteria; public class MapScopeStore implements ScopeStore { private static final Logger LOG = Logger.getLogger(MapScopeStore.class); private final AuthorizationProvider authorizationProvider; final MapKeycloakTransaction tx; - private final MapStorage scopeStore; public MapScopeStore(KeycloakSession session, MapStorage scopeStore, AuthorizationProvider provider) { this.authorizationProvider = provider; - this.scopeStore = scopeStore; this.tx = scopeStore.createTransaction(session); session.getTransactionManager().enlist(tx); } @@ -61,7 +60,7 @@ public class MapScopeStore implements ScopeStore { } private ModelCriteriaBuilder forResourceServer(String resourceServerId) { - ModelCriteriaBuilder mcb = scopeStore.createCriteriaBuilder(); + ModelCriteriaBuilder mcb = criteria(); return resourceServerId == null ? mcb diff --git a/model/map/src/main/java/org/keycloak/models/map/client/MapClientProvider.java b/model/map/src/main/java/org/keycloak/models/map/client/MapClientProvider.java index 3d22d420b4..0486f93e9f 100644 --- a/model/map/src/main/java/org/keycloak/models/map/client/MapClientProvider.java +++ b/model/map/src/main/java/org/keycloak/models/map/client/MapClientProvider.java @@ -46,6 +46,7 @@ import static org.keycloak.common.util.StackUtil.getShortStackTrace; import org.keycloak.models.ClientScopeModel; import static org.keycloak.models.map.storage.QueryParameters.Order.ASCENDING; import static org.keycloak.models.map.storage.QueryParameters.withCriteria; +import static org.keycloak.models.map.storage.criteria.DefaultModelCriteria.criteria; import org.keycloak.protocol.oidc.OIDCLoginProtocol; import java.util.HashSet; @@ -55,12 +56,10 @@ public class MapClientProvider implements ClientProvider { private static final Logger LOG = Logger.getLogger(MapClientProvider.class); private final KeycloakSession session; final MapKeycloakTransaction tx; - private final MapStorage clientStore; private final ConcurrentMap> clientRegisteredNodesStore; public MapClientProvider(KeycloakSession session, MapStorage clientStore, ConcurrentMap> clientRegisteredNodesStore) { this.session = session; - this.clientStore = clientStore; this.clientRegisteredNodesStore = clientRegisteredNodesStore; this.tx = clientStore.createTransaction(session); session.getTransactionManager().enlist(tx); @@ -120,8 +119,8 @@ public class MapClientProvider implements ClientProvider { @Override public Stream getClientsStream(RealmModel realm, Integer firstResult, Integer maxResults) { - ModelCriteriaBuilder mcb = clientStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()); + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()); return tx.read(withCriteria(mcb).pagination(firstResult, maxResults, SearchableFields.CLIENT_ID)) .map(entityToAdapterFunc(realm)); @@ -129,8 +128,8 @@ public class MapClientProvider implements ClientProvider { @Override public Stream getClientsStream(RealmModel realm) { - ModelCriteriaBuilder mcb = clientStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()); + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()); return tx.read(withCriteria(mcb).orderBy(SearchableFields.CLIENT_ID, ASCENDING)) .map(entityToAdapterFunc(realm)); @@ -213,8 +212,8 @@ public class MapClientProvider implements ClientProvider { @Override public long getClientsCount(RealmModel realm) { - ModelCriteriaBuilder mcb = clientStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()); + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()); return tx.getCount(withCriteria(mcb)); } @@ -240,9 +239,9 @@ public class MapClientProvider implements ClientProvider { } LOG.tracef("getClientByClientId(%s, %s)%s", realm, clientId, getShortStackTrace()); - ModelCriteriaBuilder mcb = clientStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) - .compare(SearchableFields.CLIENT_ID, Operator.ILIKE, clientId); + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) + .compare(SearchableFields.CLIENT_ID, Operator.ILIKE, clientId); return tx.read(withCriteria(mcb)) .map(entityToAdapterFunc(realm)) @@ -257,9 +256,9 @@ public class MapClientProvider implements ClientProvider { return Stream.empty(); } - ModelCriteriaBuilder mcb = clientStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) - .compare(SearchableFields.CLIENT_ID, Operator.ILIKE, "%" + clientId + "%"); + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) + .compare(SearchableFields.CLIENT_ID, Operator.ILIKE, "%" + clientId + "%"); return tx.read(withCriteria(mcb).pagination(firstResult, maxResults, SearchableFields.CLIENT_ID)) .map(entityToAdapterFunc(realm)); @@ -267,8 +266,8 @@ public class MapClientProvider implements ClientProvider { @Override public Stream searchClientsByAttributes(RealmModel realm, Map attributes, Integer firstResult, Integer maxResults) { - ModelCriteriaBuilder mcb = clientStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()); + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()); for (Map.Entry entry : attributes.entrySet()) { mcb = mcb.compare(SearchableFields.ATTRIBUTE, Operator.EQ, entry.getKey(), entry.getValue()); @@ -332,9 +331,9 @@ public class MapClientProvider implements ClientProvider { @Override public Map> getAllRedirectUrisOfEnabledClients(RealmModel realm) { - ModelCriteriaBuilder mcb = clientStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) - .compare(SearchableFields.ENABLED, Operator.EQ, Boolean.TRUE); + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) + .compare(SearchableFields.ENABLED, Operator.EQ, Boolean.TRUE); try (Stream st = tx.read(withCriteria(mcb))) { return st @@ -347,9 +346,10 @@ public class MapClientProvider implements ClientProvider { } public void preRemove(RealmModel realm, RoleModel role) { - ModelCriteriaBuilder mcb = clientStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) - .compare(SearchableFields.SCOPE_MAPPING_ROLE, Operator.EQ, role.getId()); + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) + .compare(SearchableFields.SCOPE_MAPPING_ROLE, Operator.EQ, role.getId()); + try (Stream toRemove = tx.read(withCriteria(mcb))) { toRemove .map(clientEntity -> session.clients().getClientById(realm, clientEntity.getId())) diff --git a/model/map/src/main/java/org/keycloak/models/map/clientscope/MapClientScopeProvider.java b/model/map/src/main/java/org/keycloak/models/map/clientscope/MapClientScopeProvider.java index 8d9c1a068b..9477389c46 100644 --- a/model/map/src/main/java/org/keycloak/models/map/clientscope/MapClientScopeProvider.java +++ b/model/map/src/main/java/org/keycloak/models/map/clientscope/MapClientScopeProvider.java @@ -38,17 +38,16 @@ import org.keycloak.models.utils.KeycloakModelUtils; import static org.keycloak.models.map.storage.QueryParameters.Order.ASCENDING; import static org.keycloak.models.map.storage.QueryParameters.withCriteria; +import static org.keycloak.models.map.storage.criteria.DefaultModelCriteria.criteria; public class MapClientScopeProvider implements ClientScopeProvider { private static final Logger LOG = Logger.getLogger(MapClientScopeProvider.class); private final KeycloakSession session; private final MapKeycloakTransaction tx; - private final MapStorage clientScopeStore; public MapClientScopeProvider(KeycloakSession session, MapStorage clientScopeStore) { this.session = session; - this.clientScopeStore = clientScopeStore; this.tx = clientScopeStore.createTransaction(session); session.getTransactionManager().enlist(tx); } @@ -69,8 +68,8 @@ public class MapClientScopeProvider implements ClientScopeProvider { @Override public Stream getClientScopesStream(RealmModel realm) { - ModelCriteriaBuilder mcb = clientScopeStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()); + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()); return tx.read(withCriteria(mcb).orderBy(SearchableFields.NAME, ASCENDING)) .map(entityToAdapterFunc(realm)); @@ -79,8 +78,8 @@ public class MapClientScopeProvider implements ClientScopeProvider { @Override public ClientScopeModel addClientScope(RealmModel realm, String id, String name) { // Check Db constraint: @UniqueConstraint(columnNames = {"REALM_ID", "NAME"}) - ModelCriteriaBuilder mcb = clientScopeStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) .compare(SearchableFields.NAME, Operator.EQ, name); if (tx.getCount(withCriteria(mcb)) > 0) { diff --git a/model/map/src/main/java/org/keycloak/models/map/group/MapGroupProvider.java b/model/map/src/main/java/org/keycloak/models/map/group/MapGroupProvider.java index af3e2a00f9..eb562d9fbe 100644 --- a/model/map/src/main/java/org/keycloak/models/map/group/MapGroupProvider.java +++ b/model/map/src/main/java/org/keycloak/models/map/group/MapGroupProvider.java @@ -41,17 +41,16 @@ import java.util.stream.Stream; import static org.keycloak.common.util.StackUtil.getShortStackTrace; import static org.keycloak.models.map.storage.QueryParameters.Order.ASCENDING; import static org.keycloak.models.map.storage.QueryParameters.withCriteria; +import static org.keycloak.models.map.storage.criteria.DefaultModelCriteria.criteria; public class MapGroupProvider implements GroupProvider { private static final Logger LOG = Logger.getLogger(MapGroupProvider.class); private final KeycloakSession session; final MapKeycloakTransaction tx; - private final MapStorage groupStore; public MapGroupProvider(KeycloakSession session, MapStorage groupStore) { this.session = session; - this.groupStore = groupStore; this.tx = groupStore.createTransaction(session); session.getTransactionManager().enlist(tx); } @@ -83,8 +82,8 @@ public class MapGroupProvider implements GroupProvider { private Stream getGroupsStreamInternal(RealmModel realm, UnaryOperator> modifier, UnaryOperator> queryParametersModifier) { LOG.tracef("getGroupsStream(%s)%s", realm, getShortStackTrace()); - ModelCriteriaBuilder mcb = groupStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()); + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()); if (modifier != null) { mcb = modifier.apply(mcb); @@ -102,8 +101,8 @@ public class MapGroupProvider implements GroupProvider { @Override public Stream getGroupsStream(RealmModel realm, Stream ids, String search, Integer first, Integer max) { - ModelCriteriaBuilder mcb = groupStore.createCriteriaBuilder() - .compare(SearchableFields.ID, Operator.IN, ids) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.ID, Operator.IN, ids) .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()); if (search != null) { @@ -117,8 +116,8 @@ public class MapGroupProvider implements GroupProvider { @Override public Long getGroupsCount(RealmModel realm, Boolean onlyTopGroups) { LOG.tracef("getGroupsCount(%s, %s)%s", realm, onlyTopGroups, getShortStackTrace()); - ModelCriteriaBuilder mcb = groupStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()); + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()); if (Objects.equals(onlyTopGroups, Boolean.TRUE)) { mcb = mcb.compare(SearchableFields.PARENT_ID, Operator.EQ, (Object) null); @@ -129,8 +128,8 @@ public class MapGroupProvider implements GroupProvider { @Override public Long getGroupsCountByNameContaining(RealmModel realm, String search) { - ModelCriteriaBuilder mcb = groupStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) .compare(SearchableFields.NAME, Operator.ILIKE, "%" + search + "%"); return tx.getCount(withCriteria(mcb)); @@ -168,8 +167,8 @@ public class MapGroupProvider implements GroupProvider { LOG.tracef("searchForGroupByNameStream(%s, %s, %d, %d)%s", realm, search, firstResult, maxResults, getShortStackTrace()); - ModelCriteriaBuilder mcb = groupStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) .compare(SearchableFields.NAME, Operator.ILIKE, "%" + search + "%"); @@ -189,8 +188,8 @@ public class MapGroupProvider implements GroupProvider { LOG.tracef("createGroup(%s, %s, %s, %s)%s", realm, id, name, toParent, getShortStackTrace()); // Check Db constraint: uniqueConstraints = { @UniqueConstraint(columnNames = {"REALM_ID", "PARENT_GROUP", "NAME"})} String parentId = toParent == null ? null : toParent.getId(); - ModelCriteriaBuilder mcb = groupStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) .compare(SearchableFields.PARENT_ID, Operator.EQ, parentId) .compare(SearchableFields.NAME, Operator.EQ, name); @@ -256,8 +255,8 @@ public class MapGroupProvider implements GroupProvider { } String parentId = toParent == null ? null : toParent.getId(); - ModelCriteriaBuilder mcb = groupStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) .compare(SearchableFields.PARENT_ID, Operator.EQ, parentId) .compare(SearchableFields.NAME, Operator.EQ, group.getName()); @@ -278,8 +277,8 @@ public class MapGroupProvider implements GroupProvider { public void addTopLevelGroup(RealmModel realm, GroupModel subGroup) { LOG.tracef("addTopLevelGroup(%s, %s)%s", realm, subGroup, getShortStackTrace()); - ModelCriteriaBuilder mcb = groupStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) .compare(SearchableFields.PARENT_ID, Operator.EQ, (Object) null) .compare(SearchableFields.NAME, Operator.EQ, subGroup.getName()); @@ -294,8 +293,8 @@ public class MapGroupProvider implements GroupProvider { public void preRemove(RealmModel realm, RoleModel role) { LOG.tracef("preRemove(%s, %s)%s", realm, role, getShortStackTrace()); - ModelCriteriaBuilder mcb = groupStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) .compare(SearchableFields.ASSIGNED_ROLE, Operator.EQ, role.getId()); try (Stream toRemove = tx.read(withCriteria(mcb))) { toRemove diff --git a/model/map/src/main/java/org/keycloak/models/map/loginFailure/MapUserLoginFailureProvider.java b/model/map/src/main/java/org/keycloak/models/map/loginFailure/MapUserLoginFailureProvider.java index 823524929d..93b7ab1d76 100644 --- a/model/map/src/main/java/org/keycloak/models/map/loginFailure/MapUserLoginFailureProvider.java +++ b/model/map/src/main/java/org/keycloak/models/map/loginFailure/MapUserLoginFailureProvider.java @@ -29,6 +29,7 @@ import java.util.function.Function; import static org.keycloak.common.util.StackUtil.getShortStackTrace; import static org.keycloak.models.map.storage.QueryParameters.withCriteria; +import static org.keycloak.models.map.storage.criteria.DefaultModelCriteria.criteria; /** * @author Martin Kanis @@ -38,11 +39,9 @@ public class MapUserLoginFailureProvider implements UserLoginFailureProvider { private static final Logger LOG = Logger.getLogger(MapUserLoginFailureProvider.class); private final KeycloakSession session; protected final MapKeycloakTransaction userLoginFailureTx; - private final MapStorage userLoginFailureStore; public MapUserLoginFailureProvider(KeycloakSession session, MapStorage userLoginFailureStore) { this.session = session; - this.userLoginFailureStore = userLoginFailureStore; userLoginFailureTx = userLoginFailureStore.createTransaction(session); session.getTransactionManager().enlistAfterCompletion(userLoginFailureTx); @@ -55,8 +54,8 @@ public class MapUserLoginFailureProvider implements UserLoginFailureProvider { @Override public UserLoginFailureModel getUserLoginFailure(RealmModel realm, String userId) { - ModelCriteriaBuilder mcb = userLoginFailureStore.createCriteriaBuilder() - .compare(UserLoginFailureModel.SearchableFields.REALM_ID, ModelCriteriaBuilder.Operator.EQ, realm.getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(UserLoginFailureModel.SearchableFields.REALM_ID, ModelCriteriaBuilder.Operator.EQ, realm.getId()) .compare(UserLoginFailureModel.SearchableFields.USER_ID, ModelCriteriaBuilder.Operator.EQ, userId); LOG.tracef("getUserLoginFailure(%s, %s)%s", realm, userId, getShortStackTrace()); @@ -69,8 +68,8 @@ public class MapUserLoginFailureProvider implements UserLoginFailureProvider { @Override public UserLoginFailureModel addUserLoginFailure(RealmModel realm, String userId) { - ModelCriteriaBuilder mcb = userLoginFailureStore.createCriteriaBuilder() - .compare(UserLoginFailureModel.SearchableFields.REALM_ID, ModelCriteriaBuilder.Operator.EQ, realm.getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(UserLoginFailureModel.SearchableFields.REALM_ID, ModelCriteriaBuilder.Operator.EQ, realm.getId()) .compare(UserLoginFailureModel.SearchableFields.USER_ID, ModelCriteriaBuilder.Operator.EQ, userId); LOG.tracef("addUserLoginFailure(%s, %s)%s", realm, userId, getShortStackTrace()); @@ -88,8 +87,8 @@ public class MapUserLoginFailureProvider implements UserLoginFailureProvider { @Override public void removeUserLoginFailure(RealmModel realm, String userId) { - ModelCriteriaBuilder mcb = userLoginFailureStore.createCriteriaBuilder() - .compare(UserLoginFailureModel.SearchableFields.REALM_ID, ModelCriteriaBuilder.Operator.EQ, realm.getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(UserLoginFailureModel.SearchableFields.REALM_ID, ModelCriteriaBuilder.Operator.EQ, realm.getId()) .compare(UserLoginFailureModel.SearchableFields.USER_ID, ModelCriteriaBuilder.Operator.EQ, userId); LOG.tracef("removeUserLoginFailure(%s, %s)%s", realm, userId, getShortStackTrace()); @@ -99,8 +98,8 @@ public class MapUserLoginFailureProvider implements UserLoginFailureProvider { @Override public void removeAllUserLoginFailures(RealmModel realm) { - ModelCriteriaBuilder mcb = userLoginFailureStore.createCriteriaBuilder() - .compare(UserLoginFailureModel.SearchableFields.REALM_ID, ModelCriteriaBuilder.Operator.EQ, realm.getId()); + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(UserLoginFailureModel.SearchableFields.REALM_ID, ModelCriteriaBuilder.Operator.EQ, realm.getId()); LOG.tracef("removeAllUserLoginFailures(%s)%s", realm, getShortStackTrace()); diff --git a/model/map/src/main/java/org/keycloak/models/map/realm/MapRealmProvider.java b/model/map/src/main/java/org/keycloak/models/map/realm/MapRealmProvider.java index 906d4306a5..40e0dc5a1f 100644 --- a/model/map/src/main/java/org/keycloak/models/map/realm/MapRealmProvider.java +++ b/model/map/src/main/java/org/keycloak/models/map/realm/MapRealmProvider.java @@ -39,17 +39,16 @@ import org.keycloak.models.map.storage.ModelCriteriaBuilder.Operator; import org.keycloak.models.utils.KeycloakModelUtils; import static org.keycloak.models.map.storage.QueryParameters.Order.ASCENDING; import static org.keycloak.models.map.storage.QueryParameters.withCriteria; +import static org.keycloak.models.map.storage.criteria.DefaultModelCriteria.criteria; public class MapRealmProvider implements RealmProvider { private static final Logger LOG = Logger.getLogger(MapRealmProvider.class); private final KeycloakSession session; final MapKeycloakTransaction tx; - private final MapStorage realmStore; public MapRealmProvider(KeycloakSession session, MapStorage realmStore) { this.session = session; - this.realmStore = realmStore; this.tx = realmStore.createTransaction(session); session.getTransactionManager().enlist(tx); } @@ -98,8 +97,8 @@ public class MapRealmProvider implements RealmProvider { LOG.tracef("getRealmByName(%s)%s", name, getShortStackTrace()); - ModelCriteriaBuilder mcb = realmStore.createCriteriaBuilder() - .compare(SearchableFields.NAME, Operator.EQ, name); + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.NAME, Operator.EQ, name); String realmId = tx.read(withCriteria(mcb)) .findFirst() @@ -111,13 +110,13 @@ public class MapRealmProvider implements RealmProvider { @Override public Stream getRealmsStream() { - return getRealmsStream(realmStore.createCriteriaBuilder()); + return getRealmsStream(criteria()); } @Override public Stream getRealmsWithProviderTypeStream(Class type) { - ModelCriteriaBuilder mcb = realmStore.createCriteriaBuilder() - .compare(SearchableFields.COMPONENT_PROVIDER_TYPE, Operator.EQ, type.getName()); + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.COMPONENT_PROVIDER_TYPE, Operator.EQ, type.getName()); return getRealmsStream(mcb); } @@ -161,8 +160,8 @@ public class MapRealmProvider implements RealmProvider { @Override public void removeExpiredClientInitialAccess() { - ModelCriteriaBuilder mcb = realmStore.createCriteriaBuilder() - .compare(SearchableFields.CLIENT_INITIAL_ACCESS, Operator.EXISTS); + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.CLIENT_INITIAL_ACCESS, Operator.EXISTS); tx.read(withCriteria(mcb)) .forEach(MapRealmEntity::removeExpiredClientInitialAccesses); diff --git a/model/map/src/main/java/org/keycloak/models/map/role/MapRoleProvider.java b/model/map/src/main/java/org/keycloak/models/map/role/MapRoleProvider.java index 7e7026afa4..551e7361f3 100644 --- a/model/map/src/main/java/org/keycloak/models/map/role/MapRoleProvider.java +++ b/model/map/src/main/java/org/keycloak/models/map/role/MapRoleProvider.java @@ -33,6 +33,7 @@ import org.keycloak.models.map.storage.MapStorage; import static org.keycloak.common.util.StackUtil.getShortStackTrace; import static org.keycloak.models.map.storage.QueryParameters.Order.ASCENDING; import static org.keycloak.models.map.storage.QueryParameters.withCriteria; +import static org.keycloak.models.map.storage.criteria.DefaultModelCriteria.criteria; import org.keycloak.models.RoleContainerModel; import org.keycloak.models.RoleModel.SearchableFields; @@ -45,11 +46,9 @@ public class MapRoleProvider implements RoleProvider { private static final Logger LOG = Logger.getLogger(MapRoleProvider.class); private final KeycloakSession session; final MapKeycloakTransaction tx; - private final MapStorage roleStore; public MapRoleProvider(KeycloakSession session, MapStorage roleStore) { this.session = session; - this.roleStore = roleStore; this.tx = roleStore.createTransaction(session); session.getTransactionManager().enlist(tx); } @@ -79,8 +78,8 @@ public class MapRoleProvider implements RoleProvider { @Override public Stream getRealmRolesStream(RealmModel realm, Integer first, Integer max) { - ModelCriteriaBuilder mcb = roleStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) .compare(SearchableFields.IS_CLIENT_ROLE, Operator.NE, true); return tx.read(withCriteria(mcb).pagination(first, max, SearchableFields.NAME)) @@ -92,8 +91,8 @@ public class MapRoleProvider implements RoleProvider { LOG.tracef("getRolesStream(%s, %s, %s, %d, %d)%s", realm, ids, search, first, max, getShortStackTrace()); if (ids == null) return Stream.empty(); - ModelCriteriaBuilder mcb = roleStore.createCriteriaBuilder() - .compare(RoleModel.SearchableFields.ID, Operator.IN, ids) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(RoleModel.SearchableFields.ID, Operator.IN, ids) .compare(RoleModel.SearchableFields.REALM_ID, Operator.EQ, realm.getId()); if (search != null) { @@ -106,8 +105,8 @@ public class MapRoleProvider implements RoleProvider { @Override public Stream getRealmRolesStream(RealmModel realm) { - ModelCriteriaBuilder mcb = roleStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) .compare(SearchableFields.IS_CLIENT_ROLE, Operator.NE, true); return tx.read(withCriteria(mcb).orderBy(SearchableFields.NAME, ASCENDING)) @@ -135,8 +134,8 @@ public class MapRoleProvider implements RoleProvider { @Override public Stream getClientRolesStream(ClientModel client, Integer first, Integer max) { - ModelCriteriaBuilder mcb = roleStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, client.getRealm().getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, client.getRealm().getId()) .compare(SearchableFields.CLIENT_ID, Operator.EQ, client.getId()); return tx.read(withCriteria(mcb).pagination(first, max, SearchableFields.NAME)) @@ -145,8 +144,8 @@ public class MapRoleProvider implements RoleProvider { @Override public Stream getClientRolesStream(ClientModel client) { - ModelCriteriaBuilder mcb = roleStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, client.getRealm().getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, client.getRealm().getId()) .compare(SearchableFields.CLIENT_ID, Operator.EQ, client.getId()); return tx.read(withCriteria(mcb).orderBy(SearchableFields.NAME, ASCENDING)) @@ -196,8 +195,8 @@ public class MapRoleProvider implements RoleProvider { } LOG.tracef("getRealmRole(%s, %s)%s", realm, name, getShortStackTrace()); - ModelCriteriaBuilder mcb = roleStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) .compare(SearchableFields.NAME, Operator.ILIKE, name); String roleId = tx.read(withCriteria(mcb)) @@ -216,8 +215,8 @@ public class MapRoleProvider implements RoleProvider { } LOG.tracef("getClientRole(%s, %s)%s", client, name, getShortStackTrace()); - ModelCriteriaBuilder mcb = roleStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, client.getRealm().getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, client.getRealm().getId()) .compare(SearchableFields.CLIENT_ID, Operator.EQ, client.getId()) .compare(SearchableFields.NAME, Operator.ILIKE, name); @@ -250,12 +249,12 @@ public class MapRoleProvider implements RoleProvider { if (search == null) { return Stream.empty(); } - ModelCriteriaBuilder mcb = roleStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) - .or( - roleStore.createCriteriaBuilder().compare(SearchableFields.NAME, Operator.ILIKE, "%" + search + "%"), - roleStore.createCriteriaBuilder().compare(SearchableFields.DESCRIPTION, Operator.ILIKE, "%" + search + "%") - ); + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) + .or( + mcb.compare(SearchableFields.NAME, Operator.ILIKE, "%" + search + "%"), + mcb.compare(SearchableFields.DESCRIPTION, Operator.ILIKE, "%" + search + "%") + ); return tx.read(withCriteria(mcb).pagination(first, max, SearchableFields.NAME)) .map(entityToAdapterFunc(realm)); @@ -266,13 +265,14 @@ public class MapRoleProvider implements RoleProvider { if (search == null) { return Stream.empty(); } - ModelCriteriaBuilder mcb = roleStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, client.getRealm().getId()) - .compare(SearchableFields.CLIENT_ID, Operator.EQ, client.getId()) - .or( - roleStore.createCriteriaBuilder().compare(SearchableFields.NAME, Operator.ILIKE, "%" + search + "%"), - roleStore.createCriteriaBuilder().compare(SearchableFields.DESCRIPTION, Operator.ILIKE, "%" + search + "%") - ); + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, client.getRealm().getId()) + .compare(SearchableFields.CLIENT_ID, Operator.EQ, client.getId()) + .or( + mcb.compare(SearchableFields.NAME, Operator.ILIKE, "%" + search + "%"), + mcb.compare(SearchableFields.DESCRIPTION, Operator.ILIKE, "%" + search + "%") + ); + return tx.read(withCriteria(mcb).pagination(first, max, SearchableFields.NAME)) .map(entityToAdapterFunc(client.getRealm())); } diff --git a/model/map/src/main/java/org/keycloak/models/map/storage/MapStorage.java b/model/map/src/main/java/org/keycloak/models/map/storage/MapStorage.java index 8cff153c4f..4debbd73b7 100644 --- a/model/map/src/main/java/org/keycloak/models/map/storage/MapStorage.java +++ b/model/map/src/main/java/org/keycloak/models/map/storage/MapStorage.java @@ -18,7 +18,6 @@ package org.keycloak.models.map.storage; import org.keycloak.models.KeycloakSession; import org.keycloak.models.map.common.AbstractEntity; -import java.util.stream.Stream; /** * Implementation of this interface interacts with a persistence storage storing various entities, e.g. users, realms. @@ -32,21 +31,6 @@ import java.util.stream.Stream; * layout and thus to support no-downtime upgrade. */ public interface MapStorage { - - /** - * Returns criteria builder for the storage engine. - * The criteria are specified in the given criteria builder based on model properties. - *
- * Note: While the criteria are formulated in terms of model properties, - * the storage engine may in turn process them into the best form that suits the - * underlying storage engine query language, e.g. to conditions on storage - * attributes or REST query parameters. - * If possible, do not delay filtering after the models are reconstructed from - * storage entities, in most cases this would be highly inefficient. - * - * @return See description. Never returns {@code null} - */ - ModelCriteriaBuilder createCriteriaBuilder(); /** * Creates a {@code MapKeycloakTransaction} object that tracks a new transaction related to this storage. diff --git a/model/map/src/main/java/org/keycloak/models/map/storage/ModelCriteriaBuilder.java b/model/map/src/main/java/org/keycloak/models/map/storage/ModelCriteriaBuilder.java index ed14d281e1..60d1da6a6c 100644 --- a/model/map/src/main/java/org/keycloak/models/map/storage/ModelCriteriaBuilder.java +++ b/model/map/src/main/java/org/keycloak/models/map/storage/ModelCriteriaBuilder.java @@ -170,18 +170,4 @@ public interface ModelCriteriaBuilder { */ ModelCriteriaBuilder not(ModelCriteriaBuilder builder); - /** - * Returns this object cast to the given class, or {@code null} if the class cannot be cast to that {@code clazz}. - * @param - * @param clazz - * @return - */ - default T unwrap(Class clazz) { - if (clazz.isInstance(this)) { - return clazz.cast(this); - } else { - return null; - } - } - } diff --git a/model/map/src/main/java/org/keycloak/models/map/storage/chm/ConcurrentHashMapKeycloakTransaction.java b/model/map/src/main/java/org/keycloak/models/map/storage/chm/ConcurrentHashMapKeycloakTransaction.java index 77626b83fa..a530eadbfa 100644 --- a/model/map/src/main/java/org/keycloak/models/map/storage/chm/ConcurrentHashMapKeycloakTransaction.java +++ b/model/map/src/main/java/org/keycloak/models/map/storage/chm/ConcurrentHashMapKeycloakTransaction.java @@ -31,9 +31,8 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import org.jboss.logging.Logger; import org.keycloak.models.map.storage.MapKeycloakTransaction; -import org.keycloak.models.map.storage.MapStorage; -import org.keycloak.models.map.storage.ModelCriteriaBuilder; import org.keycloak.models.map.storage.QueryParameters; +import org.keycloak.models.map.storage.criteria.DefaultModelCriteria; import org.keycloak.utils.StreamsUtil; public class ConcurrentHashMapKeycloakTransaction implements MapKeycloakTransaction { @@ -168,6 +167,9 @@ public class ConcurrentHashMapKeycloakTransaction read(QueryParameters queryParameters) { + DefaultModelCriteria mcb = (DefaultModelCriteria) queryParameters.getModelCriteriaBuilder(); + MapModelCriteriaBuilder mapMcb = (MapModelCriteriaBuilder) mcb.flashToModelCriteriaBuilder(map.createCriteriaBuilder()); + Predicate filterOutAllBulkDeletedObjects = tasks.values().stream() .filter(BulkDeleteOperation.class::isInstance) .map(BulkDeleteOperation.class::cast) @@ -175,8 +177,6 @@ public class ConcurrentHashMapKeycloakTransaction true); - ModelCriteriaBuilder mcb = queryParameters.getModelCriteriaBuilder(); - Stream updatedAndNotRemovedObjectsStream = this.map.read(queryParameters) .filter(filterOutAllBulkDeletedObjects) .map(this::getUpdated) // If the object has been removed, tx.get will return null, otherwise it will return me.getValue() @@ -184,7 +184,6 @@ public class ConcurrentHashMapKeycloakTransaction mapMcb = mcb.unwrap(MapModelCriteriaBuilder.class); Stream res = mapMcb == null ? updatedAndNotRemovedObjectsStream : Stream.concat( @@ -401,12 +400,8 @@ public class ConcurrentHashMapKeycloakTransaction getFilterForNonDeletedObjects() { - if (! (queryParameters.getModelCriteriaBuilder() instanceof MapModelCriteriaBuilder)) { - return t -> true; - } - - @SuppressWarnings("unchecked") - final MapModelCriteriaBuilder mmcb = (MapModelCriteriaBuilder) queryParameters.getModelCriteriaBuilder(); + DefaultModelCriteria mcb = (DefaultModelCriteria) queryParameters.getModelCriteriaBuilder(); + MapModelCriteriaBuilder mmcb = (MapModelCriteriaBuilder) mcb.flashToModelCriteriaBuilder(map.createCriteriaBuilder()); Predicate entityFilter = mmcb.getEntityFilter(); Predicate keyFilter = mmcb.getKeyFilter(); diff --git a/model/map/src/main/java/org/keycloak/models/map/storage/chm/ConcurrentHashMapStorage.java b/model/map/src/main/java/org/keycloak/models/map/storage/chm/ConcurrentHashMapStorage.java index 1e24e2c3de..b05abe1e50 100644 --- a/model/map/src/main/java/org/keycloak/models/map/storage/chm/ConcurrentHashMapStorage.java +++ b/model/map/src/main/java/org/keycloak/models/map/storage/chm/ConcurrentHashMapStorage.java @@ -25,6 +25,7 @@ import org.keycloak.models.map.common.UpdatableEntity; import org.keycloak.models.map.storage.MapStorage; import org.keycloak.models.map.storage.ModelCriteriaBuilder; import org.keycloak.models.map.storage.QueryParameters; +import org.keycloak.models.map.storage.criteria.DefaultModelCriteria; import org.keycloak.storage.SearchableModelField; import java.util.Comparator; @@ -123,11 +124,9 @@ public class ConcurrentHashMapStorage queryParameters) { - ModelCriteriaBuilder criteria = queryParameters.getModelCriteriaBuilder(); + DefaultModelCriteria criteria = (DefaultModelCriteria) queryParameters.getModelCriteriaBuilder(); if (criteria == null) { long res = store.size(); @@ -136,12 +135,9 @@ public class ConcurrentHashMapStorage b = criteria.unwrap(MapModelCriteriaBuilder.class); - if (b == null) { - throw new IllegalStateException("Incompatible class: " + criteria.getClass()); - } - Predicate keyFilter = b.getKeyFilter(); - Predicate entityFilter = b.getEntityFilter(); + MapModelCriteriaBuilder mcb = (MapModelCriteriaBuilder) criteria.flashToModelCriteriaBuilder(createCriteriaBuilder()); + Predicate keyFilter = mcb.getKeyFilter(); + Predicate entityFilter = mcb.getEntityFilter(); Stream> storeStream = store.entrySet().stream(); final AtomicLong res = new AtomicLong(0); @@ -159,11 +155,6 @@ public class ConcurrentHashMapStorage createCriteriaBuilder() { - return new MapModelCriteriaBuilder<>(keyConvertor, fieldPredicates); - } - @Override @SuppressWarnings("unchecked") public MapKeycloakTransaction createTransaction(KeycloakSession session) { @@ -171,6 +162,10 @@ public class ConcurrentHashMapStorage(this, keyConvertor, cloner) : sessionTransaction; } + public ModelCriteriaBuilder createCriteriaBuilder() { + return new MapModelCriteriaBuilder<>(keyConvertor, fieldPredicates); + } + public StringKeyConvertor getKeyConvertor() { return keyConvertor; } @@ -181,24 +176,19 @@ public class ConcurrentHashMapStorage read(QueryParameters queryParameters) { - ModelCriteriaBuilder criteria = queryParameters.getModelCriteriaBuilder(); + DefaultModelCriteria criteria = (DefaultModelCriteria) queryParameters.getModelCriteriaBuilder(); if (criteria == null) { return Stream.empty(); } + + MapModelCriteriaBuilder mcb = (MapModelCriteriaBuilder) criteria.flashToModelCriteriaBuilder(createCriteriaBuilder()); Stream> stream = store.entrySet().stream(); - @SuppressWarnings("unchecked") - MapModelCriteriaBuilder b = criteria.unwrap(MapModelCriteriaBuilder.class); - if (b == null) { - throw new IllegalStateException("Incompatible class: " + criteria.getClass()); - } - Predicate keyFilter = b.getKeyFilter(); - Predicate entityFilter = b.getEntityFilter(); + Predicate keyFilter = mcb.getKeyFilter(); + Predicate entityFilter = mcb.getEntityFilter(); stream = stream.filter(me -> keyFilter.test(me.getKey()) && entityFilter.test(me.getValue())); return stream.map(Map.Entry::getValue); @@ -210,8 +200,6 @@ public class ConcurrentHashMapStorage queryParameters) { return read(queryParameters).count(); diff --git a/model/map/src/main/java/org/keycloak/models/map/storage/chm/ConcurrentHashMapStorageProviderFactory.java b/model/map/src/main/java/org/keycloak/models/map/storage/chm/ConcurrentHashMapStorageProviderFactory.java index 691cafef8c..3a187fb219 100644 --- a/model/map/src/main/java/org/keycloak/models/map/storage/chm/ConcurrentHashMapStorageProviderFactory.java +++ b/model/map/src/main/java/org/keycloak/models/map/storage/chm/ConcurrentHashMapStorageProviderFactory.java @@ -78,6 +78,7 @@ import java.util.LinkedList; import java.util.Map; import static org.keycloak.models.map.storage.QueryParameters.withCriteria; +import static org.keycloak.models.map.storage.criteria.DefaultModelCriteria.criteria; /** * @@ -240,7 +241,7 @@ public class ConcurrentHashMapStorageProviderFactory implements AmphibianProvide try { if (storageDirectory != null) { LOG.debugf("Storing contents to %s", f.getCanonicalPath()); - final ModelCriteriaBuilder readAllCriteria = store.createCriteriaBuilder(); + final ModelCriteriaBuilder readAllCriteria = criteria(); Serialization.MAPPER.writeValue(f, store.read(withCriteria(readAllCriteria))); } else { LOG.debugf("Not storing contents of %s because directory not set", mapName); diff --git a/model/map/src/main/java/org/keycloak/models/map/storage/chm/MapModelCriteriaBuilder.java b/model/map/src/main/java/org/keycloak/models/map/storage/chm/MapModelCriteriaBuilder.java index 3dac1d3516..21f27cfe4f 100644 --- a/model/map/src/main/java/org/keycloak/models/map/storage/chm/MapModelCriteriaBuilder.java +++ b/model/map/src/main/java/org/keycloak/models/map/storage/chm/MapModelCriteriaBuilder.java @@ -93,10 +93,7 @@ public class MapModelCriteriaBuilder implements @SuppressWarnings("unchecked") @Override public MapModelCriteriaBuilder not(ModelCriteriaBuilder builder) { - MapModelCriteriaBuilder b = builder.unwrap(MapModelCriteriaBuilder.class); - if (b == null) { - throw new ClassCastException("Incompatible class: " + builder.getClass()); - } + MapModelCriteriaBuilder b = (MapModelCriteriaBuilder) builder; Predicate resIndexFilter = b.getKeyFilter() == ALWAYS_TRUE ? ALWAYS_TRUE : b.getKeyFilter().negate(); Predicate resEntityFilter = b.getEntityFilter() == ALWAYS_TRUE ? ALWAYS_TRUE : b.getEntityFilter().negate(); diff --git a/model/map/src/main/java/org/keycloak/models/map/storage/chm/UserSessionConcurrentHashMapStorage.java b/model/map/src/main/java/org/keycloak/models/map/storage/chm/UserSessionConcurrentHashMapStorage.java index 34f4625196..ff8adb701d 100644 --- a/model/map/src/main/java/org/keycloak/models/map/storage/chm/UserSessionConcurrentHashMapStorage.java +++ b/model/map/src/main/java/org/keycloak/models/map/storage/chm/UserSessionConcurrentHashMapStorage.java @@ -26,6 +26,7 @@ import org.keycloak.models.map.storage.MapKeycloakTransaction; import org.keycloak.models.map.storage.ModelCriteriaBuilder; import org.keycloak.models.map.storage.ModelCriteriaBuilder.Operator; import org.keycloak.models.map.storage.QueryParameters; +import org.keycloak.models.map.storage.criteria.DefaultModelCriteria; import org.keycloak.models.map.userSession.MapAuthenticatedClientSessionEntity; import org.keycloak.models.map.userSession.MapUserSessionEntity; import java.util.Set; @@ -55,14 +56,16 @@ public class UserSessionConcurrentHashMapStorage extends ConcurrentHashMapSto @Override public long delete(QueryParameters queryParameters) { Set ids = read(queryParameters).map(AbstractEntity::getId).collect(Collectors.toSet()); - ModelCriteriaBuilder csMcb = clientSessionStore.createCriteriaBuilder().compare(AuthenticatedClientSessionModel.SearchableFields.USER_SESSION_ID, Operator.IN, ids); + ModelCriteriaBuilder csMcb = DefaultModelCriteria.criteria() + .compare(AuthenticatedClientSessionModel.SearchableFields.USER_SESSION_ID, Operator.IN, ids); clientSessionTr.delete(withCriteria(csMcb)); return super.delete(queryParameters); } @Override public boolean delete(String key) { - ModelCriteriaBuilder csMcb = clientSessionStore.createCriteriaBuilder().compare(AuthenticatedClientSessionModel.SearchableFields.USER_SESSION_ID, Operator.EQ, key); + ModelCriteriaBuilder csMcb = DefaultModelCriteria.criteria() + .compare(AuthenticatedClientSessionModel.SearchableFields.USER_SESSION_ID, Operator.EQ, key); clientSessionTr.delete(withCriteria(csMcb)); return super.delete(key); } diff --git a/model/map/src/main/java/org/keycloak/models/map/storage/criteria/DefaultModelCriteria.java b/model/map/src/main/java/org/keycloak/models/map/storage/criteria/DefaultModelCriteria.java index 0062d5101d..63811d58bb 100644 --- a/model/map/src/main/java/org/keycloak/models/map/storage/criteria/DefaultModelCriteria.java +++ b/model/map/src/main/java/org/keycloak/models/map/storage/criteria/DefaultModelCriteria.java @@ -65,16 +65,16 @@ public class DefaultModelCriteria implements ModelCriteriaBuilder { @Override public DefaultModelCriteria and(ModelCriteriaBuilder... mcbs) { if (mcbs.length == 1) { - ModelCriteriaNode toBeChild = ((DefaultModelCriteria) mcbs[0].unwrap(DefaultModelCriteria.class)).node; + ModelCriteriaNode toBeChild = ((DefaultModelCriteria) mcbs[0]).node; if (toBeChild.getNodeOperator() == ExtOperator.AND || toBeChild.getNodeOperator() == ExtOperator.OR) { - return ((DefaultModelCriteria) mcbs[0].unwrap(DefaultModelCriteria.class)); + return (DefaultModelCriteria) mcbs[0]; } } final ModelCriteriaNode targetNode = new ModelCriteriaNode<>(ExtOperator.AND); AtomicBoolean hasFalseNode = new AtomicBoolean(false); for (ModelCriteriaBuilder mcb : mcbs) { - final ModelCriteriaNode nodeToAdd = ((DefaultModelCriteria) mcb.unwrap(DefaultModelCriteria.class)).node; + final ModelCriteriaNode nodeToAdd = ((DefaultModelCriteria) mcb).node; getNodesToAddForAndOr(nodeToAdd, ExtOperator.AND) .filter(ModelCriteriaNode::isNotTrueNode) .peek(n -> { if (n.isFalseNode()) hasFalseNode.lazySet(true); }) @@ -97,16 +97,16 @@ public class DefaultModelCriteria implements ModelCriteriaBuilder { @Override public DefaultModelCriteria or(ModelCriteriaBuilder... mcbs) { if (mcbs.length == 1) { - ModelCriteriaNode toBeChild = ((DefaultModelCriteria) mcbs[0].unwrap(DefaultModelCriteria.class)).node; + ModelCriteriaNode toBeChild = ((DefaultModelCriteria) mcbs[0]).node; if (toBeChild.getNodeOperator() == ExtOperator.AND || toBeChild.getNodeOperator() == ExtOperator.OR) { - return ((DefaultModelCriteria) mcbs[0].unwrap(DefaultModelCriteria.class)); + return ((DefaultModelCriteria) mcbs[0]); } } final ModelCriteriaNode targetNode = new ModelCriteriaNode<>(ExtOperator.OR); AtomicBoolean hasTrueNode = new AtomicBoolean(false); for (ModelCriteriaBuilder mcb : mcbs) { - final ModelCriteriaNode nodeToAdd = ((DefaultModelCriteria) mcb.unwrap(DefaultModelCriteria.class)).node; + final ModelCriteriaNode nodeToAdd = ((DefaultModelCriteria) mcb).node; getNodesToAddForAndOr(nodeToAdd, ExtOperator.OR) .filter(ModelCriteriaNode::isNotFalseNode) .peek(n -> { if (n.isTrueNode()) hasTrueNode.lazySet(true); }) @@ -129,7 +129,7 @@ public class DefaultModelCriteria implements ModelCriteriaBuilder { @Override public DefaultModelCriteria not(ModelCriteriaBuilder mcb) { final ModelCriteriaNode targetNode = new ModelCriteriaNode<>(ExtOperator.NOT); - ModelCriteriaNode toBeChild = ((DefaultModelCriteria) mcb.unwrap(DefaultModelCriteria.class)).node; + ModelCriteriaNode toBeChild = ((DefaultModelCriteria) mcb).node; if (toBeChild.getNodeOperator() == ExtOperator.NOT) { return compare(toBeChild.getChildren().get(0).cloneTree()); } @@ -144,6 +144,9 @@ public class DefaultModelCriteria implements ModelCriteriaBuilder { * @return Updated {@code ModelCriteriaBuilder} */ public > C flashToModelCriteriaBuilder(C mcb) { + if (isEmpty()) { + return mcb; + } return mcb == null ? null : node.flashToModelCriteriaBuilder(mcb); } diff --git a/model/map/src/main/java/org/keycloak/models/map/user/MapUserProvider.java b/model/map/src/main/java/org/keycloak/models/map/user/MapUserProvider.java index 1b8a22557e..36447e20e5 100644 --- a/model/map/src/main/java/org/keycloak/models/map/user/MapUserProvider.java +++ b/model/map/src/main/java/org/keycloak/models/map/user/MapUserProvider.java @@ -71,18 +71,17 @@ import static org.keycloak.models.UserModel.LAST_NAME; import static org.keycloak.models.UserModel.USERNAME; import static org.keycloak.models.map.storage.QueryParameters.Order.ASCENDING; import static org.keycloak.models.map.storage.QueryParameters.withCriteria; +import static org.keycloak.models.map.storage.criteria.DefaultModelCriteria.criteria; public class MapUserProvider implements UserProvider.Streams, UserCredentialStore.Streams { private static final Logger LOG = Logger.getLogger(MapUserProvider.class); private final KeycloakSession session; final MapKeycloakTransaction tx; - private final MapStorage userStore; public MapUserProvider(KeycloakSession session, MapStorage store) { this.session = session; - this.userStore = store; - this.tx = userStore.createTransaction(session); + this.tx = store.createTransaction(session); session.getTransactionManager().enlist(tx); } @@ -155,8 +154,8 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor public void preRemove(RealmModel realm, IdentityProviderModel provider) { String socialProvider = provider.getAlias(); LOG.tracef("preRemove[RealmModel realm, IdentityProviderModel provider](%s, %s)%s", realm, socialProvider, getShortStackTrace()); - ModelCriteriaBuilder mcb = userStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) .compare(SearchableFields.IDP_AND_USER, Operator.EQ, socialProvider); tx.read(withCriteria(mcb)) @@ -190,8 +189,8 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor @Override public UserModel getUserByFederatedIdentity(RealmModel realm, FederatedIdentityModel socialLink) { LOG.tracef("getUserByFederatedIdentity(%s, %s)%s", realm, socialLink, getShortStackTrace()); - ModelCriteriaBuilder mcb = userStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) .compare(SearchableFields.IDP_AND_USER, Operator.EQ, socialLink.getIdentityProvider(), socialLink.getUserId()); return tx.read(withCriteria(mcb)) @@ -279,8 +278,8 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor @Override public UserModel getServiceAccount(ClientModel client) { LOG.tracef("getServiceAccount(%s)%s", client.getId(), getShortStackTrace()); - ModelCriteriaBuilder mcb = userStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, client.getRealm().getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, client.getRealm().getId()) .compare(SearchableFields.SERVICE_ACCOUNT_CLIENT, Operator.EQ, client.getId()); return tx.read(withCriteria(mcb)) @@ -302,8 +301,8 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor @Override public UserModel addUser(RealmModel realm, String id, String username, boolean addDefaultRoles, boolean addDefaultRequiredActions) { LOG.tracef("addUser(%s, %s, %s, %s, %s)%s", realm, id, username, addDefaultRoles, addDefaultRequiredActions, getShortStackTrace()); - ModelCriteriaBuilder mcb = userStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) .compare(SearchableFields.USERNAME, Operator.EQ, username); if (tx.getCount(withCriteria(mcb)) > 0) { @@ -342,8 +341,8 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor @Override public void preRemove(RealmModel realm) { LOG.tracef("preRemove[RealmModel](%s)%s", realm, getShortStackTrace()); - ModelCriteriaBuilder mcb = userStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()); + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()); tx.delete(withCriteria(mcb)); } @@ -351,8 +350,8 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor @Override public void removeImportedUsers(RealmModel realm, String storageProviderId) { LOG.tracef("removeImportedUsers(%s, %s)%s", realm, storageProviderId, getShortStackTrace()); - ModelCriteriaBuilder mcb = userStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) .compare(SearchableFields.FEDERATION_LINK, Operator.EQ, storageProviderId); tx.delete(withCriteria(mcb)); @@ -361,8 +360,8 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor @Override public void unlinkUsers(RealmModel realm, String storageProviderId) { LOG.tracef("unlinkUsers(%s, %s)%s", realm, storageProviderId, getShortStackTrace()); - ModelCriteriaBuilder mcb = userStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) .compare(SearchableFields.FEDERATION_LINK, Operator.EQ, storageProviderId); try (Stream s = tx.read(withCriteria(mcb))) { @@ -374,8 +373,8 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor public void preRemove(RealmModel realm, RoleModel role) { String roleId = role.getId(); LOG.tracef("preRemove[RoleModel](%s, %s)%s", realm, roleId, getShortStackTrace()); - ModelCriteriaBuilder mcb = userStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) .compare(SearchableFields.ASSIGNED_ROLE, Operator.EQ, roleId); try (Stream s = tx.read(withCriteria(mcb))) { @@ -387,8 +386,8 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor public void preRemove(RealmModel realm, GroupModel group) { String groupId = group.getId(); LOG.tracef("preRemove[GroupModel](%s, %s)%s", realm, groupId, getShortStackTrace()); - ModelCriteriaBuilder mcb = userStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) .compare(SearchableFields.ASSIGNED_GROUP, Operator.EQ, groupId); try (Stream s = tx.read(withCriteria(mcb))) { @@ -400,8 +399,8 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor public void preRemove(RealmModel realm, ClientModel client) { String clientId = client.getId(); LOG.tracef("preRemove[ClientModel](%s, %s)%s", realm, clientId, getShortStackTrace()); - ModelCriteriaBuilder mcb = userStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) .compare(SearchableFields.CONSENT_FOR_CLIENT, Operator.EQ, clientId); try (Stream s = tx.read(withCriteria(mcb))) { @@ -419,8 +418,8 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor String clientScopeId = clientScope.getId(); LOG.tracef("preRemove[ClientScopeModel](%s)%s", clientScopeId, getShortStackTrace()); - ModelCriteriaBuilder mcb = userStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, clientScope.getRealm().getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, clientScope.getRealm().getId()) .compare(SearchableFields.CONSENT_WITH_CLIENT_SCOPE, Operator.EQ, clientScopeId); try (Stream s = tx.read(withCriteria(mcb))) { @@ -437,8 +436,8 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor removeImportedUsers(realm, componentId); } if (component.getProviderType().equals(ClientStorageProvider.class.getName())) { - ModelCriteriaBuilder mcb = userStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) .compare(SearchableFields.CONSENT_CLIENT_FEDERATION_LINK, Operator.EQ, componentId); try (Stream s = tx.read(withCriteria(mcb))) { @@ -465,8 +464,8 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor public void grantToAllUsers(RealmModel realm, RoleModel role) { String roleId = role.getId(); LOG.tracef("grantToAllUsers(%s, %s)%s", realm, roleId, getShortStackTrace()); - ModelCriteriaBuilder mcb = userStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()); + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()); try (Stream s = tx.read(withCriteria(mcb))) { s.forEach(entity -> entity.addRolesMembership(roleId)); @@ -483,8 +482,8 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor public UserModel getUserByUsername(RealmModel realm, String username) { if (username == null) return null; LOG.tracef("getUserByUsername(%s, %s)%s", realm, username, getShortStackTrace()); - ModelCriteriaBuilder mcb = userStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) .compare(SearchableFields.USERNAME, Operator.ILIKE, username); try (Stream s = tx.read(withCriteria(mcb))) { @@ -496,8 +495,8 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor @Override public UserModel getUserByEmail(RealmModel realm, String email) { LOG.tracef("getUserByEmail(%s, %s)%s", realm, email, getShortStackTrace()); - ModelCriteriaBuilder mcb = userStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) .compare(SearchableFields.EMAIL, Operator.EQ, email); List usersWithEmail = tx.read(withCriteria(mcb)) @@ -527,8 +526,8 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor @Override public int getUsersCount(RealmModel realm, boolean includeServiceAccount) { LOG.tracef("getUsersCount(%s, %s)%s", realm, includeServiceAccount, getShortStackTrace()); - ModelCriteriaBuilder mcb = userStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()); + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()); if (! includeServiceAccount) { mcb = mcb.compare(SearchableFields.SERVICE_ACCOUNT_CLIENT, Operator.NOT_EXISTS); @@ -540,8 +539,8 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor @Override public Stream getUsersStream(RealmModel realm, Integer firstResult, Integer maxResults, boolean includeServiceAccounts) { LOG.tracef("getUsersStream(%s, %d, %d, %s)%s", realm, firstResult, maxResults, includeServiceAccounts, getShortStackTrace()); - ModelCriteriaBuilder mcb = userStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()); + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()); if (! includeServiceAccounts) { mcb = mcb.compare(SearchableFields.SERVICE_ACCOUNT_CLIENT, Operator.NOT_EXISTS); @@ -570,8 +569,8 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor public Stream searchForUserStream(RealmModel realm, Map attributes, Integer firstResult, Integer maxResults) { LOG.tracef("searchForUserStream(%s, %s, %d, %d)%s", realm, attributes, firstResult, maxResults, getShortStackTrace()); - ModelCriteriaBuilder mcb = userStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()); + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()); if (! session.getAttributeOrDefault(UserModel.INCLUDE_SERVICE_ACCOUNT, true)) { mcb = mcb.compare(SearchableFields.SERVICE_ACCOUNT_CLIENT, Operator.NOT_EXISTS); @@ -597,10 +596,10 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor } final String s = exactSearch ? stringToSearch : ("%" + stringToSearch + "%"); mcb = mcb.or( - userStore.createCriteriaBuilder().compare(SearchableFields.USERNAME, Operator.ILIKE, s), - userStore.createCriteriaBuilder().compare(SearchableFields.EMAIL, Operator.ILIKE, s), - userStore.createCriteriaBuilder().compare(SearchableFields.FIRST_NAME, Operator.ILIKE, s), - userStore.createCriteriaBuilder().compare(SearchableFields.LAST_NAME, Operator.ILIKE, s) + mcb.compare(SearchableFields.USERNAME, Operator.ILIKE, s), + mcb.compare(SearchableFields.EMAIL, Operator.ILIKE, s), + mcb.compare(SearchableFields.FIRST_NAME, Operator.ILIKE, s), + mcb.compare(SearchableFields.LAST_NAME, Operator.ILIKE, s) ); } break; @@ -676,8 +675,8 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor @Override public Stream getGroupMembersStream(RealmModel realm, GroupModel group, Integer firstResult, Integer maxResults) { LOG.tracef("getGroupMembersStream(%s, %s, %d, %d)%s", realm, group.getId(), firstResult, maxResults, getShortStackTrace()); - ModelCriteriaBuilder mcb = userStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) .compare(SearchableFields.ASSIGNED_GROUP, Operator.EQ, group.getId()); return tx.read(withCriteria(mcb).pagination(firstResult, maxResults, SearchableFields.USERNAME)) @@ -687,8 +686,8 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor @Override public Stream searchForUserByUserAttributeStream(RealmModel realm, String attrName, String attrValue) { LOG.tracef("searchForUserByUserAttributeStream(%s, %s, %s)%s", realm, attrName, attrValue, getShortStackTrace()); - ModelCriteriaBuilder mcb = userStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) .compare(SearchableFields.ATTRIBUTE, Operator.EQ, attrName, attrValue); return tx.read(withCriteria(mcb).orderBy(SearchableFields.USERNAME, ASCENDING)) @@ -715,8 +714,8 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor @Override public Stream getRoleMembersStream(RealmModel realm, RoleModel role, Integer firstResult, Integer maxResults) { LOG.tracef("getRoleMembersStream(%s, %s, %d, %d)%s", realm, role, firstResult, maxResults, getShortStackTrace()); - ModelCriteriaBuilder mcb = userStore.createCriteriaBuilder() - .compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) .compare(SearchableFields.ASSIGNED_ROLE, Operator.EQ, role.getId()); return tx.read(withCriteria(mcb).pagination(firstResult, maxResults, SearchableFields.USERNAME)) diff --git a/model/map/src/main/java/org/keycloak/models/map/userSession/MapUserSessionProvider.java b/model/map/src/main/java/org/keycloak/models/map/userSession/MapUserSessionProvider.java index b2435336bd..8aa7761611 100644 --- a/model/map/src/main/java/org/keycloak/models/map/userSession/MapUserSessionProvider.java +++ b/model/map/src/main/java/org/keycloak/models/map/userSession/MapUserSessionProvider.java @@ -30,6 +30,7 @@ import org.keycloak.models.UserSessionProvider; import org.keycloak.models.map.storage.MapKeycloakTransaction; import org.keycloak.models.map.storage.MapStorage; import org.keycloak.models.map.storage.ModelCriteriaBuilder; +import org.keycloak.models.map.storage.criteria.DefaultModelCriteria; import java.util.Arrays; import java.util.Collection; @@ -48,6 +49,7 @@ import static org.keycloak.common.util.StackUtil.getShortStackTrace; import static org.keycloak.models.UserSessionModel.CORRESPONDING_SESSION_ID; import static org.keycloak.models.UserSessionModel.SessionPersistenceState.TRANSIENT; import static org.keycloak.models.map.storage.QueryParameters.withCriteria; +import static org.keycloak.models.map.storage.criteria.DefaultModelCriteria.criteria; import static org.keycloak.models.map.userSession.SessionExpiration.setClientSessionExpiration; import static org.keycloak.models.map.userSession.SessionExpiration.setUserSessionExpiration; @@ -60,8 +62,6 @@ public class MapUserSessionProvider implements UserSessionProvider { private final KeycloakSession session; protected final MapKeycloakTransaction userSessionTx; protected final MapKeycloakTransaction clientSessionTx; - private final MapStorage userSessionStore; - private final MapStorage clientSessionStore; /** * Storage for transient user sessions which lifespan is limited to one request. @@ -71,8 +71,6 @@ public class MapUserSessionProvider implements UserSessionProvider { public MapUserSessionProvider(KeycloakSession session, MapStorage userSessionStore, MapStorage clientSessionStore) { this.session = session; - this.userSessionStore = userSessionStore; - this.clientSessionStore = clientSessionStore; userSessionTx = userSessionStore.createTransaction(session); clientSessionTx = clientSessionStore.createTransaction(session); @@ -175,8 +173,8 @@ public class MapUserSessionProvider implements UserSessionProvider { return null; } - ModelCriteriaBuilder mcb = clientSessionStore.createCriteriaBuilder() - .compare(AuthenticatedClientSessionModel.SearchableFields.ID, ModelCriteriaBuilder.Operator.EQ, clientSessionId) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(AuthenticatedClientSessionModel.SearchableFields.ID, ModelCriteriaBuilder.Operator.EQ, clientSessionId) .compare(AuthenticatedClientSessionModel.SearchableFields.USER_SESSION_ID, ModelCriteriaBuilder.Operator.EQ, userSession.getId()) .compare(AuthenticatedClientSessionModel.SearchableFields.REALM_ID, ModelCriteriaBuilder.Operator.EQ, userSession.getRealm().getId()) .compare(AuthenticatedClientSessionModel.SearchableFields.CLIENT_ID, ModelCriteriaBuilder.Operator.EQ, client.getId()) @@ -370,8 +368,8 @@ public class MapUserSessionProvider implements UserSessionProvider { @Override public void removeUserSessions(RealmModel realm, UserModel user) { - ModelCriteriaBuilder mcb = userSessionStore.createCriteriaBuilder() - .compare(UserSessionModel.SearchableFields.REALM_ID, ModelCriteriaBuilder.Operator.EQ, realm.getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(UserSessionModel.SearchableFields.REALM_ID, ModelCriteriaBuilder.Operator.EQ, realm.getId()) .compare(UserSessionModel.SearchableFields.USER_ID, ModelCriteriaBuilder.Operator.EQ, user.getId()); LOG.tracef("removeUserSessions(%s, %s)%s", realm, user, getShortStackTrace()); @@ -576,8 +574,8 @@ public class MapUserSessionProvider implements UserSessionProvider { } // first get a user entity by ID - ModelCriteriaBuilder mcb = userSessionStore.createCriteriaBuilder() - .compare(UserSessionModel.SearchableFields.REALM_ID, ModelCriteriaBuilder.Operator.EQ, realm.getId()) + ModelCriteriaBuilder mcb = criteria(); + mcb = mcb.compare(UserSessionModel.SearchableFields.REALM_ID, ModelCriteriaBuilder.Operator.EQ, realm.getId()) .compare(UserSessionModel.SearchableFields.ID, ModelCriteriaBuilder.Operator.EQ, userSessionId); // check if it's an offline user session @@ -605,7 +603,7 @@ public class MapUserSessionProvider implements UserSessionProvider { } private ModelCriteriaBuilder realmAndOfflineCriteriaBuilder(RealmModel realm, boolean offline) { - return userSessionStore.createCriteriaBuilder() + return DefaultModelCriteria.criteria() .compare(UserSessionModel.SearchableFields.REALM_ID, ModelCriteriaBuilder.Operator.EQ, realm.getId()) .compare(UserSessionModel.SearchableFields.IS_OFFLINE, ModelCriteriaBuilder.Operator.EQ, offline); }