parent
99f27497f4
commit
c18a682f50
14 changed files with 409 additions and 24 deletions
|
@ -215,6 +215,17 @@ public abstract class AbstractGenerateEntityImplementationsProcessor extends Abs
|
||||||
return "deepClone(" + parameterName + ")";
|
return "deepClone(" + parameterName + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected String removeUndefined(TypeMirror fieldType, String parameterName) {
|
||||||
|
TypeElement typeElement = elements.getTypeElement(types.erasure(fieldType).toString());
|
||||||
|
boolean isMapType = isMapType(typeElement);
|
||||||
|
|
||||||
|
return parameterName + (isMapType ? ".values()" : "") + ".removeIf(org.keycloak.models.map.common.UndefinedValuesUtils::isUndefined)";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String isUndefined(String parameterName) {
|
||||||
|
return "org.keycloak.models.map.common.UndefinedValuesUtils.isUndefined(" + parameterName + ")";
|
||||||
|
}
|
||||||
|
|
||||||
protected boolean isEnumType(TypeMirror fieldType) {
|
protected boolean isEnumType(TypeMirror fieldType) {
|
||||||
return types.asElement(fieldType).getKind() == ElementKind.ENUM;
|
return types.asElement(fieldType).getKind() == ElementKind.ENUM;
|
||||||
}
|
}
|
||||||
|
|
|
@ -426,16 +426,26 @@ public class GenerateEntityImplementationsProcessor extends AbstractGenerateEnti
|
||||||
if (! isImmutableFinalType(fieldType)) {
|
if (! isImmutableFinalType(fieldType)) {
|
||||||
pw.println(" p0 = " + deepClone(firstParameterType, "p0") + ";");
|
pw.println(" p0 = " + deepClone(firstParameterType, "p0") + ";");
|
||||||
}
|
}
|
||||||
|
if (isCollection(firstParameterType)) {
|
||||||
|
pw.println(" if (p0 != null) {");
|
||||||
|
pw.println(" " + removeUndefined(firstParameterType, "p0") + ";");
|
||||||
|
pw.println(" if (" + isUndefined("p0") + ") p0 = null;");
|
||||||
|
pw.println(" }");
|
||||||
|
}
|
||||||
pw.println(" updated |= ! Objects.equals(" + fieldName + ", p0);");
|
pw.println(" updated |= ! Objects.equals(" + fieldName + ", p0);");
|
||||||
pw.println(" " + fieldName + " = p0;");
|
pw.println(" " + fieldName + " = p0;");
|
||||||
pw.println(" }");
|
pw.println(" }");
|
||||||
return true;
|
return true;
|
||||||
case COLLECTION_ADD:
|
case COLLECTION_ADD:
|
||||||
pw.println(" @SuppressWarnings(\"unchecked\") @Override public " + method.getReturnType() + " " + method.getSimpleName() + "(" + firstParameterType + " p0) {");
|
pw.println(" @SuppressWarnings(\"unchecked\") @Override public " + method.getReturnType() + " " + method.getSimpleName() + "(" + firstParameterType + " p0) {");
|
||||||
pw.println(" if (" + fieldName + " == null) { " + fieldName + " = " + interfaceToImplementation(typeElement, "") + "; }");
|
|
||||||
if (! isImmutableFinalType(firstParameterType)) {
|
if (! isImmutableFinalType(firstParameterType)) {
|
||||||
pw.println(" p0 = " + deepClone(firstParameterType, "p0") + ";");
|
pw.println(" p0 = " + deepClone(firstParameterType, "p0") + ";");
|
||||||
}
|
}
|
||||||
|
if (isCollection(firstParameterType)) {
|
||||||
|
pw.println(" if (p0 != null) " + removeUndefined(firstParameterType, "p0") + ";");
|
||||||
|
}
|
||||||
|
pw.println(" if (" + isUndefined("p0") + ") return;");
|
||||||
|
pw.println(" if (" + fieldName + " == null) { " + fieldName + " = " + interfaceToImplementation(typeElement, "") + "; }");
|
||||||
if (isSetType(typeElement)) {
|
if (isSetType(typeElement)) {
|
||||||
pw.println(" updated |= " + fieldName + ".add(p0);");
|
pw.println(" updated |= " + fieldName + ".add(p0);");
|
||||||
} else {
|
} else {
|
||||||
|
@ -456,10 +466,16 @@ public class GenerateEntityImplementationsProcessor extends AbstractGenerateEnti
|
||||||
case MAP_ADD:
|
case MAP_ADD:
|
||||||
TypeMirror secondParameterType = method.getParameters().get(1).asType();
|
TypeMirror secondParameterType = method.getParameters().get(1).asType();
|
||||||
pw.println(" @SuppressWarnings(\"unchecked\") @Override public " + method.getReturnType() + " " + method.getSimpleName() + "(" + firstParameterType + " p0, " + secondParameterType + " p1) {");
|
pw.println(" @SuppressWarnings(\"unchecked\") @Override public " + method.getReturnType() + " " + method.getSimpleName() + "(" + firstParameterType + " p0, " + secondParameterType + " p1) {");
|
||||||
pw.println(" if (" + fieldName + " == null) { " + fieldName + " = " + interfaceToImplementation(typeElement, "") + "; }");
|
|
||||||
if (! isImmutableFinalType(secondParameterType)) {
|
if (! isImmutableFinalType(secondParameterType)) {
|
||||||
pw.println(" p1 = " + deepClone(secondParameterType, "p1") + ";");
|
pw.println(" p1 = " + deepClone(secondParameterType, "p1") + ";");
|
||||||
}
|
}
|
||||||
|
if (isCollection(secondParameterType)) {
|
||||||
|
pw.println(" if (p1 != null) " + removeUndefined(secondParameterType, "p1") + ";");
|
||||||
|
}
|
||||||
|
pw.println(" boolean valueUndefined = " + isUndefined("p1") + ";");
|
||||||
|
pw.println(" if (valueUndefined) { if (" + fieldName + " != null) { updated |= " + fieldName + ".remove(p0) != null; } return; }");
|
||||||
|
pw.println(" if (" + fieldName + " == null) { " + fieldName + " = " + interfaceToImplementation(typeElement, "") + "; }");
|
||||||
|
|
||||||
pw.println(" Object v = " + fieldName + ".put(p0, p1);");
|
pw.println(" Object v = " + fieldName + ".put(p0, p1);");
|
||||||
pw.println(" updated |= ! Objects.equals(v, p1);");
|
pw.println(" updated |= ! Objects.equals(v, p1);");
|
||||||
pw.println(" }");
|
pw.println(" }");
|
||||||
|
|
|
@ -334,6 +334,9 @@ public class GenerateHotRodEntityImplementationsProcessor extends AbstractGenera
|
||||||
if (! isImmutableFinalType(firstParameterType)) {
|
if (! isImmutableFinalType(firstParameterType)) {
|
||||||
pw.println(" p0 = " + deepClone(firstParameterType, "p0") + ";");
|
pw.println(" p0 = " + deepClone(firstParameterType, "p0") + ";");
|
||||||
}
|
}
|
||||||
|
if (isCollection(firstParameterType)) {
|
||||||
|
pw.println(" if (p0 != null) " + removeUndefined(firstParameterType, "p0") + ";");
|
||||||
|
}
|
||||||
pw.println(" " + hotRodFieldType.toString() + " migrated = " + migrateToType(hotRodFieldType, firstParameterType, "p0") + ";");
|
pw.println(" " + hotRodFieldType.toString() + " migrated = " + migrateToType(hotRodFieldType, firstParameterType, "p0") + ";");
|
||||||
pw.println(" " + hotRodEntityField("updated") + " |= ! Objects.equals(" + hotRodEntityField(fieldName) + ", migrated);");
|
pw.println(" " + hotRodEntityField("updated") + " |= ! Objects.equals(" + hotRodEntityField(fieldName) + ", migrated);");
|
||||||
pw.println(" " + hotRodEntityField(fieldName) + " = migrated;");
|
pw.println(" " + hotRodEntityField(fieldName) + " = migrated;");
|
||||||
|
@ -342,10 +345,14 @@ public class GenerateHotRodEntityImplementationsProcessor extends AbstractGenera
|
||||||
case COLLECTION_ADD:
|
case COLLECTION_ADD:
|
||||||
TypeMirror collectionItemType = getGenericsDeclaration(hotRodFieldType).get(0);
|
TypeMirror collectionItemType = getGenericsDeclaration(hotRodFieldType).get(0);
|
||||||
pw.println(" @SuppressWarnings(\"unchecked\") @Override public " + method.getReturnType() + " " + method.getSimpleName() + "(" + firstParameterType + " p0) {");
|
pw.println(" @SuppressWarnings(\"unchecked\") @Override public " + method.getReturnType() + " " + method.getSimpleName() + "(" + firstParameterType + " p0) {");
|
||||||
pw.println(" if (" + hotRodEntityField(fieldName) + " == null) { " + hotRodEntityField(fieldName) + " = " + interfaceToImplementation(typeElement, "") + "; }");
|
|
||||||
if (! isImmutableFinalType(firstParameterType)) {
|
if (! isImmutableFinalType(firstParameterType)) {
|
||||||
pw.println(" p0 = " + deepClone(firstParameterType, "p0") + ";");
|
pw.println(" p0 = " + deepClone(firstParameterType, "p0") + ";");
|
||||||
}
|
}
|
||||||
|
if (isCollection(firstParameterType)) {
|
||||||
|
pw.println(" if (p0 != null) " + removeUndefined(firstParameterType, "p0") + ";");
|
||||||
|
}
|
||||||
|
pw.println(" if (" + isUndefined("p0") + ") return;");
|
||||||
|
pw.println(" if (" + hotRodEntityField(fieldName) + " == null) { " + hotRodEntityField(fieldName) + " = " + interfaceToImplementation(typeElement, "") + "; }");
|
||||||
pw.println(" " + collectionItemType.toString() + " migrated = " + migrateToType(collectionItemType, firstParameterType, "p0") + ";");
|
pw.println(" " + collectionItemType.toString() + " migrated = " + migrateToType(collectionItemType, firstParameterType, "p0") + ";");
|
||||||
if (isSetType(typeElement)) {
|
if (isSetType(typeElement)) {
|
||||||
pw.println(" " + hotRodEntityField("updated") + " |= " + hotRodEntityField(fieldName) + ".add(migrated);");
|
pw.println(" " + hotRodEntityField("updated") + " |= " + hotRodEntityField(fieldName) + ".add(migrated);");
|
||||||
|
@ -380,10 +387,13 @@ public class GenerateHotRodEntityImplementationsProcessor extends AbstractGenera
|
||||||
TypeMirror secondParameterType = method.getParameters().get(1).asType();
|
TypeMirror secondParameterType = method.getParameters().get(1).asType();
|
||||||
pw.println(" @SuppressWarnings(\"unchecked\") @Override public " + method.getReturnType() + " " + method.getSimpleName() + "(" + firstParameterType + " p0, " + secondParameterType + " p1) {");
|
pw.println(" @SuppressWarnings(\"unchecked\") @Override public " + method.getReturnType() + " " + method.getSimpleName() + "(" + firstParameterType + " p0, " + secondParameterType + " p1) {");
|
||||||
pw.println(" if (" + hotRodEntityField(fieldName) + " == null) { " + hotRodEntityField(fieldName) + " = " + interfaceToImplementation((TypeElement) types.asElement(types.erasure(hotRodFieldType)), "") + "; }");
|
pw.println(" if (" + hotRodEntityField(fieldName) + " == null) { " + hotRodEntityField(fieldName) + " = " + interfaceToImplementation((TypeElement) types.asElement(types.erasure(hotRodFieldType)), "") + "; }");
|
||||||
pw.println(" boolean valueUndefined = p1 == null" + (isCollection(secondParameterType) ? " || p1.isEmpty()" : "") + ";");
|
|
||||||
if (! isImmutableFinalType(secondParameterType)) {
|
if (! isImmutableFinalType(secondParameterType)) {
|
||||||
pw.println(" p1 = " + deepClone(secondParameterType, "p1") + ";");
|
pw.println(" p1 = " + deepClone(secondParameterType, "p1") + ";");
|
||||||
}
|
}
|
||||||
|
if (isCollection(secondParameterType)) {
|
||||||
|
pw.println(" if (p1 != null) " + removeUndefined(secondParameterType, "p1") + ";");
|
||||||
|
}
|
||||||
|
pw.println(" boolean valueUndefined = " + isUndefined("p1") + ";");
|
||||||
pw.println(" " + hotRodEntityField("updated") + " |= " + hotRodUtils.getQualifiedName().toString() + ".removeFromSetByMapKey("
|
pw.println(" " + hotRodEntityField("updated") + " |= " + hotRodUtils.getQualifiedName().toString() + ".removeFromSetByMapKey("
|
||||||
+ hotRodEntityField(fieldName) + ", "
|
+ hotRodEntityField(fieldName) + ", "
|
||||||
+ "p0, "
|
+ "p0, "
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
package org.keycloak.models.map.client;
|
package org.keycloak.models.map.client;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
@ -50,8 +51,8 @@ public class MapProtocolMapperUtils {
|
||||||
res.setId(entity.getId());
|
res.setId(entity.getId());
|
||||||
res.setName(entity.getName());
|
res.setName(entity.getName());
|
||||||
res.setProtocolMapper(entity.getProtocolMapper());
|
res.setProtocolMapper(entity.getProtocolMapper());
|
||||||
res.setConfig(entity.getConfig());
|
Map<String, String> config = entity.getConfig();
|
||||||
|
res.setConfig(config == null ? new HashMap<>(): new HashMap<>(config));
|
||||||
res.setProtocol(protocol);
|
res.setProtocol(protocol);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2022 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.common;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This Util class defines conditions when objects can be considered undefined
|
||||||
|
* <br/>
|
||||||
|
* <br/>
|
||||||
|
* For example:
|
||||||
|
* <ul>
|
||||||
|
* <li>{@link String} is undefined if it is {@code null} or {@code empty}</li>
|
||||||
|
* <li>{@link Collection} is undefined if it is {@code null}, {@code empty} or all items are undefined</li>
|
||||||
|
* <li>{@link Map} is undefined if it is {@code null}, {@code empty}, or all values are undefined</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
public class UndefinedValuesUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decides whether the {@link Object o} is defined or not
|
||||||
|
*
|
||||||
|
* @param o object to check
|
||||||
|
* @return true when the {@link Object o} is undefined, false otherwise
|
||||||
|
*/
|
||||||
|
public static boolean isUndefined(Object o) {
|
||||||
|
if (o == null) {
|
||||||
|
return true;
|
||||||
|
} else if (o instanceof Collection) {
|
||||||
|
return isUndefinedCollection((Collection<?>) o);
|
||||||
|
} else if (o instanceof Map) {
|
||||||
|
return isUndefinedMap((Map<?, ?>) o);
|
||||||
|
} else if (o instanceof String) {
|
||||||
|
return isUndefinedString((String) o);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isUndefinedCollection(Collection<?> collection) {
|
||||||
|
return collection.isEmpty() || collection.stream().allMatch(UndefinedValuesUtils::isUndefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isUndefinedMap(Map<?, ?> map) {
|
||||||
|
return map.isEmpty() || map.values().stream().allMatch(UndefinedValuesUtils::isUndefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isUndefinedString(String str) {
|
||||||
|
return str.trim().isEmpty();
|
||||||
|
}
|
||||||
|
}
|
|
@ -438,6 +438,7 @@ public interface MapRealmEntity extends UpdatableEntity, AbstractEntity, EntityW
|
||||||
|
|
||||||
Map<String, String> getBrowserSecurityHeaders();
|
Map<String, String> getBrowserSecurityHeaders();
|
||||||
void setBrowserSecurityHeaders(Map<String, String> headers);
|
void setBrowserSecurityHeaders(Map<String, String> headers);
|
||||||
|
void setBrowserSecurityHeader(String name, String value);
|
||||||
|
|
||||||
Map<String, String> getSmtpConfig();
|
Map<String, String> getSmtpConfig();
|
||||||
void setSmtpConfig(Map<String, String> smtpConfig);
|
void setSmtpConfig(Map<String, String> smtpConfig);
|
||||||
|
|
|
@ -53,7 +53,7 @@ public interface MapComponentEntity extends UpdatableEntity, AbstractEntity {
|
||||||
model.setSubType(entity.getSubType());
|
model.setSubType(entity.getSubType());
|
||||||
model.setParentId(entity.getParentId());
|
model.setParentId(entity.getParentId());
|
||||||
Map<String, List<String>> config = entity.getConfig();
|
Map<String, List<String>> config = entity.getConfig();
|
||||||
model.setConfig(config == null ? null : new MultivaluedHashMap<>(config));
|
model.setConfig(config == null ? new MultivaluedHashMap<>() : new MultivaluedHashMap<>(config));
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ public interface MapIdentityProviderEntity extends UpdatableEntity, AbstractEnti
|
||||||
entity.setLinkOnly(model.isLinkOnly());
|
entity.setLinkOnly(model.isLinkOnly());
|
||||||
entity.setAddReadTokenRoleOnCreate(model.isAddReadTokenRoleOnCreate());
|
entity.setAddReadTokenRoleOnCreate(model.isAddReadTokenRoleOnCreate());
|
||||||
entity.setAuthenticateByDefault(model.isAuthenticateByDefault());
|
entity.setAuthenticateByDefault(model.isAuthenticateByDefault());
|
||||||
entity.setConfig(model.getConfig() == null ? null : new HashMap<>(model.getConfig()));
|
entity.setConfig(model.getConfig());
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +71,8 @@ public interface MapIdentityProviderEntity extends UpdatableEntity, AbstractEnti
|
||||||
model.setAddReadTokenRoleOnCreate(addReadTokenRoleOnCreate == null ? false : addReadTokenRoleOnCreate);
|
model.setAddReadTokenRoleOnCreate(addReadTokenRoleOnCreate == null ? false : addReadTokenRoleOnCreate);
|
||||||
Boolean authenticateByDefault = entity.isAuthenticateByDefault();
|
Boolean authenticateByDefault = entity.isAuthenticateByDefault();
|
||||||
model.setAuthenticateByDefault(authenticateByDefault == null ? false : authenticateByDefault);
|
model.setAuthenticateByDefault(authenticateByDefault == null ? false : authenticateByDefault);
|
||||||
model.setConfig(entity.getConfig() == null ? null : new HashMap<>(entity.getConfig()));
|
Map<String, String> config = entity.getConfig();
|
||||||
|
model.setConfig(config == null ? new HashMap<>() : new HashMap<>(config));
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ public interface MapIdentityProviderMapperEntity extends UpdatableEntity, Abstra
|
||||||
entity.setName(model.getName());
|
entity.setName(model.getName());
|
||||||
entity.setIdentityProviderAlias(model.getIdentityProviderAlias());
|
entity.setIdentityProviderAlias(model.getIdentityProviderAlias());
|
||||||
entity.setIdentityProviderMapper(model.getIdentityProviderMapper());
|
entity.setIdentityProviderMapper(model.getIdentityProviderMapper());
|
||||||
entity.setConfig(model.getConfig() == null ? null : new HashMap<>(model.getConfig()));
|
entity.setConfig(model.getConfig());
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +49,8 @@ public interface MapIdentityProviderMapperEntity extends UpdatableEntity, Abstra
|
||||||
model.setName(entity.getName());
|
model.setName(entity.getName());
|
||||||
model.setIdentityProviderAlias(entity.getIdentityProviderAlias());
|
model.setIdentityProviderAlias(entity.getIdentityProviderAlias());
|
||||||
model.setIdentityProviderMapper(entity.getIdentityProviderMapper());
|
model.setIdentityProviderMapper(entity.getIdentityProviderMapper());
|
||||||
model.setConfig(entity.getConfig() == null ? null : new HashMap<>(entity.getConfig()));
|
Map<String, String> config = entity.getConfig();
|
||||||
|
model.setConfig(config == null ? new HashMap<>() : new HashMap<>(config));
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,8 @@ public interface MapRequiredActionProviderEntity extends UpdatableEntity, Abstra
|
||||||
model.setEnabled(enabled == null ? false : enabled);
|
model.setEnabled(enabled == null ? false : enabled);
|
||||||
Boolean defaultAction = entity.isDefaultAction();
|
Boolean defaultAction = entity.isDefaultAction();
|
||||||
model.setDefaultAction(defaultAction == null ? false : defaultAction);
|
model.setDefaultAction(defaultAction == null ? false : defaultAction);
|
||||||
model.setConfig(entity.getConfig());
|
Map<String, String> config = entity.getConfig();
|
||||||
|
model.setConfig(config == null ? new HashMap<>() : new HashMap<>(config));
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ public interface MapWebAuthnPolicyEntity extends UpdatableEntity {
|
||||||
entity.setUserVerificationRequirement(model.getUserVerificationRequirement());
|
entity.setUserVerificationRequirement(model.getUserVerificationRequirement());
|
||||||
entity.setCreateTimeout(model.getCreateTimeout());
|
entity.setCreateTimeout(model.getCreateTimeout());
|
||||||
entity.setAvoidSameAuthenticatorRegister(model.isAvoidSameAuthenticatorRegister());
|
entity.setAvoidSameAuthenticatorRegister(model.isAvoidSameAuthenticatorRegister());
|
||||||
entity.setAcceptableAaguids(model.getAcceptableAaguids() == null ? null : new LinkedList<>(model.getAcceptableAaguids()));
|
entity.setAcceptableAaguids(model.getAcceptableAaguids());
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +58,8 @@ public interface MapWebAuthnPolicyEntity extends UpdatableEntity {
|
||||||
model.setUserVerificationRequirement(entity.getUserVerificationRequirement());
|
model.setUserVerificationRequirement(entity.getUserVerificationRequirement());
|
||||||
model.setCreateTimeout(entity.getCreateTimeout());
|
model.setCreateTimeout(entity.getCreateTimeout());
|
||||||
model.setAvoidSameAuthenticatorRegister(entity.isAvoidSameAuthenticatorRegister());
|
model.setAvoidSameAuthenticatorRegister(entity.isAvoidSameAuthenticatorRegister());
|
||||||
model.setAcceptableAaguids(entity.getAcceptableAaguids() == null ? null : new LinkedList<>(entity.getAcceptableAaguids()));
|
List<String> acceptableAaguids = entity.getAcceptableAaguids();
|
||||||
|
model.setAcceptableAaguids(acceptableAaguids == null ? new LinkedList<>() : new LinkedList<>(acceptableAaguids));
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,8 @@ package org.keycloak.models.map.client;
|
||||||
import org.keycloak.models.map.common.DeepCloner;
|
import org.keycloak.models.map.common.DeepCloner;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.Matchers.contains;
|
import static org.hamcrest.Matchers.contains;
|
||||||
|
@ -86,9 +88,10 @@ public class MapClientEntityClonerTest {
|
||||||
newInstance.setAttribute("attr", Arrays.asList("aa", "bb", "cc"));
|
newInstance.setAttribute("attr", Arrays.asList("aa", "bb", "cc"));
|
||||||
MapProtocolMapperEntity pmm = new MapProtocolMapperEntityImpl();
|
MapProtocolMapperEntity pmm = new MapProtocolMapperEntityImpl();
|
||||||
pmm.setId("pmm-id");
|
pmm.setId("pmm-id");
|
||||||
pmm.setConfig(new HashMap<>());
|
Map<String, String> config = new HashMap<>();
|
||||||
pmm.getConfig().put("key1", "value1");
|
config.put("key1", "value1");
|
||||||
pmm.getConfig().put("key2", "value2");
|
config.put("key2", "value2");
|
||||||
|
pmm.setConfig(config);
|
||||||
newInstance.setProtocolMapper("pmm-id", pmm);
|
newInstance.setProtocolMapper("pmm-id", pmm);
|
||||||
newInstance.setAttribute("attr", Arrays.asList("aa", "bb", "cc"));
|
newInstance.setAttribute("attr", Arrays.asList("aa", "bb", "cc"));
|
||||||
|
|
||||||
|
@ -122,9 +125,11 @@ public class MapClientEntityClonerTest {
|
||||||
newInstance.setAttribute("attr", Arrays.asList("aa", "bb", "cc"));
|
newInstance.setAttribute("attr", Arrays.asList("aa", "bb", "cc"));
|
||||||
MapProtocolMapperEntity pmm = new MapProtocolMapperEntityImpl();
|
MapProtocolMapperEntity pmm = new MapProtocolMapperEntityImpl();
|
||||||
pmm.setId("pmm-id");
|
pmm.setId("pmm-id");
|
||||||
pmm.setConfig(new HashMap<>());
|
Map<String, String> config = new HashMap<>();
|
||||||
pmm.getConfig().put("key1", "value1");
|
config.put("key1", "value1");
|
||||||
pmm.getConfig().put("key2", "value2");
|
config.put("key2", "value2");
|
||||||
|
pmm.setConfig(config);
|
||||||
|
|
||||||
newInstance.setProtocolMapper("pmm-id", pmm);
|
newInstance.setProtocolMapper("pmm-id", pmm);
|
||||||
newInstance.setAttribute("attr", Arrays.asList("aa", "bb", "cc"));
|
newInstance.setAttribute("attr", Arrays.asList("aa", "bb", "cc"));
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,267 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2022 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.realm;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
|
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||||
|
import static org.hamcrest.CoreMatchers.nullValue;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.aMapWithSize;
|
||||||
|
import static org.hamcrest.Matchers.allOf;
|
||||||
|
import static org.hamcrest.Matchers.anEmptyMap;
|
||||||
|
import static org.hamcrest.Matchers.contains;
|
||||||
|
import static org.hamcrest.Matchers.hasEntry;
|
||||||
|
import static org.hamcrest.Matchers.hasKey;
|
||||||
|
|
||||||
|
public class RealmEntityUndefinedValuesTest {
|
||||||
|
|
||||||
|
public MapRealmEntity newMapRealmEntity() {
|
||||||
|
return new MapRealmEntityImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUndefinedValuesToCollection() {
|
||||||
|
// setup
|
||||||
|
MapRealmEntity realmEntity = newMapRealmEntity();
|
||||||
|
{
|
||||||
|
// when
|
||||||
|
realmEntity.setEventsListeners(null);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(realmEntity.getEventsListeners(), nullValue());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// when
|
||||||
|
realmEntity.setEventsListeners(Collections.emptySet());
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(realmEntity.getEventsListeners(), nullValue());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// when
|
||||||
|
realmEntity.setEventsListeners(Collections.singleton(null));
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(realmEntity.getEventsListeners(), nullValue());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// when
|
||||||
|
realmEntity.setEventsListeners(Collections.singleton("listener1"));
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(realmEntity.getEventsListeners(), contains("listener1"));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// when
|
||||||
|
realmEntity.setEventsListeners(Collections.emptySet());
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(realmEntity.getEventsListeners(), nullValue());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// when
|
||||||
|
realmEntity.addOptionalClientScopeId(null);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(realmEntity.getOptionalClientScopeIds(), nullValue());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// when
|
||||||
|
realmEntity.addOptionalClientScopeId("id1");
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(realmEntity.getOptionalClientScopeIds(), notNullValue());
|
||||||
|
assertThat(realmEntity.getOptionalClientScopeIds(), contains("id1"));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// when
|
||||||
|
realmEntity.addOptionalClientScopeId(null);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(realmEntity.getOptionalClientScopeIds(), notNullValue());
|
||||||
|
assertThat(realmEntity.getOptionalClientScopeIds(), contains("id1"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddUndefinedValuesToMapStringString() {
|
||||||
|
// setup
|
||||||
|
MapRealmEntity realmEntity = newMapRealmEntity();
|
||||||
|
Map<String, String> headers = new HashMap<>();
|
||||||
|
|
||||||
|
{
|
||||||
|
// when
|
||||||
|
realmEntity.setBrowserSecurityHeaders(Collections.emptyMap());
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(realmEntity.getBrowserSecurityHeaders(), nullValue());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// when
|
||||||
|
headers.put("key1", null);
|
||||||
|
realmEntity.setBrowserSecurityHeaders(headers);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(realmEntity.getBrowserSecurityHeaders(), nullValue());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// when
|
||||||
|
headers.put("key1", "value1");
|
||||||
|
realmEntity.setBrowserSecurityHeaders(headers);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(realmEntity.getBrowserSecurityHeaders(), notNullValue());
|
||||||
|
assertThat(realmEntity.getBrowserSecurityHeaders(), allOf(aMapWithSize(1), hasEntry(equalTo("key1"), equalTo("value1"))));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// when
|
||||||
|
headers.put("key2", null);
|
||||||
|
realmEntity.setBrowserSecurityHeaders(headers);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(realmEntity.getBrowserSecurityHeaders(), notNullValue());
|
||||||
|
assertThat(realmEntity.getBrowserSecurityHeaders(), allOf(aMapWithSize(1), hasEntry(equalTo("key1"), equalTo("value1"))));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// when
|
||||||
|
realmEntity.setBrowserSecurityHeaders(Collections.emptyMap());
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(realmEntity.getBrowserSecurityHeaders(), nullValue());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// when
|
||||||
|
realmEntity.setBrowserSecurityHeader("key1", null);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(realmEntity.getBrowserSecurityHeaders(), nullValue());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// when
|
||||||
|
realmEntity.setBrowserSecurityHeader("key1", "value1");
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(realmEntity.getBrowserSecurityHeaders(), allOf(aMapWithSize(1), hasEntry(equalTo("key1"), equalTo("value1"))));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// when
|
||||||
|
realmEntity.setBrowserSecurityHeader("key2", null);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(realmEntity.getBrowserSecurityHeaders(), allOf(aMapWithSize(1), hasEntry(equalTo("key1"), equalTo("value1"))));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// when
|
||||||
|
realmEntity.setBrowserSecurityHeader("key1", null);
|
||||||
|
|
||||||
|
// then
|
||||||
|
// TODO: Should we set map to null if we remove last entry by calling set*(key, null) method?
|
||||||
|
assertThat(realmEntity.getBrowserSecurityHeaders(), anEmptyMap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddUndefinedValuesToMapStringList() {
|
||||||
|
MapRealmEntity realmEntity = newMapRealmEntity();
|
||||||
|
Map<String, List<String>> attributes = new HashMap<>();
|
||||||
|
|
||||||
|
{
|
||||||
|
// when
|
||||||
|
attributes.put("key1", Collections.emptyList());
|
||||||
|
realmEntity.setAttributes(attributes);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(realmEntity.getAttributes(), nullValue());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// when
|
||||||
|
attributes.put("key1", Collections.singletonList(null));
|
||||||
|
realmEntity.setAttributes(attributes);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(realmEntity.getAttributes(), nullValue());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// when
|
||||||
|
attributes.put("key1", Arrays.asList(null, null, null));
|
||||||
|
realmEntity.setAttributes(attributes);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(realmEntity.getAttributes(), nullValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddUndefinedValuesToMapStringMap() {
|
||||||
|
MapRealmEntity realmEntity = newMapRealmEntity();
|
||||||
|
Map<String, String> localizationTexts = new HashMap<>();
|
||||||
|
|
||||||
|
{
|
||||||
|
// when
|
||||||
|
realmEntity.setLocalizationText("en", Collections.emptyMap());
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(realmEntity.getLocalizationText("en"), nullValue());
|
||||||
|
assertThat(realmEntity.getLocalizationTexts(), nullValue());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// when
|
||||||
|
realmEntity.setLocalizationText("en", Collections.singletonMap("key1", null));
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(realmEntity.getLocalizationText("en"), nullValue());
|
||||||
|
assertThat(realmEntity.getLocalizationTexts(), nullValue());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// when
|
||||||
|
realmEntity.setLocalizationText("en", Collections.singletonMap("key1", "value1"));
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(realmEntity.getLocalizationTexts(), allOf(aMapWithSize(1), hasKey("en")));
|
||||||
|
assertThat(realmEntity.getLocalizationText("en"), allOf(aMapWithSize(1), hasEntry(equalTo("key1"), equalTo("value1"))));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// when
|
||||||
|
localizationTexts.put("key1", "value1");
|
||||||
|
localizationTexts.put("key2", null);
|
||||||
|
realmEntity.setLocalizationText("en", localizationTexts);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(realmEntity.getLocalizationTexts(), allOf(aMapWithSize(1), hasKey("en")));
|
||||||
|
assertThat(realmEntity.getLocalizationText("en"), allOf(aMapWithSize(1), hasEntry(equalTo("key1"), equalTo("value1"))));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// when
|
||||||
|
localizationTexts.put("key1", null);
|
||||||
|
localizationTexts.put("key2", null);
|
||||||
|
realmEntity.setLocalizationText("en", localizationTexts);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(realmEntity.getLocalizationTexts(), anEmptyMap());
|
||||||
|
assertThat(realmEntity.getLocalizationText("en"), nullValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -61,9 +61,12 @@ import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.anyOf;
|
||||||
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
|
import static org.hamcrest.CoreMatchers.nullValue;
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertThat;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
import static org.keycloak.testsuite.Assert.assertNames;
|
import static org.keycloak.testsuite.Assert.assertNames;
|
||||||
|
@ -698,7 +701,7 @@ public class ClientScopeTest extends AbstractClientTest {
|
||||||
scopeRep = clientScopes().get(scopeDefId).toRepresentation();
|
scopeRep = clientScopes().get(scopeDefId).toRepresentation();
|
||||||
assertEquals("non-dynamic-scope-def", scopeRep.getName());
|
assertEquals("non-dynamic-scope-def", scopeRep.getName());
|
||||||
assertEquals("false", scopeRep.getAttributes().get(ClientScopeModel.IS_DYNAMIC_SCOPE));
|
assertEquals("false", scopeRep.getAttributes().get(ClientScopeModel.IS_DYNAMIC_SCOPE));
|
||||||
assertEquals("", scopeRep.getAttributes().get(ClientScopeModel.DYNAMIC_SCOPE_REGEXP));
|
assertThat(scopeRep.getAttributes().get(ClientScopeModel.DYNAMIC_SCOPE_REGEXP), anyOf(nullValue(), equalTo("")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -766,7 +769,7 @@ public class ClientScopeTest extends AbstractClientTest {
|
||||||
clientScopes().get(scopeDefId).update(scopeRep);
|
clientScopes().get(scopeDefId).update(scopeRep);
|
||||||
Assert.fail("This update should fail");
|
Assert.fail("This update should fail");
|
||||||
} catch (ClientErrorException ex) {
|
} catch (ClientErrorException ex) {
|
||||||
MatcherAssert.assertThat(ex.getResponse(), Matchers.statusCodeIs(Status.BAD_REQUEST));
|
assertThat(ex.getResponse(), Matchers.statusCodeIs(Status.BAD_REQUEST));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -794,7 +797,7 @@ public class ClientScopeTest extends AbstractClientTest {
|
||||||
clientResource.addDefaultClientScope(optionalClientScopeId);
|
clientResource.addDefaultClientScope(optionalClientScopeId);
|
||||||
Assert.fail("A Dynamic Scope shouldn't not be assigned as a default scope to a client");
|
Assert.fail("A Dynamic Scope shouldn't not be assigned as a default scope to a client");
|
||||||
} catch (ClientErrorException ex) {
|
} catch (ClientErrorException ex) {
|
||||||
MatcherAssert.assertThat(ex.getResponse(), Matchers.statusCodeIs(Status.BAD_REQUEST));
|
assertThat(ex.getResponse(), Matchers.statusCodeIs(Status.BAD_REQUEST));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue