KEYCLOAK-16077 Remove need for MapStorage.replace
This commit is contained in:
parent
1418c6e938
commit
925f089d62
14 changed files with 53 additions and 62 deletions
|
@ -23,7 +23,7 @@ import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.KeycloakSessionFactory;
|
import org.keycloak.models.KeycloakSessionFactory;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RealmModel.ClientRemovedEvent;
|
import org.keycloak.models.ClientModel.ClientRemovedEvent;
|
||||||
import org.keycloak.representations.idm.authorization.ClientPolicyRepresentation;
|
import org.keycloak.representations.idm.authorization.ClientPolicyRepresentation;
|
||||||
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
|
import org.keycloak.representations.idm.authorization.PolicyRepresentation;
|
||||||
import org.keycloak.util.JsonSerialization;
|
import org.keycloak.util.JsonSerialization;
|
||||||
|
|
|
@ -32,6 +32,7 @@ import org.keycloak.jose.jwk.JWK;
|
||||||
import org.keycloak.keys.PublicKeyStorageProvider;
|
import org.keycloak.keys.PublicKeyStorageProvider;
|
||||||
import org.keycloak.keys.PublicKeyStorageProviderFactory;
|
import org.keycloak.keys.PublicKeyStorageProviderFactory;
|
||||||
import org.keycloak.keys.PublicKeyStorageUtils;
|
import org.keycloak.keys.PublicKeyStorageUtils;
|
||||||
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.KeycloakSessionFactory;
|
import org.keycloak.models.KeycloakSessionFactory;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
|
@ -117,15 +118,15 @@ public class InfinispanPublicKeyStorageProviderFactory implements PublicKeyStora
|
||||||
private SessionAndKeyHolder getCacheKeyToInvalidate(ProviderEvent event) {
|
private SessionAndKeyHolder getCacheKeyToInvalidate(ProviderEvent event) {
|
||||||
ArrayList<String> cacheKeys = new ArrayList<>();
|
ArrayList<String> cacheKeys = new ArrayList<>();
|
||||||
String cacheKey = null;
|
String cacheKey = null;
|
||||||
if (event instanceof RealmModel.ClientUpdatedEvent) {
|
if (event instanceof ClientModel.ClientUpdatedEvent) {
|
||||||
RealmModel.ClientUpdatedEvent eventt = (RealmModel.ClientUpdatedEvent) event;
|
ClientModel.ClientUpdatedEvent eventt = (ClientModel.ClientUpdatedEvent) event;
|
||||||
cacheKey = PublicKeyStorageUtils.getClientModelCacheKey(eventt.getUpdatedClient().getRealm().getId(), eventt.getUpdatedClient().getId(), JWK.Use.SIG);
|
cacheKey = PublicKeyStorageUtils.getClientModelCacheKey(eventt.getUpdatedClient().getRealm().getId(), eventt.getUpdatedClient().getId(), JWK.Use.SIG);
|
||||||
cacheKeys.add(cacheKey);
|
cacheKeys.add(cacheKey);
|
||||||
cacheKey = PublicKeyStorageUtils.getClientModelCacheKey(eventt.getUpdatedClient().getRealm().getId(), eventt.getUpdatedClient().getId(), JWK.Use.ENCRYPTION);
|
cacheKey = PublicKeyStorageUtils.getClientModelCacheKey(eventt.getUpdatedClient().getRealm().getId(), eventt.getUpdatedClient().getId(), JWK.Use.ENCRYPTION);
|
||||||
cacheKeys.add(cacheKey);
|
cacheKeys.add(cacheKey);
|
||||||
return new SessionAndKeyHolder(eventt.getKeycloakSession(), cacheKeys);
|
return new SessionAndKeyHolder(eventt.getKeycloakSession(), cacheKeys);
|
||||||
} else if (event instanceof RealmModel.ClientRemovedEvent) {
|
} else if (event instanceof ClientModel.ClientRemovedEvent) {
|
||||||
RealmModel.ClientRemovedEvent eventt = (RealmModel.ClientRemovedEvent) event;
|
ClientModel.ClientRemovedEvent eventt = (ClientModel.ClientRemovedEvent) event;
|
||||||
cacheKey = PublicKeyStorageUtils.getClientModelCacheKey(eventt.getClient().getRealm().getId(), eventt.getClient().getId(), JWK.Use.SIG);
|
cacheKey = PublicKeyStorageUtils.getClientModelCacheKey(eventt.getClient().getRealm().getId(), eventt.getClient().getId(), JWK.Use.SIG);
|
||||||
cacheKeys.add(cacheKey);
|
cacheKeys.add(cacheKey);
|
||||||
cacheKey = PublicKeyStorageUtils.getClientModelCacheKey(eventt.getClient().getRealm().getId(), eventt.getClient().getId(), JWK.Use.ENCRYPTION);
|
cacheKey = PublicKeyStorageUtils.getClientModelCacheKey(eventt.getClient().getRealm().getId(), eventt.getClient().getId(), JWK.Use.ENCRYPTION);
|
||||||
|
|
|
@ -513,8 +513,7 @@ public class ClientAdapter implements ClientModel, JpaModel<ClientEntity> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateClient() {
|
public void updateClient() {
|
||||||
em.flush();
|
session.getKeycloakSessionFactory().publish(new ClientModel.ClientUpdatedEvent() {
|
||||||
session.getKeycloakSessionFactory().publish(new RealmModel.ClientUpdatedEvent() {
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClientModel getUpdatedClient() {
|
public ClientModel getUpdatedClient() {
|
||||||
|
|
|
@ -624,6 +624,10 @@ public class JpaRealmProvider implements RealmProvider, ClientProvider, GroupPro
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClientModel addClient(RealmModel realm, String id, String clientId) {
|
public ClientModel addClient(RealmModel realm, String id, String clientId) {
|
||||||
|
if (id == null) {
|
||||||
|
id = KeycloakModelUtils.generateId();
|
||||||
|
}
|
||||||
|
|
||||||
if (clientId == null) {
|
if (clientId == null) {
|
||||||
clientId = id;
|
clientId = id;
|
||||||
}
|
}
|
||||||
|
@ -638,16 +642,10 @@ public class JpaRealmProvider implements RealmProvider, ClientProvider, GroupPro
|
||||||
RealmEntity realmRef = em.getReference(RealmEntity.class, realm.getId());
|
RealmEntity realmRef = em.getReference(RealmEntity.class, realm.getId());
|
||||||
entity.setRealm(realmRef);
|
entity.setRealm(realmRef);
|
||||||
em.persist(entity);
|
em.persist(entity);
|
||||||
em.flush();
|
|
||||||
final ClientModel resource = new ClientAdapter(realm, em, session, entity);
|
final ClientModel resource = new ClientAdapter(realm, em, session, entity);
|
||||||
|
|
||||||
em.flush();
|
session.getKeycloakSessionFactory().publish((ClientModel.ClientCreationEvent) () -> resource);
|
||||||
session.getKeycloakSessionFactory().publish(new RealmModel.ClientCreationEvent() {
|
|
||||||
@Override
|
|
||||||
public ClientModel getCreatedClient() {
|
|
||||||
return resource;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return resource;
|
return resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -745,7 +743,7 @@ public class JpaRealmProvider implements RealmProvider, ClientProvider, GroupPro
|
||||||
|
|
||||||
ClientEntity clientEntity = em.find(ClientEntity.class, id, LockModeType.PESSIMISTIC_WRITE);
|
ClientEntity clientEntity = em.find(ClientEntity.class, id, LockModeType.PESSIMISTIC_WRITE);
|
||||||
|
|
||||||
session.getKeycloakSessionFactory().publish(new RealmModel.ClientRemovedEvent() {
|
session.getKeycloakSessionFactory().publish(new ClientModel.ClientRemovedEvent() {
|
||||||
@Override
|
@Override
|
||||||
public ClientModel getClient() {
|
public ClientModel getClient() {
|
||||||
return client;
|
return client;
|
||||||
|
|
|
@ -19,12 +19,12 @@ package org.keycloak.models.map.client;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
|
import org.keycloak.models.ClientModel.ClientUpdatedEvent;
|
||||||
import org.keycloak.models.ClientProvider;
|
import org.keycloak.models.ClientProvider;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.ModelDuplicateException;
|
import org.keycloak.models.ModelDuplicateException;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
|
|
||||||
import org.keycloak.models.RealmModel.ClientUpdatedEvent;
|
|
||||||
import org.keycloak.models.map.storage.MapKeycloakTransaction;
|
import org.keycloak.models.map.storage.MapKeycloakTransaction;
|
||||||
import org.keycloak.models.map.common.Serialization;
|
import org.keycloak.models.map.common.Serialization;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
@ -71,7 +71,7 @@ public class MapClientProvider implements ClientProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClientUpdatedEvent clientUpdatedEvent(ClientModel c) {
|
private ClientUpdatedEvent clientUpdatedEvent(ClientModel c) {
|
||||||
return new RealmModel.ClientUpdatedEvent() {
|
return new ClientModel.ClientUpdatedEvent() {
|
||||||
@Override
|
@Override
|
||||||
public ClientModel getUpdatedClient() {
|
public ClientModel getUpdatedClient() {
|
||||||
return c;
|
return c;
|
||||||
|
@ -96,8 +96,6 @@ public class MapClientProvider implements ClientProvider {
|
||||||
return origEntity -> new MapClientAdapter(session, realm, registerEntityForChanges(origEntity)) {
|
return origEntity -> new MapClientAdapter(session, realm, registerEntityForChanges(origEntity)) {
|
||||||
@Override
|
@Override
|
||||||
public void updateClient() {
|
public void updateClient() {
|
||||||
// commit
|
|
||||||
MapClientProvider.this.tx.replace(entity.getId(), this.entity);
|
|
||||||
session.getKeycloakSessionFactory().publish(clientUpdatedEvent(this));
|
session.getKeycloakSessionFactory().publish(clientUpdatedEvent(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,7 +176,7 @@ public class MapClientProvider implements ClientProvider {
|
||||||
final ClientModel resource = entityToAdapterFunc(realm).apply(entity);
|
final ClientModel resource = entityToAdapterFunc(realm).apply(entity);
|
||||||
|
|
||||||
// TODO: Sending an event should be extracted to store layer
|
// TODO: Sending an event should be extracted to store layer
|
||||||
session.getKeycloakSessionFactory().publish((RealmModel.ClientCreationEvent) () -> resource);
|
session.getKeycloakSessionFactory().publish((ClientModel.ClientCreationEvent) () -> resource);
|
||||||
resource.updateClient(); // This is actualy strange contract - it should be the store code to call updateClient
|
resource.updateClient(); // This is actualy strange contract - it should be the store code to call updateClient
|
||||||
|
|
||||||
return resource;
|
return resource;
|
||||||
|
@ -214,7 +212,7 @@ public class MapClientProvider implements ClientProvider {
|
||||||
session.users().preRemove(realm, client);
|
session.users().preRemove(realm, client);
|
||||||
session.roles().removeRoles(client);
|
session.roles().removeRoles(client);
|
||||||
|
|
||||||
session.getKeycloakSessionFactory().publish(new RealmModel.ClientRemovedEvent() {
|
session.getKeycloakSessionFactory().publish(new ClientModel.ClientRemovedEvent() {
|
||||||
@Override
|
@Override
|
||||||
public ClientModel getClient() {
|
public ClientModel getClient() {
|
||||||
return client;
|
return client;
|
||||||
|
|
|
@ -65,17 +65,6 @@ public class MapKeycloakTransaction<K, V> implements KeycloakTransaction {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
REPLACE {
|
|
||||||
@Override
|
|
||||||
protected <K, V> MapTaskWithValue<K, V> taskFor(K key, V value) {
|
|
||||||
return new MapTaskWithValue<K, V>(value) {
|
|
||||||
@Override
|
|
||||||
public void execute(MapStorage<K, V> map) {
|
|
||||||
map.replace(key, getValue());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
;
|
;
|
||||||
|
|
||||||
protected abstract <K, V> MapTaskWithValue<K, V> taskFor(K key, V value);
|
protected abstract <K, V> MapTaskWithValue<K, V> taskFor(K key, V value);
|
||||||
|
@ -179,10 +168,6 @@ public class MapKeycloakTransaction<K, V> implements KeycloakTransaction {
|
||||||
tasks.merge(taskKey, op, MapTaskCompose::new);
|
tasks.merge(taskKey, op, MapTaskCompose::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void replace(K key, V value) {
|
|
||||||
addTask(MapOperation.REPLACE, key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void remove(K key) {
|
public void remove(K key) {
|
||||||
addTask(MapOperation.REMOVE, key, null);
|
addTask(MapOperation.REMOVE, key, null);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,8 +34,6 @@ public interface MapStorage<K, V> {
|
||||||
|
|
||||||
V remove(K key);
|
V remove(K key);
|
||||||
|
|
||||||
V replace(K key, V value);
|
|
||||||
|
|
||||||
Set<K> keySet();
|
Set<K> keySet();
|
||||||
|
|
||||||
Set<Map.Entry<K,V>> entrySet();
|
Set<Map.Entry<K,V>> entrySet();
|
||||||
|
|
|
@ -28,7 +28,7 @@ import org.keycloak.authorization.store.syncronization.Synchronizer;
|
||||||
import org.keycloak.authorization.store.syncronization.UserSynchronizer;
|
import org.keycloak.authorization.store.syncronization.UserSynchronizer;
|
||||||
import org.keycloak.models.GroupModel;
|
import org.keycloak.models.GroupModel;
|
||||||
import org.keycloak.models.KeycloakSessionFactory;
|
import org.keycloak.models.KeycloakSessionFactory;
|
||||||
import org.keycloak.models.RealmModel.ClientRemovedEvent;
|
import org.keycloak.models.ClientModel.ClientRemovedEvent;
|
||||||
import org.keycloak.models.RealmModel.RealmRemovedEvent;
|
import org.keycloak.models.RealmModel.RealmRemovedEvent;
|
||||||
import org.keycloak.models.UserModel.UserRemovedEvent;
|
import org.keycloak.models.UserModel.UserRemovedEvent;
|
||||||
import org.keycloak.provider.ProviderEvent;
|
import org.keycloak.provider.ProviderEvent;
|
||||||
|
|
|
@ -30,7 +30,7 @@ import org.keycloak.authorization.policy.provider.PolicyProviderFactory;
|
||||||
import org.keycloak.authorization.store.ResourceServerStore;
|
import org.keycloak.authorization.store.ResourceServerStore;
|
||||||
import org.keycloak.authorization.store.StoreFactory;
|
import org.keycloak.authorization.store.StoreFactory;
|
||||||
import org.keycloak.models.KeycloakSessionFactory;
|
import org.keycloak.models.KeycloakSessionFactory;
|
||||||
import org.keycloak.models.RealmModel.ClientRemovedEvent;
|
import org.keycloak.models.ClientModel.ClientRemovedEvent;
|
||||||
import org.keycloak.provider.ProviderFactory;
|
import org.keycloak.provider.ProviderFactory;
|
||||||
import org.keycloak.representations.idm.authorization.ClientPolicyRepresentation;
|
import org.keycloak.representations.idm.authorization.ClientPolicyRepresentation;
|
||||||
|
|
||||||
|
|
|
@ -46,8 +46,8 @@ public abstract class AbstractLoginProtocolFactory implements LoginProtocolFacto
|
||||||
factory.register(new ProviderEventListener() {
|
factory.register(new ProviderEventListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onEvent(ProviderEvent event) {
|
public void onEvent(ProviderEvent event) {
|
||||||
if (event instanceof RealmModel.ClientCreationEvent) {
|
if (event instanceof ClientModel.ClientCreationEvent) {
|
||||||
ClientModel client = ((RealmModel.ClientCreationEvent)event).getCreatedClient();
|
ClientModel client = ((ClientModel.ClientCreationEvent)event).getCreatedClient();
|
||||||
addDefaultClientScopes(client.getRealm(), client);
|
addDefaultClientScopes(client.getRealm(), client);
|
||||||
addDefaults(client);
|
addDefaults(client);
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,7 +120,7 @@ public abstract class AbstractClientStorageAdapter extends UnsupportedOperations
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void updateClient() {
|
public void updateClient() {
|
||||||
session.getKeycloakSessionFactory().publish(new RealmModel.ClientUpdatedEvent() {
|
session.getKeycloakSessionFactory().publish(new ClientModel.ClientUpdatedEvent() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClientModel getUpdatedClient() {
|
public ClientModel getUpdatedClient() {
|
||||||
|
|
|
@ -21,6 +21,8 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.keycloak.common.util.ObjectUtil;
|
import org.keycloak.common.util.ObjectUtil;
|
||||||
|
import org.keycloak.provider.ProviderEvent;
|
||||||
|
import org.keycloak.provider.ProviderEventManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
@ -34,10 +36,35 @@ public interface ClientModel extends ClientScopeModel, RoleContainerModel, Prot
|
||||||
String PUBLIC_KEY = "publicKey";
|
String PUBLIC_KEY = "publicKey";
|
||||||
String X509CERTIFICATE = "X509Certificate";
|
String X509CERTIFICATE = "X509Certificate";
|
||||||
|
|
||||||
|
interface ClientCreationEvent extends ProviderEvent {
|
||||||
|
ClientModel getCreatedClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called also during client creation after client is fully initialized (including all attributes etc)
|
||||||
|
interface ClientUpdatedEvent extends ProviderEvent {
|
||||||
|
ClientModel getUpdatedClient();
|
||||||
|
KeycloakSession getKeycloakSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ClientRemovedEvent extends ProviderEvent {
|
||||||
|
ClientModel getClient();
|
||||||
|
KeycloakSession getKeycloakSession();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores the current state of the client immediately to the underlying store, similarly to a commit.
|
* Notifies other providers that this client has been updated.
|
||||||
|
* <p>
|
||||||
|
* After a client is updated, providers can register for {@link ClientUpdatedEvent}.
|
||||||
|
* The setters in this model do not send an update for individual updates of the model.
|
||||||
|
* This method is here to allow for sending this event for this client,
|
||||||
|
* allowsing for to group multiple changes of a client and signal that
|
||||||
|
* all the changes in this client have been performed.
|
||||||
*
|
*
|
||||||
* @deprecated Do not use, to be removed
|
* @deprecated Do not use, to be removed
|
||||||
|
*
|
||||||
|
* @see ProviderEvent
|
||||||
|
* @see ProviderEventManager
|
||||||
|
* @see ClientUpdatedEvent
|
||||||
*/
|
*/
|
||||||
void updateClient();
|
void updateClient();
|
||||||
|
|
||||||
|
|
|
@ -52,21 +52,6 @@ public interface RealmModel extends RoleContainerModel {
|
||||||
KeycloakSession getKeycloakSession();
|
KeycloakSession getKeycloakSession();
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ClientCreationEvent extends ProviderEvent {
|
|
||||||
ClientModel getCreatedClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called also during client creation after client is fully initialized (including all attributes etc)
|
|
||||||
interface ClientUpdatedEvent extends ProviderEvent {
|
|
||||||
ClientModel getUpdatedClient();
|
|
||||||
KeycloakSession getKeycloakSession();
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ClientRemovedEvent extends ProviderEvent {
|
|
||||||
ClientModel getClient();
|
|
||||||
KeycloakSession getKeycloakSession();
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IdentityProviderUpdatedEvent extends ProviderEvent {
|
interface IdentityProviderUpdatedEvent extends ProviderEvent {
|
||||||
RealmModel getRealm();
|
RealmModel getRealm();
|
||||||
IdentityProviderModel getUpdatedIdentityProvider();
|
IdentityProviderModel getUpdatedIdentityProvider();
|
||||||
|
|
|
@ -69,8 +69,8 @@ public class AdminPermissions {
|
||||||
realm = (RealmModel)role.getContainer();
|
realm = (RealmModel)role.getContainer();
|
||||||
}
|
}
|
||||||
management(cast.getKeycloakSession(), realm).roles().setPermissionsEnabled(role, false);
|
management(cast.getKeycloakSession(), realm).roles().setPermissionsEnabled(role, false);
|
||||||
} else if (event instanceof RealmModel.ClientRemovedEvent) {
|
} else if (event instanceof ClientModel.ClientRemovedEvent) {
|
||||||
RealmModel.ClientRemovedEvent cast = (RealmModel.ClientRemovedEvent)event;
|
ClientModel.ClientRemovedEvent cast = (ClientModel.ClientRemovedEvent)event;
|
||||||
management(cast.getKeycloakSession(), cast.getClient().getRealm()).clients().setPermissionsEnabled(cast.getClient(), false);
|
management(cast.getKeycloakSession(), cast.getClient().getRealm()).clients().setPermissionsEnabled(cast.getClient(), false);
|
||||||
} else if (event instanceof GroupModel.GroupRemovedEvent) {
|
} else if (event instanceof GroupModel.GroupRemovedEvent) {
|
||||||
GroupModel.GroupRemovedEvent cast = (GroupModel.GroupRemovedEvent)event;
|
GroupModel.GroupRemovedEvent cast = (GroupModel.GroupRemovedEvent)event;
|
||||||
|
|
Loading…
Reference in a new issue