Skip to content

Commit

Permalink
use @ContextConfiguration, faster en more SRP
Browse files Browse the repository at this point in the history
  • Loading branch information
bhuism committed Jan 9, 2025
1 parent daaadd0 commit b6be87f
Show file tree
Hide file tree
Showing 63 changed files with 120 additions and 94 deletions.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public WsExchangeTokenResponse exchangeToken(final String callerOIN,

final var encodedToken = aesGcmCryptographerService.decrypt(
wsExchangeTokenForIdentifierRequest.getToken(), callerOIN);
final var token = tokenConverter.decode(encodedToken);
final var token = tokenConverter.deSerialize(encodedToken);
if (!oinValidator.isValid(callerOIN, token)) {
throw new InvalidOINException("CallerOIN and token are mismatched.");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ public SecretKey createSecretKey(final String salt) {
pseudoniemenServiceProperties.getTokenPrivateKey());
final var saltBytes = salt.getBytes(StandardCharsets.UTF_8);
final var salterSecretBytes = ByteArrayUtil.concat(keyBytes, saltBytes);
final var key = messageDigestWrapper.getMessageDigestInstance().digest(salterSecretBytes);
final var key = messageDigestWrapper.instance().digest(salterSecretBytes);
return new SecretKeySpec(key, "AES");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,10 @@ public class AesGcmSivCryptographerServiceImpl implements AesGcmSivCryptographer
@Override
public AEADParameters createSecretKey(final String salt) {

final var nonce16 = messageDigestWrapper.getMessageDigestInstance()
.digest(salt.getBytes(StandardCharsets.UTF_8));
final var nonce16 = messageDigestWrapper.instance().digest(salt.getBytes(StandardCharsets.UTF_8));
final var nonce12 = Arrays.copyOf(nonce16, NONCE_LENTH);
final var identifierPrivateKey = pseudoniemenServiceProperties.getIdentifierPrivateKey();
final var keyParameter = new KeyParameter(
base64Wrapper.decode(identifierPrivateKey));
final var keyParameter = new KeyParameter(base64Wrapper.decode(identifierPrivateKey));
return new AEADParameters(keyParameter, MAC_SIZE, nonce12);
}

Expand All @@ -64,16 +62,14 @@ public AEADParameters createSecretKey(final String salt) {
* @throws IOException if an I/O error occurs during encryption
*/
@Override
public String encrypt(final Identifier identifier, final String salt)
throws InvalidCipherTextException, IOException {
public String encrypt(final Identifier identifier, final String salt) throws InvalidCipherTextException, IOException {

final var plaintext = identifierConverter.encode(identifier);
final var plaintext = identifierConverter.serialize(identifier);
final var cipher = new GCMSIVBlockCipher(AesUtility.getAESEngine());
cipher.init(true, createSecretKey(salt));
final var plainTextBytes = plaintext.getBytes(StandardCharsets.UTF_8);
final var ciphertext = new byte[cipher.getOutputSize(plainTextBytes.length)];
final var outputLength = cipher.processBytes(plainTextBytes, 0, plainTextBytes.length,
ciphertext, 0);
final var outputLength = cipher.processBytes(plainTextBytes, 0, plainTextBytes.length, ciphertext, 0);
cipher.doFinal(ciphertext, outputLength);
cipher.reset();
return base64Wrapper.encodeToString(ciphertext);
Expand All @@ -95,12 +91,11 @@ public Identifier decrypt(final String ciphertextString, final String salt) {
cipher.init(false, createSecretKey(salt));
final var ciphertext = base64Wrapper.decode(ciphertextString);
final var plaintext = new byte[cipher.getOutputSize(ciphertext.length)];
final var outputLength = cipher.processBytes(ciphertext, 0, ciphertext.length, plaintext,
0);
final var outputLength = cipher.processBytes(ciphertext, 0, ciphertext.length, plaintext, 0);
cipher.doFinal(plaintext, outputLength);
cipher.reset();
final var encodedIdentifier = new String(plaintext, StandardCharsets.UTF_8);
return identifierConverter.decode(encodedIdentifier);
return identifierConverter.deSerialize(encodedIdentifier);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class IdentifierConverter {
* @return the JSON string representation of the given Identifier object
* @throws IOException if an I/O error occurs during encoding
*/
public String encode(final Identifier identifier) throws IOException {
public String serialize(final Identifier identifier) throws IOException {

final StringWriter stringWriter = new StringWriter();
objectMapper.writeValue(stringWriter, identifier);
Expand All @@ -38,7 +38,7 @@ public String encode(final Identifier identifier) throws IOException {
* @return the deserialized Identifier object
* @throws JsonProcessingException if an error occurs while processing the JSON string
*/
public Identifier decode(final String encodedIdentifier) throws JsonProcessingException {
public Identifier deSerialize(final String encodedIdentifier) throws JsonProcessingException {

return objectMapper.readValue(encodedIdentifier, Identifier.class);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class TokenConverter {
* @return the JSON string representation of the given Token object
* @throws IOException if an I/O error occurs during encoding
*/
public String encode(final Token token) throws IOException {
public String serialize(final Token token) throws IOException {

final var stringWriter = new StringWriter();
objectMapper.writeValue(stringWriter, token);
Expand All @@ -38,7 +38,7 @@ public String encode(final Token token) throws IOException {
* @return the decoded Token object
* @throws JsonProcessingException if the JSON string cannot be parsed into a Token object
*/
public Token decode(final String encodedToken) throws JsonProcessingException {
public Token deSerialize(final String encodedToken) throws JsonProcessingException {

return objectMapper.readValue(encodedToken, Token.class);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public WsGetTokenResponse map(final String bsn, final long creationDate,
throws IOException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException {

return WsGetTokenResponse.builder()
.token(aesGcmCryptographerService.encrypt(tokenConverter.encode(Token.builder()
.token(aesGcmCryptographerService.encrypt(tokenConverter.serialize(Token.builder()
.version(V_1)
.bsn(bsn)
.creationDate(creationDate)
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
@Component
public final class Base64Wrapper {

public static final Decoder DECODER = Base64.getDecoder();
public static final Encoder ENCODER = Base64.getEncoder();
private static final Decoder DECODER = Base64.getDecoder();
private static final Encoder ENCODER = Base64.getEncoder();

/**
* Decodes a Base64-encoded string into its original byte array representation.
Expand Down
35 changes: 35 additions & 0 deletions src/main/java/nl/appsource/utils/MessageDigestWrapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package nl.appsource.utils;

import jakarta.annotation.PostConstruct;
import lombok.SneakyThrows;
import org.springframework.stereotype.Component;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

@Component
public final class MessageDigestWrapper {

private static final String SHA_256 = "SHA-256";
private MessageDigest messageDigest;

@PostConstruct
private void init() {
try {
messageDigest = MessageDigest.getInstance(SHA_256);
} catch (NoSuchAlgorithmException e) {
// fail early, fail hard
throw new RuntimeException(e);
}
}

/**
* Creates and returns a new instance of the MessageDigest configured for the SHA-256 algorithm.
*
* @return a MessageDigest instance initialized to use the SHA-256 algorithm
*/
@SneakyThrows
public MessageDigest instance() {
return messageDigest;
}
}
23 changes: 0 additions & 23 deletions src/main/java/nl/ictu/utils/MessageDigestWrapper.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,15 @@ void testExchangeToken_BsnIdentifier() throws Exception {
.build();
// Stubbing dependencies
when(aesGcmCryptographerService.decrypt(encryptedToken, callerOIN)).thenReturn(decodedToken);
when(tokenConverter.decode(decodedToken)).thenReturn(mockToken);
when(tokenConverter.deSerialize(decodedToken)).thenReturn(mockToken);
when(oinValidator.isValid(callerOIN, mockToken)).thenReturn(true);
var expectedResponse = mock(WsExchangeTokenResponse.class);
when(bsnTokenMapper.map(mockToken)).thenReturn(expectedResponse);
// WHEN
final var actualResponse = exchangeTokenService.exchangeToken(callerOIN, request);
// THEN
verify(aesGcmCryptographerService).decrypt(encryptedToken, callerOIN);
verify(tokenConverter).decode(decodedToken);
verify(tokenConverter).deSerialize(decodedToken);
verify(oinValidator).isValid(callerOIN, mockToken);
verify(bsnTokenMapper).map(mockToken);
assertEquals(expectedResponse, actualResponse);
Expand All @@ -99,15 +99,15 @@ void testExchangeToken_OrganisationPseudoIdentifier() throws Exception {
.build();
// Stubbing dependencies
when(aesGcmCryptographerService.decrypt(encryptedToken, callerOIN)).thenReturn(decodedToken);
when(tokenConverter.decode(decodedToken)).thenReturn(mockToken);
when(tokenConverter.deSerialize(decodedToken)).thenReturn(mockToken);
when(oinValidator.isValid(callerOIN, mockToken)).thenReturn(true);
final var expectedResponse = mock(WsExchangeTokenResponse.class);
when(organisationPseudoTokenMapper.map(callerOIN, mockToken)).thenReturn(expectedResponse);
// WHEN
final var actualResponse = exchangeTokenService.exchangeToken(callerOIN, request);
// THEN
verify(aesGcmCryptographerService).decrypt(encryptedToken, callerOIN);
verify(tokenConverter).decode(decodedToken);
verify(tokenConverter).deSerialize(decodedToken);
verify(oinValidator).isValid(callerOIN, mockToken);
verify(organisationPseudoTokenMapper).map(callerOIN, mockToken);
assertEquals(expectedResponse, actualResponse);
Expand All @@ -127,12 +127,12 @@ void testExchangeToken_InvalidOIN() throws Exception {
.build();
// Stubbing dependencies
when(aesGcmCryptographerService.decrypt(encryptedToken, callerOIN)).thenReturn(decodedToken);
when(tokenConverter.decode(decodedToken)).thenReturn(mockToken);
when(tokenConverter.deSerialize(decodedToken)).thenReturn(mockToken);
when(oinValidator.isValid(callerOIN, mockToken)).thenReturn(false); // Invalid OIN
// WHEN & THEN
assertThrows(InvalidOINException.class, () -> exchangeTokenService.exchangeToken(callerOIN, request));
verify(aesGcmCryptographerService).decrypt(encryptedToken, callerOIN);
verify(tokenConverter).decode(decodedToken);
verify(tokenConverter).deSerialize(decodedToken);
verify(oinValidator).isValid(callerOIN, mockToken);
verifyNoInteractions(bsnTokenMapper, organisationPseudoTokenMapper);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package nl.appsource.service;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import nl.appsource.configuration.PseudoniemenServiceProperties;
import nl.appsource.service.crypto.AesGcmCryptographerService;
Expand All @@ -8,7 +9,11 @@
import nl.appsource.utils.MessageDigestWrapper;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.test.context.ActiveProfiles;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import java.util.Arrays;
import java.util.HashSet;
Expand All @@ -20,15 +25,23 @@
* Class for testing {@link AesGcmCryptographerServiceImpl}
*/
@Slf4j
@ActiveProfiles("test")
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {Base64Wrapper.class, ObjectMapper.class, AesGcmCryptographerServiceImpl.class, MessageDigestWrapper.class, TestAesGcmCryptographerServiceImpl.TestConfiguration.class})
class TestAesGcmCryptographerServiceImpl {

private final AesGcmCryptographerService aesGcmCryptographerService = new AesGcmCryptographerServiceImpl(
new Base64Wrapper(),
new MessageDigestWrapper(),
new PseudoniemenServiceProperties().setTokenPrivateKey(
"bFUyS1FRTVpON0pCSFFRRGdtSllSeUQ1MlRna2txVmI=")
);
@Autowired
private AesGcmCryptographerService aesGcmCryptographerService;

@org.springframework.boot.test.context.TestConfiguration
static class TestConfiguration {
@Bean
public PseudoniemenServiceProperties pseudoniemenServiceProperties() {
return new PseudoniemenServiceProperties()
.setTokenPrivateKey("i4dfBykN5Fjw9p3ADxvpRUhpbFSXepRSOcRGuaiJ4iQ=")
.setIdentifierPrivateKey("b2RPRGh6aThiMmluVEpMWVVJM2lOTGlWekVCU2hDMEU=");
}
}

private final Set<String> testStrings = new HashSet<>(
Arrays.asList("a", "bb", "dsv", "ghad", "dhaht", "uDg5Av", "d93fdvv", "dj83hzHo",
"38iKawKv9", "dk(gkzm)Mh", "gjk)s3$g9cQ"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,40 @@
import nl.appsource.utils.MessageDigestWrapper;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.test.context.ActiveProfiles;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;

/**
* Class for testing {@link AesGcmSivCryptographerService}
*/
@Slf4j
@ActiveProfiles("test")
class TestAesGcmSivCryptographerService {
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {Base64Wrapper.class, ObjectMapper.class, AesGcmSivCryptographerServiceImpl.class, IdentifierConverter.class, MessageDigestWrapper.class, TestAesGcmSivCryptographerServiceImpl.TestConfiguration.class})
class TestAesGcmSivCryptographerServiceImpl {

private final AesGcmSivCryptographerService aesGcmSivCryptographerService = new AesGcmSivCryptographerServiceImpl(
new PseudoniemenServiceProperties().setIdentifierPrivateKey(
"QTBtVEhLN3EwMHJ3QXN1ZUFqNzVrT3hDQTBIWWNIZTU="),
new MessageDigestWrapper(),
new IdentifierConverter(new ObjectMapper()),
new Base64Wrapper()
);
private final Set<String> testStrings = new HashSet<>(
Arrays.asList("a", "bb", "dsv", "ghad", "dhaht", "uDg5Av", "d93fdvv", "dj83hzHo",
"38iKawKv9", "dk(gkzm)Mh", "gjk)s3$g9cQ"));
@Autowired
private AesGcmSivCryptographerService aesGcmSivCryptographerService;

private final Set<String> testStrings = new HashSet<>(Arrays.asList("a", "bb", "dsv", "ghad", "dhaht", "uDg5Av", "d93fdvv", "dj83hzHo", "38iKawKv9", "dk(gkzm)Mh", "gjk)s3$g9cQ"));

@org.springframework.boot.test.context.TestConfiguration
static class TestConfiguration {
@Bean
public PseudoniemenServiceProperties pseudoniemenServiceProperties() {
return new PseudoniemenServiceProperties()
.setTokenPrivateKey("i4dfBykN5Fjw9p3ADxvpRUhpbFSXepRSOcRGuaiJ4iQ=")
.setIdentifierPrivateKey("b2RPRGh6aThiMmluVEpMWVVJM2lOTGlWekVCU2hDMEU=");
}
}

@Test
@DisplayName("""
Expand All @@ -48,13 +57,9 @@ void testEncyptDecryptForDifferentStringLengths() {
testStrings.forEach(plain -> {
try {
// GIVEN
final var crypted = aesGcmSivCryptographerService.encrypt(Identifier.builder()
.bsn(plain)
.build(),
"helloHowAreyo12345678");
final var crypted = aesGcmSivCryptographerService.encrypt(Identifier.builder().bsn(plain).build(), "helloHowAreyo12345678");
// WHEN
final var actual = aesGcmSivCryptographerService.decrypt(crypted,
"helloHowAreyo12345678");
final var actual = aesGcmSivCryptographerService.decrypt(crypted, "helloHowAreyo12345678");
// THEN
assertThat(actual.getBsn()).isEqualTo(plain);
} catch (final Exception e) {
Expand Down
Loading

0 comments on commit b6be87f

Please sign in to comment.