Generate map-like collection accessors

Along the way fixes also problem with field delegates which
applied manually-crafted methods like `MapUserEntity.removeCredential(id)`
to the delegate itself rather than to the underlying object.

Co-authored-By: Michal Hajas <mhajas@redhat.com>

Closes: #17223
This commit is contained in:
Hynek Mlnarik 2023-02-20 20:23:23 +01:00 committed by Hynek Mlnařík
parent 878debd2ab
commit 7d136c5cca
27 changed files with 314 additions and 471 deletions

View File

@ -0,0 +1,41 @@
/*
* Copyright 2023 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.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Determines getter of a field which is unique across a set of the same entities within the same context.
* This field can be used as unique key in map-like access to a collection. For example, in the set of
* user consents, this can be client ID.
*
* @author hmlnarik
*/
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.METHOD)
public @interface CollectionKey {
/**
* Priority of this annotation: The higher the value, the more appropriate the annotation is.
* @return
*/
public int priority() default 0;
}

View File

@ -17,6 +17,7 @@
package org.keycloak.models.map.processor;
import org.keycloak.models.map.annotations.CollectionKey;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.Element;
@ -37,6 +38,7 @@ import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@ -90,6 +92,39 @@ public abstract class AbstractGenerateEntityImplementationsProcessor extends Abs
return true;
}
public ExecutableElement getCollectionKey(TypeMirror fieldType, ExecutableElement callingMethod) {
if (! Util.isCollectionType(elements.getTypeElement(types.erasure(fieldType).toString()))) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Invalid collection type: " + fieldType, callingMethod);
return null;
}
TypeMirror collectionType = getGenericsDeclaration(fieldType).get(0);
TypeElement collectionTypeEl = elements.getTypeElement(types.erasure(collectionType).toString());
Iterator<ExecutableElement> it = elements.getAllMembers(collectionTypeEl).stream()
.filter(el -> el.getKind() == ElementKind.METHOD)
.filter(el -> el.getAnnotation(CollectionKey.class) != null)
.sorted(Comparator.comparing((Element el) -> el.getAnnotation(CollectionKey.class).priority()).reversed())
.filter(ExecutableElement.class::isInstance)
.map(ExecutableElement.class::cast)
.iterator();
ExecutableElement res = null;
if (it.hasNext()) {
res = it.next();
if (! res.getParameters().isEmpty() || ! "java.lang.String".equals(res.getReturnType().toString())) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Invalid getter annotated with @CollectionKey in " + res, callingMethod);
}
if (it.hasNext() && it.next().getAnnotation(CollectionKey.class).priority() == res.getAnnotation(CollectionKey.class).priority()) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Multiple getters annotated with @CollectionKey found: " + res + ", " + it.next(), callingMethod);
}
} else {
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "No getters annotated with @CollectionKey in " + collectionType, callingMethod);
}
return res;
}
protected boolean testAnnotationElement(TypeElement kind) { return true; }
protected void afterAnnotationProcessing() {}
protected abstract Generator[] getGenerators();

View File

@ -33,6 +33,9 @@ import static org.keycloak.models.map.processor.Util.pluralToSingular;
* @author hmlnarik
*/
enum FieldAccessorType {
// Order does matter, see {@link #getMethod}
GETTER {
@Override
public boolean is(ExecutableElement method, String fieldName, Types types, TypeMirror fieldType) {
@ -95,6 +98,28 @@ enum FieldAccessorType {
&& types.isSameType(res.get(0), method.getParameters().get(0).asType());
}
},
COLLECTION_GET_BY_ID {
@Override
public boolean is(ExecutableElement method, String fieldName, Types types, TypeMirror fieldType) {
String fieldNameSingular = pluralToSingular(fieldName);
String getFromCollection = "get" + fieldNameSingular;
List<TypeMirror> res = getGenericsDeclaration(fieldType);
return Objects.equals(getFromCollection, method.getSimpleName().toString())
&& method.getParameters().size() == 1
&& res.size() == 1
&& Objects.equals("java.lang.String", method.getParameters().get(0).asType().toString());
}
},
COLLECTION_DELETE_BY_ID {
@Override
public boolean is(ExecutableElement method, String fieldName, Types types, TypeMirror fieldType) {
String fieldNameSingular = pluralToSingular(fieldName);
String removeFromCollection = "remove" + fieldNameSingular;
return Objects.equals(removeFromCollection, method.getSimpleName().toString())
&& method.getParameters().size() == 1
&& Objects.equals("java.lang.String", method.getParameters().get(0).asType().toString());
}
},
UNKNOWN /* Must be the last */ {
@Override
public boolean is(ExecutableElement method, String fieldName, Types types, TypeMirror fieldType) {

View File

@ -225,6 +225,7 @@ public class GenerateEntityImplementationsProcessor extends AbstractGenerateEnti
pw.println(" }");
return;
case COLLECTION_DELETE:
{
String returnType = method.getReturnType().getKind() == TypeKind.VOID ? "Void" : method.getReturnType().toString();
TypeElement fieldTypeElement = elements.getTypeElement(types.erasure(fieldType).toString());
if (Util.isMapType(fieldTypeElement)) {
@ -235,10 +236,28 @@ public class GenerateEntityImplementationsProcessor extends AbstractGenerateEnti
if (method.getReturnType().getKind() == TypeKind.VOID) {
pw.println(" e." + method.getSimpleName() + "((" + firstParameterType + ") p0); return null;");
} else {
pw.println(" return (" + method.getReturnType() + ") e." + method.getSimpleName() + "((" + firstParameterType + ") p0);");
pw.println(" return e." + method.getSimpleName() + "((" + firstParameterType + ") p0);");
}
pw.println(" }");
return;
}
case COLLECTION_DELETE_BY_ID:
{
String returnType = method.getReturnType().getKind() == TypeKind.VOID ? "Void" : method.getReturnType().toString();
pw.println(" @SuppressWarnings(\"unchecked\") @Override public <K> " + returnType + " mapRemove(" + className + " e, K p0) {");
if (method.getReturnType().getKind() == TypeKind.VOID) {
pw.println(" e." + method.getSimpleName() + "((String) p0); return null;");
} else {
pw.println(" return e." + method.getSimpleName() + "((String) p0);");
}
pw.println(" }");
return;
}
case COLLECTION_GET_BY_ID:
pw.println(" @SuppressWarnings(\"unchecked\") @Override public <K> " + method.getReturnType() + " mapGet(" + className + " e, K key) {");
pw.println(" return e." + method.getSimpleName() + "((" + firstParameterType + ") key);");
pw.println(" }");
return;
case MAP_ADD:
TypeMirror secondParameterType = method.getParameters().get(1).asType();
pw.println(" @SuppressWarnings(\"unchecked\") @Override public <K, T> void mapPut(" + className + " e, K key, T value) {");
@ -288,6 +307,7 @@ public class GenerateEntityImplementationsProcessor extends AbstractGenerateEnti
}
pw.println("import java.util.Objects;");
pw.println("import java.util.Optional;");
pw.println("import " + FQN_DEEP_CLONER + ";");
pw.println("// DO NOT CHANGE THIS CLASS, IT IS GENERATED AUTOMATICALLY BY " + GenerateEntityImplementationsProcessor.class.getSimpleName());
generatedAnnotation(pw);
@ -454,6 +474,7 @@ public class GenerateEntityImplementationsProcessor extends AbstractGenerateEnti
pw.println(" }");
return true;
case COLLECTION_DELETE:
{
boolean needsReturn = method.getReturnType().getKind() != TypeKind.VOID;
pw.println(" @SuppressWarnings(\"unchecked\") @Override public " + method.getReturnType() + " " + method.getSimpleName() + "(" + firstParameterType + " p0) {");
pw.println(" if (" + fieldName + " == null) { return" + (needsReturn ? " false" : "") + "; }");
@ -462,6 +483,25 @@ public class GenerateEntityImplementationsProcessor extends AbstractGenerateEnti
if (needsReturn) pw.println(" return removed;");
pw.println(" }");
return true;
}
case COLLECTION_DELETE_BY_ID:
{
boolean needsReturn = method.getReturnType().getKind() != TypeKind.VOID;
pw.println(" @SuppressWarnings(\"unchecked\") @Override public " + method.getReturnType() + " " + method.getSimpleName() + "(String p0) {");
pw.println(" boolean removed = " + fieldName + " != null && " + fieldName + ".removeIf(o -> Objects.equals(o." + getCollectionKey(fieldType, method) + ", p0));");
pw.println(" updated |= removed;");
if (needsReturn) pw.println(" return removed;");
pw.println(" }");
return true;
}
case COLLECTION_GET_BY_ID:
{
pw.println(" @SuppressWarnings(\"unchecked\") @Override public " + method.getReturnType() + " " + method.getSimpleName() + "(String p0) {");
pw.println(" if (" + fieldName + " == null || " + fieldName + ".isEmpty()) return Optional.empty();");
pw.println(" return " + fieldName + ".stream().filter(o -> Objects.equals(o." + getCollectionKey(fieldType, method) + ", p0)).findFirst();");
pw.println(" }");
return true;
}
case MAP_ADD:
TypeMirror secondParameterType = method.getParameters().get(1).asType();
pw.println(" @SuppressWarnings(\"unchecked\") @Override public " + method.getReturnType() + " " + method.getSimpleName() + "(" + firstParameterType + " p0, " + secondParameterType + " p1) {");
@ -580,6 +620,7 @@ public class GenerateEntityImplementationsProcessor extends AbstractGenerateEnti
pw.println(" }");
return true;
case COLLECTION_DELETE:
{
pw.println(" @SuppressWarnings(\"unchecked\") @Override public " + method.getReturnType() + " " + method.getSimpleName() + "(" + firstParameterType + " p0) {");
TypeElement fieldTypeElement = elements.getTypeElement(types.erasure(fieldType).toString());
String removeMethod = Util.isMapType(fieldTypeElement) ? "mapRemove" : "collectionRemove";
@ -590,12 +631,25 @@ public class GenerateEntityImplementationsProcessor extends AbstractGenerateEnti
}
pw.println(" }");
return true;
}
case COLLECTION_DELETE_BY_ID:
{
pw.println(" @SuppressWarnings(\"unchecked\") @Override public " + method.getReturnType() + " " + method.getSimpleName() + "(String p0) {");
if (method.getReturnType().getKind() == TypeKind.VOID) {
pw.println(" entityFieldDelegate.mapRemove(" + fieldName + ", p0);");
} else {
pw.println(" return (" + method.getReturnType() + ") entityFieldDelegate.mapRemove(" + fieldName + ", p0);");
}
pw.println(" }");
return true;
}
case MAP_ADD:
TypeMirror secondParameterType = method.getParameters().get(1).asType();
pw.println(" @SuppressWarnings(\"unchecked\") @Override public " + method.getReturnType() + " " + method.getSimpleName() + "(" + firstParameterType + " p0, " + secondParameterType + " p1) {");
pw.println(" entityFieldDelegate.mapPut(" + fieldName + ", p0, p1);");
pw.println(" }");
return true;
case COLLECTION_GET_BY_ID:
case MAP_GET:
pw.println(" @SuppressWarnings(\"unchecked\") @Override public " + method.getReturnType() + " " + method.getSimpleName() + "(" + firstParameterType + " p0) {");
pw.println(" return (" + method.getReturnType() + ") entityFieldDelegate.mapGet(" + fieldName + ", p0);");

View File

@ -344,6 +344,13 @@ public class GenerateHotRodEntityImplementationsProcessor extends AbstractGenera
return "this." + ENTITY_VARIABLE + "." + fieldName;
}
private String getFieldNameForCollectionKey(TypeMirror fieldType, ExecutableElement callingMethod) {
ExecutableElement collectionKey = getCollectionKey(fieldType, callingMethod);
char[] c = determineAttributeFromMethodName(collectionKey).toCharArray();
c[0] = Character.toLowerCase(c[0]);
return new String(c);
}
private boolean printMethodBody(PrintWriter pw, FieldAccessorType accessorType, ExecutableElement method, String fieldName, TypeMirror fieldType, TypeMirror hotRodFieldType) {
TypeMirror firstParameterType = method.getParameters().isEmpty()
? types.getNullType()
@ -393,6 +400,7 @@ public class GenerateHotRodEntityImplementationsProcessor extends AbstractGenera
pw.println(" }");
return true;
case COLLECTION_DELETE:
{
collectionItemType = getGenericsDeclaration(hotRodFieldType).get(0);
boolean needsReturn = method.getReturnType().getKind() != TypeKind.VOID;
pw.println(" @SuppressWarnings(\"unchecked\") @Override public " + method.getReturnType() + " " + method.getSimpleName() + "(" + firstParameterType + " p0) {");
@ -412,6 +420,27 @@ public class GenerateHotRodEntityImplementationsProcessor extends AbstractGenera
if (needsReturn) pw.println(" return removed;");
pw.println(" }");
return true;
}
case COLLECTION_DELETE_BY_ID:
{
boolean needsReturn = method.getReturnType().getKind() != TypeKind.VOID;
pw.println(" @SuppressWarnings(\"unchecked\") @Override public " + method.getReturnType() + " " + method.getSimpleName() + "(String p0) {");
pw.println(" boolean removed = " + hotRodEntityField(fieldName) + " != null && " + hotRodEntityField(fieldName) + ".removeIf(o -> Objects.equals(o." + getFieldNameForCollectionKey(fieldType, method) + ", p0));");
pw.println(" " + hotRodEntityField("updated") + " |= removed;");
if (needsReturn) pw.println(" return removed;");
pw.println(" }");
return true;
}
case COLLECTION_GET_BY_ID:
{
collectionItemType = getGenericsDeclaration(hotRodFieldType).get(0);
TypeMirror returnTypeGeneric = getGenericsDeclaration(method.getReturnType()).get(0);
pw.println(" @SuppressWarnings(\"unchecked\") @Override public " + method.getReturnType() + " " + method.getSimpleName() + "(String p0) {");
pw.println(" if (" + hotRodEntityField(fieldName) + " == null || " + hotRodEntityField(fieldName) + ".isEmpty()) return Optional.empty();");
pw.println(" return " + hotRodEntityField(fieldName) + ".stream().filter(o -> Objects.equals(o." + getFieldNameForCollectionKey(fieldType, method) + ", p0)).findFirst().map(e -> " + migrateToType(returnTypeGeneric, collectionItemType, "e") + ");");
pw.println(" }");
return true;
}
case MAP_ADD:
collectionItemType = getGenericsDeclaration(hotRodFieldType).get(0);
TypeMirror secondParameterType = method.getParameters().get(1).asType();

View File

@ -99,26 +99,6 @@ public class HotRodRootAuthenticationSessionEntity extends AbstractHotRodEntity
entity.updated |= id != null;
}
@Override
public Optional<MapAuthenticationSessionEntity> getAuthenticationSession(String tabId) {
HotRodRootAuthenticationSessionEntity rootAuthSession = getHotRodEntity();
if (rootAuthSession.authenticationSessions == null || rootAuthSession.authenticationSessions.isEmpty()) return Optional.empty();
return rootAuthSession.authenticationSessions.stream()
.filter(as -> Objects.equals(as.tabId, tabId))
.findFirst()
.map(HotRodAuthenticationSessionEntityDelegate::new);
}
@Override
public Boolean removeAuthenticationSession(String tabId) {
HotRodRootAuthenticationSessionEntity rootAuthSession = getHotRodEntity();
boolean removed = rootAuthSession.authenticationSessions != null &&
rootAuthSession.authenticationSessions.removeIf(c -> Objects.equals(c.tabId, tabId));
rootAuthSession.updated |= removed;
return removed;
}
@Override
public boolean isUpdated() {
HotRodRootAuthenticationSessionEntity rootAuthSession = getHotRodEntity();

View File

@ -209,20 +209,6 @@ public class HotRodClientEntity extends AbstractHotRodEntity {
.filter(me -> Objects.equals(me.getValue(), defaultScope))
.map(Map.Entry::getKey);
}
@Override
public Optional<MapProtocolMapperEntity> getProtocolMapper(String id) {
Set<MapProtocolMapperEntity> mappers = getProtocolMappers();
if (mappers == null || mappers.isEmpty()) return Optional.empty();
return mappers.stream().filter(m -> Objects.equals(m.getId(), id)).findFirst();
}
@Override
public void removeProtocolMapper(String id) {
HotRodClientEntity entity = getHotRodEntity();
entity.updated |= entity.protocolMappers != null && entity.protocolMappers.removeIf(m -> Objects.equals(m.id, id));
}
}
@Override

View File

@ -109,20 +109,6 @@ public class HotRodClientScopeEntity extends AbstractHotRodEntity {
entity.id = id;
entity.updated |= id != null;
}
@Override
public Optional<MapProtocolMapperEntity> getProtocolMapper(String id) {
Set<MapProtocolMapperEntity> mappers = getProtocolMappers();
if (mappers == null || mappers.isEmpty()) return Optional.empty();
return mappers.stream().filter(m -> Objects.equals(m.getId(), id)).findFirst();
}
@Override
public void removeProtocolMapper(String id) {
HotRodClientScopeEntity entity = getHotRodEntity();
entity.updated |= entity.protocolMappers != null && entity.protocolMappers.removeIf(m -> Objects.equals(m.id, id));
}
}
@Override

View File

@ -323,126 +323,6 @@ public class HotRodRealmEntity extends AbstractHotRodEntity {
Optional.ofNullable(getWebAuthnPolicyPasswordless()).ifPresent(UpdatableEntity::clearUpdatedFlag);
}
@Override
public Optional<MapComponentEntity> getComponent(String id) {
Set<HotRodComponentEntity> set = getHotRodEntity().components;
if (set == null || set.isEmpty()) return Optional.empty();
return set.stream().filter(ob -> Objects.equals(ob.id, id)).findFirst().map(HotRodComponentEntityDelegate::new);
}
@Override
public Boolean removeComponent(String componentId) {
Set<HotRodComponentEntity> set = getHotRodEntity().components;
boolean removed = set != null && set.removeIf(ob -> Objects.equals(ob.id, componentId));
getHotRodEntity().updated |= removed;
return removed;
}
@Override
public Optional<MapAuthenticationExecutionEntity> getAuthenticationExecution(String id) {
Set<HotRodAuthenticationExecutionEntity> set = getHotRodEntity().authenticationExecutions;
if (set == null || set.isEmpty()) return Optional.empty();
return set.stream().filter(ob -> Objects.equals(ob.id, id)).findFirst().map(HotRodAuthenticationExecutionEntityDelegate::new);
}
@Override
public Boolean removeAuthenticationExecution(String executionId) {
Set<HotRodAuthenticationExecutionEntity> set = getHotRodEntity().authenticationExecutions;
boolean removed = set != null && set.removeIf(ob -> Objects.equals(ob.id, executionId));
getHotRodEntity().updated |= removed;
return removed;
}
@Override
public Optional<MapAuthenticationFlowEntity> getAuthenticationFlow(String flowId) {
Set<HotRodAuthenticationFlowEntity> set = getHotRodEntity().authenticationFlows;
if (set == null || set.isEmpty()) return Optional.empty();
return set.stream().filter(ob -> Objects.equals(ob.id, flowId)).findFirst().map(HotRodAuthenticationFlowEntityDelegate::new);
}
@Override
public Boolean removeAuthenticationFlow(String flowId) {
Set<HotRodAuthenticationFlowEntity> set = getHotRodEntity().authenticationFlows;
boolean removed = set != null && set.removeIf(ob -> Objects.equals(ob.id, flowId));
getHotRodEntity().updated |= removed;
return removed;
}
@Override
public Boolean removeAuthenticatorConfig(String authenticatorConfigId) {
Set<HotRodAuthenticatorConfigEntity> set = getHotRodEntity().authenticatorConfigs;
boolean removed = set != null && set.removeIf(ob -> Objects.equals(ob.id, authenticatorConfigId));
getHotRodEntity().updated |= removed;
return removed;
}
@Override
public Optional<MapAuthenticatorConfigEntity> getAuthenticatorConfig(String authenticatorConfigId) {
Set<HotRodAuthenticatorConfigEntity> set = getHotRodEntity().authenticatorConfigs;
if (set == null || set.isEmpty()) return Optional.empty();
return set.stream().filter(ob -> Objects.equals(ob.id, authenticatorConfigId)).findFirst().map(HotRodAuthenticatorConfigEntityDelegate::new);
}
@Override
public Boolean removeIdentityProviderMapper(String identityProviderMapperId) {
Set<HotRodIdentityProviderMapperEntity> set = getHotRodEntity().identityProviderMappers;
boolean removed = set != null && set.removeIf(ob -> Objects.equals(ob.id, identityProviderMapperId));
getHotRodEntity().updated |= removed;
return removed;
}
@Override
public Optional<MapIdentityProviderMapperEntity> getIdentityProviderMapper(String identityProviderMapperId) {
Set<HotRodIdentityProviderMapperEntity> set = getHotRodEntity().identityProviderMappers;
if (set == null || set.isEmpty()) return Optional.empty();
return set.stream().filter(ob -> Objects.equals(ob.id, identityProviderMapperId)).findFirst().map(HotRodIdentityProviderMapperEntityDelegate::new);
}
@Override
public Boolean removeIdentityProvider(String identityProviderId) {
Set<HotRodIdentityProviderEntity> set = getHotRodEntity().identityProviders;
boolean removed = set != null && set.removeIf(ob -> Objects.equals(ob.id, identityProviderId));
getHotRodEntity().updated |= removed;
return removed;
}
@Override
public Optional<MapClientInitialAccessEntity> getClientInitialAccess(String clientInitialAccessId) {
Set<HotRodClientInitialAccessEntity> set = getHotRodEntity().clientInitialAccesses;
if (set == null || set.isEmpty()) return Optional.empty();
return set.stream().filter(ob -> Objects.equals(ob.id, clientInitialAccessId)).findFirst().map(HotRodClientInitialAccessEntityDelegate::new);
}
@Override
public Boolean removeClientInitialAccess(String clientInitialAccessId) {
Set<HotRodClientInitialAccessEntity> set = getHotRodEntity().clientInitialAccesses;
boolean removed = set != null && set.removeIf(ob -> Objects.equals(ob.id, clientInitialAccessId));
getHotRodEntity().updated |= removed;
return removed;
}
@Override
public Optional<MapRequiredActionProviderEntity> getRequiredActionProvider(String requiredActionProviderId) {
Set<HotRodRequiredActionProviderEntity> set = getHotRodEntity().requiredActionProviders;
if (set == null || set.isEmpty()) return Optional.empty();
return set.stream().filter(ob -> Objects.equals(ob.id, requiredActionProviderId)).findFirst().map(HotRodRequiredActionProviderEntityDelegate::new);
}
@Override
public Boolean removeRequiredActionProvider(String requiredActionProviderId) {
Set<HotRodRequiredActionProviderEntity> set = getHotRodEntity().requiredActionProviders;
boolean removed = set != null && set.removeIf(ob -> Objects.equals(ob.id, requiredActionProviderId));
getHotRodEntity().updated |= removed;
return removed;
}
@Override
public boolean hasClientInitialAccess() {
Set<MapClientInitialAccessEntity> cias = getClientInitialAccesses();

View File

@ -227,38 +227,6 @@ public class HotRodUserEntity extends AbstractHotRodEntity {
Optional.ofNullable(getFederatedIdentities()).orElseGet(Collections::emptySet).forEach(UpdatableEntity::clearUpdatedFlag);
}
@Override
public Optional<MapUserConsentEntity> getUserConsent(String clientId) {
Set<HotRodUserConsentEntity> ucs = getHotRodEntity().userConsents;
if (ucs == null || ucs.isEmpty()) return Optional.empty();
return ucs.stream().filter(uc -> Objects.equals(uc.clientId, clientId)).findFirst().map(HotRodUserConsentEntityDelegate::new);
}
@Override
public Boolean removeUserConsent(String clientId) {
Set<HotRodUserConsentEntity> consents = getHotRodEntity().userConsents;
boolean removed = consents != null && consents.removeIf(uc -> Objects.equals(uc.clientId, clientId));
getHotRodEntity().updated |= removed;
return removed;
}
@Override
public Optional<MapUserCredentialEntity> getCredential(String id) {
List<HotRodUserCredentialEntity> uce = getHotRodEntity().credentials;
if (uce == null || uce.isEmpty()) return Optional.empty();
return uce.stream().filter(uc -> Objects.equals(uc.id, id)).findFirst().map(HotRodUserCredentialEntityDelegate::new);
}
@Override
public Boolean removeCredential(String id) {
List<HotRodUserCredentialEntity> credentials = getHotRodEntity().credentials;
boolean removed = credentials != null && credentials.removeIf(c -> Objects.equals(c.id, id));
getHotRodEntity().updated |= removed;
return removed;
}
@Override
public Boolean moveCredential(String credentialId, String newPreviousCredentialId) {
// 1 - Get all credentials from the entity.
@ -302,22 +270,6 @@ public class HotRodUserEntity extends AbstractHotRodEntity {
return true;
}
@Override
public Optional<MapUserFederatedIdentityEntity> getFederatedIdentity(String identityProviderId) {
Set<HotRodUserFederatedIdentityEntity> fes = getHotRodEntity().federatedIdentities;
if (fes == null || fes.isEmpty()) return Optional.empty();
return fes.stream().filter(fi -> Objects.equals(fi.identityProvider, identityProviderId)).findFirst().map(HotRodUserFederatedIdentityEntityDelegate::new);
}
@Override
public Boolean removeFederatedIdentity(String identityProviderId) {
Set<HotRodUserFederatedIdentityEntity> federatedIdentities = getHotRodEntity().federatedIdentities;
boolean removed = federatedIdentities != null && federatedIdentities.removeIf(fi -> Objects.equals(fi.identityProvider, identityProviderId));
getHotRodEntity().updated |= removed;
return removed;
}
}
@Override

View File

@ -166,25 +166,6 @@ public class HotRodUserSessionEntity extends AbstractHotRodEntity {
Optional.ofNullable(getAuthenticatedClientSessions()).orElseGet(Collections::emptySet).forEach(UpdatableEntity::clearUpdatedFlag);
}
@Override
public Optional<MapAuthenticatedClientSessionEntity> getAuthenticatedClientSession(String clientUUID) {
Set<HotRodAuthenticatedClientSessionEntityReference> acss = getHotRodEntity().authenticatedClientSessions;
if (acss == null || acss.isEmpty()) return Optional.empty();
return acss.stream()
.filter(acs -> Objects.equals(acs.clientId, clientUUID))
.findFirst()
.map(HotRodTypesUtils::migrateHotRodAuthenticatedClientSessionEntityReferenceToMapAuthenticatedClientSessionEntity);
}
@Override
public Boolean removeAuthenticatedClientSession(String clientUUID) {
Set<HotRodAuthenticatedClientSessionEntityReference> acss = getHotRodEntity().authenticatedClientSessions;
boolean removed = acss != null && acss.removeIf(uc -> Objects.equals(uc.clientId, clientUUID));
getHotRodEntity().updated |= removed;
return removed;
}
@Override
public void clearAuthenticatedClientSessions() {
HotRodUserSessionEntity entity = getHotRodEntity();

View File

@ -47,6 +47,7 @@ import static org.keycloak.models.map.storage.jpa.Constants.CURRENT_SCHEMA_VERSI
import org.keycloak.models.map.common.UuidValidator;
import org.keycloak.models.map.storage.jpa.JpaRootVersionedEntity;
import org.keycloak.models.map.storage.jpa.hibernate.jsonb.JsonbType;
import java.util.Optional;
/**
* There are some fields marked by {@code @Column(insertable = false, updatable = false)}.
@ -215,11 +216,21 @@ public class JpaClientEntity extends AbstractClientEntity implements JpaRootVers
return metadata.getProtocolMappers();
}
@Override
public Optional<MapProtocolMapperEntity> getProtocolMapper(String id) {
return metadata.getProtocolMapper(id);
}
@Override
public void addProtocolMapper(MapProtocolMapperEntity mapping) {
metadata.addProtocolMapper(mapping);
}
@Override
public void removeProtocolMapper(String id) {
metadata.removeProtocolMapper(id);
}
@Override
public void addRedirectUri(String redirectUri) {
metadata.addRedirectUri(redirectUri);

View File

@ -47,6 +47,7 @@ import static org.keycloak.models.map.storage.jpa.Constants.CURRENT_SCHEMA_VERSI
import org.keycloak.models.map.common.UuidValidator;
import org.keycloak.models.map.storage.jpa.JpaRootVersionedEntity;
import org.keycloak.models.map.storage.jpa.hibernate.jsonb.JsonbType;
import java.util.Optional;
/**
* There are some fields marked by {@code @Column(insertable = false, updatable = false)}.
@ -162,11 +163,21 @@ public class JpaClientScopeEntity extends AbstractClientScopeEntity implements J
return metadata.getProtocolMappers();
}
@Override
public Optional<MapProtocolMapperEntity> getProtocolMapper(String id) {
return metadata.getProtocolMapper(id);
}
@Override
public void addProtocolMapper(MapProtocolMapperEntity mapping) {
metadata.addProtocolMapper(mapping);
}
@Override
public void removeProtocolMapper(String id) {
metadata.removeProtocolMapper(id);
}
@Override
public void addScopeMapping(String id) {
metadata.addScopeMapping(id);

View File

@ -902,41 +902,80 @@ public class JpaRealmEntity extends MapRealmEntity.AbstractRealmEntity implement
return this.metadata.getAuthenticationFlows();
}
@Override
public Optional<MapAuthenticationFlowEntity> getAuthenticationFlow(String p0) {
return metadata.getAuthenticationFlow(p0);
}
@Override
public void addAuthenticationFlow(MapAuthenticationFlowEntity authenticationFlow) {
this.metadata.addAuthenticationFlow(authenticationFlow);
}
@Override
public Boolean removeAuthenticationFlow(String p0) {
return metadata.removeAuthenticationFlow(p0);
}
@Override
public Set<MapAuthenticationExecutionEntity> getAuthenticationExecutions() {
return this.metadata.getAuthenticationExecutions();
}
public Optional<MapAuthenticationExecutionEntity> getAuthenticationExecution(String p0) {
return metadata.getAuthenticationExecution(p0);
}
@Override
public void addAuthenticationExecution(MapAuthenticationExecutionEntity authenticationExecution) {
this.metadata.addAuthenticationExecution(authenticationExecution);
}
@Override
public Boolean removeAuthenticationExecution(String p0) {
return metadata.removeAuthenticationExecution(p0);
}
@Override
public Set<MapAuthenticatorConfigEntity> getAuthenticatorConfigs() {
return this.metadata.getAuthenticatorConfigs();
}
@Override
public Optional<MapAuthenticatorConfigEntity> getAuthenticatorConfig(String p0) {
return metadata.getAuthenticatorConfig(p0);
}
@Override
public void addAuthenticatorConfig(MapAuthenticatorConfigEntity authenticatorConfig) {
this.metadata.addAuthenticatorConfig(authenticatorConfig);
}
@Override
public Boolean removeAuthenticatorConfig(String p0) {
return metadata.removeAuthenticatorConfig(p0);
}
@Override
public Set<MapRequiredActionProviderEntity> getRequiredActionProviders() {
return this.metadata.getRequiredActionProviders();
}
@Override
public Optional<MapRequiredActionProviderEntity> getRequiredActionProvider(String requiredActionProviderId) {
return this.metadata.getRequiredActionProvider(requiredActionProviderId);
}
@Override
public void addRequiredActionProvider(MapRequiredActionProviderEntity requiredActionProvider) {
this.metadata.addRequiredActionProvider(requiredActionProvider);
}
@Override
public Boolean removeRequiredActionProvider(String requiredActionProviderId) {
return this.metadata.removeRequiredActionProvider(requiredActionProviderId);
}
@Override
public Set<MapIdentityProviderEntity> getIdentityProviders() {
return this.metadata.getIdentityProviders();
@ -947,6 +986,11 @@ public class JpaRealmEntity extends MapRealmEntity.AbstractRealmEntity implement
this.metadata.addIdentityProvider(identityProvider);
}
@Override
public Boolean removeIdentityProvider(String p0) {
return metadata.removeIdentityProvider(p0);
}
@Override
public void addIdentityProviderMapper(MapIdentityProviderMapperEntity identityProviderMapper) {
this.metadata.addIdentityProviderMapper(identityProviderMapper);
@ -957,16 +1001,36 @@ public class JpaRealmEntity extends MapRealmEntity.AbstractRealmEntity implement
return this.metadata.getIdentityProviderMappers();
}
@Override
public Optional<MapIdentityProviderMapperEntity> getIdentityProviderMapper(String p0) {
return metadata.getIdentityProviderMapper(p0);
}
@Override
public Boolean removeIdentityProviderMapper(String p0) {
return metadata.removeIdentityProviderMapper(p0);
}
@Override
public Set<MapClientInitialAccessEntity> getClientInitialAccesses() {
return this.metadata.getClientInitialAccesses();
}
@Override
public Optional<MapClientInitialAccessEntity> getClientInitialAccess(String p0) {
return metadata.getClientInitialAccess(p0);
}
@Override
public void addClientInitialAccess(MapClientInitialAccessEntity clientInitialAccess) {
this.metadata.addClientInitialAccess(clientInitialAccess);
}
@Override
public Boolean removeClientInitialAccess(String p0) {
return metadata.removeClientInitialAccess(p0);
}
@Override
public Map<String, List<String>> getAttributes() {
Map<String, List<String>> result = new HashMap<>();

View File

@ -54,6 +54,7 @@ import org.keycloak.models.map.user.MapUserEntity;
import org.keycloak.models.map.user.MapUserFederatedIdentityEntity;
import org.keycloak.models.utils.KeycloakModelUtils;
import java.util.Optional;
import static org.keycloak.models.map.storage.jpa.JpaMapStorageProviderFactory.CLONER;
/**
@ -471,6 +472,14 @@ public class JpaUserEntity extends MapUserEntity.AbstractUserEntity implements J
return this.consents.stream().map(MapUserConsentEntity.class::cast).collect(Collectors.toSet());
}
@Override
public Optional<MapUserConsentEntity> getUserConsent(String clientId) {
return this.consents.stream()
.map(MapUserConsentEntity.class::cast)
.filter(muce -> Objects.equals(muce.getClientId(), clientId))
.findAny();
}
@Override
public void setUserConsents(Set<MapUserConsentEntity> userConsents) {
this.consents.clear();
@ -489,7 +498,7 @@ public class JpaUserEntity extends MapUserEntity.AbstractUserEntity implements J
@Override
public Boolean removeUserConsent(MapUserConsentEntity userConsentEntity) {
return this.consents.removeIf(uc -> Objects.equals(uc.getClientId(), userConsentEntity.getClientId()));
return removeUserConsent(userConsentEntity.getClientId());
}
@Override
@ -503,6 +512,11 @@ public class JpaUserEntity extends MapUserEntity.AbstractUserEntity implements J
return this.metadata.getCredentials();
}
@Override
public Optional<MapUserCredentialEntity> getCredential(String id) {
return metadata.getCredential(id);
}
@Override
public void setCredentials(List<MapUserCredentialEntity> credentials) {
this.metadata.setCredentials(credentials);
@ -515,7 +529,12 @@ public class JpaUserEntity extends MapUserEntity.AbstractUserEntity implements J
@Override
public Boolean removeCredential(MapUserCredentialEntity credentialEntity) {
return super.removeCredential(credentialEntity.getId());
return removeCredential(credentialEntity.getId());
}
@Override
public Boolean removeCredential(String id) {
return metadata.removeCredential(id);
}
//user federated identities
@ -524,6 +543,14 @@ public class JpaUserEntity extends MapUserEntity.AbstractUserEntity implements J
return this.federatedIdentities.stream().map(MapUserFederatedIdentityEntity.class::cast).collect(Collectors.toSet());
}
@Override
public Optional<MapUserFederatedIdentityEntity> getFederatedIdentity(String identityProviderId) {
return this.federatedIdentities.stream()
.map(MapUserFederatedIdentityEntity.class::cast)
.filter(muce -> Objects.equals(muce.getIdentityProvider(), identityProviderId))
.findAny();
}
@Override
public void setFederatedIdentities(Set<MapUserFederatedIdentityEntity> federatedIdentities) {
this.federatedIdentities.clear();
@ -542,7 +569,7 @@ public class JpaUserEntity extends MapUserEntity.AbstractUserEntity implements J
@Override
public Boolean removeFederatedIdentity(MapUserFederatedIdentityEntity federatedIdentity) {
return this.federatedIdentities.removeIf(fi -> Objects.equals(fi.getIdentityProvider(), federatedIdentity.getIdentityProvider()));
return removeFederatedIdentity(federatedIdentity.getIdentityProvider());
}
@Override

View File

@ -16,6 +16,7 @@
*/
package org.keycloak.models.map.authSession;
import org.keycloak.models.map.annotations.CollectionKey;
import org.keycloak.models.map.annotations.GenerateEntityImplementations;
import org.keycloak.models.map.common.DeepCloner;
import org.keycloak.models.map.common.UpdatableEntity;
@ -31,6 +32,7 @@ import java.util.Set;
@DeepCloner.Root
public interface MapAuthenticationSessionEntity extends UpdatableEntity {
@CollectionKey
String getTabId();
void setTabId(String tabId);

View File

@ -53,22 +53,6 @@ public interface MapRootAuthenticationSessionEntity extends AbstractEntity, Upda
this.updated |= id != null;
}
@Override
public Optional<MapAuthenticationSessionEntity> getAuthenticationSession(String tabId) {
Set<MapAuthenticationSessionEntity> authenticationSessions = getAuthenticationSessions();
if (authenticationSessions == null || authenticationSessions.isEmpty()) return Optional.empty();
return authenticationSessions.stream().filter(as -> Objects.equals(as.getTabId(), tabId)).findFirst();
}
@Override
public Boolean removeAuthenticationSession(String tabId) {
Set<MapAuthenticationSessionEntity> authenticationSessions = getAuthenticationSessions();
boolean removed = authenticationSessions != null && authenticationSessions.removeIf(c -> Objects.equals(c.getTabId(), tabId));
this.updated |= removed;
return removed;
}
@Override
public boolean isUpdated() {
return this.updated ||

View File

@ -75,20 +75,6 @@ public interface MapClientEntity extends AbstractEntity, UpdatableEntity, Entity
.filter(me -> Objects.equals(me.getValue(), defaultScope))
.map(Entry::getKey);
}
@Override
public Optional<MapProtocolMapperEntity> getProtocolMapper(String id) {
Set<MapProtocolMapperEntity> mappers = getProtocolMappers();
if (mappers == null || mappers.isEmpty()) return Optional.empty();
return mappers.stream().filter(mapper -> Objects.equals(mapper.getId(), id)).findFirst();
}
@Override
public void removeProtocolMapper(String id) {
Set<MapProtocolMapperEntity> mappers = getProtocolMappers();
this.updated |= mappers != null && mappers.removeIf(mapper -> Objects.equals(mapper.getId(), id));
}
}
Map<String, Boolean> getClientScopes();

View File

@ -48,20 +48,6 @@ public interface MapClientScopeEntity extends AbstractEntity, UpdatableEntity, E
this.id = id;
this.updated |= id != null;
}
@Override
public Optional<MapProtocolMapperEntity> getProtocolMapper(String id) {
Set<MapProtocolMapperEntity> mappers = getProtocolMappers();
if (mappers == null || mappers.isEmpty()) return Optional.empty();
return mappers.stream().filter(m -> Objects.equals(m.getId(), id)).findFirst();
}
@Override
public void removeProtocolMapper(String id) {
Set<MapProtocolMapperEntity> mappers = getProtocolMappers();
this.updated |= mappers != null && mappers.removeIf(m -> Objects.equals(m.getId(), id));
}
}
String getName();

