From 34226a848a4834860007383a7bb750c03b710b96 Mon Sep 17 00:00:00 2001 From: Tihomir Surdilovic Date: Sat, 4 Sep 2021 15:28:22 -0400 Subject: [PATCH] Addint auth Signed-off-by: Tihomir Surdilovic --- .../AuthDefinitionDeserializer.java | 82 +++++++++++++++++++ .../api/mapper/WorkflowModule.java | 4 +- .../serializers/AuthDefinitionSerializer.java | 72 ++++++++++++++++ .../api/serializers/WorkflowSerializer.java | 4 + api/src/main/resources/schema/auth/auth.json | 34 ++++++++ .../resources/schema/auth/basicauthdef.json | 23 ++++++ .../resources/schema/auth/bearerauthdef.json | 17 ++++ .../main/resources/schema/auth/oauthdef.json | 79 ++++++++++++++++++ .../schema/functions/functiondef.json | 5 ++ api/src/main/resources/schema/workflow.json | 3 + .../api/test/MarkupToWorkflowTest.java | 64 +++++++++++++++ .../api/test/WorkflowToMarkupTest.java | 25 +++++- .../test/resources/features/authbasic.json | 13 +++ api/src/test/resources/features/authbasic.yml | 9 ++ .../test/resources/features/authbearer.json | 12 +++ .../test/resources/features/authbearer.yml | 8 ++ .../test/resources/features/authoauth.json | 15 ++++ api/src/test/resources/features/authoauth.yml | 11 +++ 18 files changed, 478 insertions(+), 2 deletions(-) create mode 100644 api/src/main/java/io/serverlessworkflow/api/deserializers/AuthDefinitionDeserializer.java create mode 100644 api/src/main/java/io/serverlessworkflow/api/serializers/AuthDefinitionSerializer.java create mode 100644 api/src/main/resources/schema/auth/auth.json create mode 100644 api/src/main/resources/schema/auth/basicauthdef.json create mode 100644 api/src/main/resources/schema/auth/bearerauthdef.json create mode 100644 api/src/main/resources/schema/auth/oauthdef.json create mode 100644 api/src/test/resources/features/authbasic.json create mode 100644 api/src/test/resources/features/authbasic.yml create mode 100644 api/src/test/resources/features/authbearer.json create mode 100644 api/src/test/resources/features/authbearer.yml create mode 100644 api/src/test/resources/features/authoauth.json create mode 100644 api/src/test/resources/features/authoauth.yml diff --git a/api/src/main/java/io/serverlessworkflow/api/deserializers/AuthDefinitionDeserializer.java b/api/src/main/java/io/serverlessworkflow/api/deserializers/AuthDefinitionDeserializer.java new file mode 100644 index 00000000..9cf0cf6e --- /dev/null +++ b/api/src/main/java/io/serverlessworkflow/api/deserializers/AuthDefinitionDeserializer.java @@ -0,0 +1,82 @@ +/* + * Copyright 2020-Present The Serverless Workflow Specification Authors + * + * 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 io.serverlessworkflow.api.deserializers; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import io.serverlessworkflow.api.auth.AuthDefinition; +import io.serverlessworkflow.api.auth.BasicAuthDefinition; +import io.serverlessworkflow.api.auth.BearerAuthDefinition; +import io.serverlessworkflow.api.auth.OauthDefinition; +import io.serverlessworkflow.api.interfaces.WorkflowPropertySource; + +import java.io.IOException; + +public class AuthDefinitionDeserializer extends StdDeserializer { + + private static final long serialVersionUID = 510l; + + @SuppressWarnings("unused") + private WorkflowPropertySource context; + + public AuthDefinitionDeserializer() { + this(AuthDefinition.class); + } + + public AuthDefinitionDeserializer(Class vc) { + super(vc); + } + + public AuthDefinitionDeserializer(WorkflowPropertySource context) { + this(AuthDefinition.class); + this.context = context; + } + + @Override + public AuthDefinition deserialize(JsonParser jp, + DeserializationContext ctxt) throws IOException { + + ObjectMapper mapper = (ObjectMapper) jp.getCodec(); + JsonNode node = jp.getCodec().readTree(jp); + + AuthDefinition authDefinition = new AuthDefinition(); + + if(node.get("name") != null) { + authDefinition.setName(node.get("name").asText()); + } + + if(node.get("scheme") != null) { + authDefinition.setScheme(AuthDefinition.Scheme.fromValue(node.get("scheme").asText())); + } + + if(node.get("properties") != null) { + JsonNode propsNode = node.get("properties"); + + if(propsNode.get("grantType") != null) { + authDefinition.setOauth(mapper.treeToValue(propsNode, OauthDefinition.class)); + } else if(propsNode.get("token") != null) { + authDefinition.setBearerauth(mapper.treeToValue(propsNode, BearerAuthDefinition.class)); + } else { + authDefinition.setBasicauth(mapper.treeToValue(propsNode, BasicAuthDefinition.class)); + } + } + + return authDefinition; + } +} diff --git a/api/src/main/java/io/serverlessworkflow/api/mapper/WorkflowModule.java b/api/src/main/java/io/serverlessworkflow/api/mapper/WorkflowModule.java index 9a154262..72500385 100644 --- a/api/src/main/java/io/serverlessworkflow/api/mapper/WorkflowModule.java +++ b/api/src/main/java/io/serverlessworkflow/api/mapper/WorkflowModule.java @@ -16,6 +16,7 @@ package io.serverlessworkflow.api.mapper; import com.fasterxml.jackson.databind.module.SimpleModule; +import io.serverlessworkflow.api.auth.AuthDefinition; import io.serverlessworkflow.api.cron.Cron; import io.serverlessworkflow.api.datainputschema.DataInputSchema; import io.serverlessworkflow.api.deserializers.*; @@ -34,7 +35,6 @@ import io.serverlessworkflow.api.states.DefaultState; import io.serverlessworkflow.api.states.OperationState; import io.serverlessworkflow.api.states.ParallelState; -import io.serverlessworkflow.api.timeouts.TimeoutsDefinition; import io.serverlessworkflow.api.transitions.Transition; import io.serverlessworkflow.api.workflow.*; @@ -76,6 +76,7 @@ private void addDefaultSerializers() { addSerializer(new CronSerializer()); addSerializer(new ScheduleSerializer()); addSerializer(new SubFlowRefSerializer()); + addSerializer(new AuthDefinitionSerializer()); addSerializer(extensionSerializer); } @@ -107,6 +108,7 @@ private void addDefaultDeserializers() { addDeserializer(Cron.class, new CronDeserializer(workflowPropertySource)); addDeserializer(Schedule.class, new ScheduleDeserializer(workflowPropertySource)); addDeserializer(DataInputSchema.class, new DataInputSchemaDeserializer(workflowPropertySource)); + addDeserializer(AuthDefinition.class, new AuthDefinitionDeserializer(workflowPropertySource)); } public ExtensionSerializer getExtensionSerializer() { diff --git a/api/src/main/java/io/serverlessworkflow/api/serializers/AuthDefinitionSerializer.java b/api/src/main/java/io/serverlessworkflow/api/serializers/AuthDefinitionSerializer.java new file mode 100644 index 00000000..fe77aede --- /dev/null +++ b/api/src/main/java/io/serverlessworkflow/api/serializers/AuthDefinitionSerializer.java @@ -0,0 +1,72 @@ +/* + * Copyright 2020-Present The Serverless Workflow Specification Authors + * + * 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 io.serverlessworkflow.api.serializers; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import io.serverlessworkflow.api.auth.AuthDefinition; + +import java.io.IOException; + +public class AuthDefinitionSerializer extends StdSerializer { + + public AuthDefinitionSerializer() { + this(AuthDefinition.class); + } + + protected AuthDefinitionSerializer(Class t) { + super(t); + } + + @Override + public void serialize(AuthDefinition authDefinition, + JsonGenerator gen, + SerializerProvider provider) throws IOException { + + gen.writeStartObject(); + if (authDefinition != null) { + if (authDefinition.getName() != null && !authDefinition.getName().isEmpty()) { + gen.writeStringField("name", + authDefinition.getName()); + } + + if (authDefinition.getScheme() != null) { + gen.writeStringField("scheme", + authDefinition.getScheme().value()); + } + + if (authDefinition.getBasicauth() != null || authDefinition.getBearerauth() != null + || authDefinition.getOauth() != null) { + + if(authDefinition.getBasicauth() != null) { + gen.writeObjectField("properties", authDefinition.getBasicauth()); + } + + if(authDefinition.getBearerauth() != null) { + gen.writeObjectField("properties", authDefinition.getBearerauth()); + } + + if(authDefinition.getOauth() != null) { + gen.writeObjectField("properties", authDefinition.getOauth()); + } + + } + } + gen.writeEndObject(); + } +} + diff --git a/api/src/main/java/io/serverlessworkflow/api/serializers/WorkflowSerializer.java b/api/src/main/java/io/serverlessworkflow/api/serializers/WorkflowSerializer.java index c2db774a..dc729731 100644 --- a/api/src/main/java/io/serverlessworkflow/api/serializers/WorkflowSerializer.java +++ b/api/src/main/java/io/serverlessworkflow/api/serializers/WorkflowSerializer.java @@ -159,6 +159,10 @@ public void serialize(Workflow workflow, gen.writeObjectField("timeouts", workflow.getTimeouts()); } + if (workflow.getAuth() != null) { + gen.writeObjectField("auth", workflow.getAuth()); + } + if (workflow.getStates() != null && !workflow.getStates().isEmpty()) { gen.writeArrayFieldStart("states"); for (State state : workflow.getStates()) { diff --git a/api/src/main/resources/schema/auth/auth.json b/api/src/main/resources/schema/auth/auth.json new file mode 100644 index 00000000..c8ece5ee --- /dev/null +++ b/api/src/main/resources/schema/auth/auth.json @@ -0,0 +1,34 @@ +{ + "type": "object", + "javaType": "io.serverlessworkflow.api.auth.AuthDefinition", + "description": "Auth Definition", + "properties": { + "name": { + "type": "string", + "description": "Unique auth definition name", + "minLength": 1 + }, + "scheme": { + "type": "string", + "description": "Defines the auth type", + "enum": [ + "basic", + "bearer", + "oauth2" + ], + "default": "basic" + }, + "basicauth": { + "$ref": "basicauthdef.json" + }, + "bearerauth": { + "$ref": "bearerauthdef.json" + }, + "oauth": { + "$ref": "oauthdef.json" + } + }, + "required": [ + + ] +} \ No newline at end of file diff --git a/api/src/main/resources/schema/auth/basicauthdef.json b/api/src/main/resources/schema/auth/basicauthdef.json new file mode 100644 index 00000000..f7c80da1 --- /dev/null +++ b/api/src/main/resources/schema/auth/basicauthdef.json @@ -0,0 +1,23 @@ +{ + "type": "object", + "javaType": "io.serverlessworkflow.api.auth.BasicAuthDefinition", + "properties": { + "username": { + "type": "string", + "description": "String or a workflow expression. Contains the user name", + "minLength": 1 + }, + "password": { + "type": "string", + "description": "String or a workflow expression. Contains the user password", + "minLength": 1 + }, + "metadata": { + "$ref": "../metadata/metadata.json" + } + }, + "required": [ + "username", + "password" + ] +} \ No newline at end of file diff --git a/api/src/main/resources/schema/auth/bearerauthdef.json b/api/src/main/resources/schema/auth/bearerauthdef.json new file mode 100644 index 00000000..61dfd137 --- /dev/null +++ b/api/src/main/resources/schema/auth/bearerauthdef.json @@ -0,0 +1,17 @@ +{ + "type": "object", + "javaType": "io.serverlessworkflow.api.auth.BearerAuthDefinition", + "properties": { + "token": { + "type": "string", + "description": "String or a workflow expression. Contains the token", + "minLength": 1 + }, + "metadata": { + "$ref": "../metadata/metadata.json" + } + }, + "required": [ + "token" + ] +} \ No newline at end of file diff --git a/api/src/main/resources/schema/auth/oauthdef.json b/api/src/main/resources/schema/auth/oauthdef.json new file mode 100644 index 00000000..4354be2c --- /dev/null +++ b/api/src/main/resources/schema/auth/oauthdef.json @@ -0,0 +1,79 @@ +{ + "type": "object", + "javaType": "io.serverlessworkflow.api.auth.OauthDefinition", + "properties": { + "authority": { + "type": "string", + "description": "String or a workflow expression. Contains the authority information", + "minLength": 1 + }, + "grantType": { + "type": "string", + "description": "Defines the grant type", + "enum": [ + "password", + "clientCredentials", + "tokenExchange" + ], + "additionalItems": false + }, + "clientId": { + "type": "string", + "description": "String or a workflow expression. Contains the client identifier", + "minLength": 1 + }, + "clientSecret": { + "type": "string", + "description": "Workflow secret or a workflow expression. Contains the client secret", + "minLength": 1 + }, + "scopes": { + "type": "array", + "description": "Array containing strings or workflow expressions. Contains the OAuth2 scopes", + "items": { + "type": "string" + }, + "minItems": 1 + }, + "username": { + "type": "string", + "description": "String or a workflow expression. Contains the user name. Used only if grantType is 'resourceOwner'", + "minLength": 1 + }, + "password": { + "type": "string", + "description": "String or a workflow expression. Contains the user password. Used only if grantType is 'resourceOwner'", + "minLength": 1 + }, + "audiences": { + "type": "array", + "description": "Array containing strings or workflow expressions. Contains the OAuth2 audiences", + "items": { + "type": "string" + }, + "minItems": 1 + }, + "subjectToken": { + "type": "string", + "description": "String or a workflow expression. Contains the subject token", + "minLength": 1 + }, + "requestedSubject": { + "type": "string", + "description": "String or a workflow expression. Contains the requested subject", + "minLength": 1 + }, + "requestedIssuer": { + "type": "string", + "description": "String or a workflow expression. Contains the requested issuer", + "minLength": 1 + }, + "metadata": { + "$ref": "../metadata/metadata.json" + } + }, + "required": [ + "grantType", + "clientId" + ] +} \ No newline at end of file diff --git a/api/src/main/resources/schema/functions/functiondef.json b/api/src/main/resources/schema/functions/functiondef.json index 2ca0a8e7..b2790653 100644 --- a/api/src/main/resources/schema/functions/functiondef.json +++ b/api/src/main/resources/schema/functions/functiondef.json @@ -23,6 +23,11 @@ ], "default": "rest" }, + "authRef": { + "type": "string", + "description": "References an auth definition name to be used to access to resource defined in the operation parameter", + "minLength": 1 + }, "metadata": { "$ref": "../metadata/metadata.json" } diff --git a/api/src/main/resources/schema/workflow.json b/api/src/main/resources/schema/workflow.json index ff5b1a7f..7e36ebfc 100644 --- a/api/src/main/resources/schema/workflow.json +++ b/api/src/main/resources/schema/workflow.json @@ -81,6 +81,9 @@ "timeouts": { "$ref": "timeouts/timeoutsdef.json" }, + "auth": { + "$ref": "auth/auth.json" + }, "states": { "type": "array", "description": "State Definitions", diff --git a/api/src/test/java/io/serverlessworkflow/api/test/MarkupToWorkflowTest.java b/api/src/test/java/io/serverlessworkflow/api/test/MarkupToWorkflowTest.java index 714faa61..581d541c 100644 --- a/api/src/test/java/io/serverlessworkflow/api/test/MarkupToWorkflowTest.java +++ b/api/src/test/java/io/serverlessworkflow/api/test/MarkupToWorkflowTest.java @@ -18,6 +18,7 @@ import com.fasterxml.jackson.databind.JsonNode; import io.serverlessworkflow.api.Workflow; import io.serverlessworkflow.api.actions.Action; +import io.serverlessworkflow.api.auth.AuthDefinition; import io.serverlessworkflow.api.branches.Branch; import io.serverlessworkflow.api.datainputschema.DataInputSchema; import io.serverlessworkflow.api.defaultdef.DefaultConditionDefinition; @@ -597,4 +598,67 @@ public void testTimeouts(String workflowLocation) { assertEquals("PT4S", branches.get(1).getTimeouts().getBranchExecTimeout()); } + + @ParameterizedTest + @ValueSource(strings = {"/features/authbasic.json", "/features/authbasic.yml"}) + public void testAuthBasic(String workflowLocation) { + Workflow workflow = Workflow.fromSource(WorkflowTestUtils.readWorkflowFile(workflowLocation)); + + assertNotNull(workflow); + assertNotNull(workflow.getId()); + assertNotNull(workflow.getName()); + + assertNotNull(workflow.getAuth()); + AuthDefinition auth = workflow.getAuth(); + assertNotNull(auth.getName()); + assertEquals("authname", auth.getName()); + assertNotNull(auth.getScheme()); + assertEquals("basic", auth.getScheme().value()); + assertNotNull(auth.getBasicauth()); + assertEquals("testuser", auth.getBasicauth().getUsername()); + assertEquals("testpassword", auth.getBasicauth().getPassword()); + } + + @ParameterizedTest + @ValueSource(strings = {"/features/authbearer.json", "/features/authbearer.yml"}) + public void testAuthBearer(String workflowLocation) { + Workflow workflow = Workflow.fromSource(WorkflowTestUtils.readWorkflowFile(workflowLocation)); + + assertNotNull(workflow); + assertNotNull(workflow.getId()); + assertNotNull(workflow.getName()); + + assertNotNull(workflow.getAuth()); + AuthDefinition auth = workflow.getAuth(); + assertNotNull(auth.getName()); + assertEquals("authname", auth.getName()); + assertNotNull(auth.getScheme()); + assertEquals("bearer", auth.getScheme().value()); + assertNotNull(auth.getBearerauth()); + assertEquals("testtoken", auth.getBearerauth().getToken()); + } + + @ParameterizedTest + @ValueSource(strings = {"/features/authoauth.json", "/features/authoauth.yml"}) + public void testAuthOAuth(String workflowLocation) { + Workflow workflow = Workflow.fromSource(WorkflowTestUtils.readWorkflowFile(workflowLocation)); + + assertNotNull(workflow); + assertNotNull(workflow.getId()); + assertNotNull(workflow.getName()); + + assertNotNull(workflow.getAuth()); + AuthDefinition auth = workflow.getAuth(); + assertNotNull(auth.getName()); + assertEquals("authname", auth.getName()); + assertNotNull(auth.getScheme()); + assertEquals("oauth2", auth.getScheme().value()); + assertNotNull(auth.getOauth()); + assertEquals("testauthority", auth.getOauth().getAuthority()); + assertEquals("clientCredentials", auth.getOauth().getGrantType().value()); + assertEquals("${ $SECRETS.clientid }", auth.getOauth().getClientId()); + assertEquals("${ $SECRETS.clientsecret }", auth.getOauth().getClientSecret()); + + System.out.println("****************\n\n " + Workflow.toJson(workflow)); + } } diff --git a/api/src/test/java/io/serverlessworkflow/api/test/WorkflowToMarkupTest.java b/api/src/test/java/io/serverlessworkflow/api/test/WorkflowToMarkupTest.java index 8bc9883a..170ff57b 100644 --- a/api/src/test/java/io/serverlessworkflow/api/test/WorkflowToMarkupTest.java +++ b/api/src/test/java/io/serverlessworkflow/api/test/WorkflowToMarkupTest.java @@ -16,6 +16,8 @@ package io.serverlessworkflow.api.test; import io.serverlessworkflow.api.Workflow; +import io.serverlessworkflow.api.auth.AuthDefinition; +import io.serverlessworkflow.api.auth.BasicAuthDefinition; import io.serverlessworkflow.api.end.End; import io.serverlessworkflow.api.events.EventDefinition; import io.serverlessworkflow.api.functions.FunctionDefinition; @@ -137,4 +139,25 @@ public void testSingleEvent() { assertNotNull(Workflow.toJson(workflow)); assertNotNull(Workflow.toYaml(workflow)); } -} + + @Test + public void testAuth() { + Workflow workflow = new Workflow().withId("test-workflow").withName("test-workflow-name").withVersion("1.0") + .withStart( + new Start() + ) + .withAuth( + new AuthDefinition().withName("authname").withScheme(AuthDefinition.Scheme.BASIC) + .withBasicauth(new BasicAuthDefinition().withUsername("testuser").withPassword("testPassword"))); + + assertNotNull(workflow); + assertNotNull(workflow.getAuth()); + assertNotNull(workflow.getAuth().getName()); + assertEquals("authname", workflow.getAuth().getName()); + assertNotNull(workflow.getAuth().getScheme()); + assertEquals("basic", workflow.getAuth().getScheme().value()); + assertNotNull(workflow.getAuth().getBasicauth()); + assertEquals("testuser", workflow.getAuth().getBasicauth().getUsername()); + assertEquals("testPassword", workflow.getAuth().getBasicauth().getPassword()); + } +} \ No newline at end of file diff --git a/api/src/test/resources/features/authbasic.json b/api/src/test/resources/features/authbasic.json new file mode 100644 index 00000000..92397db4 --- /dev/null +++ b/api/src/test/resources/features/authbasic.json @@ -0,0 +1,13 @@ +{ + "id" : "test-workflow", + "name" : "test-workflow-name", + "version" : "1.0", + "auth" : { + "name" : "authname", + "scheme" : "basic", + "properties" : { + "username" : "testuser", + "password" : "testpassword" + } + } +} \ No newline at end of file diff --git a/api/src/test/resources/features/authbasic.yml b/api/src/test/resources/features/authbasic.yml new file mode 100644 index 00000000..963dc63e --- /dev/null +++ b/api/src/test/resources/features/authbasic.yml @@ -0,0 +1,9 @@ +id: test-workflow +name: test-workflow-name +version: '1.0' +auth: + name: authname + scheme: basic + properties: + username: testuser + password: testpassword diff --git a/api/src/test/resources/features/authbearer.json b/api/src/test/resources/features/authbearer.json new file mode 100644 index 00000000..304d1685 --- /dev/null +++ b/api/src/test/resources/features/authbearer.json @@ -0,0 +1,12 @@ +{ + "id" : "test-workflow", + "name" : "test-workflow-name", + "version" : "1.0", + "auth" : { + "name" : "authname", + "scheme" : "bearer", + "properties" : { + "token" : "testtoken" + } + } +} \ No newline at end of file diff --git a/api/src/test/resources/features/authbearer.yml b/api/src/test/resources/features/authbearer.yml new file mode 100644 index 00000000..0a815386 --- /dev/null +++ b/api/src/test/resources/features/authbearer.yml @@ -0,0 +1,8 @@ +id: test-workflow +name: test-workflow-name +version: '1.0' +auth: + name: authname + scheme: bearer + properties: + token: testtoken diff --git a/api/src/test/resources/features/authoauth.json b/api/src/test/resources/features/authoauth.json new file mode 100644 index 00000000..da845606 --- /dev/null +++ b/api/src/test/resources/features/authoauth.json @@ -0,0 +1,15 @@ +{ + "id" : "test-workflow", + "name" : "test-workflow-name", + "version" : "1.0", + "auth" : { + "name" : "authname", + "scheme" : "oauth2", + "properties" : { + "authority" : "testauthority", + "grantType" : "clientCredentials", + "clientId": "${ $SECRETS.clientid }", + "clientSecret": "${ $SECRETS.clientsecret }" + } + } +} \ No newline at end of file diff --git a/api/src/test/resources/features/authoauth.yml b/api/src/test/resources/features/authoauth.yml new file mode 100644 index 00000000..8741297c --- /dev/null +++ b/api/src/test/resources/features/authoauth.yml @@ -0,0 +1,11 @@ +id: test-workflow +name: test-workflow-name +version: '1.0' +auth: + name: authname + scheme: oauth2 + properties: + authority: testauthority + grantType: clientCredentials + clientId: "${ $SECRETS.clientid }" + clientSecret: "${ $SECRETS.clientsecret }" pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy