KEYCLOAK-13306 Model fixes for check realm when lookup by ID
(cherry picked from commit e40a62de31f6f5d326234314a9e285010665f707)
This commit is contained in:
parent
821405e175
commit
b29810c923
4 changed files with 627 additions and 32 deletions
|
@ -250,14 +250,17 @@ public class InfinispanUserSessionProvider implements UserSessionProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected UserSessionAdapter getUserSession(RealmModel realm, String id, boolean offline) {
|
protected UserSessionAdapter getUserSession(RealmModel realm, String id, boolean offline) {
|
||||||
UserSessionEntity entity = getUserSessionEntity(id, offline);
|
UserSessionEntity entity = getUserSessionEntity(realm, id, offline);
|
||||||
return wrap(realm, entity, offline);
|
return wrap(realm, entity, offline);
|
||||||
}
|
}
|
||||||
|
|
||||||
private UserSessionEntity getUserSessionEntity(String id, boolean offline) {
|
private UserSessionEntity getUserSessionEntity(RealmModel realm, String id, boolean offline) {
|
||||||
InfinispanChangelogBasedTransaction<String, UserSessionEntity> tx = getTransaction(offline);
|
InfinispanChangelogBasedTransaction<String, UserSessionEntity> tx = getTransaction(offline);
|
||||||
SessionEntityWrapper<UserSessionEntity> entityWrapper = tx.get(id);
|
SessionEntityWrapper<UserSessionEntity> entityWrapper = tx.get(id);
|
||||||
return entityWrapper==null ? null : entityWrapper.getEntity();
|
if (entityWrapper==null) return null;
|
||||||
|
UserSessionEntity entity = entityWrapper.getEntity();
|
||||||
|
if (!entity.getRealmId().equals(realm.getId())) return null;
|
||||||
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -455,7 +458,7 @@ public class InfinispanUserSessionProvider implements UserSessionProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeUserSession(RealmModel realm, UserSessionModel session) {
|
public void removeUserSession(RealmModel realm, UserSessionModel session) {
|
||||||
UserSessionEntity entity = getUserSessionEntity(session, false);
|
UserSessionEntity entity = getUserSessionEntity(realm, session, false);
|
||||||
if (entity != null) {
|
if (entity != null) {
|
||||||
removeUserSession(entity, false);
|
removeUserSession(entity, false);
|
||||||
}
|
}
|
||||||
|
@ -801,11 +804,12 @@ public class InfinispanUserSessionProvider implements UserSessionProvider {
|
||||||
return entity != null ? new UserLoginFailureAdapter(this, key, entity) : null;
|
return entity != null ? new UserLoginFailureAdapter(this, key, entity) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
UserSessionEntity getUserSessionEntity(UserSessionModel userSession, boolean offline) {
|
UserSessionEntity getUserSessionEntity(RealmModel realm, UserSessionModel userSession, boolean offline) {
|
||||||
if (userSession instanceof UserSessionAdapter) {
|
if (userSession instanceof UserSessionAdapter) {
|
||||||
|
if (!userSession.getRealm().equals(realm)) return null;
|
||||||
return ((UserSessionAdapter) userSession).getEntity();
|
return ((UserSessionAdapter) userSession).getEntity();
|
||||||
} else {
|
} else {
|
||||||
return getUserSessionEntity(userSession.getId(), offline);
|
return getUserSessionEntity(realm, userSession.getId(), offline);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -829,7 +833,7 @@ public class InfinispanUserSessionProvider implements UserSessionProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeOfflineUserSession(RealmModel realm, UserSessionModel userSession) {
|
public void removeOfflineUserSession(RealmModel realm, UserSessionModel userSession) {
|
||||||
UserSessionEntity userSessionEntity = getUserSessionEntity(userSession, true);
|
UserSessionEntity userSessionEntity = getUserSessionEntity(realm, userSession, true);
|
||||||
if (userSessionEntity != null) {
|
if (userSessionEntity != null) {
|
||||||
removeUserSession(userSessionEntity, true);
|
removeUserSession(userSessionEntity, true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -364,6 +364,10 @@ public class JpaRealmProvider implements RealmProvider {
|
||||||
container.removeDefaultRoles(role.getName());
|
container.removeDefaultRoles(role.getName());
|
||||||
}
|
}
|
||||||
RoleEntity roleEntity = em.getReference(RoleEntity.class, role.getId());
|
RoleEntity roleEntity = em.getReference(RoleEntity.class, role.getId());
|
||||||
|
if (roleEntity == null || !roleEntity.getRealmId().equals(realm.getId())) {
|
||||||
|
// Throw model exception to ensure transaction rollback and revert previous operations (removing default roles) as well
|
||||||
|
throw new ModelException("Role not found or trying to remove role from incorrect realm");
|
||||||
|
}
|
||||||
String compositeRoleTable = JpaUtils.getTableNameForNativeQuery("COMPOSITE_ROLE", em);
|
String compositeRoleTable = JpaUtils.getTableNameForNativeQuery("COMPOSITE_ROLE", em);
|
||||||
em.createNativeQuery("delete from " + compositeRoleTable + " where CHILD_ROLE = :role").setParameter("role", roleEntity).executeUpdate();
|
em.createNativeQuery("delete from " + compositeRoleTable + " where CHILD_ROLE = :role").setParameter("role", roleEntity).executeUpdate();
|
||||||
realm.getClients().forEach(c -> c.deleteScopeMapping(role));
|
realm.getClients().forEach(c -> c.deleteScopeMapping(role));
|
||||||
|
@ -786,20 +790,18 @@ public class JpaRealmProvider implements RealmProvider {
|
||||||
@Override
|
@Override
|
||||||
public ClientInitialAccessModel getClientInitialAccessModel(RealmModel realm, String id) {
|
public ClientInitialAccessModel getClientInitialAccessModel(RealmModel realm, String id) {
|
||||||
ClientInitialAccessEntity entity = em.find(ClientInitialAccessEntity.class, id);
|
ClientInitialAccessEntity entity = em.find(ClientInitialAccessEntity.class, id);
|
||||||
if (entity == null) {
|
if (entity == null) return null;
|
||||||
return null;
|
if (!entity.getRealm().getId().equals(realm.getId())) return null;
|
||||||
} else {
|
return entityToModel(entity);
|
||||||
return entityToModel(entity);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeClientInitialAccessModel(RealmModel realm, String id) {
|
public void removeClientInitialAccessModel(RealmModel realm, String id) {
|
||||||
ClientInitialAccessEntity entity = em.find(ClientInitialAccessEntity.class, id, LockModeType.PESSIMISTIC_WRITE);
|
ClientInitialAccessEntity entity = em.find(ClientInitialAccessEntity.class, id, LockModeType.PESSIMISTIC_WRITE);
|
||||||
if (entity != null) {
|
if (entity == null) return;
|
||||||
em.remove(entity);
|
if (!entity.getRealm().getId().equals(realm.getId())) return;
|
||||||
em.flush();
|
em.remove(entity);
|
||||||
}
|
em.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1651,7 +1651,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthenticationFlowModel getAuthenticationFlowById(String id) {
|
public AuthenticationFlowModel getAuthenticationFlowById(String id) {
|
||||||
AuthenticationFlowEntity entity = em.find(AuthenticationFlowEntity.class, id);
|
AuthenticationFlowEntity entity = getAuthenticationFlowEntity(id, false);
|
||||||
if (entity == null) return null;
|
if (entity == null) return null;
|
||||||
return entityToModel(entity);
|
return entityToModel(entity);
|
||||||
}
|
}
|
||||||
|
@ -1661,15 +1661,15 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
|
||||||
if (KeycloakModelUtils.isFlowUsed(this, model)) {
|
if (KeycloakModelUtils.isFlowUsed(this, model)) {
|
||||||
throw new ModelException("Cannot remove authentication flow, it is currently in use");
|
throw new ModelException("Cannot remove authentication flow, it is currently in use");
|
||||||
}
|
}
|
||||||
AuthenticationFlowEntity entity = em.find(AuthenticationFlowEntity.class, model.getId(), LockModeType.PESSIMISTIC_WRITE);
|
AuthenticationFlowEntity entity = getAuthenticationFlowEntity(model.getId(), true);
|
||||||
|
if (entity == null) return;
|
||||||
em.remove(entity);
|
em.remove(entity);
|
||||||
em.flush();
|
em.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateAuthenticationFlow(AuthenticationFlowModel model) {
|
public void updateAuthenticationFlow(AuthenticationFlowModel model) {
|
||||||
AuthenticationFlowEntity entity = em.find(AuthenticationFlowEntity.class, model.getId());
|
AuthenticationFlowEntity entity = getAuthenticationFlowEntity(model.getId(), false);
|
||||||
if (entity == null) return;
|
if (entity == null) return;
|
||||||
entity.setAlias(model.getAlias());
|
entity.setAlias(model.getAlias());
|
||||||
entity.setDescription(model.getDescription());
|
entity.setDescription(model.getDescription());
|
||||||
|
@ -1679,6 +1679,15 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private AuthenticationFlowEntity getAuthenticationFlowEntity(String id, boolean readForRemove) {
|
||||||
|
AuthenticationFlowEntity entity = readForRemove
|
||||||
|
? em.find(AuthenticationFlowEntity.class, id, LockModeType.PESSIMISTIC_WRITE)
|
||||||
|
: em.find(AuthenticationFlowEntity.class, id);
|
||||||
|
if (entity == null) return null;
|
||||||
|
if (!entity.getRealm().equals(getEntity())) return null;
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthenticationFlowModel addAuthenticationFlow(AuthenticationFlowModel model) {
|
public AuthenticationFlowModel addAuthenticationFlow(AuthenticationFlowModel model) {
|
||||||
AuthenticationFlowEntity entity = new AuthenticationFlowEntity();
|
AuthenticationFlowEntity entity = new AuthenticationFlowEntity();
|
||||||
|
@ -1723,7 +1732,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthenticationExecutionModel getAuthenticationExecutionById(String id) {
|
public AuthenticationExecutionModel getAuthenticationExecutionById(String id) {
|
||||||
AuthenticationExecutionEntity entity = em.find(AuthenticationExecutionEntity.class, id);
|
AuthenticationExecutionEntity entity = getAuthenticationExecution(id, false);
|
||||||
if (entity == null) return null;
|
if (entity == null) return null;
|
||||||
return entityToModel(entity);
|
return entityToModel(entity);
|
||||||
}
|
}
|
||||||
|
@ -1761,7 +1770,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateAuthenticatorExecution(AuthenticationExecutionModel model) {
|
public void updateAuthenticatorExecution(AuthenticationExecutionModel model) {
|
||||||
AuthenticationExecutionEntity entity = em.find(AuthenticationExecutionEntity.class, model.getId());
|
AuthenticationExecutionEntity entity = getAuthenticationExecution(model.getId(), false);
|
||||||
if (entity == null) return;
|
if (entity == null) return;
|
||||||
entity.setAutheticatorFlow(model.isAuthenticatorFlow());
|
entity.setAutheticatorFlow(model.isAuthenticatorFlow());
|
||||||
entity.setAuthenticator(model.getAuthenticator());
|
entity.setAuthenticator(model.getAuthenticator());
|
||||||
|
@ -1778,13 +1787,22 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeAuthenticatorExecution(AuthenticationExecutionModel model) {
|
public void removeAuthenticatorExecution(AuthenticationExecutionModel model) {
|
||||||
AuthenticationExecutionEntity entity = em.find(AuthenticationExecutionEntity.class, model.getId(), LockModeType.PESSIMISTIC_WRITE);
|
AuthenticationExecutionEntity entity = getAuthenticationExecution(model.getId(), true);
|
||||||
if (entity == null) return;
|
if (entity == null) return;
|
||||||
em.remove(entity);
|
em.remove(entity);
|
||||||
em.flush();
|
em.flush();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private AuthenticationExecutionEntity getAuthenticationExecution(String id, boolean readForRemove) {
|
||||||
|
AuthenticationExecutionEntity entity = readForRemove
|
||||||
|
? em.find(AuthenticationExecutionEntity.class, id, LockModeType.PESSIMISTIC_WRITE)
|
||||||
|
: em.find(AuthenticationExecutionEntity.class, id);
|
||||||
|
if (entity == null) return null;
|
||||||
|
if (!entity.getRealm().equals(getEntity())) return null;
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthenticatorConfigModel addAuthenticatorConfig(AuthenticatorConfigModel model) {
|
public AuthenticatorConfigModel addAuthenticatorConfig(AuthenticatorConfigModel model) {
|
||||||
AuthenticatorConfigEntity auth = new AuthenticatorConfigEntity();
|
AuthenticatorConfigEntity auth = new AuthenticatorConfigEntity();
|
||||||
|
@ -1801,7 +1819,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeAuthenticatorConfig(AuthenticatorConfigModel model) {
|
public void removeAuthenticatorConfig(AuthenticatorConfigModel model) {
|
||||||
AuthenticatorConfigEntity entity = em.find(AuthenticatorConfigEntity.class, model.getId(), LockModeType.PESSIMISTIC_WRITE);
|
AuthenticatorConfigEntity entity = getAuthenticatorConfigEntity(model.getId(), true);
|
||||||
if (entity == null) return;
|
if (entity == null) return;
|
||||||
em.remove(entity);
|
em.remove(entity);
|
||||||
em.flush();
|
em.flush();
|
||||||
|
@ -1810,7 +1828,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AuthenticatorConfigModel getAuthenticatorConfigById(String id) {
|
public AuthenticatorConfigModel getAuthenticatorConfigById(String id) {
|
||||||
AuthenticatorConfigEntity entity = em.find(AuthenticatorConfigEntity.class, id);
|
AuthenticatorConfigEntity entity = getAuthenticatorConfigEntity(id, false);
|
||||||
if (entity == null) return null;
|
if (entity == null) return null;
|
||||||
return entityToModel(entity);
|
return entityToModel(entity);
|
||||||
}
|
}
|
||||||
|
@ -1827,7 +1845,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateAuthenticatorConfig(AuthenticatorConfigModel model) {
|
public void updateAuthenticatorConfig(AuthenticatorConfigModel model) {
|
||||||
AuthenticatorConfigEntity entity = em.find(AuthenticatorConfigEntity.class, model.getId());
|
AuthenticatorConfigEntity entity = getAuthenticatorConfigEntity(model.getId(), false);
|
||||||
if (entity == null) return;
|
if (entity == null) return;
|
||||||
entity.setAlias(model.getAlias());
|
entity.setAlias(model.getAlias());
|
||||||
if (entity.getConfig() == null) {
|
if (entity.getConfig() == null) {
|
||||||
|
@ -1842,6 +1860,15 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private AuthenticatorConfigEntity getAuthenticatorConfigEntity(String id, boolean readForRemove) {
|
||||||
|
AuthenticatorConfigEntity entity = readForRemove
|
||||||
|
? em.find(AuthenticatorConfigEntity.class, id, LockModeType.PESSIMISTIC_WRITE)
|
||||||
|
: em.find(AuthenticatorConfigEntity.class, id);
|
||||||
|
if (entity == null) return null;
|
||||||
|
if (!entity.getRealm().equals(getEntity())) return null;
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<AuthenticatorConfigModel> getAuthenticatorConfigs() {
|
public List<AuthenticatorConfigModel> getAuthenticatorConfigs() {
|
||||||
Collection<AuthenticatorConfigEntity> entities = realm.getAuthenticatorConfigs();
|
Collection<AuthenticatorConfigEntity> entities = realm.getAuthenticatorConfigs();
|
||||||
|
@ -1875,7 +1902,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeRequiredActionProvider(RequiredActionProviderModel model) {
|
public void removeRequiredActionProvider(RequiredActionProviderModel model) {
|
||||||
RequiredActionProviderEntity entity = em.find(RequiredActionProviderEntity.class, model.getId(), LockModeType.PESSIMISTIC_WRITE);
|
RequiredActionProviderEntity entity = getRequiredProviderEntity(model.getId(), true);
|
||||||
if (entity == null) return;
|
if (entity == null) return;
|
||||||
em.remove(entity);
|
em.remove(entity);
|
||||||
em.flush();
|
em.flush();
|
||||||
|
@ -1884,7 +1911,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RequiredActionProviderModel getRequiredActionProviderById(String id) {
|
public RequiredActionProviderModel getRequiredActionProviderById(String id) {
|
||||||
RequiredActionProviderEntity entity = em.find(RequiredActionProviderEntity.class, id);
|
RequiredActionProviderEntity entity = getRequiredProviderEntity(id, false);
|
||||||
if (entity == null) return null;
|
if (entity == null) return null;
|
||||||
return entityToModel(entity);
|
return entityToModel(entity);
|
||||||
}
|
}
|
||||||
|
@ -1906,7 +1933,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateRequiredActionProvider(RequiredActionProviderModel model) {
|
public void updateRequiredActionProvider(RequiredActionProviderModel model) {
|
||||||
RequiredActionProviderEntity entity = em.find(RequiredActionProviderEntity.class, model.getId());
|
RequiredActionProviderEntity entity = getRequiredProviderEntity(model.getId(), false);
|
||||||
if (entity == null) return;
|
if (entity == null) return;
|
||||||
entity.setAlias(model.getAlias());
|
entity.setAlias(model.getAlias());
|
||||||
entity.setProviderId(model.getProviderId());
|
entity.setProviderId(model.getProviderId());
|
||||||
|
@ -1938,6 +1965,15 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
|
||||||
return Collections.unmodifiableList(actions);
|
return Collections.unmodifiableList(actions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private RequiredActionProviderEntity getRequiredProviderEntity(String id, boolean readForRemove) {
|
||||||
|
RequiredActionProviderEntity entity = readForRemove
|
||||||
|
? em.find(RequiredActionProviderEntity.class, id, LockModeType.PESSIMISTIC_WRITE)
|
||||||
|
: em.find(RequiredActionProviderEntity.class, id);
|
||||||
|
if (entity == null) return null;
|
||||||
|
if (!entity.getRealm().equals(getEntity())) return null;
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RequiredActionProviderModel getRequiredActionProviderByAlias(String alias) {
|
public RequiredActionProviderModel getRequiredActionProviderByAlias(String alias) {
|
||||||
for (RequiredActionProviderModel action : getRequiredActionProviders()) {
|
for (RequiredActionProviderModel action : getRequiredActionProviders()) {
|
||||||
|
@ -2178,7 +2214,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
|
||||||
public void updateComponent(ComponentModel component) {
|
public void updateComponent(ComponentModel component) {
|
||||||
ComponentUtil.getComponentFactory(session, component).validateConfiguration(session, this, component);
|
ComponentUtil.getComponentFactory(session, component).validateConfiguration(session, this, component);
|
||||||
|
|
||||||
ComponentEntity c = em.find(ComponentEntity.class, component.getId());
|
ComponentEntity c = getComponentEntity(component.getId());
|
||||||
if (c == null) return;
|
if (c == null) return;
|
||||||
ComponentModel old = entityToModel(c);
|
ComponentModel old = entityToModel(c);
|
||||||
c.setName(component.getName());
|
c.setName(component.getName());
|
||||||
|
@ -2194,7 +2230,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeComponent(ComponentModel component) {
|
public void removeComponent(ComponentModel component) {
|
||||||
ComponentEntity c = em.find(ComponentEntity.class, component.getId());
|
ComponentEntity c = getComponentEntity(component.getId());
|
||||||
if (c == null) return;
|
if (c == null) return;
|
||||||
session.users().preRemove(this, component);
|
session.users().preRemove(this, component);
|
||||||
ComponentUtil.notifyPreRemove(session, this, component);
|
ComponentUtil.notifyPreRemove(session, this, component);
|
||||||
|
@ -2260,8 +2296,14 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ComponentModel getComponent(String id) {
|
public ComponentModel getComponent(String id) {
|
||||||
|
ComponentEntity c = getComponentEntity(id);
|
||||||
|
return c==null ? null : entityToModel(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ComponentEntity getComponentEntity(String id) {
|
||||||
ComponentEntity c = em.find(ComponentEntity.class, id);
|
ComponentEntity c = em.find(ComponentEntity.class, id);
|
||||||
if (c == null) return null;
|
if (c == null) return null;
|
||||||
return entityToModel(c);
|
if (!c.getRealm().equals(getEntity())) return null;
|
||||||
|
return c;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,547 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2019 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.testsuite.model;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.keycloak.component.ComponentModel;
|
||||||
|
import org.keycloak.models.AuthenticationExecutionModel;
|
||||||
|
import org.keycloak.models.AuthenticationFlowModel;
|
||||||
|
import org.keycloak.models.AuthenticatorConfigModel;
|
||||||
|
import org.keycloak.models.ClientInitialAccessModel;
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
import org.keycloak.models.ModelException;
|
||||||
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.RealmProvider;
|
||||||
|
import org.keycloak.models.RequiredActionProviderModel;
|
||||||
|
import org.keycloak.models.RoleModel;
|
||||||
|
import org.keycloak.models.UserModel;
|
||||||
|
import org.keycloak.models.UserSessionModel;
|
||||||
|
import org.keycloak.models.utils.DefaultAuthenticationFlows;
|
||||||
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
|
import org.keycloak.representations.idm.UserRepresentation;
|
||||||
|
import org.keycloak.testsuite.AbstractKeycloakTest;
|
||||||
|
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude;
|
||||||
|
import org.keycloak.testsuite.arquillian.annotation.ModelTest;
|
||||||
|
import org.keycloak.testsuite.util.RealmBuilder;
|
||||||
|
import org.keycloak.testsuite.util.UserBuilder;
|
||||||
|
|
||||||
|
import static org.keycloak.testsuite.admin.AbstractAdminTest.loadJson;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for the CRUD scenarios when the operation is called on the object, which is owned by different realm
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
|
*/
|
||||||
|
@AuthServerContainerExclude(AuthServerContainerExclude.AuthServer.REMOTE)
|
||||||
|
public class OwnerReplacementTest extends AbstractKeycloakTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addTestRealms(List<RealmRepresentation> testRealms) {
|
||||||
|
log.debug("Adding test realm for import from testrealm.json");
|
||||||
|
RealmRepresentation testRealm = loadJson(getClass().getResourceAsStream("/testrealm.json"), RealmRepresentation.class);
|
||||||
|
testRealms.add(testRealm);
|
||||||
|
|
||||||
|
UserRepresentation user = UserBuilder.create()
|
||||||
|
.username("foo@user")
|
||||||
|
.email("foo@user.com")
|
||||||
|
.password("password")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
RealmRepresentation realm2 = RealmBuilder.create()
|
||||||
|
.name("foo")
|
||||||
|
.user(user)
|
||||||
|
.build();
|
||||||
|
realm2.setId("foo");
|
||||||
|
testRealms.add(realm2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@ModelTest
|
||||||
|
public void componentsTest(KeycloakSession session1) {
|
||||||
|
doTest(session1,
|
||||||
|
// Get ID of some component from realm1
|
||||||
|
((session, realm1) -> {
|
||||||
|
|
||||||
|
List<ComponentModel> components = realm1.getComponents();
|
||||||
|
return components.get(0).getId();
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Test lookup realm1 component in realm2 should not work
|
||||||
|
((session, realm2, realm1ComponentId) -> {
|
||||||
|
|
||||||
|
ComponentModel component = realm2.getComponent(realm1ComponentId);
|
||||||
|
Assert.assertNull(component);
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Try to update some component in realm1 through the realm2
|
||||||
|
((session, realm1, realm2, realm1ComponentId) -> {
|
||||||
|
|
||||||
|
ComponentModel component = realm1.getComponent(realm1ComponentId);
|
||||||
|
component.put("key1", "Val1");
|
||||||
|
realm2.updateComponent(component);
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Test update from above was not successful
|
||||||
|
((session, realm1, realm1ComponentId) -> {
|
||||||
|
|
||||||
|
ComponentModel component = realm1.getComponent(realm1ComponentId);
|
||||||
|
Assert.assertNull(component.get("key1"));
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Try remove component from realm1 in the context of realm2
|
||||||
|
((session, realm1, realm2, realm1ComponentId) -> {
|
||||||
|
|
||||||
|
ComponentModel component = realm1.getComponent(realm1ComponentId);
|
||||||
|
realm2.removeComponent(component);
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Test remove from above was not successful
|
||||||
|
((session, realm1, realm1ComponentId) -> {
|
||||||
|
|
||||||
|
ComponentModel component = realm1.getComponent(realm1ComponentId);
|
||||||
|
Assert.assertNotNull(component);
|
||||||
|
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@ModelTest
|
||||||
|
public void requiredActionProvidersTest(KeycloakSession session1) {
|
||||||
|
doTest(session1,
|
||||||
|
// Get ID of some object from realm1
|
||||||
|
((session, realm1) -> {
|
||||||
|
|
||||||
|
List<RequiredActionProviderModel> reqActions = realm1.getRequiredActionProviders();
|
||||||
|
return reqActions.get(0).getId();
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Test lookup realm1 object in realm2 should not work
|
||||||
|
((session, realm2, realm1ReqActionId) -> {
|
||||||
|
|
||||||
|
RequiredActionProviderModel reqAction = realm2.getRequiredActionProviderById(realm1ReqActionId);
|
||||||
|
Assert.assertNull(reqAction);
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Try to update some object in realm1 through the realm2
|
||||||
|
((session, realm1, realm2, realm1ReqActionId) -> {
|
||||||
|
|
||||||
|
RequiredActionProviderModel reqAction = realm1.getRequiredActionProviderById(realm1ReqActionId);
|
||||||
|
reqAction.getConfig().put("key1", "Val1");
|
||||||
|
realm2.updateRequiredActionProvider(reqAction);
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Test update from above was not successful
|
||||||
|
((session, realm1, realm1ReqActionId) -> {
|
||||||
|
|
||||||
|
RequiredActionProviderModel reqAction = realm1.getRequiredActionProviderById(realm1ReqActionId);
|
||||||
|
Assert.assertNull(reqAction.getConfig().get("key1"));
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Try remove object from realm1 in the context of realm2
|
||||||
|
((session, realm1, realm2, realm1ReqActionId) -> {
|
||||||
|
|
||||||
|
RequiredActionProviderModel reqAction = realm1.getRequiredActionProviderById(realm1ReqActionId);
|
||||||
|
realm2.removeRequiredActionProvider(reqAction);
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Test remove from above was not successful
|
||||||
|
((session, realm1, realm1ReqActionId) -> {
|
||||||
|
|
||||||
|
RequiredActionProviderModel reqAction = realm1.getRequiredActionProviderById(realm1ReqActionId);
|
||||||
|
Assert.assertNotNull(reqAction);
|
||||||
|
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@ModelTest
|
||||||
|
public void authenticationFlowsTest(KeycloakSession session1) {
|
||||||
|
doTest(session1,
|
||||||
|
// Get ID of some object from realm1
|
||||||
|
((session, realm1) -> {
|
||||||
|
|
||||||
|
AuthenticationFlowModel flow = realm1.getFlowByAlias(DefaultAuthenticationFlows.BROWSER_FLOW);
|
||||||
|
return flow.getId();
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Test lookup realm1 object in realm2 should not work
|
||||||
|
((session, realm2, realm1FlowId) -> {
|
||||||
|
|
||||||
|
AuthenticationFlowModel flow = realm2.getAuthenticationFlowById(realm1FlowId);
|
||||||
|
Assert.assertNull(flow);
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Try to update some object in realm1 through the realm2
|
||||||
|
((session, realm1, realm2, realm1FlowId) -> {
|
||||||
|
|
||||||
|
AuthenticationFlowModel flow = realm1.getAuthenticationFlowById(realm1FlowId);
|
||||||
|
flow.setDescription("foo");
|
||||||
|
realm2.updateAuthenticationFlow(flow);
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Test update from above was not successful
|
||||||
|
((session, realm1, realm1FlowId) -> {
|
||||||
|
|
||||||
|
AuthenticationFlowModel flow = realm1.getAuthenticationFlowById(realm1FlowId);
|
||||||
|
Assert.assertNotEquals("foo", flow.getDescription());
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Try remove object from realm1 in the context of realm2
|
||||||
|
((session, realm1, realm2, realm1FlowId) -> {
|
||||||
|
|
||||||
|
AuthenticationFlowModel flow = realm1.getAuthenticationFlowById(realm1FlowId);
|
||||||
|
realm2.removeAuthenticationFlow(flow);
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Test remove from above was not successful
|
||||||
|
((session, realm1, realm1FlowId) -> {
|
||||||
|
|
||||||
|
AuthenticationFlowModel flow = realm1.getAuthenticationFlowById(realm1FlowId);
|
||||||
|
Assert.assertNotNull(flow);
|
||||||
|
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@ModelTest
|
||||||
|
public void authenticationExecutionsTest(KeycloakSession session1) {
|
||||||
|
doTest(session1,
|
||||||
|
// Get ID of some object from realm1
|
||||||
|
((session, realm1) -> {
|
||||||
|
|
||||||
|
AuthenticationFlowModel flow = realm1.getFlowByAlias(DefaultAuthenticationFlows.BROWSER_FLOW);
|
||||||
|
List<AuthenticationExecutionModel> executions = realm1.getAuthenticationExecutions(flow.getId());
|
||||||
|
return executions.get(0).getId();
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Test lookup realm1 object in realm2 should not work
|
||||||
|
((session, realm2, realm1ExecutionId) -> {
|
||||||
|
|
||||||
|
AuthenticationExecutionModel execution = realm2.getAuthenticationExecutionById(realm1ExecutionId);
|
||||||
|
Assert.assertNull(execution);
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Try to update some object in realm1 through the realm2
|
||||||
|
((session, realm1, realm2, realm1ExecutionId) -> {
|
||||||
|
|
||||||
|
AuthenticationExecutionModel execution = realm1.getAuthenticationExecutionById(realm1ExecutionId);
|
||||||
|
execution.setPriority(1234);
|
||||||
|
realm2.updateAuthenticatorExecution(execution);
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Test update from above was not successful
|
||||||
|
((session, realm1, realm1ExecutionId) -> {
|
||||||
|
|
||||||
|
AuthenticationExecutionModel execution = realm1.getAuthenticationExecutionById(realm1ExecutionId);
|
||||||
|
Assert.assertNotEquals(1234, execution.getPriority());
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Try remove object from realm1 in the context of realm2
|
||||||
|
((session, realm1, realm2, realm1ExecutionId) -> {
|
||||||
|
|
||||||
|
AuthenticationExecutionModel execution = realm1.getAuthenticationExecutionById(realm1ExecutionId);
|
||||||
|
realm2.removeAuthenticatorExecution(execution);
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Test remove from above was not successful
|
||||||
|
((session,realm1, realm1ExecutionId) -> {
|
||||||
|
|
||||||
|
AuthenticationExecutionModel execution = realm1.getAuthenticationExecutionById(realm1ExecutionId);
|
||||||
|
Assert.assertNotNull(execution);
|
||||||
|
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@ModelTest
|
||||||
|
public void authenticationConfigsTest(KeycloakSession session1) {
|
||||||
|
doTest(session1,
|
||||||
|
// Get ID of some object from realm1
|
||||||
|
((session, realm1) -> {
|
||||||
|
|
||||||
|
List<AuthenticatorConfigModel> configs = realm1.getAuthenticatorConfigs();
|
||||||
|
return configs.get(0).getId();
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Test lookup realm1 object in realm2 should not work
|
||||||
|
((session, realm2, realm1AuthConfigId) -> {
|
||||||
|
|
||||||
|
AuthenticatorConfigModel config = realm2.getAuthenticatorConfigById(realm1AuthConfigId);
|
||||||
|
Assert.assertNull(config);
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Try to update some object in realm1 through the realm2
|
||||||
|
((session, realm1, realm2, realm1AuthConfigId) -> {
|
||||||
|
|
||||||
|
AuthenticatorConfigModel config = realm1.getAuthenticatorConfigById(realm1AuthConfigId);
|
||||||
|
config.getConfig().put("key1", "val1");
|
||||||
|
realm2.updateAuthenticatorConfig(config);
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Test update from above was not successful
|
||||||
|
((session, realm1, realm1AuthConfigId) -> {
|
||||||
|
|
||||||
|
AuthenticatorConfigModel config = realm1.getAuthenticatorConfigById(realm1AuthConfigId);
|
||||||
|
Assert.assertNull(config.getConfig().get("key1"));
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Try remove object from realm1 in the context of realm2
|
||||||
|
((session, realm1, realm2, realm1AuthConfigId) -> {
|
||||||
|
|
||||||
|
AuthenticatorConfigModel config = realm1.getAuthenticatorConfigById(realm1AuthConfigId);
|
||||||
|
realm2.removeAuthenticatorConfig(config);
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Test remove from above was not successful
|
||||||
|
((session, realm1, realm1AuthConfigId) -> {
|
||||||
|
|
||||||
|
AuthenticatorConfigModel config = realm1.getAuthenticatorConfigById(realm1AuthConfigId);
|
||||||
|
Assert.assertNotNull(config);
|
||||||
|
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@ModelTest
|
||||||
|
public void clientInitialAccessTest(KeycloakSession session1) {
|
||||||
|
doTest(session1,
|
||||||
|
// Get ID of some object from realm1
|
||||||
|
((session, realm1) -> {
|
||||||
|
|
||||||
|
ClientInitialAccessModel clientInitialAccess = session.getProvider(RealmProvider.class).createClientInitialAccessModel(realm1, 10, 20);
|
||||||
|
return clientInitialAccess.getId();
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Test lookup realm1 object in realm2 should not work
|
||||||
|
((session, realm2, realm1ClientInitialAccessId) -> {
|
||||||
|
|
||||||
|
ClientInitialAccessModel clientInitialAccess = session.getProvider(RealmProvider.class).getClientInitialAccessModel(realm2, realm1ClientInitialAccessId);
|
||||||
|
Assert.assertNull(clientInitialAccess);
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Try to update some object in realm1 through the realm2
|
||||||
|
((session, realm1, realm2, realm1ClientInitialAccessId) -> {
|
||||||
|
|
||||||
|
// No-op, update not supported for clientInitialAccessModel
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Test update from above was not successful
|
||||||
|
((session, realm1, realm1ClientInitialAccessId) -> {
|
||||||
|
|
||||||
|
// No-op, update not supported for clientInitialAccessModel
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Try remove object from realm1 in the context of realm2
|
||||||
|
((session, realm1, realm2, realm1ClientInitialAccessId) -> {
|
||||||
|
|
||||||
|
session.getProvider(RealmProvider.class).removeClientInitialAccessModel(realm2, realm1ClientInitialAccessId);
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Test remove from above was not successful
|
||||||
|
((session, realm1, realm1ClientInitialAccessId) -> {
|
||||||
|
|
||||||
|
ClientInitialAccessModel clientInitialAccess = session.getProvider(RealmProvider.class).getClientInitialAccessModel(realm1, realm1ClientInitialAccessId);
|
||||||
|
Assert.assertNotNull(clientInitialAccess);
|
||||||
|
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@ModelTest
|
||||||
|
public void rolesTest(KeycloakSession session1) {
|
||||||
|
doTest(session1,
|
||||||
|
// Get ID of some object from realm1
|
||||||
|
((session, realm1) -> {
|
||||||
|
|
||||||
|
RoleModel role = session.getProvider(RealmProvider.class).addRealmRole(realm1, "foo");
|
||||||
|
realm1.addDefaultRole("foo");
|
||||||
|
return role.getId();
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Test lookup realm1 object in realm2 should not work
|
||||||
|
((session, realm2, realm1RoleId) -> {
|
||||||
|
|
||||||
|
RoleModel role = session.getProvider(RealmProvider.class).getRoleById(realm1RoleId, realm2);
|
||||||
|
Assert.assertNull(role);
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Try to update some object in realm1 through the realm2
|
||||||
|
((session, realm1, realm2, realm1RoleId) -> {
|
||||||
|
|
||||||
|
// No-op, update done directly by calling operations on RoleModel. No explicit updateRole method on the RealmModel
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Test update from above was not successful
|
||||||
|
((session, realm1, realm1RoleId) -> {
|
||||||
|
|
||||||
|
// No-op, update done directly by calling operations on RoleModel. No explicit updateRole method on the RealmModel
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Try remove object from realm1 in the context of realm2
|
||||||
|
((session, realm1, realm2, realm1RoleId) -> {
|
||||||
|
|
||||||
|
RoleModel role = session.getProvider(RealmProvider.class).getRoleById(realm1RoleId, realm1);
|
||||||
|
session.getProvider(RealmProvider.class).removeRole(realm2, role);
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Test remove from above was not successful
|
||||||
|
((session, realm1, realm1RoleId) -> {
|
||||||
|
|
||||||
|
RoleModel role = session.getProvider(RealmProvider.class).getRoleById(realm1RoleId, realm1);
|
||||||
|
Assert.assertNotNull(role);
|
||||||
|
Assert.assertTrue(realm1.getDefaultRoles().contains("foo"));
|
||||||
|
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@ModelTest
|
||||||
|
public void userSessionsTest(KeycloakSession session1) {
|
||||||
|
doTest(session1,
|
||||||
|
// Get ID of some object from realm1
|
||||||
|
((session, realm1) -> {
|
||||||
|
|
||||||
|
UserModel user = session.users().getUserByUsername("test-user@localhost", realm1);
|
||||||
|
UserSessionModel userSession = session.sessions().createUserSession(realm1, user, user.getUsername(), "1.2.3.4", "bar", false, null, null);
|
||||||
|
return userSession.getId();
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Test lookup realm1 object in realm2 should not work
|
||||||
|
((session, realm2, realm1SessionId) -> {
|
||||||
|
|
||||||
|
UserSessionModel userSession = session.sessions().getUserSession(realm2, realm1SessionId);
|
||||||
|
Assert.assertNull(userSession);
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Try to update some object in realm1 through the realm2
|
||||||
|
((session, realm1, realm2, realm1SessionId) -> {
|
||||||
|
|
||||||
|
// No-op, update done directly by calling operations on UserSessionModel. No explicit update method
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Test update from above was not successful
|
||||||
|
((session, realm1, realm1SessionId) -> {
|
||||||
|
|
||||||
|
// No-op, update done directly by calling operations on UserSessionModel. No explicit update method.
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Try remove object from realm1 in the context of realm2
|
||||||
|
((session, realm1, realm2, realm1SessionId) -> {
|
||||||
|
|
||||||
|
UserSessionModel userSession = session.sessions().getUserSession(realm1, realm1SessionId);
|
||||||
|
session.sessions().removeUserSession(realm2, userSession);
|
||||||
|
|
||||||
|
}),
|
||||||
|
// Test remove from above was not successful
|
||||||
|
((session, realm1, realm1SessionId) -> {
|
||||||
|
|
||||||
|
UserSessionModel userSession = session.sessions().getUserSession(realm1, realm1SessionId);
|
||||||
|
Assert.assertNotNull(userSession);
|
||||||
|
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void doTest(KeycloakSession session1,
|
||||||
|
BiFunction<KeycloakSession, RealmModel, String> realm1ObjectIdProducer,
|
||||||
|
TriConsumer<KeycloakSession, RealmModel, String> testLookupRealm1ObjectInRealm2,
|
||||||
|
TetraConsumer<KeycloakSession, RealmModel, RealmModel, String> updaterRealm1ObjectInRealm2,
|
||||||
|
TriConsumer<KeycloakSession, RealmModel, String> testUpdateFailed,
|
||||||
|
TetraConsumer<KeycloakSession, RealmModel, RealmModel, String> removeRealm1ObjectInRealm2,
|
||||||
|
TriConsumer<KeycloakSession, RealmModel, String> testRemoveFailed
|
||||||
|
) {
|
||||||
|
|
||||||
|
// Transaction 1 - Lookup object of realm1
|
||||||
|
AtomicReference<String> realm1ObjectId = new AtomicReference<>();
|
||||||
|
KeycloakModelUtils.runJobInTransaction(session1.getKeycloakSessionFactory(), (KeycloakSession session) -> {
|
||||||
|
|
||||||
|
RealmModel realm1 = session.getProvider(RealmProvider.class).getRealm("test");
|
||||||
|
|
||||||
|
realm1ObjectId.set(realm1ObjectIdProducer.apply(session, realm1));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// Transaction 2
|
||||||
|
KeycloakModelUtils.runJobInTransaction(session1.getKeycloakSessionFactory(), (KeycloakSession session) -> {
|
||||||
|
|
||||||
|
RealmModel realm1 = session.getProvider(RealmProvider.class).getRealm("test");
|
||||||
|
RealmModel realm2 = session.getProvider(RealmProvider.class).getRealm("foo");
|
||||||
|
|
||||||
|
testLookupRealm1ObjectInRealm2.accept(session, realm2, realm1ObjectId.get());
|
||||||
|
updaterRealm1ObjectInRealm2.accept(session, realm1, realm2, realm1ObjectId.get());
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// Transaction 3
|
||||||
|
KeycloakModelUtils.runJobInTransaction(session1.getKeycloakSessionFactory(), (KeycloakSession session) -> {
|
||||||
|
RealmModel realm1 = session.getProvider(RealmProvider.class).getRealm("test");
|
||||||
|
|
||||||
|
testUpdateFailed.accept(session, realm1, realm1ObjectId.get());
|
||||||
|
});
|
||||||
|
|
||||||
|
// Transaction 4
|
||||||
|
try {
|
||||||
|
KeycloakModelUtils.runJobInTransaction(session1.getKeycloakSessionFactory(), (KeycloakSession session) -> {
|
||||||
|
RealmModel realm1 = session.getProvider(RealmProvider.class).getRealm("test");
|
||||||
|
RealmModel realm2 = session.getProvider(RealmProvider.class).getRealm("foo");
|
||||||
|
removeRealm1ObjectInRealm2.accept(session, realm1, realm2, realm1ObjectId.get());
|
||||||
|
|
||||||
|
});
|
||||||
|
} catch (ModelException e) {
|
||||||
|
// This is fine. Attempt to remove on incorrect object can throw an exception in some cases, which will enforce transaction rollback
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transaction 5
|
||||||
|
KeycloakModelUtils.runJobInTransaction(session1.getKeycloakSessionFactory(), (KeycloakSession session) -> {
|
||||||
|
RealmModel realm1 = session.getProvider(RealmProvider.class).getRealm("test");
|
||||||
|
|
||||||
|
testRemoveFailed.accept(session, realm1, realm1ObjectId.get());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface TriConsumer<T, U, V> {
|
||||||
|
void accept(T var1, U var2, V var3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface TetraConsumer<T, U, V, W> {
|
||||||
|
void accept(T var1, U var2, V var3, W var4);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue