From fac72e2de67ffe1d72fbe1895c7a14c2330038b3 Mon Sep 17 00:00:00 2001 From: Tausif Rahman Date: Thu, 5 Mar 2026 17:37:48 +0000 Subject: [PATCH 1/2] CRED-2149: Add PAT auth support to Java API client - templates and tests --- .../src/generator/templates/ApiClient.j2 | 29 +++++++ .../api/client/auth/HttpBearerAuthTest.java | 82 +++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 src/test/java/com/datadog/api/client/auth/HttpBearerAuthTest.java diff --git a/.generator/src/generator/templates/ApiClient.j2 b/.generator/src/generator/templates/ApiClient.j2 index 9a8c33b0476..b2b8574f793 100644 --- a/.generator/src/generator/templates/ApiClient.j2 +++ b/.generator/src/generator/templates/ApiClient.j2 @@ -223,6 +223,16 @@ public class ApiClient { } defaultApiClient.configureApiKeys(secrets); + {%- for name, schema in specs.v2.components.securitySchemes.items() %} + {%- if schema.type == "http" and "x-env-name" in schema %} + // Configure {{ name }} authorization + String {{ name }}Token = System.getenv("{{ schema["x-env-name"] }}"); + if ({{ name }}Token != null) { + defaultApiClient.setBearerToken({{ name }}Token); + } + {%- endif %} + {%- endfor %} + return defaultApiClient; } @@ -279,6 +289,15 @@ public class ApiClient { } else { authentications.put("{{ name }}", new {{ schema.type|upperfirst ~ "Auth" }}("{{ schema["in"] }}", "{{ schema.name }}")); } + {%- elif schema.type == "http" %} + if (authMap != null) { + auth = authMap.get("{{ name }}"); + } + if (auth instanceof HttpBearerAuth) { + authentications.put("{{ name }}", auth); + } else { + authentications.put("{{ name }}", new HttpBearerAuth("{{ schema.scheme }}")); + } {%- endif %} {%- endfor %} // Prevent the authentications from being modified. @@ -1580,5 +1599,15 @@ public class ApiClient { } auth.applyToParams(queryParams, headerParams, cookieParams, "", "", uri); } + {%- for name, schema in specs.v2.components.securitySchemes.items() %} + {%- if schema.type == "http" %} + // Apply bearer token auth if configured (sent alongside any other auth headers). + Authentication {{ name }} = authentications.get("{{ name }}"); + if ({{ name }} instanceof HttpBearerAuth + && ((HttpBearerAuth) {{ name }}).getBearerToken() != null) { + {{ name }}.applyToParams(queryParams, headerParams, cookieParams, "", "", uri); + } + {%- endif %} + {%- endfor %} } } diff --git a/src/test/java/com/datadog/api/client/auth/HttpBearerAuthTest.java b/src/test/java/com/datadog/api/client/auth/HttpBearerAuthTest.java new file mode 100644 index 00000000000..295c1b27ce0 --- /dev/null +++ b/src/test/java/com/datadog/api/client/auth/HttpBearerAuthTest.java @@ -0,0 +1,82 @@ +/* + * Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. + * This product includes software developed at Datadog (https://www.datadoghq.com/). + * Copyright 2019-Present Datadog, Inc. + */ + +package com.datadog.api.client.auth; + +import static org.junit.Assert.*; + +import com.datadog.api.client.ApiClient; +import com.datadog.api.client.ApiException; +import com.datadog.api.client.Pair; +import java.net.URI; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.junit.Test; + +public class HttpBearerAuthTest { + + @Test + public void testSetAndGetBearerToken() { + HttpBearerAuth auth = new HttpBearerAuth("bearer"); + assertNull(auth.getBearerToken()); + + auth.setBearerToken("test-token-123"); + assertEquals("test-token-123", auth.getBearerToken()); + } + + @Test + public void testApplyToParamsAddsBearerHeader() throws ApiException { + HttpBearerAuth auth = new HttpBearerAuth("bearer"); + auth.setBearerToken("my-pat-token"); + + List queryParams = new ArrayList<>(); + Map headerParams = new HashMap<>(); + Map cookieParams = new HashMap<>(); + + auth.applyToParams( + queryParams, headerParams, cookieParams, "", "", URI.create("https://example.com")); + + assertEquals("Bearer my-pat-token", headerParams.get("Authorization")); + assertTrue(queryParams.isEmpty()); + assertTrue(cookieParams.isEmpty()); + } + + @Test + public void testApplyToParamsNullTokenIsNoOp() throws ApiException { + HttpBearerAuth auth = new HttpBearerAuth("bearer"); + + List queryParams = new ArrayList<>(); + Map headerParams = new HashMap<>(); + Map cookieParams = new HashMap<>(); + + auth.applyToParams( + queryParams, headerParams, cookieParams, "", "", URI.create("https://example.com")); + + assertFalse(headerParams.containsKey("Authorization")); + } + + @Test + public void testApiClientRegistersBearerAuth() { + ApiClient client = new ApiClient(); + // setBearerToken should not throw since bearerAuth is now registered + client.setBearerToken("test-pat"); + } + + @Test + public void testApiClientSetBearerTokenApplied() throws ApiException { + ApiClient client = new ApiClient(); + client.setBearerToken("my-pat-token"); + + // Verify through the authentication map that the token was set + Map auths = client.getAuthentications(); + Authentication auth = auths.get("bearerAuth"); + assertNotNull("bearerAuth should be registered", auth); + assertTrue("bearerAuth should be HttpBearerAuth", auth instanceof HttpBearerAuth); + assertEquals("my-pat-token", ((HttpBearerAuth) auth).getBearerToken()); + } +} From 98ae115808e11b53c9841e6e08c259491a5fbf2b Mon Sep 17 00:00:00 2001 From: Tausif Rahman Date: Thu, 5 Mar 2026 17:40:03 +0000 Subject: [PATCH 2/2] CRED-2149: Regenerated client code from templates --- .../com/datadog/api/client/ApiClient.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/main/java/com/datadog/api/client/ApiClient.java b/src/main/java/com/datadog/api/client/ApiClient.java index e5a488f9638..f76b52eda28 100644 --- a/src/main/java/com/datadog/api/client/ApiClient.java +++ b/src/main/java/com/datadog/api/client/ApiClient.java @@ -1008,6 +1008,11 @@ public static ApiClient getDefaultApiClient() { secrets.put("appKeyAuth", appKeyAuth); } defaultApiClient.configureApiKeys(secrets); + // Configure bearerAuth authorization + String bearerAuthToken = System.getenv("DD_BEARER_TOKEN"); + if (bearerAuthToken != null) { + defaultApiClient.setBearerToken(bearerAuthToken); + } return defaultApiClient; } @@ -1068,6 +1073,14 @@ public ApiClient(Map authMap) { } else { authentications.put("appKeyAuth", new ApiKeyAuth("header", "DD-APPLICATION-KEY")); } + if (authMap != null) { + auth = authMap.get("bearerAuth"); + } + if (auth instanceof HttpBearerAuth) { + authentications.put("bearerAuth", auth); + } else { + authentications.put("bearerAuth", new HttpBearerAuth("bearer")); + } // Prevent the authentications from being modified. authentications = Collections.unmodifiableMap(authentications); } @@ -2450,5 +2463,11 @@ protected void updateParamsForAuth( } auth.applyToParams(queryParams, headerParams, cookieParams, "", "", uri); } + // Apply bearer token auth if configured (sent alongside any other auth headers). + Authentication bearerAuth = authentications.get("bearerAuth"); + if (bearerAuth instanceof HttpBearerAuth + && ((HttpBearerAuth) bearerAuth).getBearerToken() != null) { + bearerAuth.applyToParams(queryParams, headerParams, cookieParams, "", "", uri); + } } }