KEYCLOAK-19709 Remove MapStorage.createCriteriaBuilder

This commit is contained in:
Martin Kanis 2021-11-02 09:14:02 +01:00 committed by Hynek Mlnařík
parent 58e8110c8d
commit 9c287aff1f
21 changed files with 221 additions and 282 deletions

View file

@ -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 <a href="mailto:mkanis@redhat.com">Martin Kanis</a>
@ -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<MapRootAuthenticationSessionEntity, RootAuthenticationSessionModel> tx;
private final MapStorage<MapRootAuthenticationSessionEntity, RootAuthenticationSessionModel> sessionStore;
private static final String AUTHENTICATION_SESSION_EVENTS = "AUTHENTICATION_SESSION_EVENTS";
public MapRootAuthenticationSessionProvider(KeycloakSession session, MapStorage<MapRootAuthenticationSessionEntity, RootAuthenticationSessionModel> 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<RootAuthenticationSessionModel> mcb = sessionStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
ModelCriteriaBuilder<RootAuthenticationSessionModel> 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<RootAuthenticationSessionModel> mcb = sessionStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId());
ModelCriteriaBuilder<RootAuthenticationSessionModel> mcb = criteria();
mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId());
tx.delete(withCriteria(mcb));
}

View file

@ -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<MapPermissionTicketEntity, PermissionTicket> tx;
private final MapStorage<MapPermissionTicketEntity, PermissionTicket> permissionTicketStore;
public MapPermissionTicketStore(KeycloakSession session, MapStorage<MapPermissionTicketEntity, PermissionTicket> 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<PermissionTicket> forResourceServer(String resourceServerId) {
ModelCriteriaBuilder<PermissionTicket> mcb = permissionTicketStore.createCriteriaBuilder();
ModelCriteriaBuilder<PermissionTicket> 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<PermissionTicket> 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<Resource> findGrantedResources(String requester, String name, int first, int max) {
ModelCriteriaBuilder<PermissionTicket> mcb = permissionTicketStore.createCriteriaBuilder()
.compare(SearchableFields.REQUESTER, Operator.EQ, requester)
ModelCriteriaBuilder<PermissionTicket> mcb = criteria();
mcb = mcb.compare(SearchableFields.REQUESTER, Operator.EQ, requester)
.compare(SearchableFields.GRANTED_TIMESTAMP, Operator.EXISTS);
Function<MapPermissionTicketEntity, Resource> ticketResourceMapper;
@ -298,8 +295,8 @@ public class MapPermissionTicketStore implements PermissionTicketStore {
@Override
public List<Resource> findGrantedOwnerResources(String owner, int first, int max) {
ModelCriteriaBuilder<PermissionTicket> mcb = permissionTicketStore.createCriteriaBuilder()
.compare(SearchableFields.OWNER, Operator.EQ, owner);
ModelCriteriaBuilder<PermissionTicket> 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)

View file

@ -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<MapPolicyEntity, Policy> tx;
private final MapStorage<MapPolicyEntity, Policy> policyStore;
public MapPolicyStore(KeycloakSession session, MapStorage<MapPolicyEntity, Policy> 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<Policy> forResourceServer(String resourceServerId) {
ModelCriteriaBuilder<Policy> mcb = policyStore.createCriteriaBuilder();
ModelCriteriaBuilder<Policy> 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<Policy> 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<Policy> 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.<Policy>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 + "]");

View file

@ -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<MapResourceEntity, Resource> tx;
private final MapStorage<MapResourceEntity, Resource> resourceStore;
public MapResourceStore(KeycloakSession session, MapStorage<MapResourceEntity, Resource> 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<Resource> forResourceServer(String resourceServerId) {
ModelCriteriaBuilder<Resource> mcb = resourceStore.createCriteriaBuilder();
ModelCriteriaBuilder<Resource> 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<Resource> 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 + "]");

View file

@ -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<MapScopeEntity, Scope> tx;
private final MapStorage<MapScopeEntity, Scope> scopeStore;
public MapScopeStore(KeycloakSession session, MapStorage<MapScopeEntity, Scope> 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<Scope> forResourceServer(String resourceServerId) {
ModelCriteriaBuilder<Scope> mcb = scopeStore.createCriteriaBuilder();
ModelCriteriaBuilder<Scope> mcb = criteria();
return resourceServerId == null
? mcb

View file

@ -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<MapClientEntity, ClientModel> tx;
private final MapStorage<MapClientEntity, ClientModel> clientStore;
private final ConcurrentMap<String, ConcurrentMap<String, Integer>> clientRegisteredNodesStore;
public MapClientProvider(KeycloakSession session, MapStorage<MapClientEntity, ClientModel> clientStore, ConcurrentMap<String, ConcurrentMap<String, Integer>> 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<ClientModel> getClientsStream(RealmModel realm, Integer firstResult, Integer maxResults) {
ModelCriteriaBuilder<ClientModel> mcb = clientStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId());
ModelCriteriaBuilder<ClientModel> 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<ClientModel> getClientsStream(RealmModel realm) {
ModelCriteriaBuilder<ClientModel> mcb = clientStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId());
ModelCriteriaBuilder<ClientModel> 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<ClientModel> mcb = clientStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId());
ModelCriteriaBuilder<ClientModel> 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<ClientModel> mcb = clientStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
.compare(SearchableFields.CLIENT_ID, Operator.ILIKE, clientId);
ModelCriteriaBuilder<ClientModel> 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<ClientModel> mcb = clientStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
.compare(SearchableFields.CLIENT_ID, Operator.ILIKE, "%" + clientId + "%");
ModelCriteriaBuilder<ClientModel> 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<ClientModel> searchClientsByAttributes(RealmModel realm, Map<String, String> attributes, Integer firstResult, Integer maxResults) {
ModelCriteriaBuilder<ClientModel> mcb = clientStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId());
ModelCriteriaBuilder<ClientModel> mcb = criteria();
mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId());
for (Map.Entry<String, String> 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<ClientModel, Set<String>> getAllRedirectUrisOfEnabledClients(RealmModel realm) {
ModelCriteriaBuilder<ClientModel> mcb = clientStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
.compare(SearchableFields.ENABLED, Operator.EQ, Boolean.TRUE);
ModelCriteriaBuilder<ClientModel> mcb = criteria();
mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
.compare(SearchableFields.ENABLED, Operator.EQ, Boolean.TRUE);
try (Stream<MapClientEntity> st = tx.read(withCriteria(mcb))) {
return st
@ -347,9 +346,10 @@ public class MapClientProvider implements ClientProvider {
}
public void preRemove(RealmModel realm, RoleModel role) {
ModelCriteriaBuilder<ClientModel> mcb = clientStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
.compare(SearchableFields.SCOPE_MAPPING_ROLE, Operator.EQ, role.getId());
ModelCriteriaBuilder<ClientModel> mcb = criteria();
mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
.compare(SearchableFields.SCOPE_MAPPING_ROLE, Operator.EQ, role.getId());
try (Stream<MapClientEntity> toRemove = tx.read(withCriteria(mcb))) {
toRemove
.map(clientEntity -> session.clients().getClientById(realm, clientEntity.getId()))

View file

@ -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<MapClientScopeEntity, ClientScopeModel> tx;
private final MapStorage<MapClientScopeEntity, ClientScopeModel> clientScopeStore;
public MapClientScopeProvider(KeycloakSession session, MapStorage<MapClientScopeEntity, ClientScopeModel> 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<ClientScopeModel> getClientScopesStream(RealmModel realm) {
ModelCriteriaBuilder<ClientScopeModel> mcb = clientScopeStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId());
ModelCriteriaBuilder<ClientScopeModel> 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<ClientScopeModel> mcb = clientScopeStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
ModelCriteriaBuilder<ClientScopeModel> mcb = criteria();
mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
.compare(SearchableFields.NAME, Operator.EQ, name);
if (tx.getCount(withCriteria(mcb)) > 0) {

View file

@ -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<MapGroupEntity, GroupModel> tx;
private final MapStorage<MapGroupEntity, GroupModel> groupStore;
public MapGroupProvider(KeycloakSession session, MapStorage<MapGroupEntity, GroupModel> 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<GroupModel> getGroupsStreamInternal(RealmModel realm, UnaryOperator<ModelCriteriaBuilder<GroupModel>> modifier, UnaryOperator<QueryParameters<GroupModel>> queryParametersModifier) {
LOG.tracef("getGroupsStream(%s)%s", realm, getShortStackTrace());
ModelCriteriaBuilder<GroupModel> mcb = groupStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId());
ModelCriteriaBuilder<GroupModel> 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<GroupModel> getGroupsStream(RealmModel realm, Stream<String> ids, String search, Integer first, Integer max) {
ModelCriteriaBuilder<GroupModel> mcb = groupStore.createCriteriaBuilder()
.compare(SearchableFields.ID, Operator.IN, ids)
ModelCriteriaBuilder<GroupModel> 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<GroupModel> mcb = groupStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId());
ModelCriteriaBuilder<GroupModel> 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<GroupModel> mcb = groupStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
ModelCriteriaBuilder<GroupModel> 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<GroupModel> mcb = groupStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
ModelCriteriaBuilder<GroupModel> 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<GroupModel> mcb = groupStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
ModelCriteriaBuilder<GroupModel> 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<GroupModel> mcb = groupStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
ModelCriteriaBuilder<GroupModel> 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<GroupModel> mcb = groupStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
ModelCriteriaBuilder<GroupModel> 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<GroupModel> mcb = groupStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
ModelCriteriaBuilder<GroupModel> mcb = criteria();
mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
.compare(SearchableFields.ASSIGNED_ROLE, Operator.EQ, role.getId());
try (Stream<MapGroupEntity> toRemove = tx.read(withCriteria(mcb))) {
toRemove

View file

@ -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 <a href="mailto:mkanis@redhat.com">Martin Kanis</a>
@ -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<MapUserLoginFailureEntity, UserLoginFailureModel> userLoginFailureTx;
private final MapStorage<MapUserLoginFailureEntity, UserLoginFailureModel> userLoginFailureStore;
public MapUserLoginFailureProvider(KeycloakSession session, MapStorage<MapUserLoginFailureEntity, UserLoginFailureModel> 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<UserLoginFailureModel> mcb = userLoginFailureStore.createCriteriaBuilder()
.compare(UserLoginFailureModel.SearchableFields.REALM_ID, ModelCriteriaBuilder.Operator.EQ, realm.getId())
ModelCriteriaBuilder<UserLoginFailureModel> 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<UserLoginFailureModel> mcb = userLoginFailureStore.createCriteriaBuilder()
.compare(UserLoginFailureModel.SearchableFields.REALM_ID, ModelCriteriaBuilder.Operator.EQ, realm.getId())
ModelCriteriaBuilder<UserLoginFailureModel> 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<UserLoginFailureModel> mcb = userLoginFailureStore.createCriteriaBuilder()
.compare(UserLoginFailureModel.SearchableFields.REALM_ID, ModelCriteriaBuilder.Operator.EQ, realm.getId())
ModelCriteriaBuilder<UserLoginFailureModel> 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<UserLoginFailureModel> mcb = userLoginFailureStore.createCriteriaBuilder()
.compare(UserLoginFailureModel.SearchableFields.REALM_ID, ModelCriteriaBuilder.Operator.EQ, realm.getId());
ModelCriteriaBuilder<UserLoginFailureModel> mcb = criteria();
mcb = mcb.compare(UserLoginFailureModel.SearchableFields.REALM_ID, ModelCriteriaBuilder.Operator.EQ, realm.getId());
LOG.tracef("removeAllUserLoginFailures(%s)%s", realm, getShortStackTrace());

View file

@ -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<MapRealmEntity, RealmModel> tx;
private final MapStorage<MapRealmEntity, RealmModel> realmStore;
public MapRealmProvider(KeycloakSession session, MapStorage<MapRealmEntity, RealmModel> 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<RealmModel> mcb = realmStore.createCriteriaBuilder()
.compare(SearchableFields.NAME, Operator.EQ, name);
ModelCriteriaBuilder<RealmModel> 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<RealmModel> getRealmsStream() {
return getRealmsStream(realmStore.createCriteriaBuilder());
return getRealmsStream(criteria());
}
@Override
public Stream<RealmModel> getRealmsWithProviderTypeStream(Class<?> type) {
ModelCriteriaBuilder<RealmModel> mcb = realmStore.createCriteriaBuilder()
.compare(SearchableFields.COMPONENT_PROVIDER_TYPE, Operator.EQ, type.getName());
ModelCriteriaBuilder<RealmModel> 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<RealmModel> mcb = realmStore.createCriteriaBuilder()
.compare(SearchableFields.CLIENT_INITIAL_ACCESS, Operator.EXISTS);
ModelCriteriaBuilder<RealmModel> mcb = criteria();
mcb = mcb.compare(SearchableFields.CLIENT_INITIAL_ACCESS, Operator.EXISTS);
tx.read(withCriteria(mcb))
.forEach(MapRealmEntity::removeExpiredClientInitialAccesses);

View file

@ -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<MapRoleEntity, RoleModel> tx;
private final MapStorage<MapRoleEntity, RoleModel> roleStore;
public MapRoleProvider(KeycloakSession session, MapStorage<MapRoleEntity, RoleModel> 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<RoleModel> getRealmRolesStream(RealmModel realm, Integer first, Integer max) {
ModelCriteriaBuilder<RoleModel> mcb = roleStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
ModelCriteriaBuilder<RoleModel> 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<RoleModel> mcb = roleStore.createCriteriaBuilder()
.compare(RoleModel.SearchableFields.ID, Operator.IN, ids)
ModelCriteriaBuilder<RoleModel> 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<RoleModel> getRealmRolesStream(RealmModel realm) {
ModelCriteriaBuilder<RoleModel> mcb = roleStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
ModelCriteriaBuilder<RoleModel> 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<RoleModel> getClientRolesStream(ClientModel client, Integer first, Integer max) {
ModelCriteriaBuilder<RoleModel> mcb = roleStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, client.getRealm().getId())
ModelCriteriaBuilder<RoleModel> 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<RoleModel> getClientRolesStream(ClientModel client) {
ModelCriteriaBuilder<RoleModel> mcb = roleStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, client.getRealm().getId())
ModelCriteriaBuilder<RoleModel> 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<RoleModel> mcb = roleStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
ModelCriteriaBuilder<RoleModel> 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<RoleModel> mcb = roleStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, client.getRealm().getId())
ModelCriteriaBuilder<RoleModel> 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<RoleModel> 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<RoleModel> 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<RoleModel> 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<RoleModel> 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()));
}

View file

@ -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<V extends AbstractEntity, M> {
/**
* Returns criteria builder for the storage engine.
* The criteria are specified in the given criteria builder based on model properties.
* <br>
* <b>Note:</b> 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 <i>not</i> 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<M> createCriteriaBuilder();
/**
* Creates a {@code MapKeycloakTransaction} object that tracks a new transaction related to this storage.

View file

@ -170,18 +170,4 @@ public interface ModelCriteriaBuilder<M> {
*/
ModelCriteriaBuilder<M> not(ModelCriteriaBuilder<M> builder);
/**
* Returns this object cast to the given class, or {@code null} if the class cannot be cast to that {@code clazz}.
* @param <T>
* @param clazz
* @return
*/
default <T extends ModelCriteriaBuilder> T unwrap(Class<T> clazz) {
if (clazz.isInstance(this)) {
return clazz.cast(this);
} else {
return null;
}
}
}

View file

@ -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<K, V extends AbstractEntity & UpdatableEntity, M> implements MapKeycloakTransaction<V, M> {
@ -168,6 +167,9 @@ public class ConcurrentHashMapKeycloakTransaction<K, V extends AbstractEntity &
*/
@Override
public Stream<V> read(QueryParameters<M> queryParameters) {
DefaultModelCriteria<M> mcb = (DefaultModelCriteria<M>) queryParameters.getModelCriteriaBuilder();
MapModelCriteriaBuilder<K,V,M> mapMcb = (MapModelCriteriaBuilder<K,V,M>) mcb.flashToModelCriteriaBuilder(map.createCriteriaBuilder());
Predicate<? super V> filterOutAllBulkDeletedObjects = tasks.values().stream()
.filter(BulkDeleteOperation.class::isInstance)
.map(BulkDeleteOperation.class::cast)
@ -175,8 +177,6 @@ public class ConcurrentHashMapKeycloakTransaction<K, V extends AbstractEntity &
.reduce(Predicate::and)
.orElse(v -> true);
ModelCriteriaBuilder<M> mcb = queryParameters.getModelCriteriaBuilder();
Stream<V> 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<K, V extends AbstractEntity &
.map(this::registerEntityForChanges);
// In case of created values stored in MapKeycloakTransaction, we need filter those according to the filter
MapModelCriteriaBuilder<K, V, M> mapMcb = mcb.unwrap(MapModelCriteriaBuilder.class);
Stream<V> res = mapMcb == null
? updatedAndNotRemovedObjectsStream
: Stream.concat(
@ -401,12 +400,8 @@ public class ConcurrentHashMapKeycloakTransaction<K, V extends AbstractEntity &
}
public Predicate<V> getFilterForNonDeletedObjects() {
if (! (queryParameters.getModelCriteriaBuilder() instanceof MapModelCriteriaBuilder)) {
return t -> true;
}
@SuppressWarnings("unchecked")
final MapModelCriteriaBuilder<K, V, M> mmcb = (MapModelCriteriaBuilder<K, V, M>) queryParameters.getModelCriteriaBuilder();
DefaultModelCriteria<M> mcb = (DefaultModelCriteria<M>) queryParameters.getModelCriteriaBuilder();
MapModelCriteriaBuilder<K,V,M> mmcb = (MapModelCriteriaBuilder<K,V,M>) mcb.flashToModelCriteriaBuilder(map.createCriteriaBuilder());
Predicate<? super V> entityFilter = mmcb.getEntityFilter();
Predicate<? super K> keyFilter = mmcb.getKeyFilter();

View file

@ -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<K, V extends AbstractEntity & UpdatableEnt
* Deletes objects that match the given criteria.
* @param queryParameters parameters for the query like firstResult, maxResult, requested ordering, etc.
* @return Number of removed objects (might return {@code -1} if not supported)
* @throws IllegalStateException If {@code criteria} is not compatible, i.e. has not been originally created
* by the {@link #createCriteriaBuilder()} method of this object.
*/
public long delete(QueryParameters<M> queryParameters) {
ModelCriteriaBuilder<M> criteria = queryParameters.getModelCriteriaBuilder();
DefaultModelCriteria<M> criteria = (DefaultModelCriteria<M>) queryParameters.getModelCriteriaBuilder();
if (criteria == null) {
long res = store.size();
@ -136,12 +135,9 @@ public class ConcurrentHashMapStorage<K, V extends AbstractEntity & UpdatableEnt
}
@SuppressWarnings("unchecked")
MapModelCriteriaBuilder<K, V, M> b = criteria.unwrap(MapModelCriteriaBuilder.class);
if (b == null) {
throw new IllegalStateException("Incompatible class: " + criteria.getClass());
}
Predicate<? super K> keyFilter = b.getKeyFilter();
Predicate<? super V> entityFilter = b.getEntityFilter();
MapModelCriteriaBuilder<K,V,M> mcb = (MapModelCriteriaBuilder<K,V,M>) criteria.flashToModelCriteriaBuilder(createCriteriaBuilder());
Predicate<? super K> keyFilter = mcb.getKeyFilter();
Predicate<? super V> entityFilter = mcb.getEntityFilter();
Stream<Entry<K, V>> storeStream = store.entrySet().stream();
final AtomicLong res = new AtomicLong(0);
@ -159,11 +155,6 @@ public class ConcurrentHashMapStorage<K, V extends AbstractEntity & UpdatableEnt
return res.get();
}
@Override
public ModelCriteriaBuilder<M> createCriteriaBuilder() {
return new MapModelCriteriaBuilder<>(keyConvertor, fieldPredicates);
}
@Override
@SuppressWarnings("unchecked")
public MapKeycloakTransaction<V, M> createTransaction(KeycloakSession session) {
@ -171,6 +162,10 @@ public class ConcurrentHashMapStorage<K, V extends AbstractEntity & UpdatableEnt
return sessionTransaction == null ? new ConcurrentHashMapKeycloakTransaction<>(this, keyConvertor, cloner) : sessionTransaction;
}
public ModelCriteriaBuilder<M> createCriteriaBuilder() {
return new MapModelCriteriaBuilder<>(keyConvertor, fieldPredicates);
}
public StringKeyConvertor<K> getKeyConvertor() {
return keyConvertor;
}
@ -181,24 +176,19 @@ public class ConcurrentHashMapStorage<K, V extends AbstractEntity & UpdatableEnt
*
* @param queryParameters parameters for the query like firstResult, maxResult, requested ordering, etc.
* @return Stream of objects. Never returns {@code null}.
* @throws IllegalStateException If {@code criteria} is not compatible, i.e. has not been originally created
* by the {@link #createCriteriaBuilder()} method of this object.
*/
public Stream<V> read(QueryParameters<M> queryParameters) {
ModelCriteriaBuilder<M> criteria = queryParameters.getModelCriteriaBuilder();
DefaultModelCriteria<M> criteria = (DefaultModelCriteria<M>) queryParameters.getModelCriteriaBuilder();
if (criteria == null) {
return Stream.empty();
}
MapModelCriteriaBuilder<K,V,M> mcb = (MapModelCriteriaBuilder<K,V,M>) criteria.flashToModelCriteriaBuilder(createCriteriaBuilder());
Stream<Entry<K, V>> stream = store.entrySet().stream();
@SuppressWarnings("unchecked")
MapModelCriteriaBuilder<K, V, M> b = criteria.unwrap(MapModelCriteriaBuilder.class);
if (b == null) {
throw new IllegalStateException("Incompatible class: " + criteria.getClass());
}
Predicate<? super K> keyFilter = b.getKeyFilter();
Predicate<? super V> entityFilter = b.getEntityFilter();
Predicate<? super K> keyFilter = mcb.getKeyFilter();
Predicate<? super V> 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<K, V extends AbstractEntity & UpdatableEnt
*
* @param queryParameters parameters for the query like firstResult, maxResult, requested ordering, etc.
* @return Number of objects. Never returns {@code null}.
* @throws IllegalStateException If {@code criteria} is not compatible, i.e. has not been originally created
* by the {@link #createCriteriaBuilder()} method of this object.
*/
public long getCount(QueryParameters<M> queryParameters) {
return read(queryParameters).count();

View file

@ -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);

View file

@ -93,10 +93,7 @@ public class MapModelCriteriaBuilder<K, V extends AbstractEntity, M> implements
@SuppressWarnings("unchecked")
@Override
public MapModelCriteriaBuilder<K, V, M> not(ModelCriteriaBuilder<M> builder) {
MapModelCriteriaBuilder<K, V, M> b = builder.unwrap(MapModelCriteriaBuilder.class);
if (b == null) {
throw new ClassCastException("Incompatible class: " + builder.getClass());
}
MapModelCriteriaBuilder<K, V, M> b = (MapModelCriteriaBuilder<K, V, M>) builder;
Predicate<? super K> resIndexFilter = b.getKeyFilter() == ALWAYS_TRUE ? ALWAYS_TRUE : b.getKeyFilter().negate();
Predicate<? super V> resEntityFilter = b.getEntityFilter() == ALWAYS_TRUE ? ALWAYS_TRUE : b.getEntityFilter().negate();

View file

@ -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<K> extends ConcurrentHashMapSto
@Override
public long delete(QueryParameters<UserSessionModel> queryParameters) {
Set<String> ids = read(queryParameters).map(AbstractEntity::getId).collect(Collectors.toSet());
ModelCriteriaBuilder<AuthenticatedClientSessionModel> csMcb = clientSessionStore.createCriteriaBuilder().compare(AuthenticatedClientSessionModel.SearchableFields.USER_SESSION_ID, Operator.IN, ids);
ModelCriteriaBuilder<AuthenticatedClientSessionModel> csMcb = DefaultModelCriteria.<AuthenticatedClientSessionModel>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<AuthenticatedClientSessionModel> csMcb = clientSessionStore.createCriteriaBuilder().compare(AuthenticatedClientSessionModel.SearchableFields.USER_SESSION_ID, Operator.EQ, key);
ModelCriteriaBuilder<AuthenticatedClientSessionModel> csMcb = DefaultModelCriteria.<AuthenticatedClientSessionModel>criteria()
.compare(AuthenticatedClientSessionModel.SearchableFields.USER_SESSION_ID, Operator.EQ, key);
clientSessionTr.delete(withCriteria(csMcb));
return super.delete(key);
}

View file

@ -65,16 +65,16 @@ public class DefaultModelCriteria<M> implements ModelCriteriaBuilder<M> {
@Override
public DefaultModelCriteria<M> and(ModelCriteriaBuilder<M>... mcbs) {
if (mcbs.length == 1) {
ModelCriteriaNode<M> toBeChild = ((DefaultModelCriteria<M>) mcbs[0].unwrap(DefaultModelCriteria.class)).node;
ModelCriteriaNode<M> toBeChild = ((DefaultModelCriteria<M>) mcbs[0]).node;
if (toBeChild.getNodeOperator() == ExtOperator.AND || toBeChild.getNodeOperator() == ExtOperator.OR) {
return ((DefaultModelCriteria<M>) mcbs[0].unwrap(DefaultModelCriteria.class));
return (DefaultModelCriteria<M>) mcbs[0];
}
}
final ModelCriteriaNode<M> targetNode = new ModelCriteriaNode<>(ExtOperator.AND);
AtomicBoolean hasFalseNode = new AtomicBoolean(false);
for (ModelCriteriaBuilder<M> mcb : mcbs) {
final ModelCriteriaNode<M> nodeToAdd = ((DefaultModelCriteria<M>) mcb.unwrap(DefaultModelCriteria.class)).node;
final ModelCriteriaNode<M> nodeToAdd = ((DefaultModelCriteria<M>) mcb).node;
getNodesToAddForAndOr(nodeToAdd, ExtOperator.AND)
.filter(ModelCriteriaNode::isNotTrueNode)
.peek(n -> { if (n.isFalseNode()) hasFalseNode.lazySet(true); })
@ -97,16 +97,16 @@ public class DefaultModelCriteria<M> implements ModelCriteriaBuilder<M> {
@Override
public DefaultModelCriteria<M> or(ModelCriteriaBuilder<M>... mcbs) {
if (mcbs.length == 1) {
ModelCriteriaNode<M> toBeChild = ((DefaultModelCriteria<M>) mcbs[0].unwrap(DefaultModelCriteria.class)).node;
ModelCriteriaNode<M> toBeChild = ((DefaultModelCriteria<M>) mcbs[0]).node;
if (toBeChild.getNodeOperator() == ExtOperator.AND || toBeChild.getNodeOperator() == ExtOperator.OR) {
return ((DefaultModelCriteria<M>) mcbs[0].unwrap(DefaultModelCriteria.class));
return ((DefaultModelCriteria<M>) mcbs[0]);
}
}
final ModelCriteriaNode<M> targetNode = new ModelCriteriaNode<>(ExtOperator.OR);
AtomicBoolean hasTrueNode = new AtomicBoolean(false);
for (ModelCriteriaBuilder<M> mcb : mcbs) {
final ModelCriteriaNode<M> nodeToAdd = ((DefaultModelCriteria<M>) mcb.unwrap(DefaultModelCriteria.class)).node;
final ModelCriteriaNode<M> nodeToAdd = ((DefaultModelCriteria<M>) mcb).node;
getNodesToAddForAndOr(nodeToAdd, ExtOperator.OR)
.filter(ModelCriteriaNode::isNotFalseNode)
.peek(n -> { if (n.isTrueNode()) hasTrueNode.lazySet(true); })
@ -129,7 +129,7 @@ public class DefaultModelCriteria<M> implements ModelCriteriaBuilder<M> {
@Override
public DefaultModelCriteria<M> not(ModelCriteriaBuilder<M> mcb) {
final ModelCriteriaNode<M> targetNode = new ModelCriteriaNode<>(ExtOperator.NOT);
ModelCriteriaNode<M> toBeChild = ((DefaultModelCriteria<M>) mcb.unwrap(DefaultModelCriteria.class)).node;
ModelCriteriaNode<M> toBeChild = ((DefaultModelCriteria<M>) mcb).node;
if (toBeChild.getNodeOperator() == ExtOperator.NOT) {
return compare(toBeChild.getChildren().get(0).cloneTree());
}
@ -144,6 +144,9 @@ public class DefaultModelCriteria<M> implements ModelCriteriaBuilder<M> {
* @return Updated {@code ModelCriteriaBuilder}
*/
public <C extends ModelCriteriaBuilder<M>> C flashToModelCriteriaBuilder(C mcb) {
if (isEmpty()) {
return mcb;
}
return mcb == null ? null : node.flashToModelCriteriaBuilder(mcb);
}

View file

@ -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<MapUserEntity, UserModel> tx;
private final MapStorage<MapUserEntity, UserModel> userStore;
public MapUserProvider(KeycloakSession session, MapStorage<MapUserEntity, UserModel> 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<UserModel> mcb = userStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
ModelCriteriaBuilder<UserModel> 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<UserModel> mcb = userStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
ModelCriteriaBuilder<UserModel> 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<UserModel> mcb = userStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, client.getRealm().getId())
ModelCriteriaBuilder<UserModel> 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<UserModel> mcb = userStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
ModelCriteriaBuilder<UserModel> 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<UserModel> mcb = userStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId());
ModelCriteriaBuilder<UserModel> 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<UserModel> mcb = userStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
ModelCriteriaBuilder<UserModel> 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<UserModel> mcb = userStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
ModelCriteriaBuilder<UserModel> mcb = criteria();
mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
.compare(SearchableFields.FEDERATION_LINK, Operator.EQ, storageProviderId);
try (Stream<MapUserEntity> 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<UserModel> mcb = userStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
ModelCriteriaBuilder<UserModel> mcb = criteria();
mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
.compare(SearchableFields.ASSIGNED_ROLE, Operator.EQ, roleId);
try (Stream<MapUserEntity> 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<UserModel> mcb = userStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
ModelCriteriaBuilder<UserModel> mcb = criteria();
mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
.compare(SearchableFields.ASSIGNED_GROUP, Operator.EQ, groupId);
try (Stream<MapUserEntity> 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<UserModel> mcb = userStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
ModelCriteriaBuilder<UserModel> mcb = criteria();
mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
.compare(SearchableFields.CONSENT_FOR_CLIENT, Operator.EQ, clientId);
try (Stream<MapUserEntity> 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<UserModel> mcb = userStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, clientScope.getRealm().getId())
ModelCriteriaBuilder<UserModel> mcb = criteria();
mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, clientScope.getRealm().getId())
.compare(SearchableFields.CONSENT_WITH_CLIENT_SCOPE, Operator.EQ, clientScopeId);
try (Stream<MapUserEntity> 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<UserModel> mcb = userStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
ModelCriteriaBuilder<UserModel> mcb = criteria();
mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
.compare(SearchableFields.CONSENT_CLIENT_FEDERATION_LINK, Operator.EQ, componentId);
try (Stream<MapUserEntity> 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<UserModel> mcb = userStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId());
ModelCriteriaBuilder<UserModel> mcb = criteria();
mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId());
try (Stream<MapUserEntity> 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<UserModel> mcb = userStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
ModelCriteriaBuilder<UserModel> mcb = criteria();
mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
.compare(SearchableFields.USERNAME, Operator.ILIKE, username);
try (Stream<MapUserEntity> 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<UserModel> mcb = userStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
ModelCriteriaBuilder<UserModel> mcb = criteria();
mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
.compare(SearchableFields.EMAIL, Operator.EQ, email);
List<MapUserEntity> 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<UserModel> mcb = userStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId());
ModelCriteriaBuilder<UserModel> 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<UserModel> getUsersStream(RealmModel realm, Integer firstResult, Integer maxResults, boolean includeServiceAccounts) {
LOG.tracef("getUsersStream(%s, %d, %d, %s)%s", realm, firstResult, maxResults, includeServiceAccounts, getShortStackTrace());
ModelCriteriaBuilder<UserModel> mcb = userStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId());
ModelCriteriaBuilder<UserModel> 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<UserModel> searchForUserStream(RealmModel realm, Map<String, String> attributes, Integer firstResult, Integer maxResults) {
LOG.tracef("searchForUserStream(%s, %s, %d, %d)%s", realm, attributes, firstResult, maxResults, getShortStackTrace());
ModelCriteriaBuilder<UserModel> mcb = userStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId());
ModelCriteriaBuilder<UserModel> 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<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group, Integer firstResult, Integer maxResults) {
LOG.tracef("getGroupMembersStream(%s, %s, %d, %d)%s", realm, group.getId(), firstResult, maxResults, getShortStackTrace());
ModelCriteriaBuilder<UserModel> mcb = userStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
ModelCriteriaBuilder<UserModel> 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<UserModel> searchForUserByUserAttributeStream(RealmModel realm, String attrName, String attrValue) {
LOG.tracef("searchForUserByUserAttributeStream(%s, %s, %s)%s", realm, attrName, attrValue, getShortStackTrace());
ModelCriteriaBuilder<UserModel> mcb = userStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
ModelCriteriaBuilder<UserModel> 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<UserModel> getRoleMembersStream(RealmModel realm, RoleModel role, Integer firstResult, Integer maxResults) {
LOG.tracef("getRoleMembersStream(%s, %s, %d, %d)%s", realm, role, firstResult, maxResults, getShortStackTrace());
ModelCriteriaBuilder<UserModel> mcb = userStore.createCriteriaBuilder()
.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
ModelCriteriaBuilder<UserModel> 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))

View file

@ -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<MapUserSessionEntity, UserSessionModel> userSessionTx;
protected final MapKeycloakTransaction<MapAuthenticatedClientSessionEntity, AuthenticatedClientSessionModel> clientSessionTx;
private final MapStorage<MapUserSessionEntity, UserSessionModel> userSessionStore;
private final MapStorage<MapAuthenticatedClientSessionEntity, AuthenticatedClientSessionModel> 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<MapUserSessionEntity, UserSessionModel> userSessionStore,
MapStorage<MapAuthenticatedClientSessionEntity, AuthenticatedClientSessionModel> 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<AuthenticatedClientSessionModel> mcb = clientSessionStore.createCriteriaBuilder()
.compare(AuthenticatedClientSessionModel.SearchableFields.ID, ModelCriteriaBuilder.Operator.EQ, clientSessionId)
ModelCriteriaBuilder<AuthenticatedClientSessionModel> 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<UserSessionModel> mcb = userSessionStore.createCriteriaBuilder()
.compare(UserSessionModel.SearchableFields.REALM_ID, ModelCriteriaBuilder.Operator.EQ, realm.getId())
ModelCriteriaBuilder<UserSessionModel> 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<UserSessionModel> mcb = userSessionStore.createCriteriaBuilder()
.compare(UserSessionModel.SearchableFields.REALM_ID, ModelCriteriaBuilder.Operator.EQ, realm.getId())
ModelCriteriaBuilder<UserSessionModel> 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<UserSessionModel> realmAndOfflineCriteriaBuilder(RealmModel realm, boolean offline) {
return userSessionStore.createCriteriaBuilder()
return DefaultModelCriteria.<UserSessionModel>criteria()
.compare(UserSessionModel.SearchableFields.REALM_ID, ModelCriteriaBuilder.Operator.EQ, realm.getId())
.compare(UserSessionModel.SearchableFields.IS_OFFLINE, ModelCriteriaBuilder.Operator.EQ, offline);
}