Skip to content

Commit

Permalink
[#36] Updated tests & configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
massenz committed Nov 19, 2022
1 parent e3435f8 commit 9dc36c7
Show file tree
Hide file tree
Showing 13 changed files with 145 additions and 116 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

package com.alertavert.opa.configuration;

import com.alertavert.opa.security.crypto.KeypairFileReader;
import com.alertavert.opa.security.crypto.KeypairReader;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
Expand All @@ -29,14 +28,12 @@
import org.springframework.context.annotation.Configuration;

import java.io.IOException;
import java.nio.file.Paths;
import java.security.KeyPair;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;

import static com.alertavert.opa.Constants.ELLIPTIC_CURVE;
import static com.alertavert.opa.Constants.PASSPHRASE;
import static com.alertavert.opa.Constants.UNDEFINED_KEYPAIR;

@Slf4j
@Configuration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.client.WebClient;

import java.util.List;

/**
* <h2>OpaServerConfiguration</h2>
*
Expand All @@ -38,15 +40,12 @@ public class OpaServerConfiguration {

private final OpaServerProperties opaServerProperties;
private final RoutesConfiguration configuration;
private final HeadersConfiguration headersConfiguration;

public OpaServerConfiguration(
OpaServerProperties opaServerProperties,
RoutesConfiguration configuration,
HeadersConfiguration headersConfiguration) {
RoutesConfiguration configuration) {
this.opaServerProperties = opaServerProperties;
this.configuration = configuration;
this.headersConfiguration = headersConfiguration;
}

/**
Expand Down Expand Up @@ -75,9 +74,14 @@ public WebClient client() {
.build();
}

@Bean
public List<String> requiredHeaders() {
return opaServerProperties.getHeaders();
}

@Bean
public OpaReactiveAuthorizationManager authorizationManager(WebClient client) {
return new OpaReactiveAuthorizationManager(client, configuration, headersConfiguration);
public OpaReactiveAuthorizationManager authorizationManager() {
return new OpaReactiveAuthorizationManager(client(), configuration,
opaServerProperties.getHeaders());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,14 @@

import com.alertavert.opa.Constants;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.http.HttpHeaders;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;


/**
Expand All @@ -45,15 +52,33 @@
* @see OpaServerConfiguration
* @author M. Massenzio, 2020-11-22
*/
@Data
@Data @Slf4j
@ConfigurationProperties(prefix = "opa")
public class OpaServerProperties {

public static final Collection<String> DEFAULT_HEADERS = List.of(
HttpHeaders.HOST,
HttpHeaders.USER_AGENT);

Boolean secure = false;
String server;
String policy;
String rule;

/**
* The list of headers to be sent to OPA to evaluate for authorization.
*
* <p> {@link #DEFAULT_HEADERS default headers} are always sent</p>
*/
List<String> headers = new ArrayList<>();


@PostConstruct
public void log() {
headers.addAll(DEFAULT_HEADERS);
log.info("Headers configured: headers = {}", headers);
}

protected String versionedApi(String api) {
return String.format("/%s/%s", Constants.OPA_VERSION, api);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

package com.alertavert.opa.security;

import com.alertavert.opa.configuration.HeadersConfiguration;
import com.alertavert.opa.configuration.OpaServerProperties;
import com.alertavert.opa.configuration.RoutesConfiguration;
import com.alertavert.opa.jwt.ApiTokenAuthentication;
Expand All @@ -40,6 +39,8 @@
import org.springframework.web.reactive.function.client.WebClientResponseException;
import reactor.core.publisher.Mono;

import javax.annotation.PostConstruct;
import javax.sound.midi.Soundbank;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
Expand All @@ -64,17 +65,20 @@
*
* @author M. Massenzio, 2020-11-22
*/
@Component
@Slf4j
@RequiredArgsConstructor
@Slf4j @RequiredArgsConstructor
public class OpaReactiveAuthorizationManager
implements ReactiveAuthorizationManager<AuthorizationContext> {

private final WebClient client;
private final RoutesConfiguration configuration;
private final HeadersConfiguration headersConfiguration;
private final List<String> requiredHeaders;
private final AntPathMatcher pathMatcher = new AntPathMatcher();

@PostConstruct
private void info() {
log.info("Configured Headers, headers = {}", requiredHeaders);
}

/**
* Determines if access is granted for a specific request, given a user's credentials (API
* token).
Expand Down Expand Up @@ -138,22 +142,26 @@ private TokenBasedAuthorizationRequest makeRequestBody(
Object credentials,
ServerHttpRequest request
) {
Map<String, String> requestHeaders = new HashMap<>();
headersConfiguration.getHeaders()
.forEach(key -> {
var value = request.getHeaders().getFirst(key);
if (value != null) {
requestHeaders.put(key, value);
}
});
Map<String, String> authnHeaders = new HashMap<>();
HttpHeaders requestHeaders = request.getHeaders();
log.debug("Adding headers, request = {}, required = {}", requestHeaders,
requiredHeaders);
if (requestHeaders != null) {
requiredHeaders.forEach(key -> {
var value = requestHeaders.getFirst(key);
if (value != null) {
authnHeaders.put(key, value);
}
});
}

String token = Objects.requireNonNull(credentials).toString();
return TokenBasedAuthorizationRequest.builder()
.input(new TokenBasedAuthorizationRequest.AuthRequestBody(token,
new TokenBasedAuthorizationRequest.Resource(
request.getMethodValue(),
request.getPath().toString(),
requestHeaders
authnHeaders
)
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import lombok.Builder;
import lombok.Value;
import lombok.extern.jackson.Jacksonized;
import org.springframework.http.HttpHeaders;

import java.util.Map;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

package com.alertavert.opa.security.aws;

import com.alertavert.opa.ExcludeFromCoverageGenerated;
import com.alertavert.opa.security.crypto.KeyLoadException;
import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Mono;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import com.alertavert.opa.AbstractTestBase;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;

import static org.assertj.core.api.Assertions.assertThat;

Expand All @@ -29,27 +31,40 @@ class OpaServerPropertiesTest extends AbstractTestBase {
@Autowired
OpaServerProperties opaServerProperties;

@Value("${opa.policy}")
String policy;
@Value("${opa.rule}")
String rule;

@Test
public void endpoint() {
assertThat(opaServerProperties.endpoint("foo"))
.isEqualTo("http://localhost:8181/v1/foo/com.alertavert.policies");
String api = "foo";
assertThat(opaServerProperties.endpoint(api))
.isEqualTo(String.format("http://localhost:8181/v1/%s/%s", api, policy));
}

@Test
public void policy() {
assertThat(opaServerProperties.policyEndpoint())
.isEqualTo("http://localhost:8181/v1/policies/com.alertavert.policies");
.isEqualTo(String.format("http://localhost:8181/v1/policies/%s", policy));
}

@Test
public void data() {
assertThat(opaServerProperties.dataEndpoint())
.isEqualTo("http://localhost:8181/v1/data/com.alertavert.policies");
.isEqualTo(String.format("http://localhost:8181/v1/data/%s", policy));
}

@Test
public void authorizationEndpoint() {
assertThat(opaServerProperties.authorization())
.isEqualTo("http://localhost:8181/v1/data/com.alertavert.policies/allow");
.isEqualTo(String.format("http://localhost:8181/v1/data/%s/%s",policy, rule));
}

@Test
public void testHeaders() {
assertThat(opaServerProperties.getHeaders()).containsExactlyInAnyOrder(
HttpHeaders.HOST, HttpHeaders.USER_AGENT, "x-test-header"
);
}
}
Loading

0 comments on commit 9dc36c7

Please sign in to comment.