From 5ff2e22f18a52649f0a27b341bc9e0118b3ac920 Mon Sep 17 00:00:00 2001 From: Stefan Guilhen Date: Wed, 12 Nov 2025 09:21:48 -0300 Subject: [PATCH] Fix representation so that workflows can be properly disabled/enabled. - also removes empty 'with' configurations from the steps when retrieving the workflow. Closes #44163 Signed-off-by: Stefan Guilhen --- .../AbstractWorkflowComponentRepresentation.java | 10 ++++++---- .../MultivaluedHashMapValueSerializer.java | 6 ++++++ .../workflows/WorkflowRepresentation.java | 13 ++++++++++++- .../workflows/WorkflowStepRepresentation.java | 2 ++ 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/org/keycloak/representations/workflows/AbstractWorkflowComponentRepresentation.java b/core/src/main/java/org/keycloak/representations/workflows/AbstractWorkflowComponentRepresentation.java index b9b7d192a36..1d95bb0b921 100644 --- a/core/src/main/java/org/keycloak/representations/workflows/AbstractWorkflowComponentRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/workflows/AbstractWorkflowComponentRepresentation.java @@ -24,7 +24,7 @@ public abstract class AbstractWorkflowComponentRepresentation { public AbstractWorkflowComponentRepresentation(String id, MultivaluedHashMap config) { this.id = id; - this.config = config; + this.setConfig(config); } public String getId() { @@ -40,10 +40,12 @@ public abstract class AbstractWorkflowComponentRepresentation { } public void setConfig(MultivaluedHashMap config) { - if (this.config == null) { - this.config = config; + if (config != null) { + if (this.config == null) { + this.config = new MultivaluedHashMap<>(); + } + this.config.putAll(config); } - this.config.putAll(config); } public void setConfig(String key, String value) { diff --git a/core/src/main/java/org/keycloak/representations/workflows/MultivaluedHashMapValueSerializer.java b/core/src/main/java/org/keycloak/representations/workflows/MultivaluedHashMapValueSerializer.java index 9165639ce13..4773ddd4d78 100644 --- a/core/src/main/java/org/keycloak/representations/workflows/MultivaluedHashMapValueSerializer.java +++ b/core/src/main/java/org/keycloak/representations/workflows/MultivaluedHashMapValueSerializer.java @@ -50,6 +50,12 @@ public final class MultivaluedHashMapValueSerializer extends JsonSerializer value) { + // if all properties are ignored, consider the map as empty + return getIgnoredProperties(provider.getGenerator()).containsAll(value.keySet()); + } + private static Set getIgnoredProperties(JsonGenerator gen) { Class parentClazz = gen.currentValue().getClass(); return Arrays.stream(parentClazz.getDeclaredMethods()) diff --git a/core/src/main/java/org/keycloak/representations/workflows/WorkflowRepresentation.java b/core/src/main/java/org/keycloak/representations/workflows/WorkflowRepresentation.java index 3c934c3dceb..710be08898c 100644 --- a/core/src/main/java/org/keycloak/representations/workflows/WorkflowRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/workflows/WorkflowRepresentation.java @@ -1,5 +1,6 @@ package org.keycloak.representations.workflows; +import static org.keycloak.representations.workflows.WorkflowConstants.CONFIG_CANCEL_IF_RUNNING; import static org.keycloak.representations.workflows.WorkflowConstants.CONFIG_CONCURRENCY; import static org.keycloak.representations.workflows.WorkflowConstants.CONFIG_CONDITIONS; import static org.keycloak.representations.workflows.WorkflowConstants.CONFIG_ENABLED; @@ -108,11 +109,21 @@ public final class WorkflowRepresentation extends AbstractWorkflowComponentRepre } public WorkflowConcurrencyRepresentation getConcurrency() { - return concurrency; + if (this.concurrency == null) { + Boolean cancelIfRunning = getConfigValue(CONFIG_CANCEL_IF_RUNNING, Boolean.class); + if (cancelIfRunning != null) { + this.concurrency = new WorkflowConcurrencyRepresentation(); + this.concurrency.setCancelIfRunning(cancelIfRunning); + } + } + return this.concurrency; } public void setConcurrency(WorkflowConcurrencyRepresentation concurrency) { this.concurrency = concurrency; + if (concurrency != null) { + setConfigValue(CONFIG_CANCEL_IF_RUNNING, concurrency.isCancelIfRunning()); + } } @JsonIgnore diff --git a/core/src/main/java/org/keycloak/representations/workflows/WorkflowStepRepresentation.java b/core/src/main/java/org/keycloak/representations/workflows/WorkflowStepRepresentation.java index 174b936853d..711f413f435 100644 --- a/core/src/main/java/org/keycloak/representations/workflows/WorkflowStepRepresentation.java +++ b/core/src/main/java/org/keycloak/representations/workflows/WorkflowStepRepresentation.java @@ -9,12 +9,14 @@ import java.time.Duration; import java.util.Arrays; import java.util.Objects; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonPropertyOrder; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.keycloak.common.util.MultivaluedHashMap; @JsonPropertyOrder({"id", CONFIG_USES, CONFIG_AFTER, CONFIG_PRIORITY, CONFIG_WITH}) +@JsonInclude(JsonInclude.Include.NON_EMPTY) public final class WorkflowStepRepresentation extends AbstractWorkflowComponentRepresentation { private final String uses;