Skip to content

Commit

Permalink
refactor: extracted BaseProtocolService into ProtocolTokenValidator
Browse files Browse the repository at this point in the history
  • Loading branch information
wolf4ood committed Feb 9, 2024
1 parent 8569352 commit 80aaf51
Show file tree
Hide file tree
Showing 16 changed files with 212 additions and 251 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,14 @@
import org.eclipse.edc.connector.policy.spi.store.PolicyDefinitionStore;
import org.eclipse.edc.connector.service.contractnegotiation.ContractNegotiationProtocolServiceImpl;
import org.eclipse.edc.connector.spi.contractnegotiation.ContractNegotiationProtocolService;
import org.eclipse.edc.connector.spi.protocol.ProtocolTokenValidator;
import org.eclipse.edc.junit.annotations.ComponentTest;
import org.eclipse.edc.policy.model.Action;
import org.eclipse.edc.policy.model.Duty;
import org.eclipse.edc.policy.model.Policy;
import org.eclipse.edc.policy.model.PolicyType;
import org.eclipse.edc.spi.iam.ClaimToken;
import org.eclipse.edc.spi.iam.IdentityService;
import org.eclipse.edc.spi.iam.TokenRepresentation;
import org.eclipse.edc.spi.iam.VerificationContext;
import org.eclipse.edc.spi.message.RemoteMessageDispatcherRegistry;
import org.eclipse.edc.spi.monitor.ConsoleMonitor;
import org.eclipse.edc.spi.protocol.ProtocolWebhook;
Expand Down Expand Up @@ -117,7 +116,7 @@ class ContractNegotiationIntegrationTest {
private final ConsumerOfferResolver offerResolver = mock();
private final RemoteMessageDispatcherRegistry providerDispatcherRegistry = mock();
private final RemoteMessageDispatcherRegistry consumerDispatcherRegistry = mock();
private final IdentityService identityService = mock();
private final ProtocolTokenValidator protocolTokenValidator = mock();
private final ProtocolWebhook protocolWebhook = () -> "http://dummy";
protected ClaimToken token = ClaimToken.Builder.newInstance().build();
protected TokenRepresentation tokenRepresentation = TokenRepresentation.Builder.newInstance().build();
Expand Down Expand Up @@ -153,9 +152,9 @@ void init() {
.protocolWebhook(protocolWebhook)
.build();

when(identityService.verifyJwtToken(eq(tokenRepresentation), isA(VerificationContext.class))).thenReturn(Result.success(token));
consumerService = new ContractNegotiationProtocolServiceImpl(consumerStore, new NoopTransactionContext(), validationService, offerResolver, identityService, mock(), new ContractNegotiationObservableImpl(), monitor, mock());
providerService = new ContractNegotiationProtocolServiceImpl(providerStore, new NoopTransactionContext(), validationService, offerResolver, identityService, mock(), new ContractNegotiationObservableImpl(), monitor, mock());
when(protocolTokenValidator.verifyToken(eq(tokenRepresentation), any(), any())).thenReturn(ServiceResult.success(token));
consumerService = new ContractNegotiationProtocolServiceImpl(consumerStore, new NoopTransactionContext(), validationService, offerResolver, protocolTokenValidator, new ContractNegotiationObservableImpl(), monitor, mock());
providerService = new ContractNegotiationProtocolServiceImpl(providerStore, new NoopTransactionContext(), validationService, offerResolver, protocolTokenValidator, new ContractNegotiationObservableImpl(), monitor, mock());
}

@AfterEach
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.eclipse.edc.connector.service.contractnegotiation.ContractNegotiationServiceImpl;
import org.eclipse.edc.connector.service.policydefinition.PolicyDefinitionEventListener;
import org.eclipse.edc.connector.service.policydefinition.PolicyDefinitionServiceImpl;
import org.eclipse.edc.connector.service.protocol.ProtocolTokenValidatorImpl;
import org.eclipse.edc.connector.service.transferprocess.TransferProcessProtocolServiceImpl;
import org.eclipse.edc.connector.service.transferprocess.TransferProcessServiceImpl;
import org.eclipse.edc.connector.spi.asset.AssetService;
Expand All @@ -47,6 +48,7 @@
import org.eclipse.edc.connector.spi.contractnegotiation.ContractNegotiationProtocolService;
import org.eclipse.edc.connector.spi.contractnegotiation.ContractNegotiationService;
import org.eclipse.edc.connector.spi.policydefinition.PolicyDefinitionService;
import org.eclipse.edc.connector.spi.protocol.ProtocolTokenValidator;
import org.eclipse.edc.connector.spi.transferprocess.TransferProcessProtocolService;
import org.eclipse.edc.connector.spi.transferprocess.TransferProcessService;
import org.eclipse.edc.connector.transfer.spi.TransferProcessManager;
Expand Down Expand Up @@ -148,6 +150,9 @@ public class ControlPlaneServicesExtension implements ServiceExtension {
@Inject
private PolicyEngine policyEngine;

@Inject(required = false)
private ProtocolTokenValidator protocolTokenValidator;

@Override
public String name() {
return NAME;
Expand All @@ -168,7 +173,7 @@ public CatalogService catalogService() {
@Provider
public CatalogProtocolService catalogProtocolService(ServiceExtensionContext context) {
return new CatalogProtocolServiceImpl(datasetResolver, participantAgentService, dataServiceRegistry,
identityService, policyEngine, monitor, context.getParticipantId(), transactionContext);
protocolTokenValidator(), context.getParticipantId(), transactionContext);
}

@Provider
Expand All @@ -191,7 +196,7 @@ public ContractNegotiationService contractNegotiationService() {
@Provider
public ContractNegotiationProtocolService contractNegotiationProtocolService() {
return new ContractNegotiationProtocolServiceImpl(contractNegotiationStore,
transactionContext, contractValidationService, consumerOfferResolver, identityService, policyEngine, contractNegotiationObservable,
transactionContext, contractValidationService, consumerOfferResolver, protocolTokenValidator(), contractNegotiationObservable,
monitor, telemetry);
}

Expand All @@ -211,6 +216,14 @@ public TransferProcessService transferProcessService() {
@Provider
public TransferProcessProtocolService transferProcessProtocolService() {
return new TransferProcessProtocolServiceImpl(transferProcessStore, transactionContext, contractNegotiationStore,
contractValidationService, identityService, policyEngine, dataAddressValidator, transferProcessObservable, clock, monitor, telemetry);
contractValidationService, protocolTokenValidator(), dataAddressValidator, transferProcessObservable, clock, monitor, telemetry);
}

@Provider
public ProtocolTokenValidator protocolTokenValidator() {
if (protocolTokenValidator == null) {
protocolTokenValidator = new ProtocolTokenValidatorImpl(identityService, policyEngine, monitor);
}
return protocolTokenValidator;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,24 @@
import org.eclipse.edc.catalog.spi.DataServiceRegistry;
import org.eclipse.edc.catalog.spi.Dataset;
import org.eclipse.edc.catalog.spi.DatasetResolver;
import org.eclipse.edc.connector.service.protocol.BaseProtocolService;
import org.eclipse.edc.connector.spi.catalog.CatalogProtocolService;
import org.eclipse.edc.policy.engine.spi.PolicyEngine;
import org.eclipse.edc.connector.spi.protocol.ProtocolTokenValidator;
import org.eclipse.edc.policy.engine.spi.PolicyScope;
import org.eclipse.edc.policy.model.Policy;
import org.eclipse.edc.spi.agent.ParticipantAgentService;
import org.eclipse.edc.spi.iam.IdentityService;
import org.eclipse.edc.spi.iam.ClaimToken;
import org.eclipse.edc.spi.iam.TokenRepresentation;
import org.eclipse.edc.spi.monitor.Monitor;
import org.eclipse.edc.spi.result.ServiceResult;
import org.eclipse.edc.transaction.spi.TransactionContext;
import org.jetbrains.annotations.NotNull;

import static java.lang.String.format;
import static org.eclipse.edc.spi.CoreConstants.EDC_NAMESPACE;

public class CatalogProtocolServiceImpl extends BaseProtocolService implements CatalogProtocolService {
public class CatalogProtocolServiceImpl implements CatalogProtocolService {

@PolicyScope
public static final String CATALOGING_REQUEST_SCOPE = "request.catalog";

private static final String PARTICIPANT_ID_PROPERTY_KEY = "participantId";

Expand All @@ -43,20 +46,18 @@ public class CatalogProtocolServiceImpl extends BaseProtocolService implements C
private final String participantId;
private final TransactionContext transactionContext;

private PolicyEngine policyEngine;
private final ProtocolTokenValidator protocolTokenValidator;

public CatalogProtocolServiceImpl(DatasetResolver datasetResolver,
ParticipantAgentService participantAgentService,
DataServiceRegistry dataServiceRegistry,
IdentityService identityService,
PolicyEngine policyEngine,
Monitor monitor,
ProtocolTokenValidator protocolTokenValidator,
String participantId,
TransactionContext transactionContext) {
super(identityService, policyEngine, monitor);
this.datasetResolver = datasetResolver;
this.participantAgentService = participantAgentService;
this.dataServiceRegistry = dataServiceRegistry;
this.protocolTokenValidator = protocolTokenValidator;
this.participantId = participantId;
this.transactionContext = transactionContext;
}
Expand Down Expand Up @@ -93,4 +94,9 @@ public ServiceResult<Catalog> getCatalog(CatalogRequestMessage message, TokenRep
return ServiceResult.success(dataset);
}));
}

private ServiceResult<ClaimToken> verifyToken(TokenRepresentation tokenRepresentation) {
return protocolTokenValidator.verifyToken(tokenRepresentation, CATALOGING_REQUEST_SCOPE, Policy.Builder.newInstance().build());
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,11 @@
import org.eclipse.edc.connector.contract.spi.validation.ContractValidationService;
import org.eclipse.edc.connector.contract.spi.validation.ValidatableConsumerOffer;
import org.eclipse.edc.connector.contract.spi.validation.ValidatedConsumerOffer;
import org.eclipse.edc.connector.service.protocol.BaseProtocolService;
import org.eclipse.edc.connector.spi.contractnegotiation.ContractNegotiationProtocolService;
import org.eclipse.edc.policy.engine.spi.PolicyEngine;
import org.eclipse.edc.connector.spi.protocol.ProtocolTokenValidator;
import org.eclipse.edc.policy.engine.spi.PolicyScope;
import org.eclipse.edc.policy.model.Policy;
import org.eclipse.edc.spi.iam.ClaimToken;
import org.eclipse.edc.spi.iam.IdentityService;
import org.eclipse.edc.spi.iam.TokenRepresentation;
import org.eclipse.edc.spi.monitor.Monitor;
import org.eclipse.edc.spi.result.ServiceResult;
Expand All @@ -51,15 +49,15 @@

import static org.eclipse.edc.connector.contract.spi.types.negotiation.ContractNegotiation.Type.PROVIDER;

public class ContractNegotiationProtocolServiceImpl extends BaseProtocolService implements ContractNegotiationProtocolService {
public class ContractNegotiationProtocolServiceImpl implements ContractNegotiationProtocolService {

@PolicyScope
private static final String CONTRACT_NEGOTIATION_REQUEST_SCOPE = "request.contract.negotiation";
public static final String CONTRACT_NEGOTIATION_REQUEST_SCOPE = "request.contract.negotiation";
private final ContractNegotiationStore store;
private final TransactionContext transactionContext;
private final ContractValidationService validationService;
private final ConsumerOfferResolver consumerOfferResolver;

private final ProtocolTokenValidator protocolTokenValidator;
private final ContractNegotiationObservable observable;
private final Monitor monitor;
private final Telemetry telemetry;
Expand All @@ -68,15 +66,14 @@ public ContractNegotiationProtocolServiceImpl(ContractNegotiationStore store,
TransactionContext transactionContext,
ContractValidationService validationService,
ConsumerOfferResolver consumerOfferResolver,
IdentityService identityService,
PolicyEngine policyEngine,
ProtocolTokenValidator protocolTokenValidator,
ContractNegotiationObservable observable,
Monitor monitor, Telemetry telemetry) {
super(identityService, policyEngine, monitor);
this.store = store;
this.transactionContext = transactionContext;
this.validationService = validationService;
this.consumerOfferResolver = consumerOfferResolver;
this.protocolTokenValidator = protocolTokenValidator;
this.observable = observable;
this.monitor = monitor;
this.telemetry = telemetry;
Expand Down Expand Up @@ -326,7 +323,7 @@ private ServiceResult<ClaimTokenContext> verifyRequest(TokenRepresentation token
}

private ServiceResult<ClaimTokenContext> verifyRequest(TokenRepresentation tokenRepresentation, Policy policy, ContractNegotiation contractNegotiation) {
var result = verifyToken(tokenRepresentation, CONTRACT_NEGOTIATION_REQUEST_SCOPE, policy);
var result = protocolTokenValidator.verifyToken(tokenRepresentation, CONTRACT_NEGOTIATION_REQUEST_SCOPE, policy);
if (result.failed()) {
monitor.debug(() -> "Verification Failed: %s".formatted(result.getFailureDetail()));
return ServiceResult.notFound("Not found");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

package org.eclipse.edc.connector.service.protocol;

import org.eclipse.edc.connector.spi.protocol.ProtocolTokenValidator;
import org.eclipse.edc.policy.engine.spi.PolicyContextImpl;
import org.eclipse.edc.policy.engine.spi.PolicyEngine;
import org.eclipse.edc.policy.model.Policy;
Expand All @@ -25,21 +26,19 @@
import org.eclipse.edc.spi.monitor.Monitor;
import org.eclipse.edc.spi.result.ServiceResult;

import java.util.List;

/**
* Base class for all protocol service implementation. This will contain common logic such as validating the JWT token
* and extracting the {@link ClaimToken}
* Implementation of {@link ProtocolTokenValidator} which uses the {@link PolicyEngine} for extracting
* the scope from the {@link Policy} within a scope
*/
public abstract class BaseProtocolService {
public class ProtocolTokenValidatorImpl implements ProtocolTokenValidator {

private final IdentityService identityService;

private final PolicyEngine policyEngine;

private final Monitor monitor;

protected BaseProtocolService(IdentityService identityService, PolicyEngine policyEngine, Monitor monitor) {
public ProtocolTokenValidatorImpl(IdentityService identityService, PolicyEngine policyEngine, Monitor monitor) {
this.identityService = identityService;
this.monitor = monitor;
this.policyEngine = policyEngine;
Expand All @@ -49,23 +48,14 @@ protected BaseProtocolService(IdentityService identityService, PolicyEngine poli
* Validate and extract the {@link ClaimToken} from the input {@link TokenRepresentation} by using the {@link IdentityService}
*
* @param tokenRepresentation The input {@link TokenRepresentation}
* @param policyScope The policy scope
* @param policy The {@link Policy}
* @return The {@link ClaimToken} if success, failure otherwise
*/
//TODO remove once this lands https://github.com/eclipse-edc/Connector/issues/3819
protected ServiceResult<ClaimToken> verifyToken(TokenRepresentation tokenRepresentation) {
// TODO: since we are pushing here the invocation of the IdentityService we don't know the audience here
// The audience removal will be tackle next. IdentityService that relies on this parameter would not work
// for the time being.

// TODO: policy extractors will be handled next
var verificationContext = VerificationContext.Builder.newInstance()
.policy(Policy.Builder.newInstance().build())
.scopes(List.of())
.build();

return verifyToken(tokenRepresentation, verificationContext);
public ServiceResult<ClaimToken> verifyToken(TokenRepresentation tokenRepresentation, String policyScope, Policy policy) {

Check notice

Code scanning / CodeQL

Missing Override annotation Note

This method overrides
ProtocolTokenValidator.verifyToken
; it is advisable to add an Override annotation.
return verifyToken(tokenRepresentation, createVerificationContext(policyScope, policy));
}

protected ServiceResult<ClaimToken> verifyToken(TokenRepresentation tokenRepresentation, VerificationContext verificationContext) {
var result = identityService.verifyJwtToken(tokenRepresentation, verificationContext);

Expand All @@ -76,19 +66,6 @@ protected ServiceResult<ClaimToken> verifyToken(TokenRepresentation tokenReprese
return ServiceResult.success(result.getContent());
}


/**
* Validate and extract the {@link ClaimToken} from the input {@link TokenRepresentation} by using the {@link IdentityService}
*
* @param tokenRepresentation The input {@link TokenRepresentation}
* @param scope The policy scope
* @param policy The {@link Policy}
* @return The {@link ClaimToken} if success, failure otherwise
*/
protected ServiceResult<ClaimToken> verifyToken(TokenRepresentation tokenRepresentation, String scope, Policy policy) {
return verifyToken(tokenRepresentation, createVerificationContext(scope, policy));
}

private VerificationContext createVerificationContext(String scope, Policy policy) {
var requestScopeBuilder = RequestScope.Builder.newInstance();
var policyContext = PolicyContextImpl.Builder.newInstance()
Expand Down

0 comments on commit 80aaf51

Please sign in to comment.