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(rest-connector): Add support for proxy auth #3894

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

ztefanie
Copy link
Contributor

@ztefanie ztefanie commented Jan 31, 2025

Description

Added support for setting proxy via env var and to add proxy auth.

Proxy config can be set via system properties or via env vars. Setting via env vars is currently handled by using an RFC3986 string, e.g. http://my-user:demo@localhost:3128/
This means it is currently not possible to set nonProxyHosts via env vars and username and passwords must be url safe.
I think we could also change this, with some effort, to setting multiple env vars. I decided to go for this version, assuming setting via env vars is more for testing / fast setups, but not complex production setups, as setting passwords in ENV vars is worse than setting in system properties. If you disagree please let me know, then i will adjust it.

I tested different use cases manually, with the following results:
image

I tried to add Unit tests for nonProxyHosts but couldn't get it working as mocking only one host / localhost is possible with Wiremock. If you think nonProxyHost unit test should be added, please give me a hint how to achieve this.

Not tested for https.

I will add this to the docs, once this is approved or at least we agreed on how to set it with env vars.

Related issues

closes https://github.com/camunda/team-connectors/issues/989

Checklist

  • PR has a milestone or the no milestone label.

@ztefanie ztefanie added this to the 8.7.0-alpha4 milestone Jan 31, 2025
@ztefanie ztefanie requested a review from a team as a code owner January 31, 2025 15:08

# Allow unauthenticated users on /path
acl no_auth_url url_regex -i path
Copy link
Contributor Author

Choose a reason for hiding this comment

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

so with this setting every path is needs username and password except "/path". I would rather have only "/protected" be protected and everything else allowed, but I am not sure if this is possible. So if you have an idea let me know.

