KEYCLOAK-18747 Turn MapClientEntity into interface + introduce delegates
Given that the Map*Entity is turned into an interface, it makes more sense to use non-primitive types to allow for null values. This enables signalizing that an entity does not define a particular value, and builds a base for definition of instances with defaults: If a value is not present in the queried instance (i.e. is `null`), the value would be obtained from a delegate containing the defaults.
This commit is contained in:
parent
2c8d4ad9b4
commit
009d4ca445
7 changed files with 1272 additions and 454 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2020 Red Hat, Inc. and/or its affiliates
|
||||
* Copyright 2021 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");
|
||||
|
@ -19,460 +19,177 @@ package org.keycloak.models.map.client;
|
|||
import org.keycloak.models.ProtocolMapperModel;
|
||||
import org.keycloak.models.map.common.AbstractEntity;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hmlnarik
|
||||
*/
|
||||
public class MapClientEntity<K> implements AbstractEntity<K> {
|
||||
|
||||
private K id;
|
||||
private String realmId;
|
||||
|
||||
private String clientId;
|
||||
private String name;
|
||||
private String description;
|
||||
private Set<String> redirectUris = new HashSet<>();
|
||||
private boolean enabled;
|
||||
private boolean alwaysDisplayInConsole;
|
||||
private String clientAuthenticatorType;
|
||||
private String secret;
|
||||
private String registrationToken;
|
||||
private String protocol;
|
||||
private Map<String, List<String>> attributes = new HashMap<>();
|
||||
private Map<String, String> authFlowBindings = new HashMap<>();
|
||||
private boolean publicClient;
|
||||
private boolean fullScopeAllowed;
|
||||
private boolean frontchannelLogout;
|
||||
private int notBefore;
|
||||
private Set<String> scope = new HashSet<>();
|
||||
private Set<String> webOrigins = new HashSet<>();
|
||||
private Map<String, ProtocolMapperModel> protocolMappers = new HashMap<>();
|
||||
private Map<String, Boolean> clientScopes = new HashMap<>();
|
||||
private Set<String> scopeMappings = new LinkedHashSet<>();
|
||||
private boolean surrogateAuthRequired;
|
||||
private String managementUrl;
|
||||
private String rootUrl;
|
||||
private String baseUrl;
|
||||
private boolean bearerOnly;
|
||||
private boolean consentRequired;
|
||||
private boolean standardFlowEnabled;
|
||||
private boolean implicitFlowEnabled;
|
||||
private boolean directAccessGrantsEnabled;
|
||||
private boolean serviceAccountsEnabled;
|
||||
private int nodeReRegistrationTimeout;
|
||||
|
||||
/**
|
||||
* Flag signalizing that any of the setters has been meaningfully used.
|
||||
*/
|
||||
protected boolean updated;
|
||||
|
||||
protected MapClientEntity() {
|
||||
this.id = null;
|
||||
this.realmId = null;
|
||||
}
|
||||
public interface MapClientEntity<K> extends AbstractEntity<K> {
|
||||
|
||||
public MapClientEntity(K id, String realmId) {
|
||||
Objects.requireNonNull(id, "id");
|
||||
Objects.requireNonNull(realmId, "realmId");
|
||||
void addClientScope(String id, Boolean defaultScope);
|
||||
|
||||
this.id = id;
|
||||
this.realmId = realmId;
|
||||
}
|
||||
ProtocolMapperModel addProtocolMapper(ProtocolMapperModel model);
|
||||
|
||||
@Override
|
||||
public K getId() {
|
||||
return this.id;
|
||||
}
|
||||
void addRedirectUri(String redirectUri);
|
||||
|
||||
@Override
|
||||
public boolean isUpdated() {
|
||||
return this.updated;
|
||||
}
|
||||
void addScopeMapping(String id);
|
||||
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
void addWebOrigin(String webOrigin);
|
||||
|
||||
public void setClientId(String clientId) {
|
||||
this.updated |= ! Objects.equals(this.clientId, clientId);
|
||||
this.clientId = clientId;
|
||||
}
|
||||
void deleteScopeMapping(String id);
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
List<String> getAttribute(String name);
|
||||
|
||||
public void setName(String name) {
|
||||
this.updated |= ! Objects.equals(this.name, name);
|
||||
this.name = name;
|
||||
}
|
||||
Map<String, List<String>> getAttributes();
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
Map<String, String> getAuthFlowBindings();
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.updated |= ! Objects.equals(this.description, description);
|
||||
this.description = description;
|
||||
}
|
||||
String getAuthenticationFlowBindingOverride(String binding);
|
||||
|
||||
public Set<String> getRedirectUris() {
|
||||
return redirectUris;
|
||||
}
|
||||
Map<String, String> getAuthenticationFlowBindingOverrides();
|
||||
|
||||
public void setRedirectUris(Set<String> redirectUris) {
|
||||
this.updated |= ! Objects.equals(this.redirectUris, redirectUris);
|
||||
this.redirectUris = redirectUris;
|
||||
}
|
||||
String getBaseUrl();
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.updated |= ! Objects.equals(this.enabled, enabled);
|
||||
this.enabled = enabled;
|
||||
}
|
||||
String getClientAuthenticatorType();
|
||||
|
||||
public boolean isAlwaysDisplayInConsole() {
|
||||
return alwaysDisplayInConsole;
|
||||
}
|
||||
|
||||
public void setAlwaysDisplayInConsole(boolean alwaysDisplayInConsole) {
|
||||
this.updated |= ! Objects.equals(this.alwaysDisplayInConsole, alwaysDisplayInConsole);
|
||||
this.alwaysDisplayInConsole = alwaysDisplayInConsole;
|
||||
}
|
||||
String getClientId();
|
||||
|
||||
public String getClientAuthenticatorType() {
|
||||
return clientAuthenticatorType;
|
||||
}
|
||||
|
||||
public void setClientAuthenticatorType(String clientAuthenticatorType) {
|
||||
this.updated |= ! Objects.equals(this.clientAuthenticatorType, clientAuthenticatorType);
|
||||
this.clientAuthenticatorType = clientAuthenticatorType;
|
||||
}
|
||||
|
||||
public String getSecret() {
|
||||
return secret;
|
||||
}
|
||||
Stream<String> getClientScopes(boolean defaultScope);
|
||||
|
||||
public void setSecret(String secret) {
|
||||
this.updated |= ! Objects.equals(this.secret, secret);
|
||||
this.secret = secret;
|
||||
}
|
||||
String getDescription();
|
||||
|
||||
public String getRegistrationToken() {
|
||||
return registrationToken;
|
||||
}
|
||||
String getManagementUrl();
|
||||
|
||||
public void setRegistrationToken(String registrationToken) {
|
||||
this.updated |= ! Objects.equals(this.registrationToken, registrationToken);
|
||||
this.registrationToken = registrationToken;
|
||||
}
|
||||
String getName();
|
||||
|
||||
public String getProtocol() {
|
||||
return protocol;
|
||||
}
|
||||
int getNodeReRegistrationTimeout();
|
||||
|
||||
public void setProtocol(String protocol) {
|
||||
this.updated |= ! Objects.equals(this.protocol, protocol);
|
||||
this.protocol = protocol;
|
||||
}
|
||||
int getNotBefore();
|
||||
|
||||
public Map<String, List<String>> getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
String getProtocol();
|
||||
|
||||
public void setAttribute(String name, List<String> values) {
|
||||
this.updated |= ! Objects.equals(this.attributes.put(name, values), values);
|
||||
}
|
||||
ProtocolMapperModel getProtocolMapperById(String id);
|
||||
|
||||
public Map<String, String> getAuthFlowBindings() {
|
||||
return authFlowBindings;
|
||||
}
|
||||
Collection<ProtocolMapperModel> getProtocolMappers();
|
||||
|
||||
public void setAuthFlowBindings(Map<String, String> authFlowBindings) {
|
||||
this.updated |= ! Objects.equals(this.authFlowBindings, authFlowBindings);
|
||||
this.authFlowBindings = authFlowBindings;
|
||||
}
|
||||
String getRealmId();
|
||||
|
||||
public boolean isPublicClient() {
|
||||
return publicClient;
|
||||
}
|
||||
Set<String> getRedirectUris();
|
||||
|
||||
public void setPublicClient(boolean publicClient) {
|
||||
this.updated |= ! Objects.equals(this.publicClient, publicClient);
|
||||
this.publicClient = publicClient;
|
||||
}
|
||||
String getRegistrationToken();
|
||||
|
||||
public boolean isFullScopeAllowed() {
|
||||
return fullScopeAllowed;
|
||||
}
|
||||
String getRootUrl();
|
||||
|
||||
public void setFullScopeAllowed(boolean fullScopeAllowed) {
|
||||
this.updated |= ! Objects.equals(this.fullScopeAllowed, fullScopeAllowed);
|
||||
this.fullScopeAllowed = fullScopeAllowed;
|
||||
}
|
||||
Set<String> getScope();
|
||||
|
||||
public boolean isFrontchannelLogout() {
|
||||
return frontchannelLogout;
|
||||
}
|
||||
Collection<String> getScopeMappings();
|
||||
|
||||
public void setFrontchannelLogout(boolean frontchannelLogout) {
|
||||
this.updated |= ! Objects.equals(this.frontchannelLogout, frontchannelLogout);
|
||||
this.frontchannelLogout = frontchannelLogout;
|
||||
}
|
||||
String getSecret();
|
||||
|
||||
public int getNotBefore() {
|
||||
return notBefore;
|
||||
}
|
||||
Set<String> getWebOrigins();
|
||||
|
||||
public void setNotBefore(int notBefore) {
|
||||
this.updated |= ! Objects.equals(this.notBefore, notBefore);
|
||||
this.notBefore = notBefore;
|
||||
}
|
||||
Boolean isAlwaysDisplayInConsole();
|
||||
|
||||
public Set<String> getScope() {
|
||||
return scope;
|
||||
}
|
||||
Boolean isBearerOnly();
|
||||
|
||||
public void setScope(Set<String> scope) {
|
||||
this.updated |= ! Objects.equals(this.scope, scope);
|
||||
this.scope.clear();
|
||||
this.scope.addAll(scope);
|
||||
}
|
||||
Boolean isConsentRequired();
|
||||
|
||||
public Set<String> getWebOrigins() {
|
||||
return webOrigins;
|
||||
}
|
||||
Boolean isDirectAccessGrantsEnabled();
|
||||
|
||||
public void setWebOrigins(Set<String> webOrigins) {
|
||||
this.updated |= ! Objects.equals(this.webOrigins, webOrigins);
|
||||
this.webOrigins.clear();
|
||||
this.webOrigins.addAll(webOrigins);
|
||||
}
|
||||
Boolean isEnabled();
|
||||
|
||||
public ProtocolMapperModel addProtocolMapper(ProtocolMapperModel model) {
|
||||
Objects.requireNonNull(model.getId(), "protocolMapper.id");
|
||||
updated = true;
|
||||
this.protocolMappers.put(model.getId(), model);
|
||||
return model;
|
||||
}
|
||||
Boolean isFrontchannelLogout();
|
||||
|
||||
public Collection<ProtocolMapperModel> getProtocolMappers() {
|
||||
return protocolMappers.values();
|
||||
}
|
||||
Boolean isFullScopeAllowed();
|
||||
|
||||
public void updateProtocolMapper(String id, ProtocolMapperModel mapping) {
|
||||
updated = true;
|
||||
protocolMappers.put(id, mapping);
|
||||
}
|
||||
Boolean isImplicitFlowEnabled();
|
||||
|
||||
public void removeProtocolMapper(String id) {
|
||||
updated |= protocolMappers.remove(id) != null;
|
||||
}
|
||||
Boolean isPublicClient();
|
||||
|
||||
public void setProtocolMappers(Collection<ProtocolMapperModel> protocolMappers) {
|
||||
this.updated |= ! Objects.equals(this.protocolMappers, protocolMappers);
|
||||
this.protocolMappers.clear();
|
||||
this.protocolMappers.putAll(protocolMappers.stream().collect(Collectors.toMap(ProtocolMapperModel::getId, Function.identity())));
|
||||
}
|
||||
Boolean isServiceAccountsEnabled();
|
||||
|
||||
public ProtocolMapperModel getProtocolMapperById(String id) {
|
||||
return id == null ? null : protocolMappers.get(id);
|
||||
}
|
||||
Boolean isStandardFlowEnabled();
|
||||
|
||||
public boolean isSurrogateAuthRequired() {
|
||||
return surrogateAuthRequired;
|
||||
}
|
||||
Boolean isSurrogateAuthRequired();
|
||||
|
||||
public void setSurrogateAuthRequired(boolean surrogateAuthRequired) {
|
||||
this.updated |= ! Objects.equals(this.surrogateAuthRequired, surrogateAuthRequired);
|
||||
this.surrogateAuthRequired = surrogateAuthRequired;
|
||||
}
|
||||
void removeAttribute(String name);
|
||||
|
||||
public String getManagementUrl() {
|
||||
return managementUrl;
|
||||
}
|
||||
void removeAuthenticationFlowBindingOverride(String binding);
|
||||
|
||||
public void setManagementUrl(String managementUrl) {
|
||||
this.updated |= ! Objects.equals(this.managementUrl, managementUrl);
|
||||
this.managementUrl = managementUrl;
|
||||
}
|
||||
void removeClientScope(String id);
|
||||
|
||||
public String getRootUrl() {
|
||||
return rootUrl;
|
||||
}
|
||||
void removeProtocolMapper(String id);
|
||||
|
||||
public void setRootUrl(String rootUrl) {
|
||||
this.updated |= ! Objects.equals(this.rootUrl, rootUrl);
|
||||
this.rootUrl = rootUrl;
|
||||
}
|
||||
void removeRedirectUri(String redirectUri);
|
||||
|
||||
public String getBaseUrl() {
|
||||
return baseUrl;
|
||||
}
|
||||
void removeWebOrigin(String webOrigin);
|
||||
|
||||
public void setBaseUrl(String baseUrl) {
|
||||
this.updated |= ! Objects.equals(this.baseUrl, baseUrl);
|
||||
this.baseUrl = baseUrl;
|
||||
}
|
||||
void setAlwaysDisplayInConsole(Boolean alwaysDisplayInConsole);
|
||||
|
||||
public boolean isBearerOnly() {
|
||||
return bearerOnly;
|
||||
}
|
||||
void setAttribute(String name, List<String> values);
|
||||
|
||||
public void setBearerOnly(boolean bearerOnly) {
|
||||
this.updated |= ! Objects.equals(this.bearerOnly, bearerOnly);
|
||||
this.bearerOnly = bearerOnly;
|
||||
}
|
||||
void setAuthFlowBindings(Map<String, String> authFlowBindings);
|
||||
|
||||
public boolean isConsentRequired() {
|
||||
return consentRequired;
|
||||
}
|
||||
void setAuthenticationFlowBindingOverride(String binding, String flowId);
|
||||
|
||||
public void setConsentRequired(boolean consentRequired) {
|
||||
this.updated |= ! Objects.equals(this.consentRequired, consentRequired);
|
||||
this.consentRequired = consentRequired;
|
||||
}
|
||||
void setBaseUrl(String baseUrl);
|
||||
|
||||
public boolean isStandardFlowEnabled() {
|
||||
return standardFlowEnabled;
|
||||
}
|
||||
void setBearerOnly(Boolean bearerOnly);
|
||||
|
||||
public void setStandardFlowEnabled(boolean standardFlowEnabled) {
|
||||
this.updated |= ! Objects.equals(this.standardFlowEnabled, standardFlowEnabled);
|
||||
this.standardFlowEnabled = standardFlowEnabled;
|
||||
}
|
||||
void setClientAuthenticatorType(String clientAuthenticatorType);
|
||||
|
||||
public boolean isImplicitFlowEnabled() {
|
||||
return implicitFlowEnabled;
|
||||
}
|
||||
void setClientId(String clientId);
|
||||
|
||||
public void setImplicitFlowEnabled(boolean implicitFlowEnabled) {
|
||||
this.updated |= ! Objects.equals(this.implicitFlowEnabled, implicitFlowEnabled);
|
||||
this.implicitFlowEnabled = implicitFlowEnabled;
|
||||
}
|
||||
void setConsentRequired(Boolean consentRequired);
|
||||
|
||||
public boolean isDirectAccessGrantsEnabled() {
|
||||
return directAccessGrantsEnabled;
|
||||
}
|
||||
void setDescription(String description);
|
||||
|
||||
public void setDirectAccessGrantsEnabled(boolean directAccessGrantsEnabled) {
|
||||
this.updated |= ! Objects.equals(this.directAccessGrantsEnabled, directAccessGrantsEnabled);
|
||||
this.directAccessGrantsEnabled = directAccessGrantsEnabled;
|
||||
}
|
||||
void setDirectAccessGrantsEnabled(Boolean directAccessGrantsEnabled);
|
||||
|
||||
public boolean isServiceAccountsEnabled() {
|
||||
return serviceAccountsEnabled;
|
||||
}
|
||||
void setEnabled(Boolean enabled);
|
||||
|
||||
public void setServiceAccountsEnabled(boolean serviceAccountsEnabled) {
|
||||
this.updated |= ! Objects.equals(this.serviceAccountsEnabled, serviceAccountsEnabled);
|
||||
this.serviceAccountsEnabled = serviceAccountsEnabled;
|
||||
}
|
||||
void setFrontchannelLogout(Boolean frontchannelLogout);
|
||||
|
||||
public int getNodeReRegistrationTimeout() {
|
||||
return nodeReRegistrationTimeout;
|
||||
}
|
||||
void setFullScopeAllowed(Boolean fullScopeAllowed);
|
||||
|
||||
public void setNodeReRegistrationTimeout(int nodeReRegistrationTimeout) {
|
||||
this.updated |= ! Objects.equals(this.nodeReRegistrationTimeout, nodeReRegistrationTimeout);
|
||||
this.nodeReRegistrationTimeout = nodeReRegistrationTimeout;
|
||||
}
|
||||
void setImplicitFlowEnabled(Boolean implicitFlowEnabled);
|
||||
|
||||
public void addWebOrigin(String webOrigin) {
|
||||
updated = true;
|
||||
this.webOrigins.add(webOrigin);
|
||||
}
|
||||
void setManagementUrl(String managementUrl);
|
||||
|
||||
public void removeWebOrigin(String webOrigin) {
|
||||
updated |= this.webOrigins.remove(webOrigin);
|
||||
}
|
||||
void setName(String name);
|
||||
|
||||
public void addRedirectUri(String redirectUri) {
|
||||
this.updated |= ! this.redirectUris.contains(redirectUri);
|
||||
this.redirectUris.add(redirectUri);
|
||||
}
|
||||
void setNodeReRegistrationTimeout(int nodeReRegistrationTimeout);
|
||||
|
||||
public void removeRedirectUri(String redirectUri) {
|
||||
updated |= this.redirectUris.remove(redirectUri);
|
||||
}
|
||||
void setNotBefore(int notBefore);
|
||||
|
||||
public void removeAttribute(String name) {
|
||||
this.updated |= this.attributes.remove(name) != null;
|
||||
}
|
||||
void setProtocol(String protocol);
|
||||
|
||||
public List<String> getAttribute(String name) {
|
||||
return attributes.getOrDefault(name, Collections.EMPTY_LIST);
|
||||
}
|
||||
void setProtocolMappers(Collection<ProtocolMapperModel> protocolMappers);
|
||||
|
||||
public String getAuthenticationFlowBindingOverride(String binding) {
|
||||
return this.authFlowBindings.get(binding);
|
||||
}
|
||||
void setPublicClient(Boolean publicClient);
|
||||
|
||||
public Map<String, String> getAuthenticationFlowBindingOverrides() {
|
||||
return this.authFlowBindings;
|
||||
}
|
||||
void setRedirectUris(Set<String> redirectUris);
|
||||
|
||||
public void removeAuthenticationFlowBindingOverride(String binding) {
|
||||
updated |= this.authFlowBindings.remove(binding) != null;
|
||||
}
|
||||
void setRegistrationToken(String registrationToken);
|
||||
|
||||
public void setAuthenticationFlowBindingOverride(String binding, String flowId) {
|
||||
this.updated = true;
|
||||
this.authFlowBindings.put(binding, flowId);
|
||||
}
|
||||
void setRootUrl(String rootUrl);
|
||||
|
||||
public Collection<String> getScopeMappings() {
|
||||
return scopeMappings;
|
||||
}
|
||||
void setScope(Set<String> scope);
|
||||
|
||||
public void addScopeMapping(String id) {
|
||||
if (id != null) {
|
||||
updated = true;
|
||||
scopeMappings.add(id);
|
||||
}
|
||||
}
|
||||
void setSecret(String secret);
|
||||
|
||||
public void deleteScopeMapping(String id) {
|
||||
updated |= scopeMappings.remove(id);
|
||||
}
|
||||
void setServiceAccountsEnabled(Boolean serviceAccountsEnabled);
|
||||
|
||||
public void addClientScope(String id, boolean defaultScope) {
|
||||
if (id != null) {
|
||||
updated = true;
|
||||
this.clientScopes.put(id, defaultScope);
|
||||
}
|
||||
}
|
||||
void setStandardFlowEnabled(Boolean standardFlowEnabled);
|
||||
|
||||
public void removeClientScope(String id) {
|
||||
if (id != null) {
|
||||
updated |= clientScopes.remove(id) != null;
|
||||
}
|
||||
}
|
||||
void setSurrogateAuthRequired(Boolean surrogateAuthRequired);
|
||||
|
||||
public Stream<String> getClientScopes(boolean defaultScope) {
|
||||
return this.clientScopes.entrySet().stream()
|
||||
.filter(me -> Objects.equals(me.getValue(), defaultScope))
|
||||
.map(Entry::getKey);
|
||||
}
|
||||
void setWebOrigins(Set<String> webOrigins);
|
||||
|
||||
public String getRealmId() {
|
||||
return this.realmId;
|
||||
}
|
||||
void updateProtocolMapper(String id, ProtocolMapperModel mapping);
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright 2021 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.models.map.client;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hmlnarik
|
||||
*/
|
||||
public class MapClientEntityDelegate<K> extends MapClientEntityLazyDelegate<K> {
|
||||
|
||||
private final MapClientEntity<K> delegate;
|
||||
|
||||
public MapClientEntityDelegate(MapClientEntity<K> delegate) {
|
||||
super(null);
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MapClientEntity<K> getDelegate() {
|
||||
return delegate;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,559 @@
|
|||
/*
|
||||
* Copyright 2020 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.models.map.client;
|
||||
|
||||
import org.keycloak.models.ProtocolMapperModel;
|
||||
import org.keycloak.models.map.common.AbstractEntity;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hmlnarik
|
||||
*/
|
||||
public class MapClientEntityImpl<K> implements MapClientEntity<K> {
|
||||
|
||||
private K id;
|
||||
private String realmId;
|
||||
|
||||
private String clientId;
|
||||
private String name;
|
||||
private String description;
|
||||
private Set<String> redirectUris = new HashSet<>();
|
||||
private boolean enabled;
|
||||
private boolean alwaysDisplayInConsole;
|
||||
private String clientAuthenticatorType;
|
||||
private String secret;
|
||||
private String registrationToken;
|
||||
private String protocol;
|
||||
private Map<String, List<String>> attributes = new HashMap<>();
|
||||
private Map<String, String> authFlowBindings = new HashMap<>();
|
||||
private boolean publicClient;
|
||||
private boolean fullScopeAllowed;
|
||||
private boolean frontchannelLogout;
|
||||
private int notBefore;
|
||||
private Set<String> scope = new HashSet<>();
|
||||
private Set<String> webOrigins = new HashSet<>();
|
||||
private Map<String, ProtocolMapperModel> protocolMappers = new HashMap<>();
|
||||
private Map<String, Boolean> clientScopes = new HashMap<>();
|
||||
private Set<String> scopeMappings = new LinkedHashSet<>();
|
||||
private boolean surrogateAuthRequired;
|
||||
private String managementUrl;
|
||||
private String rootUrl;
|
||||
private String baseUrl;
|
||||
private boolean bearerOnly;
|
||||
private boolean consentRequired;
|
||||
private boolean standardFlowEnabled;
|
||||
private boolean implicitFlowEnabled;
|
||||
private boolean directAccessGrantsEnabled;
|
||||
private boolean serviceAccountsEnabled;
|
||||
private int nodeReRegistrationTimeout;
|
||||
|
||||
/**
|
||||
* Flag signalizing that any of the setters has been meaningfully used.
|
||||
*/
|
||||
protected boolean updated;
|
||||
|
||||
protected MapClientEntityImpl() {
|
||||
this.id = null;
|
||||
this.realmId = null;
|
||||
}
|
||||
|
||||
public MapClientEntityImpl(K id, String realmId) {
|
||||
Objects.requireNonNull(id, "id");
|
||||
Objects.requireNonNull(realmId, "realmId");
|
||||
|
||||
this.id = id;
|
||||
this.realmId = realmId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public K getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUpdated() {
|
||||
return this.updated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClientId(String clientId) {
|
||||
this.updated |= ! Objects.equals(this.clientId, clientId);
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
this.updated |= ! Objects.equals(this.name, name);
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDescription(String description) {
|
||||
this.updated |= ! Objects.equals(this.description, description);
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getRedirectUris() {
|
||||
return redirectUris;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRedirectUris(Set<String> redirectUris) {
|
||||
this.updated |= ! Objects.equals(this.redirectUris, redirectUris);
|
||||
this.redirectUris = redirectUris;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(Boolean enabled) {
|
||||
this.updated |= ! Objects.equals(this.enabled, enabled);
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isAlwaysDisplayInConsole() {
|
||||
return alwaysDisplayInConsole;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlwaysDisplayInConsole(Boolean alwaysDisplayInConsole) {
|
||||
this.updated |= ! Objects.equals(this.alwaysDisplayInConsole, alwaysDisplayInConsole);
|
||||
this.alwaysDisplayInConsole = alwaysDisplayInConsole;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClientAuthenticatorType() {
|
||||
return clientAuthenticatorType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClientAuthenticatorType(String clientAuthenticatorType) {
|
||||
this.updated |= ! Objects.equals(this.clientAuthenticatorType, clientAuthenticatorType);
|
||||
this.clientAuthenticatorType = clientAuthenticatorType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSecret() {
|
||||
return secret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSecret(String secret) {
|
||||
this.updated |= ! Objects.equals(this.secret, secret);
|
||||
this.secret = secret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRegistrationToken() {
|
||||
return registrationToken;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRegistrationToken(String registrationToken) {
|
||||
this.updated |= ! Objects.equals(this.registrationToken, registrationToken);
|
||||
this.registrationToken = registrationToken;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProtocol() {
|
||||
return protocol;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProtocol(String protocol) {
|
||||
this.updated |= ! Objects.equals(this.protocol, protocol);
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<String>> getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttribute(String name, List<String> values) {
|
||||
this.updated |= ! Objects.equals(this.attributes.put(name, values), values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getAuthFlowBindings() {
|
||||
return authFlowBindings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAuthFlowBindings(Map<String, String> authFlowBindings) {
|
||||
this.updated |= ! Objects.equals(this.authFlowBindings, authFlowBindings);
|
||||
this.authFlowBindings = authFlowBindings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isPublicClient() {
|
||||
return publicClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPublicClient(Boolean publicClient) {
|
||||
this.updated |= ! Objects.equals(this.publicClient, publicClient);
|
||||
this.publicClient = publicClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isFullScopeAllowed() {
|
||||
return fullScopeAllowed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFullScopeAllowed(Boolean fullScopeAllowed) {
|
||||
this.updated |= ! Objects.equals(this.fullScopeAllowed, fullScopeAllowed);
|
||||
this.fullScopeAllowed = fullScopeAllowed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isFrontchannelLogout() {
|
||||
return frontchannelLogout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFrontchannelLogout(Boolean frontchannelLogout) {
|
||||
this.updated |= ! Objects.equals(this.frontchannelLogout, frontchannelLogout);
|
||||
this.frontchannelLogout = frontchannelLogout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNotBefore() {
|
||||
return notBefore;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNotBefore(int notBefore) {
|
||||
this.updated |= ! Objects.equals(this.notBefore, notBefore);
|
||||
this.notBefore = notBefore;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getScope() {
|
||||
return scope;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScope(Set<String> scope) {
|
||||
this.updated |= ! Objects.equals(this.scope, scope);
|
||||
this.scope.clear();
|
||||
this.scope.addAll(scope);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getWebOrigins() {
|
||||
return webOrigins;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWebOrigins(Set<String> webOrigins) {
|
||||
this.updated |= ! Objects.equals(this.webOrigins, webOrigins);
|
||||
this.webOrigins.clear();
|
||||
this.webOrigins.addAll(webOrigins);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProtocolMapperModel addProtocolMapper(ProtocolMapperModel model) {
|
||||
Objects.requireNonNull(model.getId(), "protocolMapper.id");
|
||||
updated = true;
|
||||
this.protocolMappers.put(model.getId(), model);
|
||||
return model;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ProtocolMapperModel> getProtocolMappers() {
|
||||
return protocolMappers.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateProtocolMapper(String id, ProtocolMapperModel mapping) {
|
||||
updated = true;
|
||||
protocolMappers.put(id, mapping);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeProtocolMapper(String id) {
|
||||
updated |= protocolMappers.remove(id) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProtocolMappers(Collection<ProtocolMapperModel> protocolMappers) {
|
||||
this.updated |= ! Objects.equals(this.protocolMappers, protocolMappers);
|
||||
this.protocolMappers.clear();
|
||||
this.protocolMappers.putAll(protocolMappers.stream().collect(Collectors.toMap(ProtocolMapperModel::getId, Function.identity())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProtocolMapperModel getProtocolMapperById(String id) {
|
||||
return id == null ? null : protocolMappers.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isSurrogateAuthRequired() {
|
||||
return surrogateAuthRequired;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSurrogateAuthRequired(Boolean surrogateAuthRequired) {
|
||||
this.updated |= ! Objects.equals(this.surrogateAuthRequired, surrogateAuthRequired);
|
||||
this.surrogateAuthRequired = surrogateAuthRequired;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getManagementUrl() {
|
||||
return managementUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setManagementUrl(String managementUrl) {
|
||||
this.updated |= ! Objects.equals(this.managementUrl, managementUrl);
|
||||
this.managementUrl = managementUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRootUrl() {
|
||||
return rootUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRootUrl(String rootUrl) {
|
||||
this.updated |= ! Objects.equals(this.rootUrl, rootUrl);
|
||||
this.rootUrl = rootUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBaseUrl() {
|
||||
return baseUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBaseUrl(String baseUrl) {
|
||||
this.updated |= ! Objects.equals(this.baseUrl, baseUrl);
|
||||
this.baseUrl = baseUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isBearerOnly() {
|
||||
return bearerOnly;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBearerOnly(Boolean bearerOnly) {
|
||||
this.updated |= ! Objects.equals(this.bearerOnly, bearerOnly);
|
||||
this.bearerOnly = bearerOnly;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isConsentRequired() {
|
||||
return consentRequired;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConsentRequired(Boolean consentRequired) {
|
||||
this.updated |= ! Objects.equals(this.consentRequired, consentRequired);
|
||||
this.consentRequired = consentRequired;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isStandardFlowEnabled() {
|
||||
return standardFlowEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStandardFlowEnabled(Boolean standardFlowEnabled) {
|
||||
this.updated |= ! Objects.equals(this.standardFlowEnabled, standardFlowEnabled);
|
||||
this.standardFlowEnabled = standardFlowEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isImplicitFlowEnabled() {
|
||||
return implicitFlowEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImplicitFlowEnabled(Boolean implicitFlowEnabled) {
|
||||
this.updated |= ! Objects.equals(this.implicitFlowEnabled, implicitFlowEnabled);
|
||||
this.implicitFlowEnabled = implicitFlowEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isDirectAccessGrantsEnabled() {
|
||||
return directAccessGrantsEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDirectAccessGrantsEnabled(Boolean directAccessGrantsEnabled) {
|
||||
this.updated |= ! Objects.equals(this.directAccessGrantsEnabled, directAccessGrantsEnabled);
|
||||
this.directAccessGrantsEnabled = directAccessGrantsEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isServiceAccountsEnabled() {
|
||||
return serviceAccountsEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setServiceAccountsEnabled(Boolean serviceAccountsEnabled) {
|
||||
this.updated |= ! Objects.equals(this.serviceAccountsEnabled, serviceAccountsEnabled);
|
||||
this.serviceAccountsEnabled = serviceAccountsEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNodeReRegistrationTimeout() {
|
||||
return nodeReRegistrationTimeout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNodeReRegistrationTimeout(int nodeReRegistrationTimeout) {
|
||||
this.updated |= ! Objects.equals(this.nodeReRegistrationTimeout, nodeReRegistrationTimeout);
|
||||
this.nodeReRegistrationTimeout = nodeReRegistrationTimeout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addWebOrigin(String webOrigin) {
|
||||
updated = true;
|
||||
this.webOrigins.add(webOrigin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeWebOrigin(String webOrigin) {
|
||||
updated |= this.webOrigins.remove(webOrigin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRedirectUri(String redirectUri) {
|
||||
this.updated |= ! this.redirectUris.contains(redirectUri);
|
||||
this.redirectUris.add(redirectUri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeRedirectUri(String redirectUri) {
|
||||
updated |= this.redirectUris.remove(redirectUri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAttribute(String name) {
|
||||
this.updated |= this.attributes.remove(name) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getAttribute(String name) {
|
||||
return attributes.getOrDefault(name, Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthenticationFlowBindingOverride(String binding) {
|
||||
return this.authFlowBindings.get(binding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getAuthenticationFlowBindingOverrides() {
|
||||
return this.authFlowBindings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAuthenticationFlowBindingOverride(String binding) {
|
||||
updated |= this.authFlowBindings.remove(binding) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAuthenticationFlowBindingOverride(String binding, String flowId) {
|
||||
this.updated = true;
|
||||
this.authFlowBindings.put(binding, flowId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getScopeMappings() {
|
||||
return scopeMappings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addScopeMapping(String id) {
|
||||
if (id != null) {
|
||||
updated = true;
|
||||
scopeMappings.add(id);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteScopeMapping(String id) {
|
||||
updated |= scopeMappings.remove(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addClientScope(String id, Boolean defaultScope) {
|
||||
if (id != null) {
|
||||
updated = true;
|
||||
this.clientScopes.put(id, defaultScope);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeClientScope(String id) {
|
||||
if (id != null) {
|
||||
updated |= clientScopes.remove(id) != null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getClientScopes(boolean defaultScope) {
|
||||
return this.clientScopes.entrySet().stream()
|
||||
.filter(me -> Objects.equals(me.getValue(), defaultScope))
|
||||
.map(Entry::getKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRealmId() {
|
||||
return this.realmId;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,468 @@
|
|||
/*
|
||||
* Copyright 2021 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.models.map.client;
|
||||
|
||||
import org.keycloak.models.ProtocolMapperModel;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicMarkableReference;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author hmlnarik
|
||||
*/
|
||||
public class MapClientEntityLazyDelegate<K> implements MapClientEntity<K> {
|
||||
|
||||
private final Supplier<MapClientEntity<K>> delegateSupplier;
|
||||
|
||||
private final AtomicMarkableReference<MapClientEntity<K>> delegate = new AtomicMarkableReference<>(null, false);
|
||||
|
||||
public MapClientEntityLazyDelegate(Supplier<MapClientEntity<K>> delegateSupplier) {
|
||||
this.delegateSupplier = delegateSupplier;
|
||||
}
|
||||
|
||||
protected MapClientEntity<K> getDelegate() {
|
||||
if (! delegate.isMarked()) {
|
||||
delegate.compareAndSet(null, delegateSupplier == null ? null : delegateSupplier.get(), false, true);
|
||||
}
|
||||
MapClientEntity<K> ref = delegate.getReference();
|
||||
if (ref == null) {
|
||||
throw new IllegalStateException("Invalid delegate obtained");
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addClientScope(String id, Boolean defaultScope) {
|
||||
getDelegate().addClientScope(id, defaultScope);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProtocolMapperModel addProtocolMapper(ProtocolMapperModel model) {
|
||||
return getDelegate().addProtocolMapper(model);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addRedirectUri(String redirectUri) {
|
||||
getDelegate().addRedirectUri(redirectUri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addScopeMapping(String id) {
|
||||
getDelegate().addScopeMapping(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addWebOrigin(String webOrigin) {
|
||||
getDelegate().addWebOrigin(webOrigin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteScopeMapping(String id) {
|
||||
getDelegate().deleteScopeMapping(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getAttribute(String name) {
|
||||
return getDelegate().getAttribute(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<String>> getAttributes() {
|
||||
return getDelegate().getAttributes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getAuthFlowBindings() {
|
||||
return getDelegate().getAuthFlowBindings();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthenticationFlowBindingOverride(String binding) {
|
||||
return getDelegate().getAuthenticationFlowBindingOverride(binding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getAuthenticationFlowBindingOverrides() {
|
||||
return getDelegate().getAuthenticationFlowBindingOverrides();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBaseUrl() {
|
||||
return getDelegate().getBaseUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClientAuthenticatorType() {
|
||||
return getDelegate().getClientAuthenticatorType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClientId() {
|
||||
return getDelegate().getClientId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getClientScopes(boolean defaultScope) {
|
||||
return getDelegate().getClientScopes(defaultScope);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return getDelegate().getDescription();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getManagementUrl() {
|
||||
return getDelegate().getManagementUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return getDelegate().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNodeReRegistrationTimeout() {
|
||||
return getDelegate().getNodeReRegistrationTimeout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNotBefore() {
|
||||
return getDelegate().getNotBefore();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProtocol() {
|
||||
return getDelegate().getProtocol();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProtocolMapperModel getProtocolMapperById(String id) {
|
||||
return getDelegate().getProtocolMapperById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ProtocolMapperModel> getProtocolMappers() {
|
||||
return getDelegate().getProtocolMappers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRealmId() {
|
||||
return getDelegate().getRealmId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getRedirectUris() {
|
||||
return getDelegate().getRedirectUris();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRegistrationToken() {
|
||||
return getDelegate().getRegistrationToken();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRootUrl() {
|
||||
return getDelegate().getRootUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getScope() {
|
||||
return getDelegate().getScope();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getScopeMappings() {
|
||||
return getDelegate().getScopeMappings();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSecret() {
|
||||
return getDelegate().getSecret();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getWebOrigins() {
|
||||
return getDelegate().getWebOrigins();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isAlwaysDisplayInConsole() {
|
||||
return getDelegate().isAlwaysDisplayInConsole();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isBearerOnly() {
|
||||
return getDelegate().isBearerOnly();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isConsentRequired() {
|
||||
return getDelegate().isConsentRequired();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isDirectAccessGrantsEnabled() {
|
||||
return getDelegate().isDirectAccessGrantsEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isEnabled() {
|
||||
return getDelegate().isEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isFrontchannelLogout() {
|
||||
return getDelegate().isFrontchannelLogout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isFullScopeAllowed() {
|
||||
return getDelegate().isFullScopeAllowed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isImplicitFlowEnabled() {
|
||||
return getDelegate().isImplicitFlowEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isPublicClient() {
|
||||
return getDelegate().isPublicClient();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isServiceAccountsEnabled() {
|
||||
return getDelegate().isServiceAccountsEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isStandardFlowEnabled() {
|
||||
return getDelegate().isStandardFlowEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isSurrogateAuthRequired() {
|
||||
return getDelegate().isSurrogateAuthRequired();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAttribute(String name) {
|
||||
getDelegate().removeAttribute(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAuthenticationFlowBindingOverride(String binding) {
|
||||
getDelegate().removeAuthenticationFlowBindingOverride(binding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeClientScope(String id) {
|
||||
getDelegate().removeClientScope(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeProtocolMapper(String id) {
|
||||
getDelegate().removeProtocolMapper(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeRedirectUri(String redirectUri) {
|
||||
getDelegate().removeRedirectUri(redirectUri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeWebOrigin(String webOrigin) {
|
||||
getDelegate().removeWebOrigin(webOrigin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlwaysDisplayInConsole(Boolean alwaysDisplayInConsole) {
|
||||
getDelegate().setAlwaysDisplayInConsole(alwaysDisplayInConsole);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttribute(String name, List<String> values) {
|
||||
getDelegate().setAttribute(name, values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAuthFlowBindings(Map<String, String> authFlowBindings) {
|
||||
getDelegate().setAuthFlowBindings(authFlowBindings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAuthenticationFlowBindingOverride(String binding, String flowId) {
|
||||
getDelegate().setAuthenticationFlowBindingOverride(binding, flowId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBaseUrl(String baseUrl) {
|
||||
getDelegate().setBaseUrl(baseUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBearerOnly(Boolean bearerOnly) {
|
||||
getDelegate().setBearerOnly(bearerOnly);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClientAuthenticatorType(String clientAuthenticatorType) {
|
||||
getDelegate().setClientAuthenticatorType(clientAuthenticatorType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClientId(String clientId) {
|
||||
getDelegate().setClientId(clientId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConsentRequired(Boolean consentRequired) {
|
||||
getDelegate().setConsentRequired(consentRequired);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDescription(String description) {
|
||||
getDelegate().setDescription(description);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDirectAccessGrantsEnabled(Boolean directAccessGrantsEnabled) {
|
||||
getDelegate().setDirectAccessGrantsEnabled(directAccessGrantsEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(Boolean enabled) {
|
||||
getDelegate().setEnabled(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFrontchannelLogout(Boolean frontchannelLogout) {
|
||||
getDelegate().setFrontchannelLogout(frontchannelLogout);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFullScopeAllowed(Boolean fullScopeAllowed) {
|
||||
getDelegate().setFullScopeAllowed(fullScopeAllowed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImplicitFlowEnabled(Boolean implicitFlowEnabled) {
|
||||
getDelegate().setImplicitFlowEnabled(implicitFlowEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setManagementUrl(String managementUrl) {
|
||||
getDelegate().setManagementUrl(managementUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
getDelegate().setName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNodeReRegistrationTimeout(int nodeReRegistrationTimeout) {
|
||||
getDelegate().setNodeReRegistrationTimeout(nodeReRegistrationTimeout);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNotBefore(int notBefore) {
|
||||
getDelegate().setNotBefore(notBefore);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProtocol(String protocol) {
|
||||
getDelegate().setProtocol(protocol);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProtocolMappers(Collection<ProtocolMapperModel> protocolMappers) {
|
||||
getDelegate().setProtocolMappers(protocolMappers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPublicClient(Boolean publicClient) {
|
||||
getDelegate().setPublicClient(publicClient);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRedirectUris(Set<String> redirectUris) {
|
||||
getDelegate().setRedirectUris(redirectUris);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRegistrationToken(String registrationToken) {
|
||||
getDelegate().setRegistrationToken(registrationToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRootUrl(String rootUrl) {
|
||||
getDelegate().setRootUrl(rootUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScope(Set<String> scope) {
|
||||
getDelegate().setScope(scope);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSecret(String secret) {
|
||||
getDelegate().setSecret(secret);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setServiceAccountsEnabled(Boolean serviceAccountsEnabled) {
|
||||
getDelegate().setServiceAccountsEnabled(serviceAccountsEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStandardFlowEnabled(Boolean standardFlowEnabled) {
|
||||
getDelegate().setStandardFlowEnabled(standardFlowEnabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSurrogateAuthRequired(Boolean surrogateAuthRequired) {
|
||||
getDelegate().setSurrogateAuthRequired(surrogateAuthRequired);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWebOrigins(Set<String> webOrigins) {
|
||||
getDelegate().setWebOrigins(webOrigins);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateProtocolMapper(String id, ProtocolMapperModel mapping) {
|
||||
getDelegate().updateProtocolMapper(id, mapping);
|
||||
}
|
||||
|
||||
@Override
|
||||
public K getId() {
|
||||
return getDelegate().getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUpdated() {
|
||||
return getDelegate().isUpdated();
|
||||
}
|
||||
|
||||
}
|
|
@ -81,10 +81,10 @@ public class MapClientProvider<K> implements ClientProvider {
|
|||
};
|
||||
}
|
||||
|
||||
private Function<MapClientEntity<K>, ClientModel> entityToAdapterFunc(RealmModel realm) {
|
||||
private <T extends MapClientEntity<K>> Function<T, ClientModel> entityToAdapterFunc(RealmModel realm) {
|
||||
// Clone entity before returning back, to avoid giving away a reference to the live object to the caller
|
||||
|
||||
return origEntity -> new MapClientAdapter<K>(session, realm, registerEntityForChanges(tx, origEntity)) {
|
||||
return (T origEntity) -> new MapClientAdapter<K>(session, realm, registerEntityForChanges(tx, origEntity)) {
|
||||
@Override
|
||||
public String getId() {
|
||||
return clientStore.getKeyConvertor().keyToString(entity.getId());
|
||||
|
@ -152,7 +152,7 @@ public class MapClientProvider<K> implements ClientProvider {
|
|||
|
||||
LOG.tracef("addClient(%s, %s, %s)%s", realm, id, clientId, getShortStackTrace());
|
||||
|
||||
MapClientEntity<K> entity = new MapClientEntity<>(entityId, realm.getId());
|
||||
MapClientEntity<K> entity = new MapClientEntityImpl<>(entityId, realm.getId());
|
||||
entity.setClientId(clientId);
|
||||
entity.setEnabled(true);
|
||||
entity.setStandardFlowEnabled(true);
|
||||
|
|
|
@ -35,8 +35,21 @@ import org.keycloak.models.RoleModel;
|
|||
import org.keycloak.models.UserLoginFailureModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.UserSessionModel;
|
||||
import org.keycloak.models.map.authSession.MapRootAuthenticationSessionEntity;
|
||||
import org.keycloak.models.map.authorization.entity.MapPermissionTicketEntity;
|
||||
import org.keycloak.models.map.authorization.entity.MapPolicyEntity;
|
||||
import org.keycloak.models.map.authorization.entity.MapResourceEntity;
|
||||
import org.keycloak.models.map.authorization.entity.MapResourceServerEntity;
|
||||
import org.keycloak.models.map.authorization.entity.MapScopeEntity;
|
||||
import org.keycloak.models.map.client.MapClientEntity;
|
||||
import org.keycloak.models.map.client.MapClientEntityImpl;
|
||||
import org.keycloak.models.map.clientscope.MapClientScopeEntity;
|
||||
import org.keycloak.models.map.common.AbstractEntity;
|
||||
import org.keycloak.models.map.common.Serialization;
|
||||
import org.keycloak.models.map.group.MapGroupEntity;
|
||||
import org.keycloak.models.map.loginFailure.MapUserLoginFailureEntity;
|
||||
import org.keycloak.models.map.realm.MapRealmEntity;
|
||||
import org.keycloak.models.map.role.MapRoleEntity;
|
||||
import com.fasterxml.jackson.databind.JavaType;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
@ -50,6 +63,8 @@ import org.keycloak.models.map.storage.MapStorageProviderFactory;
|
|||
import org.keycloak.models.map.storage.ModelCriteriaBuilder;
|
||||
import org.keycloak.models.map.userSession.MapAuthenticatedClientSessionEntity;
|
||||
import org.keycloak.models.map.storage.StringKeyConvertor;
|
||||
import org.keycloak.models.map.user.MapUserEntity;
|
||||
import org.keycloak.models.map.userSession.MapUserSessionEntity;
|
||||
import org.keycloak.provider.EnvironmentDependentProviderFactory;
|
||||
import org.keycloak.provider.ProviderConfigProperty;
|
||||
import org.keycloak.sessions.RootAuthenticationSessionModel;
|
||||
|
@ -100,6 +115,27 @@ public class ConcurrentHashMapStorageProviderFactory implements AmphibianProvide
|
|||
MODEL_TO_NAME.put(org.keycloak.authorization.model.Scope.class, "authz-scopes");
|
||||
}
|
||||
|
||||
public static final Map<Class<?>, Class<?>> INTERFACE_TO_IMPL = new HashMap<>();
|
||||
static {
|
||||
INTERFACE_TO_IMPL.put(MapClientEntity.class, MapClientEntityImpl.class);
|
||||
// INTERFACE_TO_IMPL.put(MapClientScopeEntity.class, MapClientScopeEntityImpl.class);
|
||||
// INTERFACE_TO_IMPL.put(MapClientEntity.class, MapClientEntityImpl.class);
|
||||
// INTERFACE_TO_IMPL.put(MapGroupEntity.class, MapGroupEntityImpl.class);
|
||||
// INTERFACE_TO_IMPL.put(MapRealmEntity.class, MapRealmEntityImpl.class);
|
||||
// INTERFACE_TO_IMPL.put(MapRoleEntity.class, MapRoleEntityImpl.class);
|
||||
// INTERFACE_TO_IMPL.put(MapRootAuthenticationSessionEntity.class, MapRootAuthenticationSessionEntityImpl.class);
|
||||
// INTERFACE_TO_IMPL.put(MapUserLoginFailureEntity.class, MapUserLoginFailureEntityImpl.class);
|
||||
// INTERFACE_TO_IMPL.put(MapUserEntity.class, MapUserEntityImpl.class);
|
||||
// INTERFACE_TO_IMPL.put(MapUserSessionEntity.class, MapUserSessionEntityImpl.class);
|
||||
//
|
||||
// // authz
|
||||
// INTERFACE_TO_IMPL.put(MapPermissionTicketEntity.class, MapPermissionTicketEntityImpl.class);
|
||||
// INTERFACE_TO_IMPL.put(MapPolicyEntity.class, MapPolicyEntityImpl.class);
|
||||
// INTERFACE_TO_IMPL.put(MapResourceServerEntity.class, MapResourceServerEntityImpl.class);
|
||||
// INTERFACE_TO_IMPL.put(MapResourceEntity.class, MapResourceEntityImpl.class);
|
||||
// INTERFACE_TO_IMPL.put(MapScopeEntity.class, MapScopeEntityImpl.class);
|
||||
}
|
||||
|
||||
private static final Map<String, StringKeyConvertor> KEY_CONVERTORS = new HashMap<>();
|
||||
static {
|
||||
KEY_CONVERTORS.put("uuid", StringKeyConvertor.UUIDKey.INSTANCE);
|
||||
|
@ -213,7 +249,8 @@ public class ConcurrentHashMapStorageProviderFactory implements AmphibianProvide
|
|||
if (f != null && f.exists()) {
|
||||
try {
|
||||
LOG.debugf("Restoring contents from %s", f.getCanonicalPath());
|
||||
JavaType type = Serialization.MAPPER.getTypeFactory().constructCollectionType(List.class, valueType);
|
||||
Class<?> valueImplType = INTERFACE_TO_IMPL.getOrDefault(valueType, valueType);
|
||||
JavaType type = Serialization.MAPPER.getTypeFactory().constructCollectionType(List.class, valueImplType);
|
||||
|
||||
List<V> values = Serialization.MAPPER.readValue(f, type);
|
||||
values.forEach((V mce) -> store.create(mce));
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.keycloak.models.KeycloakSession;
|
|||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RealmProvider;
|
||||
import org.keycloak.models.map.client.MapClientEntity;
|
||||
import org.keycloak.models.map.client.MapClientEntityImpl;
|
||||
import org.keycloak.models.map.client.MapClientProviderFactory;
|
||||
import org.keycloak.models.map.storage.MapStorage;
|
||||
import org.keycloak.models.map.storage.MapStorageProvider;
|
||||
|
@ -114,9 +115,9 @@ public class MapStorageTest extends KeycloakModelTest {
|
|||
assertClientDoesNotExist(storage2, idMain, kcMain, kc2);
|
||||
assertClientDoesNotExist(storage2, id1, kc1, kc2);
|
||||
|
||||
MapClientEntity<K> clientMain = new MapClientEntity<>(idMain, realmId);
|
||||
MapClientEntity<K1> client1 = new MapClientEntity<>(id1, realmId);
|
||||
MapClientEntity<K2> client2 = new MapClientEntity<>(id2, realmId);
|
||||
MapClientEntity<K> clientMain = new MapClientEntityImpl<>(idMain, realmId);
|
||||
MapClientEntity<K1> client1 = new MapClientEntityImpl<>(id1, realmId);
|
||||
MapClientEntity<K2> client2 = new MapClientEntityImpl<>(id2, realmId);
|
||||
|
||||
storageMain.create(clientMain);
|
||||
storage1.create(client1);
|
||||
|
|
Loading…
Reference in a new issue