parent
0a8e132c7c
commit
09c0a69a8f
18 changed files with 664 additions and 36 deletions
|
@ -26,6 +26,8 @@ import org.keycloak.authorization.model.ResourceServer;
|
||||||
import org.keycloak.authorization.model.Scope;
|
import org.keycloak.authorization.model.Scope;
|
||||||
import org.keycloak.common.Profile;
|
import org.keycloak.common.Profile;
|
||||||
import org.keycloak.component.AmphibianProviderFactory;
|
import org.keycloak.component.AmphibianProviderFactory;
|
||||||
|
import org.keycloak.events.Event;
|
||||||
|
import org.keycloak.events.admin.AdminEvent;
|
||||||
import org.keycloak.models.AuthenticatedClientSessionModel;
|
import org.keycloak.models.AuthenticatedClientSessionModel;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.ClientScopeModel;
|
import org.keycloak.models.ClientScopeModel;
|
||||||
|
@ -47,6 +49,8 @@ import org.keycloak.models.map.authSession.MapRootAuthenticationSessionEntity;
|
||||||
import org.keycloak.models.map.clientscope.MapClientScopeEntity;
|
import org.keycloak.models.map.clientscope.MapClientScopeEntity;
|
||||||
import org.keycloak.models.map.common.AbstractEntity;
|
import org.keycloak.models.map.common.AbstractEntity;
|
||||||
import org.keycloak.models.map.common.StringKeyConverter;
|
import org.keycloak.models.map.common.StringKeyConverter;
|
||||||
|
import org.keycloak.models.map.events.MapAdminEventEntity;
|
||||||
|
import org.keycloak.models.map.events.MapAuthEventEntity;
|
||||||
import org.keycloak.models.map.group.MapGroupEntity;
|
import org.keycloak.models.map.group.MapGroupEntity;
|
||||||
import org.keycloak.models.map.loginFailure.MapUserLoginFailureEntity;
|
import org.keycloak.models.map.loginFailure.MapUserLoginFailureEntity;
|
||||||
import org.keycloak.models.map.realm.MapRealmEntity;
|
import org.keycloak.models.map.realm.MapRealmEntity;
|
||||||
|
@ -77,6 +81,10 @@ import org.keycloak.models.map.storage.hotRod.authorization.HotRodScopeEntity;
|
||||||
import org.keycloak.models.map.storage.hotRod.authorization.HotRodScopeEntityDelegate;
|
import org.keycloak.models.map.storage.hotRod.authorization.HotRodScopeEntityDelegate;
|
||||||
import org.keycloak.models.map.storage.hotRod.common.AbstractHotRodEntity;
|
import org.keycloak.models.map.storage.hotRod.common.AbstractHotRodEntity;
|
||||||
import org.keycloak.models.map.storage.hotRod.common.HotRodEntityDelegate;
|
import org.keycloak.models.map.storage.hotRod.common.HotRodEntityDelegate;
|
||||||
|
import org.keycloak.models.map.storage.hotRod.events.HotRodAdminEventEntity;
|
||||||
|
import org.keycloak.models.map.storage.hotRod.events.HotRodAdminEventEntityDelegate;
|
||||||
|
import org.keycloak.models.map.storage.hotRod.events.HotRodAuthEventEntity;
|
||||||
|
import org.keycloak.models.map.storage.hotRod.events.HotRodAuthEventEntityDelegate;
|
||||||
import org.keycloak.models.map.storage.hotRod.loginFailure.HotRodUserLoginFailureEntity;
|
import org.keycloak.models.map.storage.hotRod.loginFailure.HotRodUserLoginFailureEntity;
|
||||||
import org.keycloak.models.map.storage.hotRod.loginFailure.HotRodUserLoginFailureEntityDelegate;
|
import org.keycloak.models.map.storage.hotRod.loginFailure.HotRodUserLoginFailureEntityDelegate;
|
||||||
import org.keycloak.models.map.storage.hotRod.role.HotRodRoleEntity;
|
import org.keycloak.models.map.storage.hotRod.role.HotRodRoleEntity;
|
||||||
|
@ -180,6 +188,9 @@ public class HotRodMapStorageProviderFactory implements AmphibianProviderFactory
|
||||||
.constructor(MapPolicyEntity.class, HotRodPolicyEntityDelegate::new)
|
.constructor(MapPolicyEntity.class, HotRodPolicyEntityDelegate::new)
|
||||||
.constructor(MapPermissionTicketEntity.class, HotRodPermissionTicketEntityDelegate::new)
|
.constructor(MapPermissionTicketEntity.class, HotRodPermissionTicketEntityDelegate::new)
|
||||||
|
|
||||||
|
.constructor(MapAuthEventEntity.class, HotRodAuthEventEntityDelegate::new)
|
||||||
|
.constructor(MapAdminEventEntity.class, HotRodAdminEventEntityDelegate::new)
|
||||||
|
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
public static final Map<Class<?>, HotRodEntityDescriptor<?, ?>> ENTITY_DESCRIPTOR_MAP = new HashMap<>();
|
public static final Map<Class<?>, HotRodEntityDescriptor<?, ?>> ENTITY_DESCRIPTOR_MAP = new HashMap<>();
|
||||||
|
@ -293,6 +304,17 @@ public class HotRodMapStorageProviderFactory implements AmphibianProviderFactory
|
||||||
return "authz";
|
return "authz";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Events
|
||||||
|
ENTITY_DESCRIPTOR_MAP.put(Event.class,
|
||||||
|
new HotRodEntityDescriptor<>(Event.class,
|
||||||
|
HotRodAuthEventEntity.class,
|
||||||
|
HotRodAuthEventEntityDelegate::new));
|
||||||
|
|
||||||
|
ENTITY_DESCRIPTOR_MAP.put(AdminEvent.class,
|
||||||
|
new HotRodEntityDescriptor<>(AdminEvent.class,
|
||||||
|
HotRodAdminEventEntity.class,
|
||||||
|
HotRodAdminEventEntityDelegate::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.keycloak.models.map.storage.hotRod;
|
||||||
|
|
||||||
import org.keycloak.authorization.model.Policy;
|
import org.keycloak.authorization.model.Policy;
|
||||||
import org.keycloak.authorization.model.Resource;
|
import org.keycloak.authorization.model.Resource;
|
||||||
|
import org.keycloak.events.Event;
|
||||||
import org.keycloak.models.AuthenticatedClientSessionModel;
|
import org.keycloak.models.AuthenticatedClientSessionModel;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.GroupModel;
|
import org.keycloak.models.GroupModel;
|
||||||
|
@ -36,6 +37,7 @@ import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.function.UnaryOperator;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@ -49,10 +51,10 @@ public class IckleQueryMapModelCriteriaBuilder<E extends AbstractHotRodEntity, M
|
||||||
private final Class<E> hotRodEntityClass;
|
private final Class<E> hotRodEntityClass;
|
||||||
private final StringBuilder whereClauseBuilder = new StringBuilder(INITIAL_BUILDER_CAPACITY);
|
private final StringBuilder whereClauseBuilder = new StringBuilder(INITIAL_BUILDER_CAPACITY);
|
||||||
private final Map<String, Object> parameters;
|
private final Map<String, Object> parameters;
|
||||||
|
private static final Pattern LIKE_PATTERN_DELIMITER = Pattern.compile("%+");
|
||||||
private static final Pattern NON_ANALYZED_FIELD_REGEX = Pattern.compile("[%_\\\\]");
|
private static final Pattern NON_ANALYZED_FIELD_REGEX = Pattern.compile("[%_\\\\]");
|
||||||
// private static final Pattern ANALYZED_FIELD_REGEX = Pattern.compile("[+!^\"~*?:\\\\]"); // TODO reevaluate once https://github.com/keycloak/keycloak/issues/9295 is fixed
|
// private static final Pattern ANALYZED_FIELD_REGEX = Pattern.compile("[+!^\"~*?:\\\\]"); // TODO reevaluate once https://github.com/keycloak/keycloak/issues/9295 is fixed
|
||||||
private static final Pattern ANALYZED_FIELD_REGEX = Pattern.compile("\\\\"); // escape "\" with extra "\"
|
private static final Pattern ANALYZED_FIELD_REGEX = Pattern.compile("\\\\"); // escape "\" with extra "\"
|
||||||
private static final Pattern SINGLE_PERCENT_CHARACTER = Pattern.compile("^%+$");
|
|
||||||
public static final Map<SearchableModelField<?>, String> INFINISPAN_NAME_OVERRIDES = new HashMap<>();
|
public static final Map<SearchableModelField<?>, String> INFINISPAN_NAME_OVERRIDES = new HashMap<>();
|
||||||
public static final Set<SearchableModelField<?>> ANALYZED_MODEL_FIELDS = new HashSet<>();
|
public static final Set<SearchableModelField<?>> ANALYZED_MODEL_FIELDS = new HashSet<>();
|
||||||
|
|
||||||
|
@ -87,6 +89,8 @@ public class IckleQueryMapModelCriteriaBuilder<E extends AbstractHotRodEntity, M
|
||||||
INFINISPAN_NAME_OVERRIDES.put(Policy.SearchableFields.SCOPE_ID, "scopeIds");
|
INFINISPAN_NAME_OVERRIDES.put(Policy.SearchableFields.SCOPE_ID, "scopeIds");
|
||||||
INFINISPAN_NAME_OVERRIDES.put(Policy.SearchableFields.ASSOCIATED_POLICY_ID, "associatedPolicyIds");
|
INFINISPAN_NAME_OVERRIDES.put(Policy.SearchableFields.ASSOCIATED_POLICY_ID, "associatedPolicyIds");
|
||||||
INFINISPAN_NAME_OVERRIDES.put(Policy.SearchableFields.CONFIG, "configs");
|
INFINISPAN_NAME_OVERRIDES.put(Policy.SearchableFields.CONFIG, "configs");
|
||||||
|
|
||||||
|
INFINISPAN_NAME_OVERRIDES.put(Event.SearchableFields.EVENT_TYPE, "type");
|
||||||
}
|
}
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
@ -223,21 +227,9 @@ public class IckleQueryMapModelCriteriaBuilder<E extends AbstractHotRodEntity, M
|
||||||
return whereClauseBuilder;
|
return whereClauseBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object sanitize(Object value) {
|
public static Object sanitizeNonAnalyzed(Object value) {
|
||||||
if (value instanceof String) {
|
if (value instanceof String) {
|
||||||
String sValue = (String) value;
|
return sanitizeEachUnitAndReplaceDelimiter((String) value, IckleQueryMapModelCriteriaBuilder::sanitizeSingleUnitNonAnalyzed, "%");
|
||||||
|
|
||||||
if(SINGLE_PERCENT_CHARACTER.matcher(sValue).matches()) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean anyBeginning = sValue.startsWith("%");
|
|
||||||
boolean anyEnd = sValue.endsWith("%");
|
|
||||||
|
|
||||||
String sanitizedString = NON_ANALYZED_FIELD_REGEX.matcher(sValue.substring(anyBeginning ? 1 : 0, sValue.length() - (anyEnd ? 1 : 0)))
|
|
||||||
.replaceAll("\\\\\\\\" + "$0");
|
|
||||||
|
|
||||||
return (anyBeginning ? "%" : "") + sanitizedString + (anyEnd ? "%" : "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
|
@ -245,26 +237,31 @@ public class IckleQueryMapModelCriteriaBuilder<E extends AbstractHotRodEntity, M
|
||||||
|
|
||||||
public static Object sanitizeAnalyzed(Object value) {
|
public static Object sanitizeAnalyzed(Object value) {
|
||||||
if (value instanceof String) {
|
if (value instanceof String) {
|
||||||
String sValue = (String) value;
|
return sanitizeEachUnitAndReplaceDelimiter((String) value, IckleQueryMapModelCriteriaBuilder::sanitizeSingleUnitAnalyzed, "*");
|
||||||
boolean anyBeginning = sValue.startsWith("%");
|
|
||||||
boolean anyEnd = sValue.endsWith("%");
|
|
||||||
|
|
||||||
if(SINGLE_PERCENT_CHARACTER.matcher(sValue).matches()) {
|
|
||||||
return "*";
|
|
||||||
}
|
|
||||||
|
|
||||||
String sanitizedString = ANALYZED_FIELD_REGEX.matcher(sValue.substring(anyBeginning ? 1 : 0, sValue.length() - (anyEnd ? 1 : 0)))
|
|
||||||
.replaceAll("\\\\\\\\"); // escape "\" with extra "\"
|
|
||||||
// .replaceAll("\\\\\\\\" + "$0"); skipped for now because Infinispan is not able to escape
|
|
||||||
// special characters for analyzed fields
|
|
||||||
// TODO reevaluate once https://github.com/keycloak/keycloak/issues/9295 is fixed
|
|
||||||
|
|
||||||
return (anyBeginning ? "*" : "") + sanitizedString + (anyEnd ? "*" : "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String sanitizeEachUnitAndReplaceDelimiter(String value, UnaryOperator<String> sanitizeSingleUnit, String replacement) {
|
||||||
|
return LIKE_PATTERN_DELIMITER.splitAsStream(value)
|
||||||
|
.map(sanitizeSingleUnit)
|
||||||
|
.collect(Collectors.joining(replacement))
|
||||||
|
+ (value.endsWith("%") ? replacement : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String sanitizeSingleUnitNonAnalyzed(String value) {
|
||||||
|
return NON_ANALYZED_FIELD_REGEX.matcher(value).replaceAll("\\\\\\\\" + "$0");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String sanitizeSingleUnitAnalyzed(String value) {
|
||||||
|
return ANALYZED_FIELD_REGEX.matcher(value).replaceAll("\\\\\\\\"); // escape "\" with extra "\"
|
||||||
|
// .replaceAll("\\\\\\\\" + "$0"); skipped for now because Infinispan is not able to escape
|
||||||
|
// special characters for analyzed fields
|
||||||
|
// TODO reevaluate once https://github.com/keycloak/keycloak/issues/9295 is fixed
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static boolean isAnalyzedModelField(SearchableModelField<?> modelField) {
|
public static boolean isAnalyzedModelField(SearchableModelField<?> modelField) {
|
||||||
return ANALYZED_MODEL_FIELDS.contains(modelField);
|
return ANALYZED_MODEL_FIELDS.contains(modelField);
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,13 +95,13 @@ public class IckleQueryOperators {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String iLike(String modelFieldName, Object[] values, Map<String, Object> parameters) {
|
private static String iLike(String modelFieldName, Object[] values, Map<String, Object> parameters) {
|
||||||
String sanitizedValue = (String) IckleQueryMapModelCriteriaBuilder.sanitize(values[0]);
|
String sanitizedValue = (String) IckleQueryMapModelCriteriaBuilder.sanitizeNonAnalyzed(values[0]);
|
||||||
return singleValueOperator(ModelCriteriaBuilder.Operator.ILIKE)
|
return singleValueOperator(ModelCriteriaBuilder.Operator.ILIKE)
|
||||||
.combine(modelFieldName + "Lowercase", new String[] {sanitizedValue.toLowerCase()}, parameters);
|
.combine(modelFieldName + "Lowercase", new String[] {sanitizedValue.toLowerCase()}, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String like(String modelFieldName, Object[] values, Map<String, Object> parameters) {
|
private static String like(String modelFieldName, Object[] values, Map<String, Object> parameters) {
|
||||||
String sanitizedValue = (String) IckleQueryMapModelCriteriaBuilder.sanitize(values[0]);
|
String sanitizedValue = (String) IckleQueryMapModelCriteriaBuilder.sanitizeNonAnalyzed(values[0]);
|
||||||
return singleValueOperator(ModelCriteriaBuilder.Operator.LIKE)
|
return singleValueOperator(ModelCriteriaBuilder.Operator.LIKE)
|
||||||
.combine(modelFieldName, new String[] {sanitizedValue}, parameters);
|
.combine(modelFieldName, new String[] {sanitizedValue}, parameters);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,17 +18,25 @@
|
||||||
package org.keycloak.models.map.storage.hotRod;
|
package org.keycloak.models.map.storage.hotRod;
|
||||||
|
|
||||||
import org.keycloak.authorization.model.Policy;
|
import org.keycloak.authorization.model.Policy;
|
||||||
|
import org.keycloak.events.Event;
|
||||||
|
import org.keycloak.events.EventType;
|
||||||
|
import org.keycloak.events.admin.AdminEvent;
|
||||||
|
import org.keycloak.events.admin.OperationType;
|
||||||
import org.keycloak.models.ClientModel;
|
import org.keycloak.models.ClientModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.UserSessionModel;
|
import org.keycloak.models.UserSessionModel;
|
||||||
import org.keycloak.models.map.storage.CriterionNotSupportedException;
|
import org.keycloak.models.map.storage.CriterionNotSupportedException;
|
||||||
import org.keycloak.models.map.storage.ModelCriteriaBuilder;
|
import org.keycloak.models.map.storage.ModelCriteriaBuilder;
|
||||||
|
import org.keycloak.models.map.storage.hotRod.common.HotRodTypesUtils;
|
||||||
import org.keycloak.storage.SearchableModelField;
|
import org.keycloak.storage.SearchableModelField;
|
||||||
import org.keycloak.storage.StorageId;
|
import org.keycloak.storage.StorageId;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static org.keycloak.models.map.storage.hotRod.IckleQueryMapModelCriteriaBuilder.getFieldName;
|
import static org.keycloak.models.map.storage.hotRod.IckleQueryMapModelCriteriaBuilder.getFieldName;
|
||||||
import static org.keycloak.models.map.storage.hotRod.IckleQueryMapModelCriteriaBuilder.sanitizeAnalyzed;
|
import static org.keycloak.models.map.storage.hotRod.IckleQueryMapModelCriteriaBuilder.sanitizeAnalyzed;
|
||||||
|
@ -58,6 +66,8 @@ public class IckleQueryWhereClauses {
|
||||||
WHERE_CLAUSE_PRODUCER_OVERRIDES.put(UserModel.SearchableFields.CONSENT_CLIENT_FEDERATION_LINK, IckleQueryWhereClauses::whereClauseForConsentClientFederationLink);
|
WHERE_CLAUSE_PRODUCER_OVERRIDES.put(UserModel.SearchableFields.CONSENT_CLIENT_FEDERATION_LINK, IckleQueryWhereClauses::whereClauseForConsentClientFederationLink);
|
||||||
WHERE_CLAUSE_PRODUCER_OVERRIDES.put(UserSessionModel.SearchableFields.CORRESPONDING_SESSION_ID, IckleQueryWhereClauses::whereClauseForCorrespondingSessionId);
|
WHERE_CLAUSE_PRODUCER_OVERRIDES.put(UserSessionModel.SearchableFields.CORRESPONDING_SESSION_ID, IckleQueryWhereClauses::whereClauseForCorrespondingSessionId);
|
||||||
WHERE_CLAUSE_PRODUCER_OVERRIDES.put(Policy.SearchableFields.CONFIG, IckleQueryWhereClauses::whereClauseForPolicyConfig);
|
WHERE_CLAUSE_PRODUCER_OVERRIDES.put(Policy.SearchableFields.CONFIG, IckleQueryWhereClauses::whereClauseForPolicyConfig);
|
||||||
|
WHERE_CLAUSE_PRODUCER_OVERRIDES.put(Event.SearchableFields.EVENT_TYPE, IckleQueryWhereClauses::whereClauseForEventType);
|
||||||
|
WHERE_CLAUSE_PRODUCER_OVERRIDES.put(AdminEvent.SearchableFields.OPERATION_TYPE, IckleQueryWhereClauses::whereClauseForOperationType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
|
@ -204,4 +214,31 @@ public class IckleQueryWhereClauses {
|
||||||
String valueClause = IckleQueryOperators.combineExpressions(op, modelFieldName + ".value", realValues, parameters);
|
String valueClause = IckleQueryOperators.combineExpressions(op, modelFieldName + ".value", realValues, parameters);
|
||||||
return "(" + nameClause + ")" + " AND " + "(" + valueClause + ")";
|
return "(" + nameClause + ")" + " AND " + "(" + valueClause + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String whereClauseForEventType(String modelFieldName, ModelCriteriaBuilder.Operator op, Object[] values, Map<String, Object> parameters) {
|
||||||
|
if (values != null && values.length == 1) {
|
||||||
|
if (values[0] instanceof EventType) {
|
||||||
|
values[0] = HotRodTypesUtils.migrateEventTypeToHotRodEventType((EventType) values[0]);
|
||||||
|
} else if (values[0] instanceof Collection) {
|
||||||
|
values[0] = ((Collection<EventType>) values[0]).stream().map(HotRodTypesUtils::migrateEventTypeToHotRodEventType).collect(Collectors.toSet());
|
||||||
|
} else if (values[0] instanceof Stream) {
|
||||||
|
values[0] = ((Stream<EventType>) values[0]).map(HotRodTypesUtils::migrateEventTypeToHotRodEventType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return produceWhereClause(modelFieldName, op, values, parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String whereClauseForOperationType(String modelFieldName, ModelCriteriaBuilder.Operator op, Object[] values, Map<String, Object> parameters) {
|
||||||
|
if (values != null && values.length == 1) {
|
||||||
|
if (values[0] instanceof OperationType) {
|
||||||
|
values[0] = HotRodTypesUtils.migrateOperationTypeToHotRodOperationType((OperationType) values[0]);
|
||||||
|
} else if (values[0] instanceof Collection) {
|
||||||
|
values[0] = ((Collection<OperationType>) values[0]).stream().map(HotRodTypesUtils::migrateOperationTypeToHotRodOperationType).collect(Collectors.toSet());
|
||||||
|
} else if (values[0] instanceof Stream) {
|
||||||
|
values[0] = ((Stream<OperationType>) values[0]).map(HotRodTypesUtils::migrateOperationTypeToHotRodOperationType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return produceWhereClause(modelFieldName, op, values, parameters);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
|
|
||||||
package org.keycloak.models.map.storage.hotRod.common;
|
package org.keycloak.models.map.storage.hotRod.common;
|
||||||
|
|
||||||
|
import org.keycloak.events.EventType;
|
||||||
|
import org.keycloak.events.admin.OperationType;
|
||||||
import org.keycloak.models.AuthenticationExecutionModel;
|
import org.keycloak.models.AuthenticationExecutionModel;
|
||||||
import org.keycloak.models.UserSessionModel;
|
import org.keycloak.models.UserSessionModel;
|
||||||
import org.keycloak.models.map.common.AbstractEntity;
|
import org.keycloak.models.map.common.AbstractEntity;
|
||||||
|
@ -24,6 +26,8 @@ import org.keycloak.models.map.storage.hotRod.authSession.HotRodAuthenticationSe
|
||||||
import org.keycloak.models.map.storage.hotRod.authorization.HotRodDecisionStrategy;
|
import org.keycloak.models.map.storage.hotRod.authorization.HotRodDecisionStrategy;
|
||||||
import org.keycloak.models.map.storage.hotRod.authorization.HotRodLogic;
|
import org.keycloak.models.map.storage.hotRod.authorization.HotRodLogic;
|
||||||
import org.keycloak.models.map.storage.hotRod.authorization.HotRodPolicyEnforcementMode;
|
import org.keycloak.models.map.storage.hotRod.authorization.HotRodPolicyEnforcementMode;
|
||||||
|
import org.keycloak.models.map.storage.hotRod.events.HotRodEventType;
|
||||||
|
import org.keycloak.models.map.storage.hotRod.events.HotRodOperationType;
|
||||||
import org.keycloak.models.map.storage.hotRod.realm.entity.HotRodLocalizationTexts;
|
import org.keycloak.models.map.storage.hotRod.realm.entity.HotRodLocalizationTexts;
|
||||||
import org.keycloak.models.map.storage.hotRod.realm.entity.HotRodRequirement;
|
import org.keycloak.models.map.storage.hotRod.realm.entity.HotRodRequirement;
|
||||||
import org.keycloak.models.map.storage.hotRod.user.HotRodUserConsentEntity;
|
import org.keycloak.models.map.storage.hotRod.user.HotRodUserConsentEntity;
|
||||||
|
@ -195,4 +199,20 @@ public class HotRodTypesUtils {
|
||||||
public static Logic migrateHotRodLogicToLogic(HotRodLogic p0) {
|
public static Logic migrateHotRodLogicToLogic(HotRodLogic p0) {
|
||||||
return p0 == null ? null : Logic.values()[p0.ordinal()];
|
return p0 == null ? null : Logic.values()[p0.ordinal()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static OperationType migrateHotRodOperationTypeToOperationType(HotRodOperationType p0) {
|
||||||
|
return p0 == null ? null : OperationType.values()[p0.ordinal()];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HotRodOperationType migrateOperationTypeToHotRodOperationType(OperationType p0) {
|
||||||
|
return p0 == null ? null : HotRodOperationType.values()[p0.ordinal()];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HotRodEventType migrateEventTypeToHotRodEventType(EventType p0) {
|
||||||
|
return p0 == null ? null : HotRodEventType.values()[p0.ordinal()];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EventType migrateHotRodEventTypeToEventType(HotRodEventType p0) {
|
||||||
|
return p0 == null ? null : EventType.values()[p0.ordinal()];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,10 @@ import org.keycloak.models.map.storage.hotRod.authorization.HotRodScopeEntity;
|
||||||
import org.keycloak.models.map.storage.hotRod.client.HotRodClientEntity;
|
import org.keycloak.models.map.storage.hotRod.client.HotRodClientEntity;
|
||||||
import org.keycloak.models.map.storage.hotRod.client.HotRodProtocolMapperEntity;
|
import org.keycloak.models.map.storage.hotRod.client.HotRodProtocolMapperEntity;
|
||||||
import org.keycloak.models.map.storage.hotRod.clientscope.HotRodClientScopeEntity;
|
import org.keycloak.models.map.storage.hotRod.clientscope.HotRodClientScopeEntity;
|
||||||
|
import org.keycloak.models.map.storage.hotRod.events.HotRodAdminEventEntity;
|
||||||
|
import org.keycloak.models.map.storage.hotRod.events.HotRodAuthEventEntity;
|
||||||
|
import org.keycloak.models.map.storage.hotRod.events.HotRodEventType;
|
||||||
|
import org.keycloak.models.map.storage.hotRod.events.HotRodOperationType;
|
||||||
import org.keycloak.models.map.storage.hotRod.group.HotRodGroupEntity;
|
import org.keycloak.models.map.storage.hotRod.group.HotRodGroupEntity;
|
||||||
import org.keycloak.models.map.storage.hotRod.loginFailure.HotRodUserLoginFailureEntity;
|
import org.keycloak.models.map.storage.hotRod.loginFailure.HotRodUserLoginFailureEntity;
|
||||||
import org.keycloak.models.map.storage.hotRod.realm.HotRodRealmEntity;
|
import org.keycloak.models.map.storage.hotRod.realm.HotRodRealmEntity;
|
||||||
|
@ -123,6 +127,12 @@ import org.keycloak.models.map.storage.hotRod.userSession.HotRodUserSessionEntit
|
||||||
HotRodLogic.class,
|
HotRodLogic.class,
|
||||||
HotRodPolicyEnforcementMode.class,
|
HotRodPolicyEnforcementMode.class,
|
||||||
|
|
||||||
|
// Events
|
||||||
|
HotRodAuthEventEntity.class,
|
||||||
|
HotRodEventType.class,
|
||||||
|
HotRodAdminEventEntity.class,
|
||||||
|
HotRodOperationType.class,
|
||||||
|
|
||||||
// Common
|
// Common
|
||||||
HotRodPair.class,
|
HotRodPair.class,
|
||||||
HotRodStringPair.class,
|
HotRodStringPair.class,
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
/*
|
||||||
|
* 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.storage.hotRod.events;
|
||||||
|
|
||||||
|
import org.infinispan.protostream.annotations.ProtoDoc;
|
||||||
|
import org.infinispan.protostream.annotations.ProtoField;
|
||||||
|
import org.keycloak.models.map.annotations.GenerateHotRodEntityImplementation;
|
||||||
|
import org.keycloak.models.map.events.MapAdminEventEntity;
|
||||||
|
import org.keycloak.models.map.storage.hotRod.common.AbstractHotRodEntity;
|
||||||
|
import org.keycloak.models.map.storage.hotRod.common.UpdatableHotRodEntityDelegateImpl;
|
||||||
|
|
||||||
|
@GenerateHotRodEntityImplementation(
|
||||||
|
implementInterface = "org.keycloak.models.map.events.MapAdminEventEntity",
|
||||||
|
inherits = "org.keycloak.models.map.storage.hotRod.events.HotRodAdminEventEntity.AbstractHotRodAdminEventEntityDelegate"
|
||||||
|
)
|
||||||
|
@ProtoDoc("@Indexed")
|
||||||
|
public class HotRodAdminEventEntity extends AbstractHotRodEntity {
|
||||||
|
|
||||||
|
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
|
||||||
|
@ProtoField(number = 1)
|
||||||
|
public Integer entityVersion = 1;
|
||||||
|
|
||||||
|
@ProtoField(number = 2)
|
||||||
|
public String id;
|
||||||
|
|
||||||
|
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
|
||||||
|
@ProtoField(number = 3)
|
||||||
|
public Long expiration;
|
||||||
|
|
||||||
|
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
|
||||||
|
@ProtoField(number = 4)
|
||||||
|
public Long timestamp;
|
||||||
|
|
||||||
|
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
|
||||||
|
@ProtoField(number = 5)
|
||||||
|
public HotRodOperationType operationType;
|
||||||
|
|
||||||
|
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
|
||||||
|
@ProtoField(number = 6)
|
||||||
|
public String authClientId;
|
||||||
|
|
||||||
|
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
|
||||||
|
@ProtoField(number = 7)
|
||||||
|
public String authIpAddress;
|
||||||
|
|
||||||
|
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
|
||||||
|
@ProtoField(number = 8)
|
||||||
|
public String authRealmId;
|
||||||
|
|
||||||
|
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
|
||||||
|
@ProtoField(number = 9)
|
||||||
|
public String authUserId;
|
||||||
|
|
||||||
|
@ProtoField(number = 10)
|
||||||
|
public String error;
|
||||||
|
|
||||||
|
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
|
||||||
|
@ProtoField(number = 11)
|
||||||
|
public String realmId;
|
||||||
|
|
||||||
|
@ProtoField(number = 12)
|
||||||
|
public String representation;
|
||||||
|
|
||||||
|
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
|
||||||
|
@ProtoField(number = 13)
|
||||||
|
public String resourcePath;
|
||||||
|
|
||||||
|
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
|
||||||
|
@ProtoField(number = 14)
|
||||||
|
public String resourceType;
|
||||||
|
|
||||||
|
public static abstract class AbstractHotRodAdminEventEntityDelegate extends UpdatableHotRodEntityDelegateImpl<HotRodAdminEventEntity> implements MapAdminEventEntity {
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return getHotRodEntity().id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setId(String id) {
|
||||||
|
HotRodAdminEventEntity entity = getHotRodEntity();
|
||||||
|
if (entity.id != null) throw new IllegalStateException("Id cannot be changed");
|
||||||
|
entity.id = id;
|
||||||
|
entity.updated |= id != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
return HotRodAdminEventEntityDelegate.entityEquals(this, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return HotRodAdminEventEntityDelegate.entityHashCode(this);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
/*
|
||||||
|
* 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.storage.hotRod.events;
|
||||||
|
|
||||||
|
import org.infinispan.protostream.annotations.ProtoDoc;
|
||||||
|
import org.infinispan.protostream.annotations.ProtoField;
|
||||||
|
import org.keycloak.models.map.annotations.GenerateHotRodEntityImplementation;
|
||||||
|
import org.keycloak.models.map.events.MapAuthEventEntity;
|
||||||
|
import org.keycloak.models.map.storage.hotRod.common.AbstractHotRodEntity;
|
||||||
|
import org.keycloak.models.map.storage.hotRod.common.HotRodPair;
|
||||||
|
import org.keycloak.models.map.storage.hotRod.common.UpdatableHotRodEntityDelegateImpl;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
@GenerateHotRodEntityImplementation(
|
||||||
|
implementInterface = "org.keycloak.models.map.events.MapAuthEventEntity",
|
||||||
|
inherits = "org.keycloak.models.map.storage.hotRod.events.HotRodAuthEventEntity.AbstractHotRodAuthEventEntityDelegate"
|
||||||
|
)
|
||||||
|
@ProtoDoc("@Indexed")
|
||||||
|
public class HotRodAuthEventEntity extends AbstractHotRodEntity {
|
||||||
|
|
||||||
|
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
|
||||||
|
@ProtoField(number = 1)
|
||||||
|
public Integer entityVersion = 1;
|
||||||
|
|
||||||
|
@ProtoField(number = 2)
|
||||||
|
public String id;
|
||||||
|
|
||||||
|
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
|
||||||
|
@ProtoField(number = 3)
|
||||||
|
public HotRodEventType type;
|
||||||
|
|
||||||
|
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
|
||||||
|
@ProtoField(number = 4)
|
||||||
|
public Long expiration;
|
||||||
|
|
||||||
|
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
|
||||||
|
@ProtoField(number = 5)
|
||||||
|
public Long timestamp;
|
||||||
|
|
||||||
|
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
|
||||||
|
@ProtoField(number = 6)
|
||||||
|
public String clientId;
|
||||||
|
|
||||||
|
@ProtoField(number = 7)
|
||||||
|
public String error;
|
||||||
|
|
||||||
|
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
|
||||||
|
@ProtoField(number = 8)
|
||||||
|
public String ipAddress;
|
||||||
|
|
||||||
|
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
|
||||||
|
@ProtoField(number = 9)
|
||||||
|
public String realmId;
|
||||||
|
|
||||||
|
@ProtoField(number = 10)
|
||||||
|
public String sessionId;
|
||||||
|
|
||||||
|
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
|
||||||
|
@ProtoField(number = 11)
|
||||||
|
public String userId;
|
||||||
|
|
||||||
|
@ProtoField(number = 12)
|
||||||
|
public Set<HotRodPair<String, String>> details;
|
||||||
|
|
||||||
|
public static abstract class AbstractHotRodAuthEventEntityDelegate extends UpdatableHotRodEntityDelegateImpl<HotRodAuthEventEntity> implements MapAuthEventEntity {
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return getHotRodEntity().id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setId(String id) {
|
||||||
|
HotRodAuthEventEntity entity = getHotRodEntity();
|
||||||
|
if (entity.id != null) throw new IllegalStateException("Id cannot be changed");
|
||||||
|
entity.id = id;
|
||||||
|
entity.updated |= id != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
return HotRodAuthEventEntityDelegate.entityEquals(this, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return HotRodAuthEventEntityDelegate.entityHashCode(this);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,238 @@
|
||||||
|
/*
|
||||||
|
* 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.storage.hotRod.events;
|
||||||
|
|
||||||
|
import org.infinispan.protostream.annotations.ProtoEnumValue;
|
||||||
|
|
||||||
|
public enum HotRodEventType {
|
||||||
|
|
||||||
|
@ProtoEnumValue(number = 0)
|
||||||
|
LOGIN,
|
||||||
|
@ProtoEnumValue(number = 1)
|
||||||
|
LOGIN_ERROR,
|
||||||
|
@ProtoEnumValue(number = 2)
|
||||||
|
REGISTER,
|
||||||
|
@ProtoEnumValue(number = 3)
|
||||||
|
REGISTER_ERROR,
|
||||||
|
@ProtoEnumValue(number = 4)
|
||||||
|
LOGOUT,
|
||||||
|
@ProtoEnumValue(number = 5)
|
||||||
|
LOGOUT_ERROR,
|
||||||
|
@ProtoEnumValue(number = 6)
|
||||||
|
CODE_TO_TOKEN,
|
||||||
|
@ProtoEnumValue(number = 7)
|
||||||
|
CODE_TO_TOKEN_ERROR,
|
||||||
|
@ProtoEnumValue(number = 8)
|
||||||
|
CLIENT_LOGIN,
|
||||||
|
@ProtoEnumValue(number = 9)
|
||||||
|
CLIENT_LOGIN_ERROR,
|
||||||
|
@ProtoEnumValue(number = 10)
|
||||||
|
REFRESH_TOKEN,
|
||||||
|
@ProtoEnumValue(number = 11)
|
||||||
|
REFRESH_TOKEN_ERROR,
|
||||||
|
@ProtoEnumValue(number = 12)
|
||||||
|
/**
|
||||||
|
* @deprecated see KEYCLOAK-2266
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
VALIDATE_ACCESS_TOKEN,
|
||||||
|
@ProtoEnumValue(number = 13)
|
||||||
|
@Deprecated
|
||||||
|
VALIDATE_ACCESS_TOKEN_ERROR,
|
||||||
|
@ProtoEnumValue(number = 14)
|
||||||
|
INTROSPECT_TOKEN,
|
||||||
|
@ProtoEnumValue(number = 15)
|
||||||
|
INTROSPECT_TOKEN_ERROR,
|
||||||
|
@ProtoEnumValue(number = 16)
|
||||||
|
FEDERATED_IDENTITY_LINK,
|
||||||
|
@ProtoEnumValue(number = 17)
|
||||||
|
FEDERATED_IDENTITY_LINK_ERROR,
|
||||||
|
@ProtoEnumValue(number = 18)
|
||||||
|
REMOVE_FEDERATED_IDENTITY,
|
||||||
|
@ProtoEnumValue(number = 19)
|
||||||
|
REMOVE_FEDERATED_IDENTITY_ERROR,
|
||||||
|
@ProtoEnumValue(number = 20)
|
||||||
|
UPDATE_EMAIL,
|
||||||
|
@ProtoEnumValue(number = 21)
|
||||||
|
UPDATE_EMAIL_ERROR,
|
||||||
|
@ProtoEnumValue(number = 22)
|
||||||
|
UPDATE_PROFILE,
|
||||||
|
@ProtoEnumValue(number = 23)
|
||||||
|
UPDATE_PROFILE_ERROR,
|
||||||
|
@ProtoEnumValue(number = 24)
|
||||||
|
UPDATE_PASSWORD,
|
||||||
|
@ProtoEnumValue(number = 25)
|
||||||
|
UPDATE_PASSWORD_ERROR,
|
||||||
|
@ProtoEnumValue(number = 26)
|
||||||
|
UPDATE_TOTP,
|
||||||
|
@ProtoEnumValue(number = 27)
|
||||||
|
UPDATE_TOTP_ERROR,
|
||||||
|
@ProtoEnumValue(number = 28)
|
||||||
|
VERIFY_EMAIL,
|
||||||
|
@ProtoEnumValue(number = 29)
|
||||||
|
VERIFY_EMAIL_ERROR,
|
||||||
|
@ProtoEnumValue(number = 30)
|
||||||
|
VERIFY_PROFILE,
|
||||||
|
@ProtoEnumValue(number = 31)
|
||||||
|
VERIFY_PROFILE_ERROR,
|
||||||
|
@ProtoEnumValue(number = 32)
|
||||||
|
REMOVE_TOTP,
|
||||||
|
@ProtoEnumValue(number = 33)
|
||||||
|
REMOVE_TOTP_ERROR,
|
||||||
|
@ProtoEnumValue(number = 34)
|
||||||
|
GRANT_CONSENT,
|
||||||
|
@ProtoEnumValue(number = 35)
|
||||||
|
GRANT_CONSENT_ERROR,
|
||||||
|
@ProtoEnumValue(number = 36)
|
||||||
|
UPDATE_CONSENT,
|
||||||
|
@ProtoEnumValue(number = 37)
|
||||||
|
UPDATE_CONSENT_ERROR,
|
||||||
|
@ProtoEnumValue(number = 38)
|
||||||
|
REVOKE_GRANT,
|
||||||
|
@ProtoEnumValue(number = 39)
|
||||||
|
REVOKE_GRANT_ERROR,
|
||||||
|
@ProtoEnumValue(number = 40)
|
||||||
|
SEND_VERIFY_EMAIL,
|
||||||
|
@ProtoEnumValue(number = 41)
|
||||||
|
SEND_VERIFY_EMAIL_ERROR,
|
||||||
|
@ProtoEnumValue(number = 42)
|
||||||
|
SEND_RESET_PASSWORD,
|
||||||
|
@ProtoEnumValue(number = 43)
|
||||||
|
SEND_RESET_PASSWORD_ERROR,
|
||||||
|
@ProtoEnumValue(number = 44)
|
||||||
|
SEND_IDENTITY_PROVIDER_LINK,
|
||||||
|
@ProtoEnumValue(number = 45)
|
||||||
|
SEND_IDENTITY_PROVIDER_LINK_ERROR,
|
||||||
|
@ProtoEnumValue(number = 46)
|
||||||
|
RESET_PASSWORD,
|
||||||
|
@ProtoEnumValue(number = 47)
|
||||||
|
RESET_PASSWORD_ERROR,
|
||||||
|
@ProtoEnumValue(number = 48)
|
||||||
|
RESTART_AUTHENTICATION,
|
||||||
|
@ProtoEnumValue(number = 49)
|
||||||
|
RESTART_AUTHENTICATION_ERROR,
|
||||||
|
@ProtoEnumValue(number = 50)
|
||||||
|
INVALID_SIGNATURE,
|
||||||
|
@ProtoEnumValue(number = 51)
|
||||||
|
INVALID_SIGNATURE_ERROR,
|
||||||
|
@ProtoEnumValue(number = 52)
|
||||||
|
REGISTER_NODE,
|
||||||
|
@ProtoEnumValue(number = 53)
|
||||||
|
REGISTER_NODE_ERROR,
|
||||||
|
@ProtoEnumValue(number = 54)
|
||||||
|
UNREGISTER_NODE,
|
||||||
|
@ProtoEnumValue(number = 55)
|
||||||
|
UNREGISTER_NODE_ERROR,
|
||||||
|
@ProtoEnumValue(number = 56)
|
||||||
|
USER_INFO_REQUEST,
|
||||||
|
@ProtoEnumValue(number = 57)
|
||||||
|
USER_INFO_REQUEST_ERROR,
|
||||||
|
@ProtoEnumValue(number = 58)
|
||||||
|
IDENTITY_PROVIDER_LINK_ACCOUNT,
|
||||||
|
@ProtoEnumValue(number = 59)
|
||||||
|
IDENTITY_PROVIDER_LINK_ACCOUNT_ERROR,
|
||||||
|
@ProtoEnumValue(number = 60)
|
||||||
|
IDENTITY_PROVIDER_LOGIN,
|
||||||
|
@ProtoEnumValue(number = 61)
|
||||||
|
IDENTITY_PROVIDER_LOGIN_ERROR,
|
||||||
|
@ProtoEnumValue(number = 62)
|
||||||
|
IDENTITY_PROVIDER_FIRST_LOGIN,
|
||||||
|
@ProtoEnumValue(number = 63)
|
||||||
|
IDENTITY_PROVIDER_FIRST_LOGIN_ERROR,
|
||||||
|
@ProtoEnumValue(number = 64)
|
||||||
|
IDENTITY_PROVIDER_POST_LOGIN,
|
||||||
|
@ProtoEnumValue(number = 65)
|
||||||
|
IDENTITY_PROVIDER_POST_LOGIN_ERROR,
|
||||||
|
@ProtoEnumValue(number = 66)
|
||||||
|
IDENTITY_PROVIDER_RESPONSE,
|
||||||
|
@ProtoEnumValue(number = 67)
|
||||||
|
IDENTITY_PROVIDER_RESPONSE_ERROR,
|
||||||
|
@ProtoEnumValue(number = 68)
|
||||||
|
IDENTITY_PROVIDER_RETRIEVE_TOKEN,
|
||||||
|
@ProtoEnumValue(number = 69)
|
||||||
|
IDENTITY_PROVIDER_RETRIEVE_TOKEN_ERROR,
|
||||||
|
@ProtoEnumValue(number = 70)
|
||||||
|
IMPERSONATE,
|
||||||
|
@ProtoEnumValue(number = 71)
|
||||||
|
IMPERSONATE_ERROR,
|
||||||
|
@ProtoEnumValue(number = 72)
|
||||||
|
CUSTOM_REQUIRED_ACTION,
|
||||||
|
@ProtoEnumValue(number = 73)
|
||||||
|
CUSTOM_REQUIRED_ACTION_ERROR,
|
||||||
|
@ProtoEnumValue(number = 74)
|
||||||
|
EXECUTE_ACTIONS,
|
||||||
|
@ProtoEnumValue(number = 75)
|
||||||
|
EXECUTE_ACTIONS_ERROR,
|
||||||
|
@ProtoEnumValue(number = 76)
|
||||||
|
EXECUTE_ACTION_TOKEN,
|
||||||
|
@ProtoEnumValue(number = 77)
|
||||||
|
EXECUTE_ACTION_TOKEN_ERROR,
|
||||||
|
@ProtoEnumValue(number = 78)
|
||||||
|
CLIENT_INFO,
|
||||||
|
@ProtoEnumValue(number = 79)
|
||||||
|
CLIENT_INFO_ERROR,
|
||||||
|
@ProtoEnumValue(number = 80)
|
||||||
|
CLIENT_REGISTER,
|
||||||
|
@ProtoEnumValue(number = 81)
|
||||||
|
CLIENT_REGISTER_ERROR,
|
||||||
|
@ProtoEnumValue(number = 82)
|
||||||
|
CLIENT_UPDATE,
|
||||||
|
@ProtoEnumValue(number = 83)
|
||||||
|
CLIENT_UPDATE_ERROR,
|
||||||
|
@ProtoEnumValue(number = 84)
|
||||||
|
CLIENT_DELETE,
|
||||||
|
@ProtoEnumValue(number = 85)
|
||||||
|
CLIENT_DELETE_ERROR,
|
||||||
|
@ProtoEnumValue(number = 86)
|
||||||
|
CLIENT_INITIATED_ACCOUNT_LINKING,
|
||||||
|
@ProtoEnumValue(number = 87)
|
||||||
|
CLIENT_INITIATED_ACCOUNT_LINKING_ERROR,
|
||||||
|
@ProtoEnumValue(number = 88)
|
||||||
|
TOKEN_EXCHANGE,
|
||||||
|
@ProtoEnumValue(number = 89)
|
||||||
|
TOKEN_EXCHANGE_ERROR,
|
||||||
|
@ProtoEnumValue(number = 90)
|
||||||
|
OAUTH2_DEVICE_AUTH,
|
||||||
|
@ProtoEnumValue(number = 91)
|
||||||
|
OAUTH2_DEVICE_AUTH_ERROR,
|
||||||
|
@ProtoEnumValue(number = 92)
|
||||||
|
OAUTH2_DEVICE_VERIFY_USER_CODE,
|
||||||
|
@ProtoEnumValue(number = 93)
|
||||||
|
OAUTH2_DEVICE_VERIFY_USER_CODE_ERROR,
|
||||||
|
@ProtoEnumValue(number = 94)
|
||||||
|
OAUTH2_DEVICE_CODE_TO_TOKEN,
|
||||||
|
@ProtoEnumValue(number = 95)
|
||||||
|
OAUTH2_DEVICE_CODE_TO_TOKEN_ERROR,
|
||||||
|
@ProtoEnumValue(number = 96)
|
||||||
|
AUTHREQID_TO_TOKEN,
|
||||||
|
@ProtoEnumValue(number = 97)
|
||||||
|
AUTHREQID_TO_TOKEN_ERROR,
|
||||||
|
@ProtoEnumValue(number = 98)
|
||||||
|
PERMISSION_TOKEN,
|
||||||
|
@ProtoEnumValue(number = 99)
|
||||||
|
PERMISSION_TOKEN_ERROR,
|
||||||
|
@ProtoEnumValue(number = 100)
|
||||||
|
DELETE_ACCOUNT,
|
||||||
|
@ProtoEnumValue(number = 101)
|
||||||
|
DELETE_ACCOUNT_ERROR,
|
||||||
|
@ProtoEnumValue(number = 102)
|
||||||
|
// PAR request.
|
||||||
|
PUSHED_AUTHORIZATION_REQUEST,
|
||||||
|
@ProtoEnumValue(number = 103)
|
||||||
|
PUSHED_AUTHORIZATION_REQUEST_ERROR;
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* 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.storage.hotRod.events;
|
||||||
|
|
||||||
|
import org.infinispan.protostream.annotations.ProtoEnumValue;
|
||||||
|
|
||||||
|
public enum HotRodOperationType {
|
||||||
|
@ProtoEnumValue(number = 0)
|
||||||
|
CREATE,
|
||||||
|
@ProtoEnumValue(number = 1)
|
||||||
|
UPDATE,
|
||||||
|
@ProtoEnumValue(number = 2)
|
||||||
|
DELETE,
|
||||||
|
@ProtoEnumValue(number = 3)
|
||||||
|
ACTION;
|
||||||
|
}
|
|
@ -100,5 +100,21 @@
|
||||||
</indexed-entities>
|
</indexed-entities>
|
||||||
</indexing>
|
</indexing>
|
||||||
</distributed-cache>
|
</distributed-cache>
|
||||||
|
<distributed-cache name="auth-events" mode="SYNC">
|
||||||
|
<encoding media-type="application/x-protostream"/>
|
||||||
|
<indexing>
|
||||||
|
<indexed-entities>
|
||||||
|
<indexed-entity>kc.HotRodAuthEventEntity</indexed-entity>
|
||||||
|
</indexed-entities>
|
||||||
|
</indexing>
|
||||||
|
</distributed-cache>
|
||||||
|
<distributed-cache name="admin-events" mode="SYNC">
|
||||||
|
<encoding media-type="application/x-protostream"/>
|
||||||
|
<indexing>
|
||||||
|
<indexed-entities>
|
||||||
|
<indexed-entity>kc.HotRodAdminEventEntity</indexed-entity>
|
||||||
|
</indexed-entities>
|
||||||
|
</indexing>
|
||||||
|
</distributed-cache>
|
||||||
</cache-container>
|
</cache-container>
|
||||||
</infinispan>
|
</infinispan>
|
||||||
|
|
|
@ -102,5 +102,21 @@
|
||||||
</indexed-entities>
|
</indexed-entities>
|
||||||
</indexing>
|
</indexing>
|
||||||
</distributed-cache>
|
</distributed-cache>
|
||||||
|
<distributed-cache name="auth-events" mode="SYNC">
|
||||||
|
<encoding media-type="application/x-protostream"/>
|
||||||
|
<indexing>
|
||||||
|
<indexed-entities>
|
||||||
|
<indexed-entity>kc.HotRodAuthEventEntity</indexed-entity>
|
||||||
|
</indexed-entities>
|
||||||
|
</indexing>
|
||||||
|
</distributed-cache>
|
||||||
|
<distributed-cache name="admin-events" mode="SYNC">
|
||||||
|
<encoding media-type="application/x-protostream"/>
|
||||||
|
<indexing>
|
||||||
|
<indexed-entities>
|
||||||
|
<indexed-entity>kc.HotRodAdminEventEntity</indexed-entity>
|
||||||
|
</indexed-entities>
|
||||||
|
</indexing>
|
||||||
|
</distributed-cache>
|
||||||
</cache-container>
|
</cache-container>
|
||||||
</infinispan>
|
</infinispan>
|
||||||
|
|
|
@ -34,7 +34,7 @@ public class AdminEvent {
|
||||||
public static final SearchableModelField<AdminEvent> AUTH_USER_ID = new SearchableModelField<>("authUserId", String.class);
|
public static final SearchableModelField<AdminEvent> AUTH_USER_ID = new SearchableModelField<>("authUserId", String.class);
|
||||||
public static final SearchableModelField<AdminEvent> AUTH_IP_ADDRESS = new SearchableModelField<>("authIpAddress", String.class);
|
public static final SearchableModelField<AdminEvent> AUTH_IP_ADDRESS = new SearchableModelField<>("authIpAddress", String.class);
|
||||||
public static final SearchableModelField<AdminEvent> OPERATION_TYPE = new SearchableModelField<>("operationType", OperationType.class);
|
public static final SearchableModelField<AdminEvent> OPERATION_TYPE = new SearchableModelField<>("operationType", OperationType.class);
|
||||||
public static final SearchableModelField<AdminEvent> RESOURCE_TYPE = new SearchableModelField<>("resourceType", ResourceType.class);
|
public static final SearchableModelField<AdminEvent> RESOURCE_TYPE = new SearchableModelField<>("resourceType", String.class);
|
||||||
public static final SearchableModelField<AdminEvent> RESOURCE_PATH = new SearchableModelField<>("resourcePath", String.class);
|
public static final SearchableModelField<AdminEvent> RESOURCE_PATH = new SearchableModelField<>("resourcePath", String.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1506,6 +1506,7 @@
|
||||||
<keycloak.realm.map.storage.provider>hotrod</keycloak.realm.map.storage.provider>
|
<keycloak.realm.map.storage.provider>hotrod</keycloak.realm.map.storage.provider>
|
||||||
<keycloak.userSession.map.storage.provider>hotrod</keycloak.userSession.map.storage.provider>
|
<keycloak.userSession.map.storage.provider>hotrod</keycloak.userSession.map.storage.provider>
|
||||||
<keycloak.authorization.map.storage.provider>hotrod</keycloak.authorization.map.storage.provider>
|
<keycloak.authorization.map.storage.provider>hotrod</keycloak.authorization.map.storage.provider>
|
||||||
|
<keycloak.eventStore.map.storage.provider>hotrod</keycloak.eventStore.map.storage.provider>
|
||||||
</systemPropertyVariables>
|
</systemPropertyVariables>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
|
@ -98,5 +98,21 @@
|
||||||
</indexed-entities>
|
</indexed-entities>
|
||||||
</indexing>
|
</indexing>
|
||||||
</distributed-cache>
|
</distributed-cache>
|
||||||
|
<distributed-cache name="auth-events" mode="SYNC">
|
||||||
|
<encoding media-type="application/x-protostream"/>
|
||||||
|
<indexing>
|
||||||
|
<indexed-entities>
|
||||||
|
<indexed-entity>kc.HotRodAuthEventEntity</indexed-entity>
|
||||||
|
</indexed-entities>
|
||||||
|
</indexing>
|
||||||
|
</distributed-cache>
|
||||||
|
<distributed-cache name="admin-events" mode="SYNC">
|
||||||
|
<encoding media-type="application/x-protostream"/>
|
||||||
|
<indexing>
|
||||||
|
<indexed-entities>
|
||||||
|
<indexed-entity>kc.HotRodAdminEventEntity</indexed-entity>
|
||||||
|
</indexed-entities>
|
||||||
|
</indexing>
|
||||||
|
</distributed-cache>
|
||||||
</cache-container>
|
</cache-container>
|
||||||
</infinispan>
|
</infinispan>
|
||||||
|
|
|
@ -90,8 +90,8 @@ public class HotRodMapStorage extends KeycloakModelParameters {
|
||||||
.config("storage-client-sessions.provider", HotRodMapStorageProviderFactory.PROVIDER_ID)
|
.config("storage-client-sessions.provider", HotRodMapStorageProviderFactory.PROVIDER_ID)
|
||||||
.spi(UserLoginFailureSpi.NAME).provider(MapUserLoginFailureProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, HotRodMapStorageProviderFactory.PROVIDER_ID)
|
.spi(UserLoginFailureSpi.NAME).provider(MapUserLoginFailureProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, HotRodMapStorageProviderFactory.PROVIDER_ID)
|
||||||
.spi("dblock").provider(NoLockingDBLockProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, ConcurrentHashMapStorageProviderFactory.PROVIDER_ID)
|
.spi("dblock").provider(NoLockingDBLockProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, ConcurrentHashMapStorageProviderFactory.PROVIDER_ID)
|
||||||
.spi(EventStoreSpi.NAME).provider(MapUserSessionProviderFactory.PROVIDER_ID).config("storage-admin-events.provider", ConcurrentHashMapStorageProviderFactory.PROVIDER_ID)
|
.spi(EventStoreSpi.NAME).provider(MapUserSessionProviderFactory.PROVIDER_ID).config("storage-admin-events.provider", HotRodMapStorageProviderFactory.PROVIDER_ID)
|
||||||
.config("storage-auth-events.provider", ConcurrentHashMapStorageProviderFactory.PROVIDER_ID);
|
.config("storage-auth-events.provider", HotRodMapStorageProviderFactory.PROVIDER_ID);
|
||||||
|
|
||||||
cf.spi(MapStorageSpi.NAME)
|
cf.spi(MapStorageSpi.NAME)
|
||||||
.provider(ConcurrentHashMapStorageProviderFactory.PROVIDER_ID)
|
.provider(ConcurrentHashMapStorageProviderFactory.PROVIDER_ID)
|
||||||
|
|
|
@ -305,6 +305,7 @@
|
||||||
<systemProperty><key>keycloak.authorization.provider</key><value>map</value></systemProperty>
|
<systemProperty><key>keycloak.authorization.provider</key><value>map</value></systemProperty>
|
||||||
<systemProperty><key>keycloak.actionToken.provider</key><value>map</value></systemProperty>
|
<systemProperty><key>keycloak.actionToken.provider</key><value>map</value></systemProperty>
|
||||||
<systemProperty><key>keycloak.singleUseObject.provider</key><value>map</value></systemProperty>
|
<systemProperty><key>keycloak.singleUseObject.provider</key><value>map</value></systemProperty>
|
||||||
|
<systemProperty><key>keycloak.eventsStore.provider</key><value>map</value></systemProperty>
|
||||||
<systemProperty><key>keycloak.authorizationCache.enabled</key><value>false</value></systemProperty>
|
<systemProperty><key>keycloak.authorizationCache.enabled</key><value>false</value></systemProperty>
|
||||||
<systemProperty><key>keycloak.realmCache.enabled</key><value>false</value></systemProperty>
|
<systemProperty><key>keycloak.realmCache.enabled</key><value>false</value></systemProperty>
|
||||||
<systemProperty><key>keycloak.userCache.enabled</key><value>false</value></systemProperty>
|
<systemProperty><key>keycloak.userCache.enabled</key><value>false</value></systemProperty>
|
||||||
|
|
|
@ -11,7 +11,15 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
"eventsStore": {
|
"eventsStore": {
|
||||||
"provider": "${keycloak.eventsStore.provider:}"
|
"provider": "${keycloak.eventsStore.provider:jpa}",
|
||||||
|
"map": {
|
||||||
|
"storage-admin-events": {
|
||||||
|
"provider": "${keycloak.eventStore.map.storage.provider:concurrenthashmap}"
|
||||||
|
},
|
||||||
|
"storage-auth-events": {
|
||||||
|
"provider": "${keycloak.eventStore.map.storage.provider:concurrenthashmap}"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"deploymentState": {
|
"deploymentState": {
|
||||||
|
|
Loading…
Reference in a new issue