View File

@ -16,12 +16,15 @@
*/
package org.keycloak.models.map.common;
import org.keycloak.models.map.annotations.CollectionKey;
/**
*
* @author hmlnarik
*/
public interface AbstractEntity {
@CollectionKey
String getId();
void setId(String id);
}

View File

@ -100,126 +100,6 @@ public interface MapRealmEntity extends UpdatableEntity, AbstractEntity, EntityW
Optional.ofNullable(getWebAuthnPolicyPasswordless()).ifPresent(UpdatableEntity::clearUpdatedFlag);
}
@Override
public Optional<MapComponentEntity> getComponent(String componentId) {
Set<MapComponentEntity> cs = getComponents();
if (cs == null || cs.isEmpty()) return Optional.empty();
return cs.stream().filter(c -> Objects.equals(c.getId(), componentId)).findFirst();
}
@Override
public Boolean removeComponent(String componentId) {
Set<MapComponentEntity> cs = getComponents();
boolean removed = cs != null && cs.removeIf(c -> Objects.equals(c.getId(), componentId));
this.updated |= removed;
return removed;
}
@Override
public Optional<MapAuthenticationFlowEntity> getAuthenticationFlow(String flowId) {
Set<MapAuthenticationFlowEntity> afs = getAuthenticationFlows();
if (afs == null || afs.isEmpty()) return Optional.empty();
return afs.stream().filter(afe -> Objects.equals(afe.getId(), flowId)).findFirst();
}
@Override
public Boolean removeAuthenticationFlow(String flowId) {
Set<MapAuthenticationFlowEntity> afs = getAuthenticationFlows();
boolean removed = afs != null && afs.removeIf(af -> Objects.equals(af.getId(), flowId));
this.updated |= removed;
return removed;
}
@Override
public Optional<MapAuthenticationExecutionEntity> getAuthenticationExecution(String executionId) {
Set<MapAuthenticationExecutionEntity> aes = getAuthenticationExecutions();
if (aes == null || aes.isEmpty()) return Optional.empty();
return aes.stream().filter(ae -> Objects.equals(ae.getId(), executionId)).findFirst();
}
@Override
public Boolean removeAuthenticationExecution(String executionId) {
Set<MapAuthenticationExecutionEntity> aes = getAuthenticationExecutions();
boolean removed = aes != null && aes.removeIf(ae -> Objects.equals(ae.getId(), executionId));
this.updated |= removed;
return removed;
}
@Override
public Optional<MapAuthenticatorConfigEntity> getAuthenticatorConfig(String authenticatorConfigId) {
Set<MapAuthenticatorConfigEntity> acs = getAuthenticatorConfigs();
if (acs == null || acs.isEmpty()) return Optional.empty();
return acs.stream().filter(ac -> Objects.equals(ac.getId(), authenticatorConfigId)).findFirst();
}
@Override
public Boolean removeAuthenticatorConfig(String authenticatorConfigId) {
Set<MapAuthenticatorConfigEntity> acs = getAuthenticatorConfigs();
boolean removed = acs != null && acs.removeIf(ac -> Objects.equals(ac.getId(), authenticatorConfigId));
this.updated |= removed;
return removed;
}
@Override
public Optional<MapRequiredActionProviderEntity> getRequiredActionProvider(String requiredActionProviderId) {
Set<MapRequiredActionProviderEntity> raps = getRequiredActionProviders();
if (raps == null || raps.isEmpty()) return Optional.empty();
return raps.stream().filter(ac -> Objects.equals(ac.getId(), requiredActionProviderId)).findFirst();
}
@Override
public Boolean removeRequiredActionProvider(String requiredActionProviderId) {
Set<MapRequiredActionProviderEntity> raps = getRequiredActionProviders();
boolean removed = raps != null && raps.removeIf(rap -> Objects.equals(rap.getId(), requiredActionProviderId));
this.updated |= removed;
return removed;
}
@Override
public Boolean removeIdentityProvider(String identityProviderId) {
Set<MapIdentityProviderEntity> ips = getIdentityProviders();
boolean removed = ips != null && ips.removeIf(ip -> Objects.equals(ip.getId(), identityProviderId));
this.updated |= removed;
return removed;
}
@Override
public Optional<MapIdentityProviderMapperEntity> getIdentityProviderMapper(String identityProviderMapperId) {
Set<MapIdentityProviderMapperEntity> ipms = getIdentityProviderMappers();
if (ipms == null || ipms.isEmpty()) return Optional.empty();
return ipms.stream().filter(ipm -> Objects.equals(ipm.getId(), identityProviderMapperId)).findFirst();
}
@Override
public Boolean removeIdentityProviderMapper(String identityProviderMapperId) {
Set<MapIdentityProviderMapperEntity> ipms = getIdentityProviderMappers();
boolean removed = ipms != null && ipms.removeIf(ipm -> Objects.equals(ipm.getId(), identityProviderMapperId));
this.updated |= removed;
return removed;
}
@Override
public Optional<MapClientInitialAccessEntity> getClientInitialAccess(String clientInitialAccessId) {
Set<MapClientInitialAccessEntity> cias = getClientInitialAccesses();
if (cias == null || cias.isEmpty()) return Optional.empty();
return cias.stream().filter(cia -> Objects.equals(cia.getId(), clientInitialAccessId)).findFirst();
}
@Override
public Boolean removeClientInitialAccess(String clientInitialAccessId) {
Set<MapClientInitialAccessEntity> cias = getClientInitialAccesses();
boolean removed = cias != null && cias.removeIf(cia -> Objects.equals(cia.getId(), clientInitialAccessId));
this.updated |= removed;
return removed;
}
@Override
public void removeExpiredClientInitialAccesses() {
Set<MapClientInitialAccessEntity> cias = getClientInitialAccesses();

View File

@ -23,6 +23,7 @@ import org.keycloak.models.ClientScopeModel;
import org.keycloak.models.ModelException;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserConsentModel;
import org.keycloak.models.map.annotations.CollectionKey;
import org.keycloak.models.map.annotations.GenerateEntityImplementations;
import org.keycloak.models.map.common.DeepCloner;
import org.keycloak.models.map.common.UpdatableEntity;
@ -77,6 +78,7 @@ public interface MapUserConsentEntity extends UpdatableEntity {
return model;
}
@CollectionKey
String getClientId();
void setClientId(String clientId);

View File

@ -19,6 +19,7 @@ package org.keycloak.models.map.user;
import org.keycloak.credential.CredentialModel;
import org.keycloak.models.map.annotations.GenerateEntityImplementations;
import org.keycloak.models.map.common.AbstractEntity;
import org.keycloak.models.map.common.DeepCloner;
import org.keycloak.models.map.common.UpdatableEntity;
import org.keycloak.models.utils.KeycloakModelUtils;
@ -27,7 +28,7 @@ import java.util.Comparator;
@GenerateEntityImplementations
@DeepCloner.Root
public interface MapUserCredentialEntity extends UpdatableEntity {
public interface MapUserCredentialEntity extends AbstractEntity, UpdatableEntity {
public static MapUserCredentialEntity fromModel(CredentialModel model) {
MapUserCredentialEntity credentialEntity = DeepCloner.DUMB_CLONER.newInstance(MapUserCredentialEntity.class);
@ -53,9 +54,6 @@ public interface MapUserCredentialEntity extends UpdatableEntity {
return model;
}
String getId();
void setId(String id);
String getType();
void setType(String type);

View File

@ -80,38 +80,6 @@ public interface MapUserEntity extends UpdatableEntity, AbstractEntity, EntityWi
this.setEmailConstraint(email == null || duplicateEmailsAllowed ? KeycloakModelUtils.generateId() : email);
}
@Override
public Optional<MapUserConsentEntity> getUserConsent(String clientId) {
Set<MapUserConsentEntity> ucs = getUserConsents();
if (ucs == null || ucs.isEmpty()) return Optional.empty();
return ucs.stream().filter(uc -> Objects.equals(uc.getClientId(), clientId)).findFirst();
}
@Override
public Boolean removeUserConsent(String clientId) {
Set<MapUserConsentEntity> consents = getUserConsents();
boolean removed = consents != null && consents.removeIf(uc -> Objects.equals(uc.getClientId(), clientId));
this.updated |= removed;
return removed;
}
@Override
public Optional<MapUserCredentialEntity> getCredential(String id) {
List<MapUserCredentialEntity> uce = getCredentials();
if (uce == null || uce.isEmpty()) return Optional.empty();
return uce.stream().filter(uc -> Objects.equals(uc.getId(), id)).findFirst();
}
@Override
public Boolean removeCredential(String id) {
List<MapUserCredentialEntity> credentials = getCredentials();
boolean removed = credentials != null && credentials.removeIf(c -> Objects.equals(c.getId(), id));
this.updated |= removed;
return removed;
}
@Override
public Boolean moveCredential(String credentialId, String newPreviousCredentialId) {
// 1 - Get all credentials from the entity.
@ -154,22 +122,6 @@ public interface MapUserEntity extends UpdatableEntity, AbstractEntity, EntityWi
this.updated = true;
return true;
}
@Override
public Optional<MapUserFederatedIdentityEntity> getFederatedIdentity(String identityProviderId) {
Set<MapUserFederatedIdentityEntity> fes = getFederatedIdentities();
if (fes == null || fes.isEmpty()) return Optional.empty();
return fes.stream().filter(fi -> Objects.equals(fi.getIdentityProvider(), identityProviderId)).findFirst();
}
@Override
public Boolean removeFederatedIdentity(String identityProviderId) {
Set<MapUserFederatedIdentityEntity> federatedIdentities = getFederatedIdentities();
boolean removed = federatedIdentities != null && federatedIdentities.removeIf(fi -> Objects.equals(fi.getIdentityProvider(), identityProviderId));
this.updated |= removed;
return removed;
}
}
String getRealmId();

View File

@ -18,6 +18,7 @@
package org.keycloak.models.map.user;
import org.keycloak.models.FederatedIdentityModel;
import org.keycloak.models.map.annotations.CollectionKey;
import org.keycloak.models.map.annotations.GenerateEntityImplementations;
import org.keycloak.models.map.common.DeepCloner;
import org.keycloak.models.map.common.UpdatableEntity;
@ -48,6 +49,7 @@ public interface MapUserFederatedIdentityEntity extends UpdatableEntity {
String getUserId();
void setUserId(String userId);
@CollectionKey
String getIdentityProvider();
void setIdentityProvider(String identityProvider);

View File

@ -16,6 +16,7 @@
*/
package org.keycloak.models.map.userSession;
import org.keycloak.models.map.annotations.CollectionKey;
import org.keycloak.models.map.annotations.GenerateEntityImplementations;
import org.keycloak.models.map.common.AbstractEntity;
@ -66,6 +67,7 @@ public interface MapAuthenticatedClientSessionEntity extends AbstractEntity, Upd
String getRealmId();
void setRealmId(String realmId);
@CollectionKey(priority = 1)
String getClientId();
void setClientId(String clientId);

View File

@ -69,22 +69,6 @@ public interface MapUserSessionEntity extends AbstractEntity, UpdatableEntity, E
Optional.ofNullable(getAuthenticatedClientSessions()).orElseGet(Collections::emptySet).forEach(UpdatableEntity::clearUpdatedFlag);
}
@Override
public Optional<MapAuthenticatedClientSessionEntity> getAuthenticatedClientSession(String clientUUID) {
Set<MapAuthenticatedClientSessionEntity> acss = getAuthenticatedClientSessions();
if (acss == null || acss.isEmpty()) return Optional.empty();
return acss.stream().filter(acs -> Objects.equals(acs.getClientId(), clientUUID)).findFirst();
}
@Override
public Boolean removeAuthenticatedClientSession(String clientUUID) {
Set<MapAuthenticatedClientSessionEntity> acss = getAuthenticatedClientSessions();
boolean removed = acss != null && acss.removeIf(uc -> Objects.equals(uc.getClientId(), clientUUID));
this.updated |= removed;
return removed;
}
@Override
public void clearAuthenticatedClientSessions() {
Set<MapAuthenticatedClientSessionEntity> acss = getAuthenticatedClientSessions();