Skip to content

Commit

Permalink
Fix NPE for component creation when realm unset but config known
Browse files Browse the repository at this point in the history
  • Loading branch information
hmlnarik committed Dec 7, 2021
1 parent 43c46db commit 95614e8
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ public static <T extends Provider> ProviderFactory<T> getComponentFactory(Keyclo
String componentId = config.get("componentId");
if (realmId == null || componentId == null) {
realmId = "ROOT";
ComponentModel cm = new ScopeComponentModel(providerClass, config, spiName);
ComponentModel cm = new ScopeComponentModel(providerClass, config, spiName, realmId);
return factory.getProviderFactory(providerClass, realmId, cm.getId(), k -> cm);
} else {
return factory.getProviderFactory(providerClass, realmId, componentId, componentModelGetter(realmId, componentId));
Expand All @@ -318,14 +318,16 @@ private static class ScopeComponentModel extends ComponentModel {
private final String componentId;
private final String providerId;
private final String providerType;
private final String realmId;
private final Scope config;

public ScopeComponentModel(Class<?> providerClass, Scope baseConfiguration, String spiName) {
public ScopeComponentModel(Class<?> providerClass, Scope baseConfiguration, String spiName, String realmId) {
final String pr = baseConfiguration.get("provider", Config.getProvider(spiName));

this.providerId = pr == null ? "default" : pr;
this.config = baseConfiguration.scope(this.providerId);
this.componentId = spiName + "-" + this.providerId;
this.componentId = spiName + "- " + (realmId == null ? "" : "f:" + realmId + ":") + this.providerId;
this.realmId = realmId;
this.providerType = providerClass.getName();
}

Expand All @@ -349,6 +351,11 @@ public String getId() {
return componentId;
}

@Override
public String getParentId() {
return realmId;
}

@Override
public boolean get(String key, boolean defaultValue) {
return config.getBoolean(key, defaultValue);
Expand All @@ -366,7 +373,6 @@ public int get(String key, int defaultValue) {

@Override
public String get(String key, String defaultValue) {

return config.get(key, defaultValue);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,12 @@ protected <T extends Provider> ProviderFactory<T> initializeFactory(Class<T> cla
newFactory.init(configScope);
newFactory.postInit(factory);

dependentInvalidations.computeIfAbsent(realmId, k -> ConcurrentHashMap.newKeySet()).add(componentId);
if (realmId == null) {
realmId = configScope.getComponentParentId();
}
if (realmId != null) {
dependentInvalidations.computeIfAbsent(realmId, k -> ConcurrentHashMap.newKeySet()).add(componentId);
}
dependentInvalidations.computeIfAbsent(newFactory.getClass(), k -> ConcurrentHashMap.newKeySet()).add(componentId);

return newFactory;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -354,15 +354,12 @@ public <T extends Provider> T getComponentProvider(Class<T> clazz, String compon
Integer hash = clazz.hashCode() + componentId.hashCode();
T provider = (T) providers.get(hash);
final RealmModel realm = getContext().getRealm();
if (realm == null) {
throw new IllegalArgumentException("Realm not set in the context.");
}

// KEYCLOAK-11890 - Avoid using HashMap.computeIfAbsent() to implement logic in outer if() block below,
// since per JDK-8071667 the remapping function should not modify the map during computation. While
// allowed on JDK 1.8, attempt of such a modification throws ConcurrentModificationException with JDK 9+
if (provider == null) {
final String realmId = realm.getId();
final String realmId = realm == null ? null : realm.getId();
ProviderFactory<T> providerFactory = factory.getProviderFactory(clazz, realmId, componentId, modelGetter);
if (providerFactory != null) {
provider = providerFactory.create(this);
Expand Down

0 comments on commit 95614e8

Please sign in to comment.