MigrateTo25_0_0 does not complete within default transaction timeout
closes #29756 Signed-off-by: mposolda <mposolda@gmail.com>
This commit is contained in:
parent
f34a7c2af4
commit
ea1cdc10bd
7 changed files with 84 additions and 5 deletions
|
@ -1455,6 +1455,16 @@ public class RealmCacheSession implements CacheRealmProvider {
|
|||
return assignedScopes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addClientScopeToAllClients(RealmModel realm, ClientScopeModel clientScope, boolean defaultClientScope) {
|
||||
getClientDelegate().addClientScopeToAllClients(realm, clientScope, defaultClientScope);
|
||||
|
||||
// This will make sure to all invalidate all clients dependent on clientScope
|
||||
listInvalidations.add(realm.getId());
|
||||
cache.clientScopeRemoval(realm.getId(), invalidations);
|
||||
invalidationEvents.add(ClientScopeRemovedEvent.create(clientScope.getId(), realm.getId()));
|
||||
}
|
||||
|
||||
// Don't cache ClientInitialAccessModel for now
|
||||
@Override
|
||||
public ClientInitialAccessModel createClientInitialAccessModel(RealmModel realm, int expiration, int count) {
|
||||
|
|
|
@ -1093,6 +1093,18 @@ public class JpaRealmProvider implements RealmProvider, ClientProvider, ClientSc
|
|||
em.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addClientScopeToAllClients(RealmModel realm, ClientScopeModel clientScope, boolean defaultClientScope) {
|
||||
if (realm.equals(clientScope.getRealm())) {
|
||||
em.createNamedQuery("addClientScopeToAllClients")
|
||||
.setParameter("realmId", realm.getId())
|
||||
.setParameter("clientScopeId", clientScope.getId())
|
||||
.setParameter("clientProtocol", clientScope.getProtocol())
|
||||
.setParameter("defaultScope", defaultClientScope)
|
||||
.executeUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ClientScopeModel> getClientScopes(RealmModel realm, ClientModel client, boolean defaultScope) {
|
||||
// Defaults to openid-connect
|
||||
|
|
|
@ -36,7 +36,8 @@ import jakarta.persistence.Table;
|
|||
@NamedQuery(name="clientScopeClientMappingIdsByClient", query="select m.clientScopeId from ClientScopeClientMappingEntity m where m.clientId = :clientId and m.defaultScope = :defaultScope"),
|
||||
@NamedQuery(name="deleteClientScopeClientMapping", query="delete from ClientScopeClientMappingEntity where clientId = :clientId and clientScopeId = :clientScopeId"),
|
||||
@NamedQuery(name="deleteClientScopeClientMappingByClient", query="delete from ClientScopeClientMappingEntity where clientId = :clientId"),
|
||||
@NamedQuery(name="deleteClientScopeClientMappingByClientScope", query="delete from ClientScopeClientMappingEntity where clientScopeId = :clientScopeId")
|
||||
@NamedQuery(name="deleteClientScopeClientMappingByClientScope", query="delete from ClientScopeClientMappingEntity where clientScopeId = :clientScopeId"),
|
||||
@NamedQuery(name="addClientScopeToAllClients", query="insert into ClientScopeClientMappingEntity (clientScopeId, defaultScope, clientId) select :clientScopeId, :defaultScope, client.id from ClientEntity client where client.realmId = :realmId and client.bearerOnly <> true and client.protocol = :clientProtocol")
|
||||
})
|
||||
@Entity
|
||||
@Table(name="CLIENT_SCOPE_CLIENT")
|
||||
|
|
|
@ -56,11 +56,14 @@ public class MigrateTo25_0_0 implements Migration {
|
|||
protected void migrateRealm(KeycloakSession session, RealmModel realm) {
|
||||
MigrationProvider migrationProvider = session.getProvider(MigrationProvider.class);
|
||||
|
||||
ClientScopeModel basicScope = KeycloakModelUtils.getClientScopeByName(realm, "basic");
|
||||
if (basicScope == null) {
|
||||
// create 'basic' client scope in the realm.
|
||||
ClientScopeModel basicScope = migrationProvider.addOIDCBasicClientScope(realm);
|
||||
basicScope = migrationProvider.addOIDCBasicClientScope(realm);
|
||||
|
||||
//add basic scope to existing clients
|
||||
realm.getClientsStream().forEach(c-> c.addClientScope(basicScope, true));
|
||||
//add basic scope to all existing OIDC clients
|
||||
session.clients().addClientScopeToAllClients(realm, basicScope, true);
|
||||
}
|
||||
|
||||
// offer a migration for persistent user sessions which was added in KC25
|
||||
session.sessions().migrate(VERSION.toString());
|
||||
|
|
|
@ -273,6 +273,11 @@ public class ClientStorageManager implements ClientProvider {
|
|||
localStorage().removeClientScope(realm, client, clientScope);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addClientScopeToAllClients(RealmModel realm, ClientScopeModel clientScope, boolean defaultClientScope) {
|
||||
localStorage().addClientScopeToAllClients(realm, clientScope, defaultClientScope);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<ClientModel, Set<String>> getAllRedirectUrisOfEnabledClients(RealmModel realm) {
|
||||
return localStorage().getAllRedirectUrisOfEnabledClients(realm);
|
||||
|
|
|
@ -124,6 +124,15 @@ public interface ClientProvider extends ClientLookupProvider, Provider {
|
|||
*/
|
||||
void removeClientScope(RealmModel realm, ClientModel client, ClientScopeModel clientScope);
|
||||
|
||||
/**
|
||||
* Add specified client scope to all non bearer-only clients in the realm, which have same protocol as specified client scope
|
||||
*
|
||||
* @param realm Realm
|
||||
* @param clientScope client scope from the specified realm, which would be added to all clients
|
||||
* @param defaultClientScope If true, then it will be added as "default" client scope. If false, then it will be added as "optional" client scope
|
||||
*/
|
||||
void addClientScopeToAllClients(RealmModel realm, ClientScopeModel clientScope, boolean defaultClientScope);
|
||||
|
||||
/**
|
||||
* Returns a map of (rootUrl, {validRedirectUris}) for all enabled clients.
|
||||
* @param realm
|
||||
|
|
|
@ -18,6 +18,7 @@ package org.keycloak.testsuite.migration;
|
|||
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.keycloak.OAuth2Constants;
|
||||
import org.keycloak.admin.client.resource.ClientResource;
|
||||
import org.keycloak.admin.client.resource.ClientsResource;
|
||||
|
@ -47,6 +48,7 @@ import org.keycloak.models.utils.TimeBasedOTP;
|
|||
import org.keycloak.protocol.oidc.OIDCConfigAttributes;
|
||||
import org.keycloak.protocol.oidc.OIDCLoginProtocolFactory;
|
||||
import org.keycloak.protocol.saml.SamlConfigAttributes;
|
||||
import org.keycloak.protocol.saml.SamlProtocolFactory;
|
||||
import org.keycloak.protocol.saml.util.ArtifactBindingUtils;
|
||||
import org.keycloak.representations.AccessToken;
|
||||
import org.keycloak.representations.RefreshToken;
|
||||
|
@ -422,6 +424,43 @@ public abstract class AbstractMigrationTest extends AbstractKeycloakTest {
|
|||
protected void testMigrationTo25_0_0() {
|
||||
// check that all expected scopes exist in the migrated realm.
|
||||
testRealmDefaultClientScopes(migrationRealm);
|
||||
testClientContainsExpectedClientScopes();
|
||||
}
|
||||
|
||||
|
||||
private void testClientContainsExpectedClientScopes() {
|
||||
// Test OIDC client contains expected client scopes
|
||||
ClientResource migrationTestOIDCClient = ApiUtil.findClientByClientId(migrationRealm, "migration-test-client");
|
||||
List<String> defaultClientScopes = migrationTestOIDCClient.getDefaultClientScopes().stream()
|
||||
.map(ClientScopeRepresentation::getName)
|
||||
.collect(Collectors.toList());
|
||||
List<String> optionalClientScopes = migrationTestOIDCClient.getOptionalClientScopes().stream()
|
||||
.map(ClientScopeRepresentation::getName)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat(defaultClientScopes, Matchers.hasItems(
|
||||
OIDCLoginProtocolFactory.BASIC_SCOPE,
|
||||
OAuth2Constants.SCOPE_PROFILE,
|
||||
OAuth2Constants.SCOPE_EMAIL
|
||||
));
|
||||
assertThat(optionalClientScopes, Matchers.hasItems(
|
||||
OAuth2Constants.SCOPE_ADDRESS,
|
||||
OAuth2Constants.OFFLINE_ACCESS,
|
||||
OAuth2Constants.SCOPE_PHONE
|
||||
));
|
||||
|
||||
// Test SAML client
|
||||
ClientResource migrationTestSAMLClient = ApiUtil.findClientByClientId(migrationRealm, "migration-saml-client");
|
||||
defaultClientScopes = migrationTestSAMLClient.getDefaultClientScopes().stream()
|
||||
.map(ClientScopeRepresentation::getName)
|
||||
.collect(Collectors.toList());
|
||||
optionalClientScopes = migrationTestSAMLClient.getOptionalClientScopes().stream()
|
||||
.map(ClientScopeRepresentation::getName)
|
||||
.collect(Collectors.toList());
|
||||
assertThat(defaultClientScopes, Matchers.hasItems(
|
||||
SamlProtocolFactory.SCOPE_ROLE_LIST
|
||||
));
|
||||
Assert.assertTrue(optionalClientScopes.isEmpty());
|
||||
}
|
||||
|
||||
protected void testDeleteAccount(RealmResource realm) {
|
||||
|
|
Loading…
Reference in a new issue