@ztefanie ztefanie requested a review from johnBgood January 31, 2025 15:10
@ztefanie ztefanie changed the title 989: Add support for proxy auth feat(rest-connector: Add support for proxy auth Jan 31, 2025
@ztefanie ztefanie changed the title feat(rest-connector: Add support for proxy auth feat(rest-connector): Add support for proxy auth Jan 31, 2025
@sbuettner
Copy link
Contributor

@ztefanie We currently only document environment variables for our component configuration and we should therefore continue to support using them also for this use-case: https://docs.camunda.io/docs/next/self-managed/connectors-deployment/connectors-configuration/

@sbuettner sbuettner modified the milestones: 8.7.0-alpha4, 8.8.0-alpha2 Feb 5, 2025
@ztefanie ztefanie requested a review from sbuettner February 7, 2025 13:28

private void setFromEnvVars() {
host = System.getenv("CONNECTOR_" + protocol.toUpperCase() + "_PROXY_HOST");
port = Integer.parseInt(System.getenv("CONNECTOR_" + protocol.toUpperCase() + "_PROXY_PORT"));

Check notice

Code scanning / CodeQL

Missing catch of NumberFormatException Note

Potential uncaught 'java.lang.NumberFormatException'.

private void setFromSystemProperties() {
host = System.getProperty(protocol + ".proxyHost");
port = Integer.parseInt(System.getProperty(protocol + ".proxyPort"));

Check notice

Code scanning / CodeQL

Missing catch of NumberFormatException Note

Potential uncaught 'java.lang.NumberFormatException'.
sourceIsSystemProperties = true;
}

public CredentialsProvider getCredentialsProvider(String uncheckedProtocol) {

Check notice

Code scanning / CodeQL

Useless parameter Note

The parameter 'uncheckedProtocol' is never used.

Copilot Autofix AI 3 days ago

To fix the problem, we need to remove the unused parameter uncheckedProtocol from the getCredentialsProvider method. This involves:

  • Removing the parameter from the method signature.
  • Updating any calls to this method to no longer pass this parameter.

This change should be made in the file connectors/http/http-base/src/main/java/io/camunda/connector/http/base/client/apache/ProxyHandler.java.

Suggested changeset 1
connectors/http/http-base/src/main/java/io/camunda/connector/http/base/client/apache/ProxyHandler.java

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/connectors/http/http-base/src/main/java/io/camunda/connector/http/base/client/apache/ProxyHandler.java b/connectors/http/http-base/src/main/java/io/camunda/connector/http/base/client/apache/ProxyHandler.java
--- a/connectors/http/http-base/src/main/java/io/camunda/connector/http/base/client/apache/ProxyHandler.java
+++ b/connectors/http/http-base/src/main/java/io/camunda/connector/http/base/client/apache/ProxyHandler.java
@@ -67,3 +67,3 @@
 
-  public CredentialsProvider getCredentialsProvider(String uncheckedProtocol) {
+  public CredentialsProvider getCredentialsProvider() {
     BasicCredentialsProvider provider = new BasicCredentialsProvider();
EOF
@@ -67,3 +67,3 @@

public CredentialsProvider getCredentialsProvider(String uncheckedProtocol) {
public CredentialsProvider getCredentialsProvider() {
BasicCredentialsProvider provider = new BasicCredentialsProvider();
Copilot is powered by AI and may make mistakes. Always verify output.
Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
return provider;
}

public HttpHost getProxyHost(String uncheckedProtocol, String requestUri) {

Check notice

Code scanning / CodeQL

Useless parameter Note

The parameter 'requestUri' is never used.

Copilot Autofix AI 3 days ago

To fix the problem, we should remove the unused requestUri parameter from the getProxyHost method. This will simplify the method signature and eliminate any confusion about the necessity of the parameter.

  • Remove the requestUri parameter from the getProxyHost method signature.
  • Update any calls to the getProxyHost method to remove the requestUri argument.
Suggested changeset 1
connectors/http/http-base/src/main/java/io/camunda/connector/http/base/client/apache/ProxyHandler.java

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/connectors/http/http-base/src/main/java/io/camunda/connector/http/base/client/apache/ProxyHandler.java b/connectors/http/http-base/src/main/java/io/camunda/connector/http/base/client/apache/ProxyHandler.java
--- a/connectors/http/http-base/src/main/java/io/camunda/connector/http/base/client/apache/ProxyHandler.java
+++ b/connectors/http/http-base/src/main/java/io/camunda/connector/http/base/client/apache/ProxyHandler.java
@@ -78,3 +78,3 @@
 
-  public HttpHost getProxyHost(String uncheckedProtocol, String requestUri) {
+  public HttpHost getProxyHost(String uncheckedProtocol) {
     return host == null
EOF
@@ -78,3 +78,3 @@

public HttpHost getProxyHost(String uncheckedProtocol, String requestUri) {
public HttpHost getProxyHost(String uncheckedProtocol) {
return host == null
Copilot is powered by AI and may make mistakes. Always verify output.
Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
: new HttpHost(fallbackOnHttpForInvalidProtocol(uncheckedProtocol), host, port);
}

private boolean doesTargetMatchNonProxy(String protocol, String requestUri) {

Check notice

Code scanning / CodeQL

Useless parameter Note

The parameter 'protocol' is never used.

Copilot Autofix AI 3 days ago

To fix the problem, we need to remove the unused protocol parameter from the doesTargetMatchNonProxy method. This involves updating the method signature and any calls to this method to exclude the protocol parameter. This change will simplify the method's interface and eliminate the unnecessary parameter.

Suggested changeset 1
connectors/http/http-base/src/main/java/io/camunda/connector/http/base/client/apache/ProxyHandler.java

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/connectors/http/http-base/src/main/java/io/camunda/connector/http/base/client/apache/ProxyHandler.java b/connectors/http/http-base/src/main/java/io/camunda/connector/http/base/client/apache/ProxyHandler.java
--- a/connectors/http/http-base/src/main/java/io/camunda/connector/http/base/client/apache/ProxyHandler.java
+++ b/connectors/http/http-base/src/main/java/io/camunda/connector/http/base/client/apache/ProxyHandler.java
@@ -34,3 +34,3 @@
         setFromEnvVars();
-        if (doesTargetMatchNonProxy(protocol, requestUrl)) {
+        if (doesTargetMatchNonProxy(requestUrl)) {
           host = null;
@@ -84,3 +84,3 @@
 
-  private boolean doesTargetMatchNonProxy(String protocol, String requestUri) {
+  private boolean doesTargetMatchNonProxy(String requestUri) {
     return (nonProxyHosts != null
EOF
@@ -34,3 +34,3 @@
setFromEnvVars();
if (doesTargetMatchNonProxy(protocol, requestUrl)) {
if (doesTargetMatchNonProxy(requestUrl)) {
host = null;
@@ -84,3 +84,3 @@

private boolean doesTargetMatchNonProxy(String protocol, String requestUri) {
private boolean doesTargetMatchNonProxy(String requestUri) {
return (nonProxyHosts != null
Copilot is powered by AI and may make mistakes. Always verify output.
Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
requestUri.matches(nonProxyHost.replace(".", "\\.").replace("*", ".*"))));
}

public HttpRoutePlanner getRoutePlanner(String uncheckedProtocol, HttpHost proxyHost) {

Check notice

Code scanning / CodeQL

Useless parameter Note

The parameter 'uncheckedProtocol' is never used.

Copilot Autofix AI 3 days ago

To fix the problem, we need to remove the unused parameter uncheckedProtocol from the method getRoutePlanner. This involves updating the method signature and ensuring that any calls to this method are also updated to remove the unnecessary argument.

  • Remove the uncheckedProtocol parameter from the getRoutePlanner method signature.
  • Update any calls to getRoutePlanner to no longer pass the uncheckedProtocol argument.
Suggested changeset 1
connectors/http/http-base/src/main/java/io/camunda/connector/http/base/client/apache/ProxyHandler.java

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/connectors/http/http-base/src/main/java/io/camunda/connector/http/base/client/apache/ProxyHandler.java b/connectors/http/http-base/src/main/java/io/camunda/connector/http/base/client/apache/ProxyHandler.java
--- a/connectors/http/http-base/src/main/java/io/camunda/connector/http/base/client/apache/ProxyHandler.java
+++ b/connectors/http/http-base/src/main/java/io/camunda/connector/http/base/client/apache/ProxyHandler.java
@@ -92,3 +92,3 @@
 
-  public HttpRoutePlanner getRoutePlanner(String uncheckedProtocol, HttpHost proxyHost) {
+  public HttpRoutePlanner getRoutePlanner(HttpHost proxyHost) {
     if (sourceIsSystemProperties) {
EOF
@@ -92,3 +92,3 @@

public HttpRoutePlanner getRoutePlanner(String uncheckedProtocol, HttpHost proxyHost) {
public HttpRoutePlanner getRoutePlanner(HttpHost proxyHost) {
if (sourceIsSystemProperties) {
Copilot is powered by AI and may make mistakes. Always verify output.
Positive Feedback
Negative Feedback

Provide additional feedback

Please help us improve GitHub Copilot by sharing more details about this comment.

Please select one or more of the options
Comment on lines +104 to +105
ProxyHandler proxyHandler =
new ProxyHandler(apacheRequest.getScheme(), apacheRequest.getUri().getHost());
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like we are creating a new proxy handler for every new request. I think this should be done once.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point. Moved it to HttpClient

Comment on lines +69 to +76
BasicCredentialsProvider provider = new BasicCredentialsProvider();
if (StringUtils.isNotBlank(host)
&& StringUtils.isNotBlank(user)
&& ArrayUtils.isNotEmpty(password)) {
provider.setCredentials(
new AuthScope(host, port), new UsernamePasswordCredentials(user, password));
}
return provider;
Copy link
Contributor

Choose a reason for hiding this comment

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

What happens if the password or another entry is empty? Should we log a warning or something?

Otherwise this will silently lead to a credentials provider without credentials.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, if password or another entry is empty a credentials provider without credentials is created. This is expected and wanted behavior, because some proxy do not require credentials. Requests to these proxies are than handled without crendentials with success. If no credentials are provided, but expected by the proxy, the execution will fail with "Proxy Authentication required" error.

Comment on lines +94 to +100
if (sourceIsSystemProperties) {
return new SystemDefaultRoutePlanner(
DefaultSchemePortResolver.INSTANCE, ProxySelector.getDefault());
} else if (proxyHost != null) {
return new DefaultProxyRoutePlanner(proxyHost);
}
return null;
Copy link
Contributor

Choose a reason for hiding this comment

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

Would be great to add some debug logs here. Otherwise it might be intransparent which config was applied.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants