From 6f42908499e1d0160d9a6fffe201fab5d4cc631b Mon Sep 17 00:00:00 2001 From: Lukasz Soszynski Date: Thu, 3 Nov 2022 16:41:15 +0100 Subject: [PATCH] Javadoc added to classes related to prxy authentication Signed-off-by: Lukasz Soszynski --- .../http/CommonProxyAuthenticationTests.java | 3 + .../http/ExtendedProxyAuthenticationTest.java | 3 + .../http/ProxyAuthenticationTest.java | 3 + .../test/framework/RolesMapping.java | 38 +++++++++++++ .../opensearch/test/framework/XffConfig.java | 30 ++++++++++ .../cluster/LocalAddressRoutePlanner.java | 18 +++++- .../test/framework/cluster/LocalCluster.java | 4 +- .../cluster/TestRestClientConfiguration.java | 55 ++++++++++++++++++- 8 files changed, 150 insertions(+), 4 deletions(-) diff --git a/src/integrationTest/java/org/opensearch/security/http/CommonProxyAuthenticationTests.java b/src/integrationTest/java/org/opensearch/security/http/CommonProxyAuthenticationTests.java index 388a82ab7d..244bd6b80e 100644 --- a/src/integrationTest/java/org/opensearch/security/http/CommonProxyAuthenticationTests.java +++ b/src/integrationTest/java/org/opensearch/security/http/CommonProxyAuthenticationTests.java @@ -26,6 +26,9 @@ import static org.hamcrest.Matchers.hasSize; import static org.opensearch.test.framework.TestSecurityConfig.Role.ALL_ACCESS; +/** +* Class defines common tests for proxy and extended-proxy authentication. Subclasses are used to run tests. +*/ abstract class CommonProxyAuthenticationTests { protected static final String RESOURCE_AUTH_INFO = "/_opendistro/_security/authinfo"; diff --git a/src/integrationTest/java/org/opensearch/security/http/ExtendedProxyAuthenticationTest.java b/src/integrationTest/java/org/opensearch/security/http/ExtendedProxyAuthenticationTest.java index 0f95a8b1b8..7ba2a6a72e 100644 --- a/src/integrationTest/java/org/opensearch/security/http/ExtendedProxyAuthenticationTest.java +++ b/src/integrationTest/java/org/opensearch/security/http/ExtendedProxyAuthenticationTest.java @@ -41,6 +41,9 @@ import static org.opensearch.security.Song.TITLE_MAGNUM_OPUS; import static org.opensearch.test.framework.TestSecurityConfig.AuthcDomain.AUTHC_HTTPBASIC_INTERNAL; +/** +* Class used to run tests defined in supper class and adds tests specific for extended-proxy authentication. +*/ @RunWith(com.carrotsearch.randomizedtesting.RandomizedRunner.class) @ThreadLeakScope(ThreadLeakScope.Scope.NONE) public class ExtendedProxyAuthenticationTest extends CommonProxyAuthenticationTests { diff --git a/src/integrationTest/java/org/opensearch/security/http/ProxyAuthenticationTest.java b/src/integrationTest/java/org/opensearch/security/http/ProxyAuthenticationTest.java index ffa3126b88..be8a68fb9d 100644 --- a/src/integrationTest/java/org/opensearch/security/http/ProxyAuthenticationTest.java +++ b/src/integrationTest/java/org/opensearch/security/http/ProxyAuthenticationTest.java @@ -26,6 +26,9 @@ import static org.opensearch.test.framework.TestSecurityConfig.AuthcDomain.AUTHC_HTTPBASIC_INTERNAL; +/** +* Class used to run tests defined in the supper class against OpenSearch cluster with configured proxy authentication. +*/ @RunWith(com.carrotsearch.randomizedtesting.RandomizedRunner.class) @ThreadLeakScope(ThreadLeakScope.Scope.NONE) public class ProxyAuthenticationTest extends CommonProxyAuthenticationTests { diff --git a/src/integrationTest/java/org/opensearch/test/framework/RolesMapping.java b/src/integrationTest/java/org/opensearch/test/framework/RolesMapping.java index 28f71144b7..8f77f22901 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/RolesMapping.java +++ b/src/integrationTest/java/org/opensearch/test/framework/RolesMapping.java @@ -20,32 +20,70 @@ import static java.util.Objects.requireNonNull; +/** +* The class represents mapping between backend roles {@link #backendRoles} to OpenSearch role defined by field {@link #roleName}. The +* class provides convenient builder-like methods and can be serialized to JSON. Serialization to JSON is required to store the class +* in an OpenSearch index which contains Security plugin configuration. +*/ public class RolesMapping implements ToXContentObject { + + /** + * OpenSearch role name + */ private String roleName; + + /** + * Backend role names + */ private List backendRoles; private boolean reserved = false; + /** + * Creates roles mapping to OpenSearch role defined by parameter role + * @param role OpenSearch role, must not be null. + */ public RolesMapping(Role role) { requireNonNull(role); this.roleName = requireNonNull(role.getName()); this.backendRoles = new ArrayList<>(); } + /** + * Defines backend role names + * @param backendRoles backend roles names + * @return current {@link RolesMapping} instance + */ public RolesMapping backendRoles(String...backendRoles) { this.backendRoles.addAll(Arrays.asList(backendRoles)); return this; } + /** + * Determines if role is reserved + * @param reserved true for reserved roles + * @return current {@link RolesMapping} instance + */ public RolesMapping reserved(boolean reserved) { this.reserved = reserved; return this; } + /** + * Returns OpenSearch role name + * @return role name + */ public String getRoleName() { return roleName; } + /** + * Controls serialization to JSON + * @param xContentBuilder must not be null + * @param params not used parameter, but required by the interface {@link ToXContentObject} + * @return builder form parameter xContentBuilder + * @throws IOException denotes error during serialization to JSON + */ @Override public XContentBuilder toXContent(XContentBuilder xContentBuilder, Params params) throws IOException { xContentBuilder.startObject(); diff --git a/src/integrationTest/java/org/opensearch/test/framework/XffConfig.java b/src/integrationTest/java/org/opensearch/test/framework/XffConfig.java index 6da9a623ef..7214104597 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/XffConfig.java +++ b/src/integrationTest/java/org/opensearch/test/framework/XffConfig.java @@ -16,10 +16,35 @@ import org.opensearch.common.xcontent.ToXContentObject; import org.opensearch.common.xcontent.XContentBuilder; +/** +*

+* XFF is an abbreviation of X-Forwarded-For. X-Forwarded-For is an HTTP header which contains client source IP address +* and additionally IP addresses of proxies which forward the request. +* The X-Forwarded-For header is used by HTTP authentication of type +*

+*
    +*
  1. proxy defined by class {@link org.opensearch.security.http.HTTPProxyAuthenticator}
  2. +*
  3. extended-proxy defined by the class {@link org.opensearch.security.http.proxy.HTTPExtendedProxyAuthenticator}
  4. +*
+* +*

+* The above authenticators use the X-Forwarded-For to determine if an HTTP request comes from trusted proxies. The trusted proxies +* are defined by a regular expression {@link #internalProxiesRegexp}. The proxy authentication can be applied only to HTTP requests +* which were forwarded by trusted HTTP proxies. +*

+* +*

+* The class can be serialized to JSON and then stored in an OpenSearch index which contains security plugin configuration. +*

+*/ public class XffConfig implements ToXContentObject { private final boolean enabled; + /** + * Regular expression used to determine if HTTP proxy is trusted or not. IP address of trusted proxies must match the regular + * expression defined by the below field. + */ private String internalProxiesRegexp; private String remoteIpHeader; @@ -28,6 +53,11 @@ public XffConfig(boolean enabled) { this.enabled = enabled; } + /** + * Builder-like method used to set value of the field {@link #internalProxiesRegexp} + * @param internalProxiesRegexp regular expression which matches IP address of a HTTP proxies if the proxies are trusted. + * @return builder + */ public XffConfig internalProxiesRegexp(String internalProxiesRegexp) { this.internalProxiesRegexp = internalProxiesRegexp; return this; diff --git a/src/integrationTest/java/org/opensearch/test/framework/cluster/LocalAddressRoutePlanner.java b/src/integrationTest/java/org/opensearch/test/framework/cluster/LocalAddressRoutePlanner.java index 6d98206d94..ab29d3206e 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/cluster/LocalAddressRoutePlanner.java +++ b/src/integrationTest/java/org/opensearch/test/framework/cluster/LocalAddressRoutePlanner.java @@ -10,21 +10,37 @@ package org.opensearch.test.framework.cluster; import java.net.InetAddress; +import java.util.Objects; import org.apache.hc.client5.http.impl.DefaultSchemePortResolver; import org.apache.hc.client5.http.impl.routing.DefaultRoutePlanner; import org.apache.hc.core5.http.HttpHost; import org.apache.hc.core5.http.protocol.HttpContext; +/** +* Class which can be used to bind Apache HTTP client to a particular network interface or its IP address so that the IP address of +* network interface is used as a source IP address of HTTP request. +*/ class LocalAddressRoutePlanner extends DefaultRoutePlanner { + /** + * IP address of one of the local network interfaces. + */ private final InetAddress localAddress; + /** + * Creates {@link LocalAddressRoutePlanner} + * @param localAddress IP address of one of the local network interfaces. Client socket used by Apache HTTP client will be bind to + * address from this parameter. The parameter must not be null. + */ public LocalAddressRoutePlanner(InetAddress localAddress) { super(DefaultSchemePortResolver.INSTANCE); - this.localAddress = localAddress; + this.localAddress = Objects.requireNonNull(localAddress); } + /** + * Determines IP address used by the client socket of Apache HTTP client + */ @Override protected InetAddress determineLocalAddress(HttpHost firstHop, HttpContext context) { return localAddress; diff --git a/src/integrationTest/java/org/opensearch/test/framework/cluster/LocalCluster.java b/src/integrationTest/java/org/opensearch/test/framework/cluster/LocalCluster.java index 607eb85463..752359c8d8 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/cluster/LocalCluster.java +++ b/src/integrationTest/java/org/opensearch/test/framework/cluster/LocalCluster.java @@ -49,12 +49,12 @@ import org.opensearch.plugins.Plugin; import org.opensearch.security.support.ConfigConstants; import org.opensearch.test.framework.AuditConfiguration; +import org.opensearch.test.framework.RolesMapping; import org.opensearch.test.framework.TestIndex; import org.opensearch.test.framework.TestSecurityConfig; import org.opensearch.test.framework.TestSecurityConfig.Role; -import org.opensearch.test.framework.audit.TestRuleAuditLogSink; -import org.opensearch.test.framework.RolesMapping; import org.opensearch.test.framework.XffConfig; +import org.opensearch.test.framework.audit.TestRuleAuditLogSink; import org.opensearch.test.framework.certificate.TestCertificates; /** diff --git a/src/integrationTest/java/org/opensearch/test/framework/cluster/TestRestClientConfiguration.java b/src/integrationTest/java/org/opensearch/test/framework/cluster/TestRestClientConfiguration.java index 36194a9671..aab5ccb477 100644 --- a/src/integrationTest/java/org/opensearch/test/framework/cluster/TestRestClientConfiguration.java +++ b/src/integrationTest/java/org/opensearch/test/framework/cluster/TestRestClientConfiguration.java @@ -26,40 +26,93 @@ import static java.util.Objects.requireNonNull; +/** +* Object which groups some parameters needed for {@link TestRestClient} creation. The class was created to reduce number of parameters +* of methods which are used to create {@link TestRestClient} . The class provides convenient builder-like methods. All fields of a class +* are nullable. +*/ public class TestRestClientConfiguration { + /** + * Username + */ private String username; + /** + * Password + */ private String password; - private List
headers = new ArrayList<>(); + /** + * HTTP headers which should be attached to each HTTP request which is sent by {@link TestRestClient} + */ + private final List
headers = new ArrayList<>(); + /** + * IP address of client socket of {@link TestRestClient} + */ private InetAddress sourceInetAddress; + /** + * Set username + * @param username username + * @return builder + */ public TestRestClientConfiguration username(String username) { this.username = username; return this; } + /** + * Set user's password + * @param password password + * @return builder + */ public TestRestClientConfiguration password(String password) { this.password = password; return this; } + /** + * Add HTTP headers which are attached to each HTTP request + * @param headers headers + * @return builder + */ public TestRestClientConfiguration headers(Header...headers) { this.headers.addAll(Arrays.asList(Objects.requireNonNull(headers, "Headers are required"))); return this; } + /** + * Add HTTP headers which are attached to each HTTP request + * @param headers list of headers + * @return builder + */ public TestRestClientConfiguration headers(List
headers) { this.headers.addAll(Objects.requireNonNull(headers, "Cannot add null headers")); return this; } + /** + * Add HTTP header to each request + * @param name header name + * @param value header value + * @return builder + */ public TestRestClientConfiguration header(String name, Object value) { return headers(new BasicHeader(name, value)); } + /** + * Set IP address of client socket used by {@link TestRestClient} + * @param sourceInetAddress IP address + * @return builder + */ public TestRestClientConfiguration sourceInetAddress(InetAddress sourceInetAddress) { this.sourceInetAddress = sourceInetAddress; return this; } + + /** + * Return complete header list. Basic authentication header is created using fields {@link #username} and {@link #password} + * @return header list + */ List
getHeaders() { return Stream.concat(createBasicAuthHeader().stream(), headers.stream()).collect(Collectors.toList()); }