Skip to content
Snippets Groups Projects
Commit af850d28 authored by Solomon Ayalew's avatar Solomon Ayalew
Browse files

Update to AWS JAVA SDK V2

parent 7e3fb5b3
No related branches found
No related tags found
1 merge request!651Update to AWS JAVA SDK V2
......@@ -28,6 +28,49 @@ The following software have components provided under the terms of this license:
- AMQP 1.0 JMS Spring Boot Starter (from https://repo1.maven.org/maven2/org/amqphub/spring/amqp-10-jms-spring-boot-starter)
- API Common (from https://github.com/googleapis, https://github.com/googleapis/api-common-java, https://repo1.maven.org/maven2/com/google/api/api-common)
- ASM based accessors helper used by json-smart (from https://urielch.github.io/)
- AWS Cryptographic Material Providers Library (from https://github.com/aws/aws-cryptographic-material-providers-library)
- AWS Database Encryption SDK for DynamoDB (from https://github.com/aws/aws-database-encryption-sdk-dynamodb)
- AWS Event Stream (from https://github.com/awslabs/aws-eventstream-java)
- AWS Java SDK :: AWS CRT Core (from https://aws.amazon.com/sdkforjava)
- AWS Java SDK :: AWS Core (from https://aws.amazon.com/sdkforjava)
- AWS Java SDK :: Annotations (from https://repo1.maven.org/maven2/software/amazon/awssdk/annotations)
- AWS Java SDK :: Arns (from https://aws.amazon.com/sdkforjava)
- AWS Java SDK :: Auth (from https://aws.amazon.com/sdkforjava)
- AWS Java SDK :: Checksums (from https://aws.amazon.com/sdkforjava)
- AWS Java SDK :: Checksums SPI (from https://aws.amazon.com/sdkforjava)
- AWS Java SDK :: Core :: Protocols :: AWS Json Protocol (from https://aws.amazon.com/sdkforjava)
- AWS Java SDK :: Core :: Protocols :: AWS Query Protocol (from https://aws.amazon.com/sdkforjava)
- AWS Java SDK :: Core :: Protocols :: AWS Xml Protocol (from https://aws.amazon.com/sdkforjava)
- AWS Java SDK :: Core :: Protocols :: Json Utils (from https://aws.amazon.com/sdkforjava)
- AWS Java SDK :: Core :: Protocols :: Protocol Core (from https://aws.amazon.com/sdkforjava)
- AWS Java SDK :: DynamoDB :: Enhanced Client (from https://aws.amazon.com/sdkforjava)
- AWS Java SDK :: Endpoints SPI (from https://repo1.maven.org/maven2/software/amazon/awssdk/endpoints-spi)
- AWS Java SDK :: HTTP Auth (from https://aws.amazon.com/sdkforjava)
- AWS Java SDK :: HTTP Auth AWS (from https://aws.amazon.com/sdkforjava)
- AWS Java SDK :: HTTP Auth Event Stream (from https://aws.amazon.com/sdkforjava)
- AWS Java SDK :: HTTP Auth SPI (from https://aws.amazon.com/sdkforjava)
- AWS Java SDK :: HTTP Client Interface (from https://repo1.maven.org/maven2/software/amazon/awssdk/http-client-spi)
- AWS Java SDK :: HTTP Clients :: Apache (from https://repo1.maven.org/maven2/software/amazon/awssdk/apache-client)
- AWS Java SDK :: HTTP Clients :: Netty Non-Blocking I/O (from https://repo1.maven.org/maven2/software/amazon/awssdk/netty-nio-client)
- AWS Java SDK :: Identity SPI (from https://aws.amazon.com/sdkforjava)
- AWS Java SDK :: Metrics SPI (from https://repo1.maven.org/maven2/software/amazon/awssdk/metrics-spi)
- AWS Java SDK :: Profiles (from https://aws.amazon.com/sdkforjava)
- AWS Java SDK :: Regions (from https://repo1.maven.org/maven2/software/amazon/awssdk/regions)
- AWS Java SDK :: Retries (from https://repo1.maven.org/maven2/software/amazon/awssdk/retries)
- AWS Java SDK :: Retries API (from https://repo1.maven.org/maven2/software/amazon/awssdk/retries-spi)
- AWS Java SDK :: SDK Core (from https://aws.amazon.com/sdkforjava)
- AWS Java SDK :: Services :: AWS KMS (from https://aws.amazon.com/sdkforjava)
- AWS Java SDK :: Services :: AWS STS (from https://aws.amazon.com/sdkforjava)
- AWS Java SDK :: Services :: AWS Secrets Manager (from https://aws.amazon.com/sdkforjava)
- AWS Java SDK :: Services :: AWS Simple Systems Management (SSM) (from https://aws.amazon.com/sdkforjava)
- AWS Java SDK :: Services :: Amazon CloudWatch Logs (from https://aws.amazon.com/sdkforjava)
- AWS Java SDK :: Services :: Amazon Cognito Identity Provider Service (from https://aws.amazon.com/sdkforjava)
- AWS Java SDK :: Services :: Amazon DynamoDB (from https://aws.amazon.com/sdkforjava)
- AWS Java SDK :: Services :: Amazon S3 (from https://aws.amazon.com/sdkforjava)
- AWS Java SDK :: Services :: Amazon SNS (from https://aws.amazon.com/sdkforjava)
- AWS Java SDK :: Services :: Amazon SQS (from https://aws.amazon.com/sdkforjava)
- AWS Java SDK :: Third Party :: Jackson-core (from https://aws.amazon.com/sdkforjava)
- AWS Java SDK :: Utilities (from https://repo1.maven.org/maven2/software/amazon/awssdk/utils)
- AWS Java SDK for AWS KMS (from https://aws.amazon.com/sdkforjava)
- AWS Java SDK for AWS STS (from https://aws.amazon.com/sdkforjava)
- AWS Java SDK for AWS Secrets Manager (from https://aws.amazon.com/sdkforjava)
......@@ -168,6 +211,7 @@ The following software have components provided under the terms of this license:
- Redisson (from http://redisson.org, https://redisson.pro)
- Retrofit (from https://github.com/square/retrofit, https://repo1.maven.org/maven2/com/squareup/retrofit2/retrofit)
- RxJava (from https://github.com/ReactiveX/RxJava)
- Smithy :: Dafny :: Conversion (from https://github.com/awslabs/smithy)
- SnakeYAML (from http://code.google.com/p/snakeyaml/, http://www.snakeyaml.org, https://bitbucket.org/snakeyaml/snakeyaml)
- Spring AOP (from http://www.springframework.org, https://github.com/spring-projects/spring-framework, https://repo1.maven.org/maven2/org/springframework/spring-aop)
- Spring Beans (from http://www.springframework.org, https://github.com/SpringSource/spring-framework, https://github.com/spring-projects/spring-framework, https://repo1.maven.org/maven2/org/springframework/spring-beans)
......@@ -322,7 +366,7 @@ BouncyCastle
========================================================================
The following software have components provided under the terms of this license:
- Bouncy Castle Provider (from http://www.bouncycastle.org/java.html, https://www.bouncycastle.org/java.html)
- Bouncy Castle Provider (from http://www.bouncycastle.org/java.html, https://www.bouncycastle.org/download/bouncy-castle-java/, https://www.bouncycastle.org/java.html)
========================================================================
CC-BY-2.5
......@@ -472,6 +516,7 @@ The following software have components provided under the terms of this license:
- Azure Java Client Runtime for ARM (from https://github.com/Azure/autorest-clientruntime-for-java)
- Azure Java Client Runtime for AutoRest (from https://github.com/Azure/autorest-clientruntime-for-java)
- Checker Qual (from https://checkerframework.org)
- DafnyRuntime (from https://github.com/dafny-lang/dafny)
- Extensions on Apache Proton-J library (from https://github.com/Azure/qpid-proton-j-extensions)
- JUL to SLF4J bridge (from http://www.slf4j.org)
- Jackson-core (from http://wiki.fasterxml.com/JacksonHome, https://github.com/FasterXML/jackson-core)
......@@ -531,6 +576,13 @@ The following software have components provided under the terms of this license:
- msal4j-persistence-extension (from https://github.com/AzureAD/microsoft-authentication-extensions-for-java, https://github.com/AzureAD/microsoft-authentication-library-for-java)
- webjars-locator-lite (from https://webjars.org)
========================================================================
RSA-MD
========================================================================
The following software have components provided under the terms of this license:
- AWS Java SDK :: Services :: Amazon SQS (from https://aws.amazon.com/sdkforjava)
========================================================================
SAX-PD
========================================================================
......
......@@ -52,7 +52,7 @@
<dependency>
<groupId>org.opengroup.osdu.core.aws</groupId>
<artifactId>os-core-lib-aws</artifactId>
<version>3.0.2</version>
<version>master-sdk-v2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opengroup.osdu</groupId>
......@@ -64,7 +64,7 @@
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-encryption-sdk-java</artifactId>
<version>2.4.0</version>
<version>3.0.1</version>
</dependency>
<!-- Third party Apache 2.0 license packages -->
......
......@@ -14,20 +14,21 @@
package org.opengroup.osdu.partition.provider.aws.security;
import org.opengroup.osdu.core.aws.entitlements.RequestKeys;
import org.opengroup.osdu.core.aws.ssm.K8sLocalParameterProvider;
import org.opengroup.osdu.core.aws.ssm.K8sParameterNotFoundException;
import java.util.Map;
import org.opengroup.osdu.core.aws.v2.entitlements.Authorizer;
import org.opengroup.osdu.core.aws.v2.entitlements.RequestKeys;
import org.opengroup.osdu.core.aws.v2.ssm.K8sLocalParameterProvider;
import org.opengroup.osdu.core.aws.v2.ssm.K8sParameterNotFoundException;
import org.opengroup.osdu.core.aws.v2.ssm.SSMUtil;
import org.opengroup.osdu.core.common.model.http.AppException;
import org.opengroup.osdu.core.common.model.http.DpsHeaders;
import org.opengroup.osdu.partition.provider.interfaces.IAuthorizationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.opengroup.osdu.core.aws.entitlements.Authorizer;
import org.opengroup.osdu.core.aws.ssm.SSMUtil;
import jakarta.annotation.PostConstruct;
import java.util.Map;
@Component
......
......@@ -18,20 +18,18 @@ import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Map;
import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.encryptionsdk.AwsCrypto;
import com.amazonaws.encryptionsdk.CryptoResult;
import com.amazonaws.encryptionsdk.kms.KmsMasterKey;
import com.amazonaws.encryptionsdk.kms.KmsMasterKeyProvider;
import com.amazonaws.encryptionsdk.CommitmentPolicy;
import lombok.Data;
import org.opengroup.osdu.core.aws.iam.IAMConfig;
import org.opengroup.osdu.core.aws.ssm.K8sLocalParameterProvider;
import org.opengroup.osdu.core.aws.v2.ssm.K8sLocalParameterProvider;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PostConstruct;
import lombok.Data;
import software.amazon.awssdk.core.SdkBytes;
import software.amazon.awssdk.services.kms.KmsClient;
import software.amazon.awssdk.services.kms.model.DecryptRequest;
import software.amazon.awssdk.services.kms.model.DecryptResponse;
import software.amazon.awssdk.services.kms.model.EncryptRequest;
import software.amazon.awssdk.services.kms.model.EncryptResponse;
/**
* <p>
......@@ -43,75 +41,56 @@ import jakarta.annotation.PostConstruct;
@Component
public class AwsKmsEncryptionClient {
@Value("${aws.kms.keyArn}")
private String keyArn;
@Value("${osdu.mongodb.database}")
private String authDatabase;
private AWSCredentialsProvider amazonAWSCredentials;
@Value("${aws.kms.keyArn}")
private String keyArn;
private KmsMasterKeyProvider keyProvider;
@Value("${osdu.mongodb.database}")
private String authDatabase;
private static final AwsCrypto crypto = AwsCrypto.builder()
.withCommitmentPolicy(CommitmentPolicy.RequireEncryptRequireDecrypt)
.build();
private KmsClient kmsClient;
public AwsKmsEncryptionClient() {
this.kmsClient = KmsClient.builder().build();
}
private final AwsCrypto instanceCrypto;
public AwsKmsEncryptionClient(KmsClient kmsClient) {
this.kmsClient = kmsClient;
}
public AwsKmsEncryptionClient() {
instanceCrypto = crypto;
}
@PostConstruct
private void initializeKeyProvider() {
public AwsKmsEncryptionClient(final AwsCrypto argCrypto) {
instanceCrypto = argCrypto;
}
// grab key arn from K8s
K8sLocalParameterProvider provider = new K8sLocalParameterProvider();
@PostConstruct
private void initializeKeyProvider() {
if (Boolean.FALSE.equals(provider.getLocalMode())) {
keyArn = provider.getParameterAsStringOrDefault("KEY_ARN", keyArn);
}
}
// grab key arn from K8s
K8sLocalParameterProvider provider = new K8sLocalParameterProvider();
public byte[] encrypt(String plainText, String id) {
Map<String, String> encryptionContext = generateEncryptionContext(id);
if (Boolean.FALSE.equals(provider.getLocalMode())) {
keyArn = provider.getParameterAsStringOrDefault("KEY_ARN", keyArn);
}
EncryptRequest request = EncryptRequest.builder().keyId(keyArn)
.plaintext(SdkBytes.fromString(plainText, StandardCharsets.UTF_8)).encryptionContext(encryptionContext)
.build();
// log in with IAM credentials
amazonAWSCredentials = IAMConfig.amazonAWSCredentials();
EncryptResponse response = kmsClient.encrypt(request);
return response.ciphertextBlob().asByteArray();
}
// generate keyProvider
this.keyProvider = KmsMasterKeyProvider.builder()
.withCredentials(amazonAWSCredentials)
.buildStrict(keyArn);
}
public String decrypt(byte[] ciphertext, String id) {
Map<String, String> encryptionContext = generateEncryptionContext(id);
public byte[] encrypt(String plainText, String id) {
DecryptRequest request = DecryptRequest.builder().keyId(keyArn)
.ciphertextBlob(SdkBytes.fromByteArray(ciphertext)).encryptionContext(encryptionContext).build();
final Map<String, String> encryptionContext = generateEncryptionContext(id);
final CryptoResult<byte[], KmsMasterKey> encryptResult = instanceCrypto.encryptData(keyProvider, plainText.getBytes(StandardCharsets.UTF_8), encryptionContext);
return encryptResult.getResult();
}
DecryptResponse response = kmsClient.decrypt(request);
return response.plaintext().asString(StandardCharsets.UTF_8);
}
public String decrypt(byte[] ciphertext, String id) {
final CryptoResult<byte[], KmsMasterKey> decryptResult = instanceCrypto.decryptData(keyProvider, ciphertext);
final Map<String, String> encryptionContext = generateEncryptionContext(id);
// throw error if context doesn't match
if (!encryptionContext.entrySet().stream()
.allMatch(e -> e.getValue().equals(decryptResult.getEncryptionContext().get(e.getKey())))) {
throw new IllegalStateException("Wrong Encryption Context!");
}
return new String(decryptResult.getResult(), StandardCharsets.UTF_8);
}
private Map<String, String> generateEncryptionContext(String id) {
return Collections.singletonMap(authDatabase, id);
}
private Map<String, String> generateEncryptionContext(String id) {
return Collections.singletonMap(authDatabase, id);
}
}
......@@ -14,8 +14,8 @@
package org.opengroup.osdu.partition.provider.aws.util;
import org.opengroup.osdu.core.aws.mongodb.MongoDBSimpleFactory;
import org.opengroup.osdu.core.aws.mongodb.config.MongoPropertiesDefaultReader;
import org.opengroup.osdu.core.aws.v2.mongodb.MongoDBSimpleFactory;
import org.opengroup.osdu.core.aws.v2.mongodb.config.MongoPropertiesDefaultReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
......
......@@ -23,10 +23,10 @@ import org.mockito.Mock;
import org.mockito.MockedConstruction;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import org.opengroup.osdu.core.aws.entitlements.Authorizer;
import org.opengroup.osdu.core.aws.entitlements.RequestKeys;
import org.opengroup.osdu.core.aws.ssm.K8sLocalParameterProvider;
import org.opengroup.osdu.core.aws.ssm.K8sParameterNotFoundException;
import org.opengroup.osdu.core.aws.v2.entitlements.Authorizer;
import org.opengroup.osdu.core.aws.v2.entitlements.RequestKeys;
import org.opengroup.osdu.core.aws.v2.ssm.K8sLocalParameterProvider;
import org.opengroup.osdu.core.aws.v2.ssm.K8sParameterNotFoundException;
import org.opengroup.osdu.core.common.model.http.AppException;
import org.opengroup.osdu.core.common.model.http.DpsHeaders;
import org.springframework.test.util.ReflectionTestUtils;
......
......@@ -18,16 +18,18 @@ package org.opengroup.osdu.partition.provider.aws.util;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.junit.Assert.fail;
import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.encryptionsdk.AwsCrypto;
import com.amazonaws.encryptionsdk.CryptoResult;
import com.amazonaws.encryptionsdk.kms.KmsMasterKey;
import com.amazonaws.encryptionsdk.kms.KmsMasterKeyProvider;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.HexFormat;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
......@@ -36,166 +38,144 @@ import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockedConstruction;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import org.opengroup.osdu.core.aws.ssm.K8sLocalParameterProvider;
import org.opengroup.osdu.core.aws.v2.ssm.K8sLocalParameterProvider;
import org.springframework.test.util.ReflectionTestUtils;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.HexFormat;
import java.util.Map;
import software.amazon.awssdk.core.SdkBytes;
import software.amazon.awssdk.services.kms.KmsClient;
import software.amazon.awssdk.services.kms.model.DecryptRequest;
import software.amazon.awssdk.services.kms.model.DecryptResponse;
import software.amazon.awssdk.services.kms.model.EncryptRequest;
import software.amazon.awssdk.services.kms.model.EncryptResponse;
@RunWith(MockitoJUnitRunner.class)
public class AwsKmsEncryptionClientTest {
@Mock
private KmsMasterKeyProvider.Builder kmsBuilder;
@Mock
private KmsMasterKeyProvider keyProvider;
@Mock
private AwsCrypto instanceCrypto;
@Mock
private CryptoResult<byte[], KmsMasterKey> cryptoResult;
@Mock
private KmsClient kmsClient;
@Captor
private ArgumentCaptor<Map<String, String>> encryptionContext;
private ArgumentCaptor<EncryptRequest> encryptRequestCaptor;
@Captor
private ArgumentCaptor<byte[]> bytesCaptor;
@InjectMocks
private AwsKmsEncryptionClient encryptionClient;
private final String KEY_ARN = "key_arn";
private final byte[] ENCRYPTED = HexFormat.of().parseHex("0123456789abcdef");
private byte[] DECRYPTED_BYTES;
private final String DECRYPTED = "Decrypted";
private final String AUTH_DATABASE = "osdu";
private final String VALID_ID = "valid_id";
private final Map<String, String> validContext = new HashMap<>();
@Before
public void setup() throws NoSuchFieldException, IllegalAccessException {
ReflectionTestUtils.setField(encryptionClient, "keyArn", KEY_ARN);
ReflectionTestUtils.setField(encryptionClient, "authDatabase", AUTH_DATABASE);
ReflectionTestUtils.setField(encryptionClient, "keyProvider", keyProvider);
DECRYPTED_BYTES = DECRYPTED.getBytes(StandardCharsets.UTF_8);
validContext.put(AUTH_DATABASE, VALID_ID);
}
@Test
public void should_return_when_initCalledWithLocal() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
final String LOCAL_KEY_ARN = "local_key_arn";
Method initializeKeyProvider = AwsKmsEncryptionClient.class.getDeclaredMethod("initializeKeyProvider");
initializeKeyProvider.setAccessible(true);
ReflectionTestUtils.setField(encryptionClient, "keyArn", LOCAL_KEY_ARN);
try (MockedConstruction<K8sLocalParameterProvider> k8sParameterProvider = Mockito.mockConstruction(K8sLocalParameterProvider.class,
(mock, context) -> {
when(mock.getParameterAsStringOrDefault(anyString(), anyString())).thenReturn("bogus_key_arn");
when(mock.getLocalMode()).thenReturn(true);
})) {
try (MockedStatic<KmsMasterKeyProvider> kmsMKPStatic = Mockito.mockStatic(KmsMasterKeyProvider.class)) {
kmsMKPStatic.when(KmsMasterKeyProvider::builder).thenReturn(kmsBuilder);
when(kmsBuilder.withCredentials(any(AWSCredentialsProvider.class))).thenReturn(kmsBuilder);
when(kmsBuilder.buildStrict(anyString())).thenReturn(keyProvider);
initializeKeyProvider.invoke(encryptionClient);
assertTrue("Must pass when `initializeKeyProvider` called with local mode enabled!", true);
assertEquals(LOCAL_KEY_ARN, ReflectionTestUtils.getField(encryptionClient, "keyArn"));
}
} finally {
ReflectionTestUtils.setField(encryptionClient, "keyArn", KEY_ARN);
}
}
@Test
public void should_return_when_initCalledWithoutLocal() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
final String OSDU_KEY_ARN = "osdu_key_arn";
Method initializeKeyProvider = AwsKmsEncryptionClient.class.getDeclaredMethod("initializeKeyProvider");
initializeKeyProvider.setAccessible(true);
ReflectionTestUtils.setField(encryptionClient, "keyArn", "bogus_key_arn");
try (MockedConstruction<K8sLocalParameterProvider> k8sParameterProvider = Mockito.mockConstruction(K8sLocalParameterProvider.class,
(mock, context) -> {
when(mock.getParameterAsStringOrDefault(anyString(), anyString())).thenReturn(OSDU_KEY_ARN);
when(mock.getLocalMode()).thenReturn(false);
})) {
try (MockedStatic<KmsMasterKeyProvider> kmsMKPStatic = Mockito.mockStatic(KmsMasterKeyProvider.class)) {
kmsMKPStatic.when(KmsMasterKeyProvider::builder).thenReturn(kmsBuilder);
when(kmsBuilder.withCredentials(any(AWSCredentialsProvider.class))).thenReturn(kmsBuilder);
when(kmsBuilder.buildStrict(anyString())).thenReturn(keyProvider);
initializeKeyProvider.invoke(encryptionClient);
assertTrue("Must pass when `initializeKeyProvider` called with OSDU mode enabled!", true);
assertEquals(OSDU_KEY_ARN, ReflectionTestUtils.getField(encryptionClient, "keyArn"));
}
} finally {
ReflectionTestUtils.setField(encryptionClient, "keyArn", KEY_ARN);
}
}
@Test
public void should_return_when_encryptCalledWithArgs() {
when(instanceCrypto.encryptData(any(KmsMasterKeyProvider.class), bytesCaptor.capture(), encryptionContext.capture())).thenReturn(cryptoResult);
when(cryptoResult.getResult()).thenReturn(ENCRYPTED);
byte[] encrypted = encryptionClient.encrypt(DECRYPTED, VALID_ID);
assertArrayEquals(ENCRYPTED, encrypted);
assertArrayEquals(DECRYPTED_BYTES, bytesCaptor.getValue());
Map<String, String> map = encryptionContext.getValue();
assertEquals(1, map.size());
assertTrue(map.containsKey(AUTH_DATABASE));
assertEquals(VALID_ID, map.get(AUTH_DATABASE));
}
@Test
public void should_return_when_decryptCalledWithValidArgs() {
when(instanceCrypto.decryptData(any(KmsMasterKeyProvider.class), bytesCaptor.capture())).thenReturn(cryptoResult);
when(cryptoResult.getResult()).thenReturn(DECRYPTED_BYTES);
when(cryptoResult.getEncryptionContext()).thenReturn(validContext);
String decrypted = encryptionClient.decrypt(ENCRYPTED, VALID_ID);
assertEquals(DECRYPTED, decrypted);
assertArrayEquals(ENCRYPTED, bytesCaptor.getValue());
}
@Test
public void should_ThrowIllegalStateException_when_decryptCalledWithInValidArgs() {
when(instanceCrypto.decryptData(any(KmsMasterKeyProvider.class), bytesCaptor.capture())).thenReturn(cryptoResult);
when(cryptoResult.getEncryptionContext()).thenReturn(validContext);
try {
String INVALID_ID = "invalid_id";
encryptionClient.decrypt(ENCRYPTED, INVALID_ID);
fail("Should throw exception when encryption contexts do not match.");
} catch (IllegalStateException exception) {
assertEquals("Wrong Encryption Context!", exception.getMessage());
}
assertArrayEquals(ENCRYPTED, bytesCaptor.getValue());
}
@Test
public void should_return_when_defaultConstructorCalled() {
AwsCrypto expectedCrypto = (AwsCrypto) ReflectionTestUtils.getField(AwsKmsEncryptionClient.class, "crypto");
AwsKmsEncryptionClient cryptoClient = new AwsKmsEncryptionClient();
AwsCrypto actualCrypto = (AwsCrypto) ReflectionTestUtils.getField(cryptoClient, "crypto");
assertEquals(expectedCrypto, actualCrypto);
}
private ArgumentCaptor<DecryptRequest> decryptRequestCaptor;
@InjectMocks
private AwsKmsEncryptionClient encryptionClient;
private final String KEY_ARN = "key_arn";
private final byte[] ENCRYPTED = HexFormat.of().parseHex("0123456789abcdef");
private final String DECRYPTED = "Decrypted";
private final String AUTH_DATABASE = "osdu";
private final String VALID_ID = "valid_id";
private final Map<String, String> validContext = new HashMap<>();
@Before
public void setup() throws NoSuchFieldException, IllegalAccessException {
ReflectionTestUtils.setField(encryptionClient, "keyArn", KEY_ARN);
ReflectionTestUtils.setField(encryptionClient, "authDatabase", AUTH_DATABASE);
validContext.put(AUTH_DATABASE, VALID_ID);
}
@Test
public void should_return_when_initCalledWithLocal()
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
final String LOCAL_KEY_ARN = "local_key_arn";
Method initializeKeyProvider = AwsKmsEncryptionClient.class.getDeclaredMethod("initializeKeyProvider");
initializeKeyProvider.setAccessible(true);
ReflectionTestUtils.setField(encryptionClient, "keyArn", LOCAL_KEY_ARN);
try (MockedConstruction<K8sLocalParameterProvider> k8sParameterProvider = Mockito
.mockConstruction(K8sLocalParameterProvider.class, (mock, context) -> {
when(mock.getParameterAsStringOrDefault(anyString(), anyString())).thenReturn("bogus_key_arn");
when(mock.getLocalMode()).thenReturn(true);
})) {
initializeKeyProvider.invoke(encryptionClient);
assertTrue("Must pass when `initializeKeyProvider` called with local mode enabled!", true);
assertEquals(LOCAL_KEY_ARN, ReflectionTestUtils.getField(encryptionClient, "keyArn"));
} finally {
ReflectionTestUtils.setField(encryptionClient, "keyArn", KEY_ARN);
}
}
@Test
public void should_return_when_initCalledWithoutLocal()
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
final String OSDU_KEY_ARN = "osdu_key_arn";
Method initializeKeyProvider = AwsKmsEncryptionClient.class.getDeclaredMethod("initializeKeyProvider");
initializeKeyProvider.setAccessible(true);
ReflectionTestUtils.setField(encryptionClient, "keyArn", "bogus_key_arn");
try (MockedConstruction<K8sLocalParameterProvider> k8sParameterProvider = Mockito
.mockConstruction(K8sLocalParameterProvider.class, (mock, context) -> {
when(mock.getParameterAsStringOrDefault(anyString(), anyString())).thenReturn(OSDU_KEY_ARN);
when(mock.getLocalMode()).thenReturn(false);
})) {
initializeKeyProvider.invoke(encryptionClient);
assertTrue("Must pass when `initializeKeyProvider` called with OSDU mode enabled!", true);
assertEquals(OSDU_KEY_ARN, ReflectionTestUtils.getField(encryptionClient, "keyArn"));
} finally {
ReflectionTestUtils.setField(encryptionClient, "keyArn", KEY_ARN);
}
}
@Test
public void should_return_when_encryptCalledWithArgs() {
// Arrange
EncryptResponse mockResponse = EncryptResponse.builder().ciphertextBlob(SdkBytes.fromByteArray(ENCRYPTED))
.build();
when(kmsClient.encrypt(any(EncryptRequest.class))).thenReturn(mockResponse);
// Act
byte[] encrypted = encryptionClient.encrypt(DECRYPTED, VALID_ID);
// Assert
assertArrayEquals(ENCRYPTED, encrypted);
verify(kmsClient).encrypt(encryptRequestCaptor.capture());
EncryptRequest capturedRequest = encryptRequestCaptor.getValue();
Map<String, String> encryptionContext = capturedRequest.encryptionContext();
assertEquals("Should have exactly one entry", 1, encryptionContext.size());
assertEquals("Should contain valid ID", VALID_ID, encryptionContext.get(AUTH_DATABASE));
assertEquals("Should match expected context", validContext, encryptionContext);
}
@Test
public void should_return_when_decryptCalledWithValidArgs() {
// Arrange
DecryptResponse mockResponse = DecryptResponse.builder()
.plaintext(SdkBytes.fromString(DECRYPTED, StandardCharsets.UTF_8)).build();
when(kmsClient.decrypt(any(DecryptRequest.class))).thenReturn(mockResponse);
// Act
String decrypted = encryptionClient.decrypt(ENCRYPTED, VALID_ID);
// Assert
assertEquals(DECRYPTED, decrypted);
verify(kmsClient).decrypt(decryptRequestCaptor.capture());
DecryptRequest capturedRequest = decryptRequestCaptor.getValue();
Map<String, String> encryptionContext = capturedRequest.encryptionContext();
assertEquals("Should have exactly one entry", 1, encryptionContext.size());
assertEquals("Should contain valid ID", VALID_ID, encryptionContext.get(AUTH_DATABASE));
assertEquals("Should match expected context", validContext, encryptionContext);
}
@Test
public void should_return_when_defaultConstructorCalled() {
// Act
AwsKmsEncryptionClient cryptoClient = new AwsKmsEncryptionClient();
// Assert
assertTrue(cryptoClient.getKmsClient() != null);
}
}
......@@ -68,8 +68,8 @@
<artifactId>os-core-lib-aws</artifactId>
<version>0.26.0-spring6-rc2</version>
</dependency>
</dependencies>
</project>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment