mirror of
https://github.com/keycloak/keycloak.git
synced 2026-01-09 23:12:06 -03:30
Ability to define workflows with YAML
Closes #42687 Signed-off-by: vramik <vramik@redhat.com> Co-authored-by: Pedro Igor <pigor.craveiro@gmail.com>
This commit is contained in:
parent
b1c0c15ad5
commit
b5ed45f2a0
@ -787,6 +787,7 @@ class KeycloakProcessor {
|
|||||||
void index(BuildProducer<IndexDependencyBuildItem> indexDependencyBuildItemBuildProducer) {
|
void index(BuildProducer<IndexDependencyBuildItem> indexDependencyBuildItemBuildProducer) {
|
||||||
indexDependencyBuildItemBuildProducer.produce(new IndexDependencyBuildItem("org.liquibase", "liquibase-core"));
|
indexDependencyBuildItemBuildProducer.produce(new IndexDependencyBuildItem("org.liquibase", "liquibase-core"));
|
||||||
indexDependencyBuildItemBuildProducer.produce(new IndexDependencyBuildItem("org.keycloak", "keycloak-services"));
|
indexDependencyBuildItemBuildProducer.produce(new IndexDependencyBuildItem("org.keycloak", "keycloak-services"));
|
||||||
|
indexDependencyBuildItemBuildProducer.produce(new IndexDependencyBuildItem("com.fasterxml.jackson.jakarta.rs", "jackson-jakarta-rs-yaml-provider"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@BuildStep
|
@BuildStep
|
||||||
|
|||||||
@ -655,6 +655,12 @@
|
|||||||
<artifactId>jna</artifactId>
|
<artifactId>jna</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- YAML -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.jakarta.rs</groupId>
|
||||||
|
<artifactId>jackson-jakarta-rs-yaml-provider</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
|
|||||||
@ -183,6 +183,11 @@
|
|||||||
<version>${woodstox.version}</version> <!-- this version has to match that of used in Wildfly -->
|
<version>${woodstox.version}</version> <!-- this version has to match that of used in Wildfly -->
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- YAML -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.jakarta.rs</groupId>
|
||||||
|
<artifactId>jackson-jakarta-rs-yaml-provider</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.zxing</groupId>
|
<groupId>com.google.zxing</groupId>
|
||||||
<artifactId>javase</artifactId>
|
<artifactId>javase</artifactId>
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import java.util.List;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.jakarta.rs.yaml.YAMLMediaTypes;
|
||||||
import jakarta.ws.rs.Consumes;
|
import jakarta.ws.rs.Consumes;
|
||||||
import jakarta.ws.rs.GET;
|
import jakarta.ws.rs.GET;
|
||||||
import jakarta.ws.rs.NotFoundException;
|
import jakarta.ws.rs.NotFoundException;
|
||||||
@ -37,7 +38,7 @@ public class WorkflowsResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes({MediaType.APPLICATION_JSON, YAMLMediaTypes.APPLICATION_JACKSON_YAML})
|
||||||
public Response create(WorkflowRepresentation rep) {
|
public Response create(WorkflowRepresentation rep) {
|
||||||
try {
|
try {
|
||||||
Workflow workflow = manager.toModel(rep);
|
Workflow workflow = manager.toModel(rep);
|
||||||
@ -49,7 +50,7 @@ public class WorkflowsResource {
|
|||||||
|
|
||||||
@Path("set")
|
@Path("set")
|
||||||
@POST
|
@POST
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes({MediaType.APPLICATION_JSON, YAMLMediaTypes.APPLICATION_JACKSON_YAML})
|
||||||
public Response createAll(WorkflowSetRepresentation workflows) {
|
public Response createAll(WorkflowSetRepresentation workflows) {
|
||||||
for (WorkflowRepresentation workflow : Optional.ofNullable(workflows.getWorkflows()).orElse(List.of())) {
|
for (WorkflowRepresentation workflow : Optional.ofNullable(workflows.getWorkflows()).orElse(List.of())) {
|
||||||
create(workflow).close();
|
create(workflow).close();
|
||||||
|
|||||||
@ -34,6 +34,9 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import jakarta.ws.rs.client.Client;
|
||||||
|
import jakarta.ws.rs.client.Entity;
|
||||||
|
import jakarta.ws.rs.client.WebTarget;
|
||||||
import jakarta.ws.rs.core.Response;
|
import jakarta.ws.rs.core.Response;
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
import jakarta.mail.MessagingException;
|
import jakarta.mail.MessagingException;
|
||||||
@ -42,6 +45,8 @@ import java.io.IOException;
|
|||||||
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.keycloak.admin.client.Keycloak;
|
||||||
|
import org.keycloak.admin.client.resource.BearerAuthFilter;
|
||||||
import org.keycloak.admin.client.resource.WorkflowsResource;
|
import org.keycloak.admin.client.resource.WorkflowsResource;
|
||||||
import org.keycloak.broker.oidc.KeycloakOIDCIdentityProviderFactory;
|
import org.keycloak.broker.oidc.KeycloakOIDCIdentityProviderFactory;
|
||||||
import org.keycloak.common.util.Time;
|
import org.keycloak.common.util.Time;
|
||||||
@ -69,6 +74,8 @@ import org.keycloak.representations.workflows.WorkflowSetRepresentation;
|
|||||||
import org.keycloak.representations.workflows.WorkflowStepRepresentation;
|
import org.keycloak.representations.workflows.WorkflowStepRepresentation;
|
||||||
import org.keycloak.representations.workflows.WorkflowConditionRepresentation;
|
import org.keycloak.representations.workflows.WorkflowConditionRepresentation;
|
||||||
import org.keycloak.representations.workflows.WorkflowRepresentation;
|
import org.keycloak.representations.workflows.WorkflowRepresentation;
|
||||||
|
import org.keycloak.testframework.annotations.InjectAdminClient;
|
||||||
|
import org.keycloak.testframework.annotations.InjectKeycloakUrls;
|
||||||
import org.keycloak.testframework.annotations.InjectRealm;
|
import org.keycloak.testframework.annotations.InjectRealm;
|
||||||
import org.keycloak.testframework.mail.MailServer;
|
import org.keycloak.testframework.mail.MailServer;
|
||||||
import org.keycloak.testframework.mail.annotations.InjectMailServer;
|
import org.keycloak.testframework.mail.annotations.InjectMailServer;
|
||||||
@ -79,7 +86,9 @@ import org.keycloak.testframework.realm.UserConfigBuilder;
|
|||||||
import org.keycloak.testframework.remote.providers.runonserver.RunOnServer;
|
import org.keycloak.testframework.remote.providers.runonserver.RunOnServer;
|
||||||
import org.keycloak.testframework.remote.runonserver.InjectRunOnServer;
|
import org.keycloak.testframework.remote.runonserver.InjectRunOnServer;
|
||||||
import org.keycloak.testframework.remote.runonserver.RunOnServerClient;
|
import org.keycloak.testframework.remote.runonserver.RunOnServerClient;
|
||||||
|
import org.keycloak.testframework.server.KeycloakUrls;
|
||||||
import org.keycloak.tests.utils.MailUtils;
|
import org.keycloak.tests.utils.MailUtils;
|
||||||
|
import org.keycloak.util.JsonSerialization;
|
||||||
|
|
||||||
@KeycloakIntegrationTest(config = WorkflowsServerConfig.class)
|
@KeycloakIntegrationTest(config = WorkflowsServerConfig.class)
|
||||||
public class WorkflowManagementTest {
|
public class WorkflowManagementTest {
|
||||||
@ -95,6 +104,12 @@ public class WorkflowManagementTest {
|
|||||||
@InjectMailServer
|
@InjectMailServer
|
||||||
private MailServer mailServer;
|
private MailServer mailServer;
|
||||||
|
|
||||||
|
@InjectKeycloakUrls
|
||||||
|
KeycloakUrls keycloakUrls;
|
||||||
|
|
||||||
|
@InjectAdminClient(ref = "managed", realmRef = "managedRealm")
|
||||||
|
Keycloak adminClient;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreate() {
|
public void testCreate() {
|
||||||
WorkflowSetRepresentation expectedWorkflows = WorkflowRepresentation.create()
|
WorkflowSetRepresentation expectedWorkflows = WorkflowRepresentation.create()
|
||||||
@ -877,6 +892,32 @@ public class WorkflowManagementTest {
|
|||||||
mailServer.runCleanup();
|
mailServer.runCleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateUsingYaml() throws IOException {
|
||||||
|
WorkflowSetRepresentation expectedWorkflows = WorkflowRepresentation.create()
|
||||||
|
.of(UserCreationTimeWorkflowProviderFactory.ID)
|
||||||
|
.withSteps(
|
||||||
|
WorkflowStepRepresentation.create().of(NotifyUserStepProviderFactory.ID)
|
||||||
|
.after(Duration.ofDays(5))
|
||||||
|
.build(),
|
||||||
|
WorkflowStepRepresentation.create().of(DisableUserStepProviderFactory.ID)
|
||||||
|
.after(Duration.ofDays(5))
|
||||||
|
.build()
|
||||||
|
).build();
|
||||||
|
|
||||||
|
Client httpClient = Keycloak.getClientProvider().newRestEasyClient(null, null, true);;
|
||||||
|
WebTarget target = httpClient.target(keycloakUrls.getBaseUrl().toString())
|
||||||
|
.path("admin")
|
||||||
|
.path("realms")
|
||||||
|
.path(managedRealm.getName())
|
||||||
|
.path("workflows")
|
||||||
|
.path("set")
|
||||||
|
.register(new BearerAuthFilter(adminClient.tokenManager()));
|
||||||
|
|
||||||
|
Response response = target.request().post(Entity.entity(JsonSerialization.writeValueAsString(expectedWorkflows), "application/yaml"));
|
||||||
|
response.close();
|
||||||
|
}
|
||||||
|
|
||||||
public static List<MimeMessage> findEmailsByRecipient(MailServer mailServer, String expectedRecipient) {
|
public static List<MimeMessage> findEmailsByRecipient(MailServer mailServer, String expectedRecipient) {
|
||||||
return Arrays.stream(mailServer.getReceivedMessages())
|
return Arrays.stream(mailServer.getReceivedMessages())
|
||||||
.filter(msg -> {
|
.filter(msg -> {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user