diff --git a/pom.xml b/pom.xml
index 521e405..10c2e5a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -10,6 +10,7 @@
+ * To configure the default algorithm, see {@link MessageDigestConfiguration}. + */ +public interface MessageDigestService { + + /** + * Get a new MessageDigest instance using the configured algorithm. + * + * @return The MessageDigest instance + */ + MessageDigest getInstance(); + + /** + * Get a new MessageDigest instance using the specified algorithm. + * + * @param algorithm the algorithm to use + * @return The MessageDigest instance + */ + MessageDigest getInstance(String algorithm); + + /** + * Digests the input using the default charset (UTF-8) and + * the configured algorithm. + * + * @param input the input to digest + * @return the digest + */ + byte[] digest(String input); + + /** + * Digests the input using the specified charset and + * the configured algorithm. + * + * @param input the input to digest + * @param charset the charset to use + * @return the digest + */ + byte[] digest(String input, Charset charset); + + /** + * Digests the input using the specified charset and algorithm. + * + * @param input the input to digest + * @param charset the charset to use + * @param algorithm the algorithm to use + * @return the digest + */ + byte[] digest(String input, Charset charset, String algorithm); + + /** + * Digests the input using the specified charset and message digest. + * + * @param input the input to digest + * @param charset the charset to use + * @param messageDigest the message digest to use + * @return the digest + */ + byte[] digest(String input, Charset charset, MessageDigest messageDigest); +} diff --git a/quarkus-message-digest-service/src/main/java/ch/phoenixtechnologies/quarkus/commons/digest/MessageDigestServiceImpl.java b/quarkus-message-digest-service/src/main/java/ch/phoenixtechnologies/quarkus/commons/digest/MessageDigestServiceImpl.java new file mode 100644 index 0000000..eb3e749 --- /dev/null +++ b/quarkus-message-digest-service/src/main/java/ch/phoenixtechnologies/quarkus/commons/digest/MessageDigestServiceImpl.java @@ -0,0 +1,55 @@ +package ch.phoenixtechnologies.quarkus.commons.digest; + +import io.quarkus.arc.DefaultBean; +import jakarta.enterprise.context.ApplicationScoped; + +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +@DefaultBean +@ApplicationScoped +class MessageDigestServiceImpl implements MessageDigestService { + + private final MessageDigestConfiguration configuration; + + MessageDigestServiceImpl(MessageDigestConfiguration configuration) { + this.configuration = configuration; + } + + @Override + public MessageDigest getInstance() { + return getInstance(configuration.defaultAlgorithm()); + } + + @Override + public MessageDigest getInstance(String algorithm) { + try { + return MessageDigest.getInstance(algorithm); + } catch (NoSuchAlgorithmException e) { + throw new IllegalArgumentException("Unknown algorithm: " + algorithm, e); + } + } + + @Override + public byte[] digest(String input) { + return digest(input, StandardCharsets.UTF_8); + } + + @Override + public byte[] digest(String input, Charset charset) { + return digest(input, charset, configuration.defaultAlgorithm()); + } + + @Override + public byte[] digest(String input, Charset charset, String algorithm) { + return digest(input, charset, getInstance(algorithm)); + } + + @Override + public byte[] digest(String input, Charset charset, MessageDigest messageDigest) { + var bytes = input.getBytes(StandardCharsets.UTF_8); + return messageDigest.digest(bytes); + } +} diff --git a/quarkus-message-digest-service/src/test/java/ch/phoenixtechnologies/quarkus/commons/digest/MessageDigestServiceImplTest.java b/quarkus-message-digest-service/src/test/java/ch/phoenixtechnologies/quarkus/commons/digest/MessageDigestServiceImplTest.java new file mode 100644 index 0000000..42647b5 --- /dev/null +++ b/quarkus-message-digest-service/src/test/java/ch/phoenixtechnologies/quarkus/commons/digest/MessageDigestServiceImplTest.java @@ -0,0 +1,81 @@ +package ch.phoenixtechnologies.quarkus.commons.digest; + +import io.quarkus.test.junit.QuarkusTest; +import jakarta.inject.Inject; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; + +@QuarkusTest +class MessageDigestServiceImplTest { + + public static final String INPUT = "test"; + public static final byte[] EXPECTED_SHA256_DIGEST = {-97, -122, -48, -127, -120, 76, 125, 101, -102, 47, -22, -96, -59, 90, -48, 21, -93, -65, 79, 27, 43, 11, -126, 44, -47, 93, 108, 21, -80, -16, 10, 8}; + + @Inject + MessageDigestServiceImpl service; + + @Test + void getInstance() { + assertThat(service.getInstance()) + .isInstanceOf(MessageDigest.class); + } + + @ParameterizedTest + @ValueSource(strings = {"SHA-256", "SHA-512", "MD5"}) + void getInstanceWithAlgorithm(String algorithm) { + assertThat(service.getInstance(algorithm)) + .isInstanceOf(MessageDigest.class); + } + + @ParameterizedTest + @ValueSource(strings = {"ADBC", "acvb", "null"}) + void getInstanceWhenUnknownAlgorithm(String algorithm) { + assertThatThrownBy(() -> service.getInstance(algorithm)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("Unknown algorithm: " + algorithm); + } + + @Test + void getInstanceWhenAlgorithmIsNull() { + assertThatThrownBy(() -> service.getInstance(null)) + .isInstanceOf(NullPointerException.class) + .hasMessageContaining("null algorithm name"); + } + + @Test + void digest() { + assertThat(service.digest(INPUT)) + .as("Digest should match expected value") + .isEqualTo(EXPECTED_SHA256_DIGEST); + } + + @Test + void digestWithCharset() { + assertThat(service.digest(INPUT, StandardCharsets.UTF_8)) + .as("Digest should match expected value") + .isEqualTo(EXPECTED_SHA256_DIGEST); + + } + + @Test + void digestWithCharsetAndAlgorithm() { + assertThat(service.digest(INPUT, StandardCharsets.UTF_8, "SHA-256")) + .as("Digest should match expected value") + .isEqualTo(EXPECTED_SHA256_DIGEST); + } + + @Test + void digestWithCharsetAndMessageDigestInstance() { + var messageDigest = service.getInstance(); + assertThat(service.digest(INPUT, StandardCharsets.UTF_8, messageDigest)) + .as("Digest should match expected value") + .isEqualTo(EXPECTED_SHA256_DIGEST); + } +} \ No newline at end of file