Skip to content

Commit

Permalink
ACC-1512 Improve test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
thijslemmens committed Jul 26, 2024
1 parent 6bbba56 commit 9a012be
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.contentgrid.gateway.security.jwt.issuer.jwk.source;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

import com.contentgrid.gateway.test.security.CryptoTestUtils;
import com.nimbusds.jose.jwk.JWK;
import java.nio.charset.StandardCharsets;
import lombok.SneakyThrows;
import org.junit.jupiter.api.Test;

class FilebasedJWKSetSourceTest {

@Test
@SneakyThrows
void testGetJWKSet() {
var activeRSAKey = CryptoTestUtils.createKeyPair("RSA", 2048);
var activeRSAResource = CryptoTestUtils.toPrivateKeyResource(activeRSAKey);
var retiredRSAKey = CryptoTestUtils.createKeyPair("RSA", 2048);
var retiredRSAResource = CryptoTestUtils.toPrivateKeyResource(retiredRSAKey);

var activeECKey = CryptoTestUtils.createKeyPair("EC", 256);
var activeECResource = CryptoTestUtils.toPrivateKeyResource(activeECKey);
var retiredECKey = CryptoTestUtils.createKeyPair("EC", 256);
var retiredECResource = CryptoTestUtils.toPrivateKeyResource(retiredECKey);

var activeOctetKeyPair = CryptoTestUtils.createOctetKeyPair();
var activeOctetResource = CryptoTestUtils.toPrivateKeyResource(activeOctetKeyPair);
var retiredOctetKeyPair = CryptoTestUtils.createOctetKeyPair();
var retiredOctetResource = CryptoTestUtils.toPrivateKeyResource(retiredOctetKeyPair);

var resourcePatternResolver = MockResourcePatternResolver.builder()
.resource("file:/keys/active_rsa.pem", activeRSAResource)
.resource("file:/keys/retired_rsa.pem", retiredRSAResource)
.resource("file:/keys/active_ec.pem", activeECResource)
.resource("file:/keys/retired_ec.pem", retiredECResource)
.resource("file:/keys/active_octet.pem", activeOctetResource)
.resource("file:/keys/retired_octet.pem", retiredOctetResource)
.build();

var filebasedJWKSetSource = new FilebasedJWKSetSource(resourcePatternResolver, "file:/keys/active_*.pem",
"file:/keys/retired_*.pem");

var jwkSet = filebasedJWKSetSource.getJWKSet(null, System.currentTimeMillis(), null);

var activeRSAJWK = JWK.parseFromPEMEncodedObjects(activeRSAResource.getContentAsString(StandardCharsets.UTF_8));
var retiredRSAJWK = JWK.parseFromPEMEncodedObjects(retiredRSAResource.getContentAsString(StandardCharsets.UTF_8));
var activeECJWK = JWK.parseFromPEMEncodedObjects(activeECResource.getContentAsString(StandardCharsets.UTF_8));
var retiredECJWK = JWK.parseFromPEMEncodedObjects(retiredECResource.getContentAsString(StandardCharsets.UTF_8));
var activeOctetJWK = JWK.parseFromPEMEncodedObjects(activeOctetResource.getContentAsString(StandardCharsets.UTF_8));
var retiredOctetJWK = JWK.parseFromPEMEncodedObjects(retiredOctetResource.getContentAsString(StandardCharsets.UTF_8));

assertEquals(6, jwkSet.getKeys().size());
assertNotNull(jwkSet.getKeyByKeyId(activeRSAJWK.computeThumbprint().toString()));
assertNotNull(jwkSet.getKeyByKeyId(retiredRSAJWK.computeThumbprint().toString()));
assertNotNull(jwkSet.getKeyByKeyId(activeECJWK.computeThumbprint().toString()));
assertNotNull(jwkSet.getKeyByKeyId(retiredECJWK.computeThumbprint().toString()));
assertNotNull(jwkSet.getKeyByKeyId(activeOctetJWK.computeThumbprint().toString()));
assertNotNull(jwkSet.getKeyByKeyId(retiredOctetJWK.computeThumbprint().toString()));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.contentgrid.gateway.security.jwt.issuer.jwk.source;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import lombok.Builder;
import lombok.RequiredArgsConstructor;
import lombok.Singular;
import org.springframework.core.io.AbstractResource;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;

@RequiredArgsConstructor
@Builder
public class MockResourcePatternResolver implements ResourcePatternResolver {

@Singular
private final Map<String, Resource> resources;

private final PathMatcher pathMatcher = new AntPathMatcher();


@Override
public Resource getResource(String location) {
return resources.getOrDefault(location, new NonExistingResource(location));
}

@Override
public ClassLoader getClassLoader() {
return null;
}

@Override
public Resource[] getResources(String locationPattern) throws IOException {
return resources.keySet()
.stream()
.filter(path -> pathMatcher.match(locationPattern, path))
.map(this::getResource)
.toArray(Resource[]::new);
}

@RequiredArgsConstructor
private static class NonExistingResource extends AbstractResource {

private final String path;

@Override
public String getDescription() {
return "NonExistingResource [%s]".formatted(path);
}

@Override
public InputStream getInputStream() throws IOException {
throw new FileNotFoundException(getDescription() + " can not be opened because it does not exist");
}

@Override
public boolean exists() {
return false;
}
}

public static class MockResourcePatternResolverBuilder {
public MockResourcePatternResolverBuilder textResource(String resourceKey, String resource) {
return resource(resourceKey, new ByteArrayResource(resource.getBytes(StandardCharsets.UTF_8)));
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package com.contentgrid.gateway.test.security;

import com.nimbusds.jose.jwk.Curve;
import com.nimbusds.jose.jwk.OctetKeyPair;
import com.nimbusds.jose.jwk.gen.OctetKeyPairGenerator;
import java.io.ByteArrayOutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.util.List;
Expand Down Expand Up @@ -49,4 +53,23 @@ public static Resource toPublicKeyResource(KeyPair keyPair) {
new PemObject("PUBLIC KEY", keyPair.getPublic().getEncoded())
));
}

@SneakyThrows
public static OctetKeyPair createOctetKeyPair() {
return new OctetKeyPairGenerator(Curve.Ed25519).generate();
}

@SneakyThrows
public static Resource toPrivateKeyResource(OctetKeyPair keyPair) {
var privateKeyOutput = new ByteArrayOutputStream();
try (var writer = new OutputStreamWriter(privateKeyOutput)) {
try (var pemWriter = new PemWriter(writer)) {
pemWriter.writeObject(new PemObject("PRIVATE KEY", keyPair.toPrivateKey().toString().getBytes(
StandardCharsets.UTF_8)));
pemWriter.writeObject(
new PemObject("PUBLIC KEY", keyPair.toPublicKey().toString().getBytes(StandardCharsets.UTF_8)));
}
}
return new InMemoryResource(privateKeyOutput.toByteArray());
}
}

0 comments on commit 9a012be

Please # to comment.