Skip to content

Commit

Permalink
feat(sme): update security policy to be compatible with async reactor
Browse files Browse the repository at this point in the history
  • Loading branch information
guillaumelamirand authored and jhaeyaert committed Aug 8, 2022
1 parent 0c89a25 commit 0aefffe
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 27 deletions.
12 changes: 6 additions & 6 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@
limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>io.gravitee.policy</groupId>
<artifactId>gravitee-policy-apikey</artifactId>
<version>2.6.0</version>
<version>2.7.0-8238-entrypoint-SNAPSHOT</version>

<name>Gravitee.io APIM - Policy - ApiKey</name>
<description>Description of the ApiKey Gravitee Policy</description>
Expand All @@ -34,8 +34,8 @@
</parent>

<properties>
<gravitee-bom.version>2.5</gravitee-bom.version>
<gravitee-gateway-api.version>1.36.0</gravitee-gateway-api.version>
<gravitee-bom.version>2.6</gravitee-bom.version>
<gravitee-gateway-api.version>1.38.0</gravitee-gateway-api.version>
<gravitee-policy-api.version>1.11.0</gravitee-policy-api.version>
<json-schema-generator-maven-plugin.version>1.1.0</json-schema-generator-maven-plugin.version>
<json-schema-generator-maven-plugin.outputDirectory>${project.build.directory}/schemas
Expand Down Expand Up @@ -207,9 +207,9 @@
<plugin>
<groupId>com.hubspot.maven.plugins</groupId>
<artifactId>prettier-maven-plugin</artifactId>
<version>0.17</version>
<version>0.18</version>
<configuration>
<nodeVersion>12.13.0</nodeVersion>
<nodeVersion>16.16.0</nodeVersion>
<prettierJavaVersion>1.6.1</prettierJavaVersion>
</configuration>
<executions>
Expand Down
36 changes: 22 additions & 14 deletions src/main/java/io/gravitee/policy/apikey/ApiKeyPolicy.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
import io.gravitee.gateway.api.service.ApiKey;
import io.gravitee.gateway.api.service.ApiKeyService;
import io.gravitee.gateway.jupiter.api.ExecutionFailure;
import io.gravitee.gateway.jupiter.api.context.Request;
import io.gravitee.gateway.jupiter.api.context.HttpExecutionContext;
import io.gravitee.gateway.jupiter.api.context.HttpRequest;
import io.gravitee.gateway.jupiter.api.context.MessageExecutionContext;
import io.gravitee.gateway.jupiter.api.context.RequestExecutionContext;
import io.gravitee.gateway.jupiter.api.policy.SecurityPolicy;
import io.gravitee.policy.apikey.configuration.ApiKeyPolicyConfiguration;
Expand All @@ -42,17 +44,14 @@
*/
public class ApiKeyPolicy extends ApiKeyPolicyV3 implements SecurityPolicy {

private static final Logger log = LoggerFactory.getLogger(ApiKeyPolicy.class);

static final String ATTR_API_KEY = ATTR_PREFIX + "api-key";
static final String ATTR_INTERNAL_API_KEY = ATTR_INTERNAL_PREFIX + "api-key";

static String API_KEY_HEADER, API_KEY_QUERY_PARAMETER;
static final String API_KEY_HEADER_PROPERTY = "policy.api-key.header";
static final String API_KEY_QUERY_PARAMETER_PROPERTY = "policy.api-key.param";
static final String DEFAULT_API_KEY_QUERY_PARAMETER = "api-key";
static final String DEFAULT_API_KEY_HEADER_PARAMETER = GraviteeHttpHeader.X_GRAVITEE_API_KEY;

private static final Logger log = LoggerFactory.getLogger(ApiKeyPolicy.class);
static String API_KEY_HEADER, API_KEY_QUERY_PARAMETER;
private final boolean propagateApiKey;

public ApiKeyPolicy(ApiKeyPolicyConfiguration configuration) {
Expand All @@ -70,7 +69,7 @@ public String id() {
* The {@link ApiKeyPolicy} is assignable if an api key is passed in the request headers.
*/
@Override
public Single<Boolean> support(RequestExecutionContext ctx) {
public Single<Boolean> support(HttpExecutionContext ctx) {
final Optional<String> optApiKey = extractApiKey(ctx);

optApiKey.ifPresent(apiKey -> ctx.setInternalAttribute(ATTR_INTERNAL_API_KEY, apiKey));
Expand All @@ -90,7 +89,7 @@ public boolean requireSubscription() {
}

@Override
public Completable onInvalidSubscription(RequestExecutionContext ctx) {
public Completable onInvalidSubscription(HttpExecutionContext ctx) {
return ctx.interruptWith(new ExecutionFailure(UNAUTHORIZED_401).key(API_KEY_INVALID_KEY).message(API_KEY_INVALID_MESSAGE));
}

Expand All @@ -105,7 +104,16 @@ public int order() {
}

@Override
public Completable onRequest(RequestExecutionContext ctx) {
public Completable onRequest(final RequestExecutionContext ctx) {
return handleSecurity(ctx);
}

@Override
public Completable onMessageRequest(final MessageExecutionContext ctx) {
return handleSecurity(ctx);
}

private Completable handleSecurity(final HttpExecutionContext ctx) {
return Completable
.defer(() -> {
try {
Expand Down Expand Up @@ -150,22 +158,22 @@ public Completable onRequest(RequestExecutionContext ctx) {
.doOnTerminate(() -> cleanupApiKey(ctx));
}

private boolean isApiKeyValid(RequestExecutionContext ctx, ApiKey apiKey) {
private boolean isApiKeyValid(HttpExecutionContext ctx, ApiKey apiKey) {
return !apiKey.isRevoked() && (apiKey.getExpireAt() == null || apiKey.getExpireAt().after(new Date(ctx.request().timestamp())));
}

private Completable interrupt401(RequestExecutionContext ctx, String key, String message) {
private Completable interrupt401(HttpExecutionContext ctx, String key, String message) {
return ctx.interruptWith(new ExecutionFailure(HttpStatusCode.UNAUTHORIZED_401).key(key).message(message));
}

private Optional<String> extractApiKey(RequestExecutionContext ctx) {
private Optional<String> extractApiKey(HttpExecutionContext ctx) {
// 1_ First, check if already resolved.
String apiKey = ctx.getInternalAttribute(ATTR_INTERNAL_API_KEY);
if (apiKey != null) {
return Optional.of(apiKey);
}

final Request request = ctx.request();
final HttpRequest request = ctx.request();

// 2_ Second, search in HTTP headers
apiKey = request.headers().get(API_KEY_HEADER);
Expand All @@ -179,7 +187,7 @@ private Optional<String> extractApiKey(RequestExecutionContext ctx) {
return Optional.ofNullable(apiKey);
}

private void cleanupApiKey(RequestExecutionContext ctx) {
private void cleanupApiKey(HttpExecutionContext ctx) {
if (!propagateApiKey) {
ctx.request().headers().remove(API_KEY_HEADER);
ctx.request().parameters().remove(API_KEY_QUERY_PARAMETER);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,15 @@
import java.util.Collections;
import java.util.Date;
import java.util.Optional;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

/**
* @author Yann TAVERNIER (yann.tavernier at graviteesource.com)
* @author GraviteeSource Team
*/
@Disabled("Disabled because failing on CCI. There is a dependency loop with the SDK and the policy.")
@GatewayTest
@DeployApi("/apis/api-key.json")
public class ApiKeyPolicyIntegrationTest extends AbstractPolicyTest<ApiKeyPolicy, ApiKeyPolicyConfiguration> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,17 @@
*/
package io.gravitee.policy.apikey;

import io.gravitee.apim.gateway.tests.sdk.configuration.GatewayConfigurationBuilder;
import io.gravitee.definition.model.Api;
import io.gravitee.definition.model.ExecutionMode;
import org.junit.jupiter.api.Disabled;

/**
* @author Jeoffrey HAEYAERT (jeoffrey.haeyaert at graviteesource.com)
* @author GraviteeSource Team
*/
@Disabled("Disabled because failing on CCI. There is a dependency loop with the SDK and the policy.")
public class ApiKeyPolicyV3CompatibilityIntegrationTest extends ApiKeyPolicyIntegrationTest {

@Override
protected void configureGateway(GatewayConfigurationBuilder gatewayConfigurationBuilder) {
super.configureGateway(gatewayConfigurationBuilder);
gatewayConfigurationBuilder.set("api.jupiterMode.enabled", "true");
}

@Override
public void configureApi(Api api) {
super.configureApi(api);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public class ApiKeyPolicyV3IntegrationTest extends ApiKeyPolicyIntegrationTest {

@Override
protected void configureGateway(GatewayConfigurationBuilder gatewayConfigurationBuilder) {
super.configureGateway(gatewayConfigurationBuilder);
gatewayConfigurationBuilder.set("api.jupiterMode.enabled", "false");
}

Expand Down

0 comments on commit 0aefffe

Please sign in to comment.