Client Scope updates are not replicated between Keycloak nodes

Fixes #33731

Signed-off-by: Pedro Ruivo <pruivo@redhat.com>
This commit is contained in:
Pedro Ruivo 2024-10-23 15:59:37 +01:00 committed by Alexander Schwartz
parent e41553bcfb
commit 84f4bd8af1
2 changed files with 108 additions and 0 deletions

View file

@ -264,6 +264,7 @@ public class RealmCacheSession implements CacheRealmProvider {
public void registerClientScopeInvalidation(String id, String realmId) {
invalidateClientScope(id);
cache.clientScopeUpdated(realmId, invalidations);
invalidationEvents.add(new CacheKeyInvalidatedEvent(id));
}
private void invalidateClientScope(String id) {

View file

@ -0,0 +1,107 @@
/*
* Copyright 2024 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.cluster;
import java.util.Map;
import jakarta.ws.rs.NotFoundException;
import org.keycloak.admin.client.resource.ClientScopeResource;
import org.keycloak.admin.client.resource.ClientScopesResource;
import org.keycloak.representations.idm.ClientScopeRepresentation;
import org.keycloak.testsuite.admin.ApiUtil;
import org.keycloak.testsuite.arquillian.ContainerInfo;
import static org.junit.Assert.assertNull;
public class ClientScopeInvalidationClusterTest extends AbstractInvalidationClusterTestWithTestRealm<ClientScopeRepresentation, ClientScopeResource> {
@Override
protected ClientScopeRepresentation createTestEntityRepresentation() {
var clientScope = new ClientScopeRepresentation();
clientScope.setName("client-scope-name");
clientScope.setDescription("client-scope-description");
clientScope.setProtocol("openid-connect");
clientScope.setAttributes(Map.of("a", "b", "c", "d"));
return clientScope;
}
@Override
protected ClientScopeResource entityResource(ClientScopeRepresentation testEntity, ContainerInfo node) {
return entityResource(testEntity.getId(), node);
}
@Override
protected ClientScopeResource entityResource(String idOrName, ContainerInfo node) {
return clientScopes(node).get(idOrName);
}
@Override
protected ClientScopeRepresentation createEntity(ClientScopeRepresentation testEntity, ContainerInfo node) {
try (var rsp = clientScopes(node).create(testEntity)) {
testEntity.setId(ApiUtil.getCreatedId(rsp));
}
return readEntity(testEntity, node);
}
@Override
protected ClientScopeRepresentation readEntity(ClientScopeRepresentation entity, ContainerInfo node) {
try {
return entityResource(entity, node).toRepresentation();
} catch (NotFoundException nfe) {
// expected when client scope doesn't exist
return null;
}
}
@Override
protected ClientScopeRepresentation updateEntity(ClientScopeRepresentation entity, ContainerInfo node) {
entityResource(entity, node).update(entity);
return readEntity(entity, node);
}
@Override
protected void deleteEntity(ClientScopeRepresentation testEntity, ContainerInfo node) {
entityResource(testEntity, node).remove();
assertNull(readEntity(testEntity, node));
}
@Override
protected ClientScopeRepresentation testEntityUpdates(ClientScopeRepresentation testEntity, boolean backendFailover) {
// groupname
testEntity.setName("name-updated");
testEntity = updateEntityOnCurrentFailNode(testEntity, "name");
verifyEntityUpdateDuringFailover(testEntity, backendFailover);
testEntity.setProtocol("protocol-updated");
testEntity = updateEntityOnCurrentFailNode(testEntity, "protocol");
verifyEntityUpdateDuringFailover(testEntity, backendFailover);
testEntity.setDescription("description-updated");
testEntity = updateEntityOnCurrentFailNode(testEntity, "description");
verifyEntityUpdateDuringFailover(testEntity, backendFailover);
testEntity.setAttributes(Map.of("updated", "updated"));
testEntity = updateEntityOnCurrentFailNode(testEntity, "attributes");
verifyEntityUpdateDuringFailover(testEntity, backendFailover);
return testEntity;
}
private ClientScopesResource clientScopes(ContainerInfo node) {
return getAdminClientFor(node).realm(testRealmName).clientScopes();
}
}