diff --git a/extensions/data-plane/data-plane-aws-s3/src/main/java/org/eclipse/edc/connector/dataplane/aws/s3/S3DataSinkFactory.java b/extensions/data-plane/data-plane-aws-s3/src/main/java/org/eclipse/edc/connector/dataplane/aws/s3/S3DataSinkFactory.java index a28441e..b02528f 100644 --- a/extensions/data-plane/data-plane-aws-s3/src/main/java/org/eclipse/edc/connector/dataplane/aws/s3/S3DataSinkFactory.java +++ b/extensions/data-plane/data-plane-aws-s3/src/main/java/org/eclipse/edc/connector/dataplane/aws/s3/S3DataSinkFactory.java @@ -10,17 +10,20 @@ * Contributors: * Bayerische Motoren Werke Aktiengesellschaft (BMW AG) * ZF Friedrichshafen AG + * Cofinity-X - fix secret deserialization * */ package org.eclipse.edc.connector.dataplane.aws.s3; +import com.fasterxml.jackson.core.type.TypeReference; import org.eclipse.edc.aws.s3.AwsClientProvider; import org.eclipse.edc.aws.s3.AwsSecretToken; import org.eclipse.edc.aws.s3.AwsTemporarySecretToken; import org.eclipse.edc.aws.s3.S3ClientRequest; import org.eclipse.edc.aws.s3.spi.S3BucketSchema; import org.eclipse.edc.aws.s3.validation.S3DataAddressCredentialsValidator; +import org.eclipse.edc.connector.controlplane.transfer.spi.types.SecretToken; import org.eclipse.edc.connector.dataplane.spi.pipeline.DataSink; import org.eclipse.edc.connector.dataplane.spi.pipeline.DataSinkFactory; import org.eclipse.edc.spi.EdcException; @@ -36,6 +39,7 @@ import org.eclipse.edc.validator.spi.Validator; import org.jetbrains.annotations.NotNull; +import java.util.HashMap; import java.util.concurrent.ExecutorService; import static java.util.Optional.ofNullable; @@ -116,7 +120,7 @@ private S3ClientRequest createS3ClientRequest(DataAddress address) { .filter(keyName -> !StringUtils.isNullOrBlank(keyName)) .map(vault::resolveSecret) .filter(secret -> !StringUtils.isNullOrBlank(secret)) - .map(s -> typeManager.readValue(s, AwsTemporarySecretToken.class)); + .map(this::deserializeSecretToken); if (awsSecretToken.isPresent()) { return S3ClientRequest.from(region, endpointOverride, awsSecretToken.get()); @@ -128,4 +132,14 @@ private S3ClientRequest createS3ClientRequest(DataAddress address) { return S3ClientRequest.from(region, endpointOverride); } } + + private SecretToken deserializeSecretToken(String secret) { + var typeReference = new TypeReference>() {}; + var map = typeManager.readValue(secret, typeReference); + if (map.containsKey("sessionToken")) { + return typeManager.readValue(secret, AwsTemporarySecretToken.class); + } else { + return typeManager.readValue(secret, AwsSecretToken.class); + } + } } diff --git a/extensions/data-plane/data-plane-aws-s3/src/main/java/org/eclipse/edc/connector/dataplane/aws/s3/S3DataSourceFactory.java b/extensions/data-plane/data-plane-aws-s3/src/main/java/org/eclipse/edc/connector/dataplane/aws/s3/S3DataSourceFactory.java index 3925be2..ad2a45c 100644 --- a/extensions/data-plane/data-plane-aws-s3/src/main/java/org/eclipse/edc/connector/dataplane/aws/s3/S3DataSourceFactory.java +++ b/extensions/data-plane/data-plane-aws-s3/src/main/java/org/eclipse/edc/connector/dataplane/aws/s3/S3DataSourceFactory.java @@ -10,17 +10,20 @@ * Contributors: * Bayerische Motoren Werke Aktiengesellschaft (BMW AG) * ZF Friedrichshafen AG - Initial implementation + * Cofinity-X - fix secret deserialization * */ package org.eclipse.edc.connector.dataplane.aws.s3; +import com.fasterxml.jackson.core.type.TypeReference; import org.eclipse.edc.aws.s3.AwsClientProvider; import org.eclipse.edc.aws.s3.AwsSecretToken; import org.eclipse.edc.aws.s3.AwsTemporarySecretToken; import org.eclipse.edc.aws.s3.S3ClientRequest; import org.eclipse.edc.aws.s3.spi.S3BucketSchema; import org.eclipse.edc.aws.s3.validation.S3DataAddressCredentialsValidator; +import org.eclipse.edc.connector.controlplane.transfer.spi.types.SecretToken; import org.eclipse.edc.connector.dataplane.spi.pipeline.DataSource; import org.eclipse.edc.connector.dataplane.spi.pipeline.DataSourceFactory; import org.eclipse.edc.spi.EdcException; @@ -36,6 +39,8 @@ import org.eclipse.edc.validator.spi.Validator; import org.jetbrains.annotations.NotNull; +import java.util.HashMap; + import static java.util.Optional.ofNullable; import static org.eclipse.edc.aws.s3.spi.S3BucketSchema.ACCESS_KEY_ID; import static org.eclipse.edc.aws.s3.spi.S3BucketSchema.BUCKET_NAME; @@ -105,7 +110,7 @@ private S3ClientRequest createS3ClientRequest(DataAddress address) { .filter(keyName -> !StringUtils.isNullOrBlank(keyName)) .map(vault::resolveSecret) .filter(secret -> !StringUtils.isNullOrBlank(secret)) - .map(s -> typeManager.readValue(s, AwsTemporarySecretToken.class)); + .map(this::deserializeSecretToken); if (awsSecretToken.isPresent()) { return S3ClientRequest.from(region, endpointOverride, awsSecretToken.get()); @@ -118,5 +123,14 @@ private S3ClientRequest createS3ClientRequest(DataAddress address) { return S3ClientRequest.from(region, endpointOverride); } } - + + private SecretToken deserializeSecretToken(String secret) { + var typeReference = new TypeReference>() {}; + var map = typeManager.readValue(secret, typeReference); + if (map.containsKey("sessionToken")) { + return typeManager.readValue(secret, AwsTemporarySecretToken.class); + } else { + return typeManager.readValue(secret, AwsSecretToken.class); + } + } } diff --git a/extensions/data-plane/data-plane-aws-s3/src/test/java/org/eclipse/edc/connector/dataplane/aws/s3/S3DataSinkFactoryTest.java b/extensions/data-plane/data-plane-aws-s3/src/test/java/org/eclipse/edc/connector/dataplane/aws/s3/S3DataSinkFactoryTest.java index 766da00..1f8646a 100644 --- a/extensions/data-plane/data-plane-aws-s3/src/test/java/org/eclipse/edc/connector/dataplane/aws/s3/S3DataSinkFactoryTest.java +++ b/extensions/data-plane/data-plane-aws-s3/src/test/java/org/eclipse/edc/connector/dataplane/aws/s3/S3DataSinkFactoryTest.java @@ -10,6 +10,7 @@ * Contributors: * Bayerische Motoren Werke Aktiengesellschaft (BMW AG) * ZF Friedrichshafen AG + * Cofinity-X - additional test for secret deserialization * */ @@ -93,6 +94,25 @@ void validate_shouldFail_whenValidatorFails() { assertThat(result).isFailed(); verify(validator).validateDestination(destination); } + + @Test + void createSink_shouldGetTheSecretTokenFromTheVault() { + var destination = TestFunctions.s3DataAddressWithCredentials(); + var secretToken = new AwsSecretToken("accessKeyId", "secretAccessKey"); + when(vault.resolveSecret(destination.getKeyName())).thenReturn(typeManager.writeValueAsString(secretToken)); + when(validator.validateDestination(any())).thenReturn(ValidationResult.success()); + var request = createRequest(destination); + + var sink = factory.createSink(request); + + assertThat(sink).isNotNull().isInstanceOf(S3DataSink.class); + var captor = ArgumentCaptor.forClass(S3ClientRequest.class); + verify(clientProvider).s3Client(captor.capture()); + var s3ClientRequest = captor.getValue(); + assertThat(s3ClientRequest.region()).isEqualTo(TestFunctions.VALID_REGION); + assertThat(s3ClientRequest.secretToken()).isInstanceOf(AwsSecretToken.class); + assertThat(s3ClientRequest.endpointOverride()).isNull(); + } @Test void createSink_shouldGetTheTemporarySecretTokenFromTheVault() { diff --git a/extensions/data-plane/data-plane-aws-s3/src/test/java/org/eclipse/edc/connector/dataplane/aws/s3/S3DataSourceFactoryTest.java b/extensions/data-plane/data-plane-aws-s3/src/test/java/org/eclipse/edc/connector/dataplane/aws/s3/S3DataSourceFactoryTest.java index 85c1ce1..4fa9c82 100644 --- a/extensions/data-plane/data-plane-aws-s3/src/test/java/org/eclipse/edc/connector/dataplane/aws/s3/S3DataSourceFactoryTest.java +++ b/extensions/data-plane/data-plane-aws-s3/src/test/java/org/eclipse/edc/connector/dataplane/aws/s3/S3DataSourceFactoryTest.java @@ -10,12 +10,14 @@ * Contributors: * Bayerische Motoren Werke Aktiengesellschaft (BMW AG) * ZF Friedrichshafen AG - Initial implementation + * Cofinity-X - additional test for secret deserialization * */ package org.eclipse.edc.connector.dataplane.aws.s3; import org.eclipse.edc.aws.s3.AwsClientProvider; +import org.eclipse.edc.aws.s3.AwsSecretToken; import org.eclipse.edc.aws.s3.AwsTemporarySecretToken; import org.eclipse.edc.aws.s3.S3ClientRequest; import org.eclipse.edc.aws.s3.spi.S3BucketSchema; @@ -120,9 +122,28 @@ void createSink_shouldLetTheProviderGetTheCredentialsIfNotProvidedByTheAddress() assertThat(s3ClientRequest.secretToken()).isNull(); assertThat(s3ClientRequest.endpointOverride()).isNull(); } - + @Test void createSource_shouldGetTheSecretTokenFromTheVault() { + when(validator.validateSource(any())).thenReturn(ValidationResult.success()); + var source = TestFunctions.s3DataAddressWithCredentials(); + var secretToken = new AwsSecretToken("accessKeyId", "secretAccessKey"); + when(vault.resolveSecret(source.getKeyName())).thenReturn(typeManager.writeValueAsString(secretToken)); + var request = createRequest(source); + + var s3Source = factory.createSource(request); + + assertThat(s3Source).isNotNull().isInstanceOf(S3DataSource.class); + var captor = ArgumentCaptor.forClass(S3ClientRequest.class); + verify(clientProvider).s3Client(captor.capture()); + var s3ClientRequest = captor.getValue(); + assertThat(s3ClientRequest.region()).isEqualTo(TestFunctions.VALID_REGION); + assertThat(s3ClientRequest.secretToken()).isInstanceOf(AwsSecretToken.class); + assertThat(s3ClientRequest.endpointOverride()).isNull(); + } + + @Test + void createSource_shouldGetTheTemporarySecretTokenFromTheVault() { when(validator.validateSource(any())).thenReturn(ValidationResult.success()); var source = TestFunctions.s3DataAddressWithCredentials(); var temporaryKey = new AwsTemporarySecretToken("temporaryId", "temporarySecret", null, 0);