8000 Users Map JPA implementation by sguilhen · Pull Request #12871 · keycloak/keycloak · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
*/
package org.keycloak.models.map.storage.jpa;

import javax.persistence.criteria.CriteriaBuilder;

public interface Constants {
public static final Integer CURRENT_SCHEMA_VERSION_ADMIN_EVENT = 1;
public static final Integer CURRENT_SCHEMA_VERSION_AUTH_EVENT = 1;
Expand All @@ -34,4 +36,8 @@ public interface Constants {
public static final Integer CURRENT_SCHEMA_VERSION_ROOT_AUTH_SESSION = 1;
public static final Integer CURRENT_SCHEMA_VERSION_SINGLE_USE_OBJECT = 1;
public static final Integer CURRENT_SCHEMA_VERSION_USER_LOGIN_FAILURE = 1;
public static final Integer CURRENT_SCHEMA_VERSION_USER = 1;
public static final Integer CURRENT_SCHEMA_VERSION_USER_CONSENT = 1;
public static final Integer CURRENT_SCHEMA_VERSION_USER_FEDERATED_IDENTITY = 1;

}
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserLoginFailureModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.dblock.DBLockProvider;
import org.keycloak.models.map.client.MapProtocolMapperEntity;
import org.keycloak.models.map.client.MapProtocolMapperEntityImpl;
Expand Down Expand Up @@ -130,6 +131,12 @@
import org.keycloak.models.map.storage.jpa.singleUseObject.JpaSingleUseObjectMapKeycloakTransaction;
import org.keycloak.models.map.storage.jpa.singleUseObject.entity.JpaSingleUseObjectEntity;
import org.keycloak.models.map.storage.jpa.updater.MapJpaUpdaterProvider;
import org.keycloak.models.map.storage.jpa.user.JpaUserMapKeycloakTransaction;
import org.keycloak.models.map.storage.jpa.user.entity.JpaUserConsentEntity;
import org.keycloak.models.map.storage.jpa.user.entity.JpaUserEntity;
import org.keycloak.models.map.storage.jpa.user.entity.JpaUserFederatedIdentityEntity;
import org.keycloak.models.map.user.MapUserCredentialEntity;
import org.keycloak.models.map.user.MapUserCredentialEntityImpl;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.provider.EnvironmentDependentProviderFactory;
import org.keycloak.sessions.RootAuthenticationSessionModel;
Expand All @@ -153,26 +160,26 @@ public class JpaMapStorageProviderFactory implements
private final String sessionTxKey;

public final static DeepCloner CLONER = new DeepCloner.Builder()
//auth-session
//auth-sessions
.constructor(JpaRootAuthenticationSessionEntity.class, JpaRootAuthenticationSessionEntity::new)
.constructor(JpaAuthenticationSessionEntity.class, JpaAuthenticationSessionEntity::new)
//authz
//authorization
.constructor(JpaResourceServerEntity.class, JpaResourceServerEntity::new)
.constructor(JpaResourceEntity.class, JpaResourceEntity::new)
.constructor(JpaScopeEntity.class, JpaScopeEntity::new)
.constructor(JpaPermissionEntity.class, JpaPermissionEntity::new)
.constructor(JpaPolicyEntity.class, JpaPolicyEntity::new)
//client
//clients
.constructor(JpaClientEntity.class, JpaClientEntity::new)
.constructor(MapProtocolMapperEntity.class, MapProtocolMapperEntityImpl::new)
//client-scope
//client-scopes
.constructor(JpaClientScopeEntity.class, JpaClientScopeEntity::new)
//event
//events
.constructor(JpaAdminEventEntity.class, JpaAdminEventEntity::new)
.constructor(JpaAuthEventEntity.class, JpaAuthEventEntity::new)
//group
//groups
.constructor(JpaGroupEntity.class, JpaGroupEntity::new)
//realm
//realms
.constructor(JpaRealmEntity.class, JpaRealmEntity::new)
.constructor(JpaComponentEntity.class, JpaComponentEntity::new)
.constructor(MapAuthenticationExecutionEntity.class, MapAuthenticationExecutionEntityImpl::new)
Expand All @@ -185,34 +192,48 @@ public class JpaMapStorageProviderFactory implements
.constructor(MapRequiredActionProviderEntity.class, MapRequiredActionProviderEntityImpl::new)
.constructor(MapRequiredCredentialEntity.class, MapRequiredCredentialEntityImpl::new)
.constructor(MapWebAuthnPolicyEntity.class, MapWebAuthnPolicyEntityImpl::new)
//role
//roles
.constructor(JpaRoleEntity.class, JpaRoleEntity::new)
//single-use-object
//single-use-objects
.constructor(JpaSingleUseObjectEntity.class, JpaSingleUseObjectEntity::new)
//user-login-failure
//user-login-failures
.constructor(JpaUserLoginFailureEntity.class, JpaUserLoginFailureEntity::new)
//users
.constructor(JpaUserEntity.class, JpaUserEntity::new)
.constructor(JpaUserConsentEntity.class, JpaUserConsentEntity::new)
.constructor(JpaUserFederatedIdentityEntity.class, JpaUserFederatedIdentityEntity::new)
.constructor(MapUserCredentialEntity.class, MapUserCredentialEntityImpl::new)
.build();

private static final Map<Class<?>, Function<EntityManager, MapKeycloakTransaction>> MODEL_TO_TX = new HashMap<>();
static {
//auth-sessions
MODEL_TO_TX.put(RootAuthenticationSessionModel.class, JpaRootAuthenticationSessionMapKeycloakTransaction::new);
MODEL_TO_TX.put(ClientScopeModel.class, JpaClientScopeMapKeycloakTransaction::new);
//authorization
MODEL_TO_TX.put(ResourceServer.class, JpaResourceServerMapKeycloakTransaction::new);
MODEL_TO_TX.put(Resource.class, JpaResourceMapKeycloakTransaction::new);
MODEL_TO_TX.put(Scope.class, JpaScopeMapKeycloakTransaction::new);
MODEL_TO_TX.put(PermissionTicket.class, JpaPermissionMapKeycloakTransaction::new);
MODEL_TO_TX.put(Policy.class, JpaPolicyMapKeycloakTransaction::new);
//clients
MODEL_TO_TX.put(ClientModel.class, JpaClientMapKeycloakTransaction::new);
//event
//client-scopes
MODEL_TO_TX.put(ClientScopeModel.class, JpaClientScopeMapKeycloakTransaction::new);
//events
MODEL_TO_TX.put(AdminEvent.class, JpaAdminEventMapKeycloakTransaction::new);
MODEL_TO_TX.put(Event.class, JpaAuthEventMapKeycloakTransaction::new);
//groups
MODEL_TO_TX.put(GroupModel.class, JpaGroupMapKeycloakTransaction::new);
//realms
MODEL_TO_TX.put(RealmModel.class, JpaRealmMapKeycloakTransaction::new);
//roles
MODEL_TO_TX.put(RoleModel.class, JpaRoleMapKeycloakTransaction::new);
//single-use-objects
MODEL_TO_TX.put(ActionTokenValueModel.class, JpaSingleUseObjectMapKeycloakTransaction::new);
//user-login-failures
MODEL_TO_TX.put(UserLoginFailureModel.class, JpaUserLoginFailureMapKeycloakTransaction::new);

//authz
MODEL_TO_TX.put(ResourceServer.class, JpaResourceServerMapKeycloakTransaction::new);
MODEL_TO_TX.put(Resource.class, JpaResourceMapKeycloakTransaction::new);
MODEL_TO_TX.put(Scope.class, JpaScopeMapKeycloakTransaction::new);
10BC8 MODEL_TO_TX.put(PermissionTicket.class, JpaPermissionMapKeycloakTransaction::new);
MODEL_TO_TX.put(Policy.class, JpaPolicyMapKeycloakTransaction::new);
//users
MODEL_TO_TX.put(UserModel.class, JpaUserMapKeycloakTransaction::new);
}

public JpaMapStorageProviderFactory() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,18 @@
import org.keycloak.models.map.storage.jpa.hibernate.jsonb.migration.JpaRootAuthenticationSessionMigration;
import org.keycloak.models.map.storage.jpa.hibernate.jsonb.migration.JpaScopeMigration;
import org.keycloak.models.map.storage.jpa.hibernate.jsonb.migration.JpaSingleUseObjectMigration;
import org.keycloak.models.map.storage.jpa.hibernate.jsonb.migration.JpaUserConsentMigration;
import org.keycloak.models.map.storage.jpa.hibernate.jsonb.migration.JpaUserFederatedIdentityMigration;
import org.keycloak.models.map.storage.jpa.hibernate.jsonb.migration.JpaUserLoginFailureMigration;
import org.keycloak.models.map.storage.jpa.hibernate.jsonb.migration.JpaUserMigration;
import org.keycloak.models.map.storage.jpa.loginFailure.entity.JpaUserLoginFailureMetadata;
import org.keycloak.models.map.storage.jpa.realm.entity.JpaComponentMetadata;
import org.keycloak.models.map.storage.jpa.realm.entity.JpaRealmMetadata;
import org.keycloak.models.map.storage.jpa.role.entity.JpaRoleMetadata;
import org.keycloak.models.map.storage.jpa.singleUseObject.entity.JpaSingleUseObjectMetadata;
import org.keycloak.models.map.storage.jpa.user.entity.JpaUserConsentMetadata;
import org.keycloak.models.map.storage.jpa.user.entity.JpaUserFederatedIdentityMetadata;
import org.keycloak.models.map.storage.jpa.user.entity.JpaUserMetadata;

import static org.keycloak.models.map.storage.jpa.Constants.CURRENT_SCHEMA_VERSION_ADMIN_EVENT;
import static org.keycloak.models.map.storage.jpa.Constants.CURRENT_SCHEMA_VERSION_AUTHZ_PERMISSION;
Expand All @@ -72,33 +78,47 @@
import static org.keycloak.models.map.storage.jpa.Constants.CURRENT_SCHEMA_VERSION_REALM;
import static org.keycloak.models.map.storage.jpa.Constants.CURRENT_SCHEMA_VERSION_ROLE;
import static org.keycloak.models.map.storage.jpa.Constants.CURRENT_SCHEMA_VERSION_SINGLE_USE_OBJECT;
import static org.keycloak.models.map.storage.jpa.Constants.CURRENT_SCHEMA_VERSION_USER;
import static org.keycloak.models.map.storage.jpa.Constants.CURRENT_SCHEMA_VERSION_USER_CONSENT;
import static org.keycloak.models.map.storage.jpa.Constants.CURRENT_SCHEMA_VERSION_USER_FEDERATED_IDENTITY;
import static org.keycloak.models.map.storage.jpa.Constants.CURRENT_SCHEMA_VERSION_USER_LOGIN_FAILURE;

public class JpaEntityMigration {

static final Map<Class<?>, BiFunction<ObjectNode, Integer, ObjectNode>> MIGRATIONS = new HashMap<>();
static {
//auth-sessions
MIGRATIONS.put(JpaAuthenticationSessionMetadata.class, (tree, entityVersion) -> migrateTreeTo(entityVersion, CURRENT_SCHEMA_VERSION_AUTH_SESSION, tree, JpaAuthenticationSessionMigration.MIGRATORS));
MIGRATIONS.put(JpaRootAuthenticationSessionMetadata.class, (tree, entityVersion) -> migrateTreeTo(entityVersion, CURRENT_SCHEMA_VERSION_AUTH_SESSION, tree, JpaRootAuthenticationSessionMigration.MIGRATORS));
//authorization
MIGRATIONS.put(JpaPermissionMetadata.class, (tree, entityVersion) -> migrateTreeTo(entityVersion, CURRENT_SCHEMA_VERSION_AUTHZ_PERMISSION, tree, JpaPermissionMigration.MIGRATORS));
MIGRATIONS.put(JpaPolicyMetadata.class, (tree, entityVersion) -> migrateTreeTo(entityVersion, CURRENT_SCHEMA_VERSION_AUTHZ_POLICY, tree, JpaPolicyMigration.MIGRATORS));
MIGRATIONS.put(JpaResourceMetadata.class, (tree, entityVersion) -> migrateTreeTo(entityVersion, CURRENT_SCHEMA_VERSION_AUTHZ_RESOURCE, tree, JpaResourceMigration.MIGRATORS));
MIGRATIONS.put(JpaResourceServerMetadata.class, (tree, entityVersion) -> migrateTreeTo(entityVersion, CURRENT_SCHEMA_VERSION_AUTHZ_RESOURCE_SERVER, tree, JpaResourceServerMigration.MIGRATORS));
MIGRATIONS.put(JpaScopeMetadata.class, (tree, entityVersion) -> migrateTreeTo(entityVersion, CURRENT_SCHEMA_VERSION_AUTHZ_SCOPE, tree, JpaScopeMigration.MIGRATORS));
//clients
MIGRATIONS.put(JpaClientMetadata.class, (tree, entityVersion) -> migrateTreeTo(entityVersion, CURRENT_SCHEMA_VERSION_CLIENT, tree, JpaClientMigration.MIGRATORS));
//client-scopes
MIGRATIONS.put(JpaClientScopeMetadata.class, (tree, entityVersion) -> migrateTreeTo(entityVersion, CURRENT_SCHEMA_VERSION_CLIENT_SCOPE, tree, JpaClientScopeMigration.MIGRATORS));
MIGRATIONS.put(JpaComponentMetadata.class, (tree, entityVersion) -> migrateTreeTo(entityVersion, CURRENT_SCHEMA_VERSION_REALM, tree, JpaComponentMigration.MIGRATORS));
//events
MIGRATIONS.put(JpaAdminEventMetadata.class, (tree, entityVersion) -> migrateTreeTo(entityVersion, CURRENT_SCHEMA_VERSION_ADMIN_EVENT, tree, JpaAdminEventMigration.MIGRATORS));
MIGRATIONS.put(JpaAuthEventMetadata.class, (tree, entityVersion) -> migrateTreeTo(entityVersion, CURRENT_SCHEMA_VERSION_AUTH_EVENT, tree, JpaAuthEventMigration.MIGRATORS));
//groups
MIGRATIONS.put(JpaGroupMetadata.class, (tree, entityVersion) -> migrateTreeTo(entityVersion, CURRENT_SCHEMA_VERSION_GROUP, tree, JpaGroupMigration.MIGRATORS));
//realms
MIGRATIONS.put(JpaComponentMetadata.class, (tree, entityVersion) -> migrateTreeTo(entityVersion, CURRENT_SCHEMA_VERSION_REALM, tree, JpaComponentMigration.MIGRATORS));
MIGRATIONS.put(JpaRealmMetadata.class, (tree, entityVersion) -> migrateTreeTo(entityVersion, CURRENT_SCHEMA_VERSION_REALM, tree, JpaRealmMigration.MIGRATORS));
//roles
MIGRATIONS.put(JpaRoleMetadata.class, (tree, entityVersion) -> migrateTreeTo(entityVersion, CURRENT_SCHEMA_VERSION_ROLE, tree, JpaRoleMigration.MIGRATORS));
//single-use-objects
MIGRATIONS.put(JpaSingleUseObjectMetadata.class, (tree, entityVersion) -> migrateTreeTo(entityVersion, CURRENT_SCHEMA_VERSION_SINGLE_USE_OBJECT, tree, JpaSingleUseObjectMigration.MIGRATORS));
//user-login-failures
MIGRATIONS.put(JpaUserLoginFailureMetadata.class, (tree, entityVersion) -> migrateTreeTo(entityVersion, CURRENT_SCHEMA_VERSION_USER_LOGIN_FAILURE,tree, JpaUserLoginFailureMigration.MIGRATORS));
//users
MIGRATIONS.put(JpaUserMetadata.class, (tree, entityVersion) -> migrateTreeTo(entityVersion, CURRENT_SCHEMA_VERSION_USER, tree, JpaUserMigration.MIGRATORS));
MIGRATIONS.put(JpaUserConsentMetadata.class, (tree, entityVersion) -> migrateTreeTo(entityVersion, CURRENT_SCHEMA_VERSION_USER_CONSENT, tree, JpaUserConsentMigration.MIGRATORS));
MIGRATIONS.put(JpaUserFederatedIdentityMetadata.class, (tree, entityVersion) -> migrateTreeTo(entityVersion, CURRENT_SCHEMA_VERSION_USER_FEDERATED_IDENTITY, tree, JpaUserFederatedIdentityMigration.MIGRATORS));

//authz
MIGRATIONS.put(JpaPermissionMetadata.class, (tree, entityVersion) -> migrateTreeTo(entityVersion, CURRENT_SCHEMA_VERSION_AUTHZ_PERMISSION, tree, JpaPermissionMigration.MIGRATORS));
MIGRATIONS.put(JpaPolicyMetadata.class, (tree, entityVersion) -> migrateTreeTo(entityVersion, CURRENT_SCHEMA_VERSION_AUTHZ_POLICY, tree, JpaPolicyMigration.MIGRATORS));
MIGRATIONS.put(JpaResourceMetadata.class, (tree, entityVersion) -> migrateTreeTo(entityVersion, CURRENT_SCHEMA_VERSION_AUTHZ_RESOURCE, tree, JpaResourceMigration.MIGRATORS));
MIGRATIONS.put(JpaResourceServerMetadata.class, (tree, entityVersion) -> migrateTreeTo(entityVersion, CURRENT_SCHEMA_VERSION_AUTHZ_RESOURCE_SERVER, tree, JpaResourceServerMigration.MIGRATORS));
MIGRATIONS.put(JpaScopeMetadata.class, (tree, entityVersion) -> migrateTreeTo(entityVersion, CURRENT_SCHEMA_VERSION_AUTHZ_SCOPE, tree, JpaScopeMigration.MIGRATORS));

// events
MIGRATIONS.put(JpaAdminEventMetadata.class, (tree, entityVersion) -> migrateTreeTo(entityVersion, CURRENT_SCHEMA_VERSION_ADMIN_EVENT, tree, JpaAdminEventMigration.MIGRATORS));
MIGRATIONS.put(JpaAuthEventMetadata.class, (tree, entityVersion) -> migrateTreeTo(entityVersion, CURRENT_SCHEMA_VERSION_AUTH_EVENT, tree, JpaAuthEventMigration.MIGRATORS));
}

private static ObjectNode migrateTreeTo(int entityVersion, Integer supportedVersion, ObjectNode node, List<Function<ObjectNode, ObjectNode>> migrators) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@
import org.keycloak.models.map.realm.entity.MapRequiredCredentialEntityImpl;
import org.keycloak.models.map.realm.entity.MapWebAuthnPolicyEntity;
import org.keycloak.models.map.realm.entity.MapWebAuthnPolicyEntityImpl;
import org.keycloak.models.map.user.MapUserCredentialEntity;
import org.keycloak.models.map.user.MapUserCredentialEntityImpl;
import org.keycloak.util.EnumWithStableIndex;

public class JsonbType extends AbstractSingleColumnStandardBasicType<Object> implements DynamicParameterizedType {
Expand All @@ -102,7 +104,9 @@ public class JsonbType extends AbstractSingleColumnStandardBasicType<Object> imp
.addAbstractTypeMapping(MapOTPPolicyEntity.class, MapOTPPolicyEntityImpl.class)
.addAbstractTypeMapping(MapRequiredActionProviderEntity.class, MapRequiredActionProviderEntityImpl.class)
.addAbstractTypeMapping(MapRequiredCredentialEntity.class, MapRequiredCredentialEntityImpl.class)
.addAbstractTypeMapping(MapWebAuthnPolicyEntity.class, MapWebAuthnPolicyEntityImpl.class))
.addAbstractTypeMapping(MapWebAuthnPolicyEntity.class, MapWebAuthnPolicyEntityImpl.class)
// user abstract type mappings
.addAbstractTypeMapping(MapUserCredentialEntity.class, MapUserCredentialEntityImpl.class))
.addMixIn(UpdatableEntity.class, IgnoreUpdatedMixIn.class)
.addMixIn(DeepCloner.class, IgnoredTypeMixIn.class)
.addMixIn(EntityWithAttributes.class, IgnoredMetadataFieldsMixIn.class)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright 2022 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.models.map.storage.jpa.hibernate.jsonb.migration;

import java.util.Arrays;
import java.util.List;
import java.util.function.Function;

import com.fasterxml.jackson.databind.node.ObjectNode;

/**
* Migration functions for user consents.
*
* @author <a href="mailto:sguilhen@redhat.com">Stefan Guilhen</a>
*/
public class JpaUserConsentMigration {

public static final List<Function<ObjectNode, ObjectNode>> MIGRATORS = Arrays.asList(
o -> o // no migration yet
);
}
Loading
0