Skip to content

Commit

Permalink
Add more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
enricovianello committed Mar 17, 2024
1 parent 4524675 commit 9144d02
Show file tree
Hide file tree
Showing 2 changed files with 158 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -84,22 +84,22 @@ public Map<String, Object> loadConfigurationForIssuer(String issuer) {
new ParameterizedTypeReference<Map<String, Object>>() {};

URI uri = UriComponentsBuilder.fromUriString(issuer + WELL_KNOWN_FRAGMENT).build().toUri();

ResponseEntity<Map<String, Object>> response = null;
try {

RequestEntity<Void> request = RequestEntity.get(uri).build();
Map<String, Object> conf = restTemplate.exchange(request, typeReference).getBody();
metadataChecks(issuer, conf);
return conf;
response = restTemplate.exchange(request, typeReference);
if (response.getStatusCodeValue() != 200) {
throw new RuntimeException(
format("Received status code: %s", response.getStatusCodeValue()));
}
metadataChecks(issuer, response.getBody());
return response.getBody();
} catch (RuntimeException e) {
final String errorMsg =
format("Unable to resolve OpenID configuration for issuer '%s' from '%s': %s", issuer,
uri, e.getMessage());

final String errorMsg = format("Unable to resolve OpenID configuration from '%s'", uri);
if (LOG.isDebugEnabled()) {
LOG.error(errorMsg, e);
LOG.error("{}: {}", errorMsg, e.getMessage());
}

throw new OidcConfigurationResolutionError(errorMsg, e);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,14 @@

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.lenient;
import static org.springframework.http.HttpStatus.NOT_FOUND;
import static org.springframework.http.HttpStatus.OK;

import java.io.File;
import java.io.IOException;
Expand All @@ -32,13 +36,15 @@
import org.italiangrid.storm.webdav.config.OAuthProperties;
import org.italiangrid.storm.webdav.oauth.utils.DefaultOidcConfigurationFetcher;
import org.italiangrid.storm.webdav.oauth.utils.OidcConfigurationFetcher;
import org.italiangrid.storm.webdav.oauth.utils.OidcConfigurationResolutionError;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
Expand All @@ -52,7 +58,10 @@
public class OidcConfigurationFetcherTests {

final static String ISSUER = "https://iam-dev.cloud.cnaf.infn.it/";
final static String JWK_URI = "https://iam-dev.cloud.cnaf.infn.it/jwk";
final static String JWK_URI = ISSUER + "jwk";

final static String ANOTHER_ISSUER = "https://iam.cloud.infn.it/";
final static String ANOTHER_JWK_URI = ANOTHER_ISSUER + "jwk";

final static String KID = "rsa1";

Expand All @@ -67,62 +76,181 @@ public class OidcConfigurationFetcherTests {
@Mock
OAuthProperties oAuthProperties;

private Map<String, Object> getMapWithIssuerAndJwkUri(String issuer, String jwkUri) {
Map<String, Object> m = Maps.newHashMap();
m.put("issuer", issuer);
m.put("jwks_uri", jwkUri);
return m;
}

@SuppressWarnings("unchecked")
private ResponseEntity<Map<String, Object>> getMockedResponseFromWellKnown() {
private ResponseEntity<Map<String, Object>> getWellKnownResponse(HttpStatus status, Map<String, Object> map) {

Map<String, Object> wellKnownMap = Maps.newHashMap();
wellKnownMap.put("issuer", ISSUER);
wellKnownMap.put("jwks_uri", JWK_URI);
ResponseEntity<Map<String, Object>> mockedEntity = (ResponseEntity<Map<String, Object>>) Mockito.mock(ResponseEntity.class);
lenient().when(mockedEntity.getBody()).thenReturn(wellKnownMap);
lenient().when(mockedEntity.getStatusCode()).thenReturn(status);
lenient().when(mockedEntity.getStatusCodeValue()).thenReturn(status.value());
lenient().when(mockedEntity.getBody()).thenReturn(map);
return mockedEntity;
}

@SuppressWarnings("unchecked")
private ResponseEntity<String> getMockedResponseFromJWKURI() throws IOException {
private String loadJwkFromFile() throws IOException {

ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("jwk/test-keystore.jwks").getFile());
String data = FileUtils.readFileToString(file, "UTF-8");
return FileUtils.readFileToString(file, "UTF-8");
}

@SuppressWarnings("unchecked")
private ResponseEntity<String> getJWKURIResponse(HttpStatus status, String data) throws IOException {

ResponseEntity<String> mockedEntity = (ResponseEntity<String>) Mockito.mock(ResponseEntity.class);
lenient().when(mockedEntity.getBody()).thenReturn(data);
lenient().when(mockedEntity.getStatusCodeValue()).thenReturn(200);
lenient().when(mockedEntity.getStatusCode()).thenReturn(status);
lenient().when(mockedEntity.getStatusCodeValue()).thenReturn(status.value());
return mockedEntity;
}

private OidcConfigurationFetcher getFetcher() throws RestClientException, IOException {

ResponseEntity<Map<String, Object>> mockedResponseMapEntity = getMockedResponseFromWellKnown();
lenient().when(restTemplate.exchange(any(), eq(typeReference))).thenReturn(mockedResponseMapEntity);
ResponseEntity<String> mockedResponseStringEntity = getMockedResponseFromJWKURI();
lenient().when(restTemplate.exchange(any(), eq(String.class))).thenReturn(mockedResponseStringEntity);
private OidcConfigurationFetcher getFetcher(ResponseEntity<Map<String, Object>> wellKnownResponse, ResponseEntity<String> jwkResponse) {

lenient().when(restTemplate.exchange(any(), eq(typeReference))).thenReturn(wellKnownResponse);
lenient().when(restTemplate.exchange(any(), eq(String.class))).thenReturn(jwkResponse);
lenient().when(restBuilder.build()).thenReturn(restTemplate);
lenient().when(restBuilder.setConnectTimeout(any())).thenReturn(restBuilder);
lenient().when(restBuilder.setReadTimeout(any())).thenReturn(restBuilder);
lenient().when(oAuthProperties.getRefreshTimeoutSeconds()).thenReturn(30);
lenient().when(oAuthProperties.getRefreshPeriodMinutes()).thenReturn(1);

return new DefaultOidcConfigurationFetcher(restBuilder, oAuthProperties);
}

private OidcConfigurationFetcher getSuccessfulFetcher() throws RestClientException, IOException {

ResponseEntity<Map<String, Object>> mockedResponseMapEntity = getWellKnownResponse(OK, getMapWithIssuerAndJwkUri(ISSUER, JWK_URI));
ResponseEntity<String> mockedResponseStringEntity = getJWKURIResponse(OK, loadJwkFromFile());
return getFetcher(mockedResponseMapEntity, mockedResponseStringEntity);
}

private OidcConfigurationFetcher getSuccessfulFetcherWithWrongIssuer() throws RestClientException, IOException {

ResponseEntity<Map<String, Object>> mockedResponseMapEntity = getWellKnownResponse(OK, getMapWithIssuerAndJwkUri(ANOTHER_ISSUER, ANOTHER_JWK_URI));
ResponseEntity<String> mockedResponseStringEntity = getJWKURIResponse(OK, loadJwkFromFile());
return getFetcher(mockedResponseMapEntity, mockedResponseStringEntity);
}

private OidcConfigurationFetcher getSuccessfulFetcherWithNoIssuer() throws RestClientException, IOException {

Map<String, Object> map = getMapWithIssuerAndJwkUri(ANOTHER_ISSUER, ANOTHER_JWK_URI);
map.remove("issuer");
ResponseEntity<Map<String, Object>> mockedResponseMapEntity = getWellKnownResponse(OK, map);
ResponseEntity<String> mockedResponseStringEntity = getJWKURIResponse(OK, loadJwkFromFile());
return getFetcher(mockedResponseMapEntity, mockedResponseStringEntity);
}

private OidcConfigurationFetcher getSuccessfulFetcherWithNoJwk() throws RestClientException, IOException {

Map<String, Object> map = getMapWithIssuerAndJwkUri(ANOTHER_ISSUER, ANOTHER_JWK_URI);
map.remove("jwks_uri");
ResponseEntity<Map<String, Object>> mockedResponseMapEntity = getWellKnownResponse(OK, map);
ResponseEntity<String> mockedResponseStringEntity = getJWKURIResponse(OK, loadJwkFromFile());
return getFetcher(mockedResponseMapEntity, mockedResponseStringEntity);
}

private OidcConfigurationFetcher getFetcherWithErrorOnFetch() throws RestClientException, IOException {

ResponseEntity<Map<String, Object>> mockedResponseMapEntity = getWellKnownResponse(NOT_FOUND, null);
return getFetcher(mockedResponseMapEntity, null);
}

private OidcConfigurationFetcher getFetcherWithErrorOnGetJwk() throws RestClientException, IOException {

ResponseEntity<Map<String, Object>> mockedResponseMapEntity = getWellKnownResponse(OK, getMapWithIssuerAndJwkUri(ISSUER, JWK_URI));
ResponseEntity<String> mockedResponseStringEntity = getJWKURIResponse(NOT_FOUND, null);
return getFetcher(mockedResponseMapEntity, mockedResponseStringEntity);
}

@Test
public void fetchWellKnownEndpointTests() throws RestClientException, IOException {
public void fetchWellKnownEndpointWithSuccessTests() throws RestClientException, IOException {

OidcConfigurationFetcher fetcher = getFetcher();
OidcConfigurationFetcher fetcher = getSuccessfulFetcher();
Map<String, Object> conf = fetcher.loadConfigurationForIssuer(ISSUER);
assertNotNull(conf);
assertThat(conf.get("issuer"), is(ISSUER));
assertThat(conf.get("jwks_uri"), is(JWK_URI));
}

@Test
public void fetchWellKnownEndpointWithErrorTests() throws RestClientException, IOException {

OidcConfigurationFetcher fetcher = getFetcherWithErrorOnFetch();
RuntimeException exception = assertThrows(RuntimeException.class, () -> {
fetcher.loadConfigurationForIssuer(ISSUER);
});
String expectedMessage = "Unable to resolve OpenID configuration from '" + ISSUER + ".well-known/openid-configuration'";
String actualMessage = exception.getMessage();

assertEquals(expectedMessage, actualMessage);
}

@Test
public void fetchWellKnownEndpointWrongIssuerTests() throws RestClientException, IOException {

OidcConfigurationFetcher fetcher = getSuccessfulFetcherWithWrongIssuer();
OidcConfigurationResolutionError exception = assertThrows(OidcConfigurationResolutionError.class, () -> {
fetcher.loadConfigurationForIssuer(ISSUER);
});
String expectedMessage = "Unable to resolve OpenID configuration from '" + ISSUER + ".well-known/openid-configuration'";
String actualMessage = exception.getMessage();

assertEquals(expectedMessage, actualMessage);

}

@Test
public void fetchWellKnownEndpointNoIssuerTests() throws RestClientException, IOException {

OidcConfigurationFetcher fetcher = getSuccessfulFetcherWithNoIssuer();
OidcConfigurationResolutionError exception = assertThrows(OidcConfigurationResolutionError.class, () -> {
fetcher.loadConfigurationForIssuer(ISSUER);
});
String expectedMessage = "Unable to resolve OpenID configuration from '" + ISSUER + ".well-known/openid-configuration'";
String actualMessage = exception.getMessage();

assertEquals(expectedMessage, actualMessage);
}

@Test
public void fetchWellKnownEndpointNoJwkTests() throws RestClientException, IOException {

OidcConfigurationFetcher fetcher = getSuccessfulFetcherWithNoJwk();
OidcConfigurationResolutionError exception = assertThrows(OidcConfigurationResolutionError.class, () -> {
fetcher.loadConfigurationForIssuer(ISSUER);
});
String expectedMessage = "Unable to resolve OpenID configuration from '" + ISSUER + ".well-known/openid-configuration'";
String actualMessage = exception.getMessage();

assertEquals(expectedMessage, actualMessage);
}

@Test
public void fetchJWKEndpointTests() throws RestClientException, IOException, RemoteKeySourceException, ParseException {

OidcConfigurationFetcher fetcher = getFetcher();
OidcConfigurationFetcher fetcher = getSuccessfulFetcher();
JWKSet key = JWKSet.parse(fetcher.loadJWKSourceForURL(URI.create(JWK_URI)));

assertNotNull(key.getKeyByKeyId(KID));
assertThat(key.getKeyByKeyId(KID).getKeyType(), is(KeyType.RSA));
}

@Test
public void fetcJWKEndpointWithErrorTests() throws RestClientException, IOException {

OidcConfigurationFetcher fetcher = getFetcherWithErrorOnGetJwk();
final URI jwkUri = URI.create(JWK_URI);
RemoteKeySourceException exception = assertThrows(RemoteKeySourceException.class, () -> {
fetcher.loadJWKSourceForURL(jwkUri);
});
String expectedMessage = "Unable to get JWK from '" + jwkUri + "'";
String actualMessage = exception.getMessage();

assertEquals(expectedMessage, actualMessage);
}
}

0 comments on commit 9144d02

Please sign in to comment.