Skip to content

Commit

Permalink
Merge pull request #360 from bci-oss/feature/352-edc-extension_2
Browse files Browse the repository at this point in the history
EDC extension
  • Loading branch information
tunacicek authored Mar 28, 2024
2 parents bee47ef + c85d70f commit 6822bfb
Show file tree
Hide file tree
Showing 8 changed files with 601 additions and 3 deletions.
31 changes: 29 additions & 2 deletions DEPENDENCIES
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,24 @@ maven/mavencentral/com.fasterxml.jackson.datatype/jackson-datatype-jdk8/2.15.4,
maven/mavencentral/com.fasterxml.jackson.datatype/jackson-datatype-jsr310/2.15.4, Apache-2.0, approved, #7930
maven/mavencentral/com.fasterxml.jackson.module/jackson-module-parameter-names/2.15.4, Apache-2.0, approved, #8803
maven/mavencentral/com.fasterxml/classmate/1.6.0, Apache-2.0, approved, clearlydefined
maven/mavencentral/com.github.ben-manes.caffeine/caffeine/3.1.8, Apache-2.0, approved, clearlydefined
maven/mavencentral/com.github.stephenc.jcip/jcip-annotations/1.0-1, Apache-2.0, approved, CQ21949
maven/mavencentral/com.google.code.findbugs/jsr305/3.0.2, Apache-2.0, approved, #20
maven/mavencentral/com.google.errorprone/error_prone_annotations/2.18.0, Apache-2.0, approved, clearlydefined
maven/mavencentral/com.google.errorprone/error_prone_annotations/2.21.1, Apache-2.0, approved, #9834
maven/mavencentral/com.google.guava/failureaccess/1.0.1, Apache-2.0, approved, CQ22654
maven/mavencentral/com.google.guava/guava/32.1.1-jre, Apache-2.0 AND CC0-1.0 AND LicenseRef-Public-Domain, approved, #9229
maven/mavencentral/com.google.guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava, Apache-2.0, approved, CQ22657
maven/mavencentral/com.google.j2objc/j2objc-annotations/2.8, Apache-2.0, approved, clearlydefined
maven/mavencentral/com.h2database/h2/2.2.220, (EPL-1.0 OR MPL-2.0) AND (LGPL-3.0-or-later OR EPL-1.0 OR MPL-2.0), approved, #9322
maven/mavencentral/com.nimbusds/nimbus-jose-jwt/9.24.4, Apache-2.0, approved, clearlydefined
maven/mavencentral/com.opencsv/opencsv/5.7.1, Apache-2.0, approved, clearlydefined
maven/mavencentral/com.squareup.okhttp3/okhttp/4.12.0, Apache-2.0, approved, #11156
maven/mavencentral/com.squareup.okio/okio-jvm/3.6.0, Apache-2.0, approved, #11158
maven/mavencentral/com.squareup.okio/okio/3.6.0, Apache-2.0, approved, #11155
maven/mavencentral/com.zaxxer/HikariCP/5.0.1, Apache-2.0, approved, clearlydefined
maven/mavencentral/dev.failsafe/failsafe-okhttp/3.3.2, Apache-2.0, approved, #9178
maven/mavencentral/dev.failsafe/failsafe/3.3.2, Apache-2.0, approved, #9268
maven/mavencentral/io.github.classgraph/classgraph/4.8.149, MIT, approved, CQ22530
maven/mavencentral/io.micrometer/micrometer-commons/1.12.3, Apache-2.0 AND (Apache-2.0 AND MIT), approved, #11679
maven/mavencentral/io.micrometer/micrometer-core/1.12.3, Apache-2.0 AND (Apache-2.0 AND MIT), approved, #11678
Expand All @@ -32,9 +39,9 @@ maven/mavencentral/io.swagger.core.v3/swagger-core-jakarta/2.2.7, Apache-2.0, ap
maven/mavencentral/io.swagger.core.v3/swagger-models-jakarta/2.2.7, Apache-2.0, approved, #5919
maven/mavencentral/jakarta.activation/jakarta.activation-api/2.1.2, EPL-2.0 OR BSD-3-Clause OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jaf
maven/mavencentral/jakarta.annotation/jakarta.annotation-api/2.1.1, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.ca
maven/mavencentral/jakarta.persistence/jakarta.persistence-api/3.1.0, EPL-2.0 OR BSD-3-Clause AND (EPL-2.0 OR BSD-3-Clause AND BSD-3-Clause), approved, #7696
maven/mavencentral/jakarta.persistence/jakarta.persistence-api/3.1.0, EPL-2.0 OR BSD-3-Clause, approved, ee4j.jpa
maven/mavencentral/jakarta.servlet/jakarta.servlet-api/6.0.0, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.servlet
maven/mavencentral/jakarta.transaction/jakarta.transaction-api/2.0.1, EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0, approved, #7697
maven/mavencentral/jakarta.transaction/jakarta.transaction-api/2.0.1, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jta
maven/mavencentral/jakarta.validation/jakarta.validation-api/3.0.2, Apache-2.0, approved, ee4j.validation
maven/mavencentral/jakarta.websocket/jakarta.websocket-api/2.1.1, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.websocket
maven/mavencentral/jakarta.websocket/jakarta.websocket-client-api/2.1.1, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.websocket
Expand All @@ -48,7 +55,22 @@ maven/mavencentral/org.apache.commons/commons-text/1.10.0, Apache-2.0, approved,
maven/mavencentral/org.apache.logging.log4j/log4j-api/2.21.1, Apache-2.0 AND (Apache-2.0 AND LGPL-2.0-or-later), approved, #11079
maven/mavencentral/org.apache.logging.log4j/log4j-to-slf4j/2.21.1, Apache-2.0, approved, #11919
maven/mavencentral/org.aspectj/aspectjweaver/1.9.21, Apache-2.0 AND BSD-3-Clause AND EPL-1.0 AND BSD-3-Clause AND Apache-1.1, approved, #7695
maven/mavencentral/org.checkerframework/checker-qual/3.37.0, MIT, approved, clearlydefined
maven/mavencentral/org.checkerframework/checker-qual/3.42.0, MIT, approved, clearlydefined
maven/mavencentral/org.eclipse.edc/connector-core/0.5.2-20240327-SNAPSHOT, Apache-2.0, approved, technology.edc
maven/mavencentral/org.eclipse.edc/core-spi/0.5.2-20240327-SNAPSHOT, Apache-2.0, approved, technology.edc
maven/mavencentral/org.eclipse.edc/data-address-http-data-spi/0.5.2-20240327-SNAPSHOT, Apache-2.0, approved, technology.edc
maven/mavencentral/org.eclipse.edc/data-plane-http-spi/0.5.2-20240327-SNAPSHOT, Apache-2.0, approved, technology.edc
maven/mavencentral/org.eclipse.edc/data-plane-spi/0.5.2-20240327-SNAPSHOT, Apache-2.0, approved, technology.edc
maven/mavencentral/org.eclipse.edc/http-spi/0.5.2-20240327-SNAPSHOT, Apache-2.0, approved, technology.edc
maven/mavencentral/org.eclipse.edc/keys-spi/0.5.2-20240327-SNAPSHOT, Apache-2.0, approved, technology.edc
maven/mavencentral/org.eclipse.edc/policy-engine-spi/0.5.2-20240327-SNAPSHOT, Apache-2.0, approved, technology.edc
maven/mavencentral/org.eclipse.edc/policy-model/0.5.2-20240327-SNAPSHOT, Apache-2.0, approved, technology.edc
maven/mavencentral/org.eclipse.edc/runtime-metamodel/0.5.2-20240327-SNAPSHOT, Apache-2.0, approved, technology.edc
maven/mavencentral/org.eclipse.edc/transaction-datasource-spi/0.5.2-20240327-SNAPSHOT, Apache-2.0, approved, technology.edc
maven/mavencentral/org.eclipse.edc/transaction-spi/0.5.2-20240327-SNAPSHOT, Apache-2.0, approved, technology.edc
maven/mavencentral/org.eclipse.edc/transform-spi/0.5.2-20240327-SNAPSHOT, Apache-2.0, approved, technology.edc
maven/mavencentral/org.eclipse.edc/validator-spi/0.5.2-20240327-SNAPSHOT, Apache-2.0, approved, technology.edc
maven/mavencentral/org.eclipse.jetty.ee10.websocket/jetty-ee10-websocket-jakarta-client/12.0.6, EPL-2.0 OR Apache-2.0, approved, rt.jetty
maven/mavencentral/org.eclipse.jetty.ee10.websocket/jetty-ee10-websocket-jakarta-common/12.0.6, EPL-2.0 OR Apache-2.0, approved, rt.jetty
maven/mavencentral/org.eclipse.jetty.ee10.websocket/jetty-ee10-websocket-jakarta-server/12.0.6, EPL-2.0 OR Apache-2.0, approved, rt.jetty
Expand Down Expand Up @@ -79,6 +101,11 @@ maven/mavencentral/org.glassfish/jakarta.json/2.0.1, EPL-2.0 OR GPL-2.0-only wit
maven/mavencentral/org.hibernate.orm/hibernate-core/6.4.4.Final, LGPL-2.1-or-later AND (EPL-2.0 OR BSD-3-Clause) AND MIT, approved, #12490
maven/mavencentral/org.hibernate.validator/hibernate-validator/8.0.1.Final, Apache-2.0, approved, clearlydefined
maven/mavencentral/org.jboss.logging/jboss-logging/3.5.3.Final, Apache-2.0, approved, #9471
maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib-common/1.9.22, Apache-2.0, approved, #14186
maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib-jdk7/1.9.22, Apache-2.0, approved, clearlydefined
maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib-jdk8/1.9.22, None, restricted, #14185
maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib/1.9.22, Apache-2.0, approved, #11827
maven/mavencentral/org.jetbrains/annotations/24.1.0, Apache-2.0, approved, clearlydefined
maven/mavencentral/org.liquibase/liquibase-core/4.19.1, Apache-2.0, approved, clearlydefined
maven/mavencentral/org.mapstruct/mapstruct/1.5.3.Final, Apache-2.0, approved, #6277
maven/mavencentral/org.openapitools/jackson-databind-nullable/0.1.0, Apache-2.0, approved, clearlydefined
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
/*******************************************************************************
* Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH and others
* Copyright (c) 2024 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
******************************************************************************/

package org.eclipse.tractusx.semantics.edc.dataplane.http.accesscontrol.client;

import java.io.IOException;
import java.time.Duration;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.edc.spi.http.EdcHttpClient;
import org.eclipse.edc.spi.monitor.Monitor;
import org.eclipse.edc.spi.types.TypeManager;
import org.eclipse.tractusx.semantics.edc.dataplane.http.accesscontrol.AccessControlServiceException;
import org.eclipse.tractusx.semantics.edc.dataplane.http.accesscontrol.HttpAccessControlCheckClientConfig;
import org.eclipse.tractusx.semantics.edc.dataplane.http.accesscontrol.HttpAccessControlCheckDtrClientConfig;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;

import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class DtrAccessVerificationClient implements HttpAccessVerificationClient {
public static final String HEADER_EDC_BPN = "Edc-Bpn";
public static final String AUTHORIZATION = "Authorization";
public static final String ACCEPT = "Accept";
public static final String CONTENT_TYPE = "Content-Type";
private static final String APPLICATION_JSON = "application/json";
private final Monitor monitor;
private final EdcHttpClient httpClient;
private final TypeManager typeManager;
private final HttpAccessControlCheckClientConfig config;
private final HttpAccessControlCheckDtrClientConfig dtrConfig;
private final LoadingCache<String, String> tokenCache;
private final Cache<RequestKey, Boolean> accessControlDecisionCache;

public DtrAccessVerificationClient(
final Monitor monitor,
final EdcHttpClient httpClient,
final Oauth2TokenClient tokenClient,
final TypeManager typeManager,
final HttpAccessControlCheckClientConfig config,
final HttpAccessControlCheckDtrClientConfig dtrConfig ) {
this.monitor = monitor;
this.httpClient = httpClient;
this.typeManager = typeManager;
this.config = config;
this.dtrConfig = dtrConfig;
this.tokenCache = Caffeine.newBuilder()
.maximumSize( config.getDtrClientConfigMap().size() )
.expireAfterWrite( Duration.ofMinutes( 5 ) )
.refreshAfterWrite( Duration.ofMinutes( 4 ) )
.build( tokenClient::getBearerToken );
final long cacheDurationMinutes = dtrConfig.getDecisionCacheDurationMinutes();
if ( cacheDurationMinutes <= 0 ) {
this.accessControlDecisionCache = null;
} else {
this.accessControlDecisionCache = Caffeine.newBuilder()
.maximumSize( 10000 )
.expireAfterWrite( Duration.ofMinutes( cacheDurationMinutes ) )
.build();
}
}

@Override
public boolean isAspectModelCall( final String url ) {
return urlMatchesPattern( url, dtrConfig.getAspectModelUrlPattern() );
}

@Override
public boolean shouldAllowAccess(
final String requestedUriPath,
@Nullable final String requestedQueryString,
final Map<String, String> additionalHeaders ) throws AccessControlServiceException {
final String requestedUrl = getTargetUrl( requestedUriPath, requestedQueryString );
final String bpn = Optional.ofNullable( additionalHeaders.get( HEADER_EDC_BPN ) )
.orElseThrow( () -> new AccessControlServiceException( "Null BPN found." ) );
final RequestKey key = new RequestKey( bpn, requestedUrl );
if ( accessControlDecisionCache == null ) {
return this.callDtr( key );
} else {
return accessControlDecisionCache.get(
key, this::callDtr );
}
}

private boolean callDtr( final RequestKey requestKey ) {
final Request dtrRequest = getDtrRequest( requestKey );
try ( Response response = httpClient.execute( dtrRequest ) ) {
return response.isSuccessful();
} catch ( final IOException exception ) {
monitor.severe( "Failed to execute DTR access verification request.", exception );
throw new AccessControlServiceException( exception );
}
}

private boolean urlMatchesPattern( final String url, final String urlPattern ) {
final Pattern pattern = Pattern.compile( urlPattern, Pattern.CASE_INSENSITIVE );
final Matcher matcher = pattern.matcher( url );
return matcher.find();
}

@NotNull
private String getTargetUrl(
final String requestedUriPath,
final String requestedQueryString ) {
final var edcBaseUrl = config.getEdcDataPlaneBaseUrl();
final var query = Optional.ofNullable( requestedQueryString )
.filter( s -> !s.isBlank() )
.map( s -> "?" + s )
.orElse( "" );
return edcBaseUrl + requestedUriPath + query;
}

@NotNull
private Request getDtrRequest( final RequestKey requestKey ) {
final String token = tokenCache.get( dtrConfig.getOauth2TokenScope() );
if ( token == null ) {
throw new AccessControlServiceException( "Token is null." );
}
final RequestBody body = RequestBody.create(
createRequest( requestKey ),
MediaType.get( APPLICATION_JSON ) );
return new Request.Builder()
.url( dtrConfig.getDtrAccessVerificationUrl() )
.addHeader( HEADER_EDC_BPN, requestKey.bpn() )
.addHeader( AUTHORIZATION, "Bearer " + token )
.addHeader( ACCEPT, APPLICATION_JSON )
.addHeader( CONTENT_TYPE, APPLICATION_JSON )
.post( body )
.build();
}

@NotNull
private String createRequest( RequestKey requestKey ) {
return typeManager.writeValueAsString( new DtrAccessVerificationRequest( requestKey.requestedUrl() ) );
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*******************************************************************************
* Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH and others
* Copyright (c) 2024 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
******************************************************************************/

package org.eclipse.tractusx.semantics.edc.dataplane.http.accesscontrol.client;

public record DtrAccessVerificationRequest(String submodelEndpointUrl) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*******************************************************************************
* Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH and others
* Copyright (c) 2024 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
******************************************************************************/

package org.eclipse.tractusx.semantics.edc.dataplane.http.accesscontrol.client;

import java.util.Map;

import org.eclipse.tractusx.semantics.edc.dataplane.http.accesscontrol.AccessControlServiceException;

public interface HttpAccessVerificationClient {

boolean isAspectModelCall( String url );

boolean shouldAllowAccess(
final String requestedUriPath, final String requestedQueryString, Map<String, String> additionalHeaders ) throws AccessControlServiceException;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*******************************************************************************
* Copyright (c) 2024 Robert Bosch Manufacturing Solutions GmbH and others
* Copyright (c) 2024 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
******************************************************************************/

package org.eclipse.tractusx.semantics.edc.dataplane.http.accesscontrol.client;

public record RequestKey(String bpn, String requestedUrl) {
}
Loading

0 comments on commit 6822bfb

Please sign in to comment.