Skip to content

Commit

Permalink
Javadoc added to classes related to prxy authentication
Browse files Browse the repository at this point in the history
Signed-off-by: Lukasz Soszynski <[email protected]>
  • Loading branch information
lukasz-soszynski-eliatra committed Nov 4, 2022
1 parent f7cf73b commit dffb6bc
Show file tree
Hide file tree
Showing 8 changed files with 150 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 <code>extended-proxy</code> authentication.
*/
@RunWith(com.carrotsearch.randomizedtesting.RandomizedRunner.class)
@ThreadLeakScope(ThreadLeakScope.Scope.NONE)
public class ExtendedProxyAuthenticationTest extends CommonProxyAuthenticationTests {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 <code>proxy</code> authentication.
*/
@RunWith(com.carrotsearch.randomizedtesting.RandomizedRunner.class)
@ThreadLeakScope(ThreadLeakScope.Scope.NONE)
public class ProxyAuthenticationTest extends CommonProxyAuthenticationTests {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> backendRoles;

private boolean reserved = false;

/**
* Creates roles mapping to OpenSearch role defined by parameter <code>role</code>
* @param role OpenSearch role, must not be <code>null</code>.
*/
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 <code>true</code> 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 <code>null</code>
* @param params not used parameter, but required by the interface {@link ToXContentObject}
* @return builder form parameter <code>xContentBuilder</code>
* @throws IOException denotes error during serialization to JSON
*/
@Override
public XContentBuilder toXContent(XContentBuilder xContentBuilder, Params params) throws IOException {
xContentBuilder.startObject();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,35 @@
import org.opensearch.common.xcontent.ToXContentObject;
import org.opensearch.common.xcontent.XContentBuilder;

/**
* <p>
* XFF is an abbreviation of <code>X-Forwarded-For</code>. 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
* </p>
* <ol>
* <li><code>proxy</code> defined by class {@link org.opensearch.security.http.HTTPProxyAuthenticator}</li>
* <li><code>extended-proxy</code> defined by the class {@link org.opensearch.security.http.proxy.HTTPExtendedProxyAuthenticator}</li>
* </ol>
*
* <p>
* 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.
* </p>
*
*<p>
* The class can be serialized to JSON and then stored in an OpenSearch index which contains security plugin configuration.
*</p>
*/
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;
Expand All @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 <code>null</code>.
*/
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<Header> headers = new ArrayList<>();
/**
* HTTP headers which should be attached to each HTTP request which is sent by {@link TestRestClient}
*/
private final List<Header> 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<Header> 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<Header> getHeaders() {
return Stream.concat(createBasicAuthHeader().stream(), headers.stream()).collect(Collectors.toList());
}
Expand Down

0 comments on commit dffb6bc

Please sign in to comment.