Add Confluence Data Center support with allow_local_address and beare…#6769
Conversation
…r token auth Make address validation configurable via allow_local_address (default false) so Confluence Data Center on internal networks is supported. Add bearer token authentication for Personal Access Tokens used by Data Center deployments. Resolves opensearch-project#6496 Signed-off-by: Srikanth Padakanti <srikanth_padakanti@apple.com>
99de791 to
f257f0f
Compare
|
Hi @dlvenable @kkondaka Please review this. Thanks. |
dlvenable
left a comment
There was a problem hiding this comment.
Thanks @srikanthpadakanti for the contribution! I have a few comments and questions.
|
|
||
| @AssertTrue(message = "Authentication config should have either basic or oauth2") | ||
| @JsonProperty("bearer_token") | ||
| private String bearerToken; |
There was a problem hiding this comment.
For OAuth2, we use PluginConfigVariable. This allows us to refresh the credentials from the Jira/Confluence source plugins themselves. Do you think this is relevant for bearer tokens?
Either way, this can support reading from secrets managers.
There was a problem hiding this comment.
Agreed on PluginConfigVariable, Will address in a follow-up since PATs don't need refresh, but secrets manager reads are valuable. Keeping scope tight for this PR.
Otherwise if you want me to implement it now, I can change String bearerToken to PluginConfigVariable bearerToken and update all usages. What do you prefer?
|
|
||
| private ConfluenceRestClient(RestTemplate restTemplate, AtlassianAuthConfig authConfig, | ||
| PluginMetrics pluginMetrics, boolean allowLocalAddress) { | ||
| super(restTemplate, authConfig, pluginMetrics, allowLocalAddress); |
There was a problem hiding this comment.
Do we need similar changes in the JiraRestClient?
There was a problem hiding this comment.
Yes, since this lives in atlassian-commons the Jira client inherits it. Will wire through JiraRestClient as well
| boolean hasBasic = basicConfig != null; | ||
| boolean hasOauth = oauth2Config != null; | ||
| return hasBasic ^ hasOauth; | ||
| boolean hasBearer = bearerToken != null && !bearerToken.isBlank(); |
There was a problem hiding this comment.
I tend to think that isEmpty is the right approach here. This would ignore an explicit " ", which is an odd configuration to be sure.
There was a problem hiding this comment.
Agreed, switching to isEmpty
| @JsonProperty("acknowledgments") | ||
| private boolean acknowledgments = false; | ||
|
|
||
| @JsonProperty("allow_local_address") |
There was a problem hiding this comment.
To me, this implies that it will allow localhost names specifically. But it is localhost and private IP.
Should we have two configurations:
allow_private_networkorallow_internal_addressto denote private IP addresses, but not localhostallow_local_addressorallow_localhost_addressto allow localhost addresses
Or maybe just update the one name?
There was a problem hiding this comment.
Makes sense to separate the concerns
| void testAllowLocalAddressStillRejectsAnyLocal() throws UnknownHostException { | ||
| InetAddress wildcardAddress = InetAddress.getByName("0.0.0.0"); | ||
| assertThrows(BadRequestException.class, () -> AddressValidation.validateInetAddress(wildcardAddress, true)); | ||
| } |
There was a problem hiding this comment.
Just to be sure, we should have some test cases that includes a public IP to be sure it is not exclusive to localhost addresses.
There was a problem hiding this comment.
Will add a positive case with a routable public IP to confirm it passes through cleanly
| assertThrows(RuntimeException.class, () -> ConfluenceConfigHelper.validateConfig(confluenceSourceConfig)); | ||
|
|
||
| when(authenticationConfig.getBearerToken()).thenReturn(""); | ||
| assertThrows(RuntimeException.class, () -> ConfluenceConfigHelper.validateConfig(confluenceSourceConfig)); |
There was a problem hiding this comment.
This has three different test cases. I think splitting them out into three different JUnit test cases/methods is ideal.
There was a problem hiding this comment.
Will break into three: null token, empty token, and blank token
| when(sourceConfig.getAuthType()).thenReturn(BEARER_TOKEN); | ||
| when(sourceConfig.getAuthenticationConfig()).thenReturn(authenticationConfig); | ||
| when(authenticationConfig.getBearerToken()).thenReturn("test-token"); | ||
| when(sourceConfig.getAccountUrl()).thenReturn("https://confluence.internal.com"); |
There was a problem hiding this comment.
I'm not sure what internal.com is. We should probably use example.com or opensearch.org (we know the latter).
There was a problem hiding this comment.
using opensearch.org
|
|
||
| @Test | ||
| void testInterceptSetsBearerAuthHeader() throws IOException { | ||
| when(authConfig.getBearerToken()).thenReturn("my-token"); |
There was a problem hiding this comment.
Generate a random value here instead of the static "my-token".
There was a problem hiding this comment.
Will generate via UUID.randomUUID().toString() for better test isolation
…t values, wire JiraRestClient Signed-off-by: Srikanth Padakanti <srikanth_padakanti@apple.com>
Description
Two changes to support Confluence Data Center deployments:
1. Configurable address validation (
allow_local_address)The existing
AddressValidation.validateInetAddress()rejects all local/private IPs, which blocks Confluence Data Center running on internalnetworks. Added a boolean config
allow_local_address(defaults tofalse) that skips site-local, loopback, and link-local checks when enabled.Multicast and any-local addresses are still rejected regardless.
Confluence Data Center uses Personal Access Tokens (PAT) for authentication. Added bearer_token as a third auth option alongside basic and oauth2.
Only one auth method can be configured at a time.
Changes are in atlassian-commons so Jira Data Center also benefits from the same allow_local_address and bearer token support.
Issues Resolved
Resolves #6496
#6496
Check List
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.