Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add nested authentication input data #10

Merged
merged 1 commit into from
Aug 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions element-templates/template-connector.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,28 @@
}
},
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: I am wondering, whether template should also contain one dynamic variable example?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could add a separate template with optional authentication to showcase this.

"label": "OAuth Token",
"label": "Username",
"description": "The username for authentication.",
"group": "authentication",
"type": "String",
"feel": "optional",
"binding": {
"type": "zeebe:input",
"name": "token"
"name": "authentication.user"
},
"constraints": {
"notEmpty": true
}
},
{
"label": "Token",
"description": "The token for authentication.",
"group": "authentication",
"type": "String",
"feel": "optional",
"binding": {
"type": "zeebe:input",
"name": "authentication.token"
},
"constraints": {
"notEmpty": true
Expand Down
61 changes: 61 additions & 0 deletions src/main/java/io/camunda/connector/Authentication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package io.camunda.connector;

import io.camunda.connector.api.ConnectorInput;
import io.camunda.connector.api.SecretStore;
import io.camunda.connector.api.Validator;
import java.util.Objects;

public class Authentication implements ConnectorInput {

private String user;
private String token;

@Override
public void validateWith(final Validator validator) {
validator.require(user, "user");
validator.require(token, "token");
if (token != null && !token.startsWith("xobx")) {
validator.addErrorMessage("Token must start with \"xobx\"");
}
}

@Override
public void replaceSecrets(final SecretStore secretStore) {
token = secretStore.replaceSecret(token);
}

public String getUser() {
return user;
}

public void setUser(String user) {
this.user = user;
}

public String getToken() {
return token;
}

public void setToken(String token) {
this.token = token;
}

@Override
public int hashCode() {
return Objects.hash(token, user);
}

@Override
public boolean equals(Object obj) {
if (this == obj) return true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's strange that auto-formatter doesn't catch such things. According to the Google Style Guide braces are always used

Suggested change
if (this == obj) return true;
if (this == obj) {
return true;
}

if (obj == null) return false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (obj == null) return false;
if (obj == null) {
return false;
}

if (getClass() != obj.getClass()) return false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (getClass() != obj.getClass()) return false;
if (getClass() != obj.getClass()) {
return false;
}

Authentication other = (Authentication) obj;
return Objects.equals(token, other.token) && Objects.equals(user, other.user);
}

@Override
public String toString() {
return "Authentication [user=" + user + ", token=" + token + "]";
}
}
26 changes: 12 additions & 14 deletions src/main/java/io/camunda/connector/MyConnectorRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,18 @@
public class MyConnectorRequest implements ConnectorInput {

private String message;
private String token;
private Authentication authentication;

@Override
public void validateWith(final Validator validator) {
validator.require(message, "message");
validator.require(token, "token");
if (token != null && !token.startsWith("xobx")) {
validator.addErrorMessage("Token must start with \"xobx\"");
}
validator.require(authentication, "authentication");
validateIfNotNull(authentication, validator);
}

@Override
public void replaceSecrets(final SecretStore secretStore) {
token = secretStore.replaceSecret(token);
replaceSecretsIfNotNull(authentication, secretStore);
}

public String getMessage() {
Expand All @@ -32,17 +30,17 @@ public void setMessage(String message) {
this.message = message;
}

public String getToken() {
return token;
public Authentication getAuthentication() {
return authentication;
}

public void setToken(String token) {
this.token = token;
public void setAuthentication(Authentication authentication) {
this.authentication = authentication;
}

@Override
public int hashCode() {
return Objects.hash(message, token);
return Objects.hash(authentication, message);
}

@Override
Expand All @@ -51,12 +49,12 @@ public boolean equals(Object obj) {
if (obj == null) return false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (obj == null) return false;
if (obj == null) {
return false;
}

if (getClass() != obj.getClass()) return false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (getClass() != obj.getClass()) return false;
if (getClass() != obj.getClass()) {
return false;
}

MyConnectorRequest other = (MyConnectorRequest) obj;
return Objects.equals(message, other.message) && Objects.equals(token, other.token);
return Objects.equals(authentication, other.authentication)
&& Objects.equals(message, other.message);
}

@Override
public String toString() {
return "MyConnectorRequest [message=" + message + ", token=" + token + "]";
return "MyConnectorRequest [message=" + message + ", authentication=" + authentication + "]";
}

}
5 changes: 4 additions & 1 deletion src/test/java/io/camunda/connector/MyFunctionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@ public class MyFunctionTest {
void shouldReturnReceivedMessageWhenExecute() throws Exception {
// given
var input = new MyConnectorRequest();
var auth = new Authentication();
input.setMessage("Hello World!");
input.setToken("xobx-test");
input.setAuthentication(auth);
auth.setToken("xobx-test");
auth.setUser("testuser");
var function = new MyConnectorFunction();
var context = ConnectorContextBuilder.create()
.variables(input)
Expand Down
49 changes: 35 additions & 14 deletions src/test/java/io/camunda/connector/MyRequestTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

import io.camunda.connector.api.Validator;
import io.camunda.connector.test.ConnectorContextBuilder;
import org.junit.jupiter.api.Test;

Expand All @@ -13,28 +11,47 @@ public class MyRequestTest {
void shouldReplaceTokenSecretWhenReplaceSecrets() {
// given
var input = new MyConnectorRequest();
var auth = new Authentication();
input.setMessage("Hello World!");
input.setToken("secrets.MY_TOKEN");
input.setAuthentication(auth);
auth.setToken("secrets.MY_TOKEN");
auth.setUser("testuser");
var context = ConnectorContextBuilder.create()
.secret("MY_TOKEN", "token value")
.build();
// when
context.replaceSecrets(input);
// then
assertThat(input)
.extracting("authentication")
.extracting("token")
.isEqualTo("token value");
}

@Test
void shouldFailWhenValidate_NoAuthentication() {
// given
var input = new MyConnectorRequest();
input.setMessage("Hello World!");
var context = ConnectorContextBuilder.create().build();
// when
assertThatThrownBy(() -> context.validate(input))
// then
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("authentication");
}

@Test
void shouldFailWhenValidate_NoToken() {
// given
var input = new MyConnectorRequest();
var auth = new Authentication();
input.setMessage("Hello World!");
var validator = new Validator();
input.validateWith(validator);
input.setAuthentication(auth);
auth.setUser("testuser");
var context = ConnectorContextBuilder.create().build();
// when
assertThatThrownBy(() -> validator.evaluate())
assertThatThrownBy(() -> context.validate(input))
// then
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("token");
Expand All @@ -44,11 +61,13 @@ void shouldFailWhenValidate_NoToken() {
void shouldFailWhenValidate_NoMesage() {
// given
var input = new MyConnectorRequest();
input.setToken("xobx-test");
var validator = new Validator();
input.validateWith(validator);
var auth = new Authentication();
input.setAuthentication(auth);
auth.setUser("testuser");
auth.setToken("xobx-test");
var context = ConnectorContextBuilder.create().build();
// when
assertThatThrownBy(() -> validator.evaluate())
assertThatThrownBy(() -> context.validate(input))
// then
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("message");
Expand All @@ -58,12 +77,14 @@ void shouldFailWhenValidate_NoMesage() {
void shouldFailWhenValidate_TokenWrongPattern() {
// given
var input = new MyConnectorRequest();
input.setToken("test");
var auth = new Authentication();
input.setMessage("foo");
var validator = new Validator();
input.validateWith(validator);
input.setAuthentication(auth);
auth.setUser("testuser");
auth.setToken("test");
var context = ConnectorContextBuilder.create().build();
// when
assertThatThrownBy(() -> validator.evaluate())
assertThatThrownBy(() -> context.validate(input))
// then
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Token must start with \"xobx\"");
Expand Down