diff --git a/sslcontext-kickstart/src/main/java/nl/altindag/ssl/util/CertificateExtractorUtils.java b/sslcontext-kickstart/src/main/java/nl/altindag/ssl/util/CertificateExtractingClient.java similarity index 79% rename from sslcontext-kickstart/src/main/java/nl/altindag/ssl/util/CertificateExtractorUtils.java rename to sslcontext-kickstart/src/main/java/nl/altindag/ssl/util/CertificateExtractingClient.java index e9158947..33049bc0 100644 --- a/sslcontext-kickstart/src/main/java/nl/altindag/ssl/util/CertificateExtractorUtils.java +++ b/sslcontext-kickstart/src/main/java/nl/altindag/ssl/util/CertificateExtractingClient.java @@ -49,21 +49,29 @@ /** * @author Hakan Altindag */ -class CertificateExtractorUtils { +public class CertificateExtractingClient { private static final Pattern CA_ISSUERS_AUTHORITY_INFO_ACCESS = Pattern.compile("(?s)^AuthorityInfoAccess\\h+\\[\\R\\s*\\[\\R.*?accessMethod:\\h+caIssuers\\R\\h*accessLocation: URIName:\\h+(https?://\\S+)", Pattern.MULTILINE); - private static CertificateExtractorUtils instance; + private static CertificateExtractingClient instance; + private final boolean shouldResolveRootCa; + private final Proxy proxy; private final SSLFactory sslFactoryForCertificateCapturing; private final SSLFactory unsafeSslFactory; private final SSLSocketFactory unsafeSslSocketFactory; private final SSLSocketFactory certificateCapturingSslSocketFactory; private final List certificatesCollector; - private Proxy proxy; + private CertificateExtractingClient(boolean shouldResolveRootCa, Proxy proxy, PasswordAuthentication passwordAuthentication) { + this.shouldResolveRootCa = shouldResolveRootCa; + this.proxy = proxy; + + if (passwordAuthentication != null) { + Authenticator authenticator = new FelixAuthenticator(passwordAuthentication); + Authenticator.setDefault(authenticator); + } - private CertificateExtractorUtils() { certificatesCollector = new CopyOnWriteArrayList<>(); X509ExtendedTrustManager certificateCapturingTrustManager = TrustManagerUtils.createCertificateCapturingTrustManager(certificatesCollector); @@ -80,20 +88,9 @@ private CertificateExtractorUtils() { unsafeSslSocketFactory = unsafeSslFactory.getSslSocketFactory(); } - protected CertificateExtractorUtils(Proxy proxy) { - this(); - this.proxy = proxy; - } - - protected CertificateExtractorUtils(Proxy proxy, PasswordAuthentication passwordAuthentication) { - this(proxy); - Authenticator authenticator = new FelixAuthenticator(passwordAuthentication); - Authenticator.setDefault(authenticator); - } - - static CertificateExtractorUtils getInstance() { + static CertificateExtractingClient getInstance() { if (instance == null) { - instance = new CertificateExtractorUtils(); + instance = new CertificateExtractingClient(true, null, null); } else { instance.certificatesCollector.clear(); SSLSessionUtils.invalidateCaches(instance.sslFactoryForCertificateCapturing); @@ -101,7 +98,7 @@ static CertificateExtractorUtils getInstance() { return instance; } - List getCertificateFromExternalSource(String url) { + public List get(String url) { try { URL parsedUrl = new URL(url); if ("https".equalsIgnoreCase(parsedUrl.getProtocol())) { @@ -110,10 +107,14 @@ List getCertificateFromExternalSource(String url) { connection.connect(); connection.disconnect(); - List rootCa = getRootCaFromChainIfPossible(certificatesCollector); - return Stream.of(certificatesCollector, rootCa) - .flatMap(Collection::stream) - .collect(toUnmodifiableList()); + if (shouldResolveRootCa) { + List resolvedRootCa = getRootCaFromChainIfPossible(certificatesCollector); + return Stream.of(certificatesCollector, resolvedRootCa) + .flatMap(Collection::stream) + .collect(toUnmodifiableList()); + } + + return Collections.unmodifiableList(certificatesCollector); } else { return Collections.emptyList(); } @@ -223,4 +224,35 @@ protected PasswordAuthentication getPasswordAuthentication() { } } + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private Proxy proxy = null; + private PasswordAuthentication passwordAuthentication = null; + private boolean shouldResolveRootCa = true; + + public Builder withProxy(Proxy proxy) { + this.proxy = proxy; + return this; + } + + public Builder withProxyPasswordAuthentication(PasswordAuthentication passwordAuthentication) { + this.passwordAuthentication = passwordAuthentication; + return this; + } + + public Builder withResolvedRootCa(boolean shouldResolveRootCa) { + this.shouldResolveRootCa = shouldResolveRootCa; + return this; + } + + public CertificateExtractingClient build() { + return new CertificateExtractingClient(shouldResolveRootCa, proxy, passwordAuthentication); + } + + } + } diff --git a/sslcontext-kickstart/src/main/java/nl/altindag/ssl/util/CertificateUtils.java b/sslcontext-kickstart/src/main/java/nl/altindag/ssl/util/CertificateUtils.java index a9f03ff7..c7750b3b 100644 --- a/sslcontext-kickstart/src/main/java/nl/altindag/ssl/util/CertificateUtils.java +++ b/sslcontext-kickstart/src/main/java/nl/altindag/ssl/util/CertificateUtils.java @@ -275,15 +275,24 @@ public static List getSystemTrustedCertificates() { } public static List getCertificatesFromExternalSource(String url) { - return CertificateExtractorUtils.getInstance().getCertificateFromExternalSource(url); + return CertificateExtractingClient.getInstance().get(url); } public static List getCertificatesFromExternalSource(Proxy proxy, String url) { - return new CertificateExtractorUtils(proxy).getCertificateFromExternalSource(url); + return CertificateExtractingClient.builder() + .withResolvedRootCa(true) + .withProxy(proxy) + .build() + .get(url); } public static List getCertificatesFromExternalSource(Proxy proxy, PasswordAuthentication passwordAuthentication, String url) { - return new CertificateExtractorUtils(proxy, passwordAuthentication).getCertificateFromExternalSource(url); + return CertificateExtractingClient.builder() + .withResolvedRootCa(true) + .withProxy(proxy) + .withProxyPasswordAuthentication(passwordAuthentication) + .build() + .get(url); } public static List getCertificatesFromExternalSourceAsPem(String url) { @@ -324,20 +333,27 @@ public static Map> getCertificatesFromExternalSour } public static Map> getCertificatesFromExternalSources(Proxy proxy, List urls) { - CertificateExtractorUtils certificateExtractorUtils = new CertificateExtractorUtils(proxy); + CertificateExtractingClient client = CertificateExtractingClient.builder() + .withResolvedRootCa(true) + .withProxy(proxy) + .build(); return urls.stream() .distinct() - .map(url -> new AbstractMap.SimpleEntry<>(url, certificateExtractorUtils.getCertificateFromExternalSource(url))) + .map(url -> new AbstractMap.SimpleEntry<>(url, client.get(url))) .collect(Collectors.collectingAndThen(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue, (key1, key2) -> key1, LinkedHashMap::new), Collections::unmodifiableMap)); } public static Map> getCertificatesFromExternalSources(Proxy proxy, PasswordAuthentication passwordAuthentication, List urls) { - CertificateExtractorUtils certificateExtractorUtils = new CertificateExtractorUtils(proxy, passwordAuthentication); + CertificateExtractingClient client = CertificateExtractingClient.builder() + .withResolvedRootCa(true) + .withProxyPasswordAuthentication(passwordAuthentication) + .withProxy(proxy) + .build(); return urls.stream() .distinct() - .map(url -> new AbstractMap.SimpleEntry<>(url, certificateExtractorUtils.getCertificateFromExternalSource(url))) + .map(url -> new AbstractMap.SimpleEntry<>(url, client.get(url))) .collect(Collectors.collectingAndThen(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue, (key1, key2) -> key1, LinkedHashMap::new), Collections::unmodifiableMap)); } diff --git a/sslcontext-kickstart/src/test/java/nl/altindag/ssl/util/CertificateExtractorUtilsShould.java b/sslcontext-kickstart/src/test/java/nl/altindag/ssl/util/CertificateExtractingClientShould.java similarity index 75% rename from sslcontext-kickstart/src/test/java/nl/altindag/ssl/util/CertificateExtractorUtilsShould.java rename to sslcontext-kickstart/src/test/java/nl/altindag/ssl/util/CertificateExtractingClientShould.java index 7fb693a9..4d1bd9af 100644 --- a/sslcontext-kickstart/src/test/java/nl/altindag/ssl/util/CertificateExtractorUtilsShould.java +++ b/sslcontext-kickstart/src/test/java/nl/altindag/ssl/util/CertificateExtractingClientShould.java @@ -45,6 +45,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; @@ -58,13 +59,13 @@ * @author Hakan Altindag */ @ExtendWith(MockitoExtension.class) -class CertificateExtractorUtilsShould { +class CertificateExtractingClientShould { @Test void getRootCaIfPossibleReturnsJdkTrustedCaCertificateWhenNoAuthorityInfoAccessExtensionIsPresent() { List certificates = CertificateUtils.getCertificatesFromExternalSource("https://www.reddit.com/"); - try (MockedStatic mockedStatic = mockStatic(CertificateExtractorUtils.class, invocation -> { + try (MockedStatic mockedStatic = mockStatic(CertificateExtractingClient.class, invocation -> { Method method = invocation.getMethod(); if ("getRootCaFromAuthorityInfoAccessExtensionIfPresent".equals(method.getName())) { return Collections.emptyList(); @@ -72,7 +73,7 @@ void getRootCaIfPossibleReturnsJdkTrustedCaCertificateWhenNoAuthorityInfoAccessE return invocation.callRealMethod(); } })) { - CertificateExtractorUtils victim = spy(CertificateExtractorUtils.getInstance()); + CertificateExtractingClient victim = spy(CertificateExtractingClient.getInstance()); X509Certificate certificate = certificates.get(certificates.size() - 1); List rootCaCertificate = victim.getRootCaIfPossible(certificate); @@ -86,7 +87,7 @@ void getRootCaIfPossibleReturnsJdkTrustedCaCertificateWhenNoAuthorityInfoAccessE void getRootCaIfPossibleReturnsEmptyListWhenNoAuthorityInfoAccessExtensionIsPresentAndNoMatching() { List certificates = CertificateUtils.getCertificatesFromExternalSource("https://www.reddit.com/"); - try (MockedStatic mockedStatic = mockStatic(CertificateExtractorUtils.class, invocation -> { + try (MockedStatic mockedStatic = mockStatic(CertificateExtractingClient.class, invocation -> { Method method = invocation.getMethod(); if ("getRootCaFromAuthorityInfoAccessExtensionIfPresent".equals(method.getName()) || "getRootCaFromJdkTrustedCertificates".equals(method.getName())) { return Collections.emptyList(); @@ -94,7 +95,7 @@ void getRootCaIfPossibleReturnsEmptyListWhenNoAuthorityInfoAccessExtensionIsPres return invocation.callRealMethod(); } })) { - CertificateExtractorUtils victim = spy(CertificateExtractorUtils.getInstance()); + CertificateExtractingClient victim = spy(CertificateExtractingClient.getInstance()); doReturn(Collections.emptyList()) .when(victim) @@ -109,21 +110,32 @@ void getRootCaIfPossibleReturnsEmptyListWhenNoAuthorityInfoAccessExtensionIsPres } } + @Test + void rootCaIsNotResolvedWhenDisabled() { + CertificateExtractingClient client = spy(CertificateExtractingClient.builder() + .withResolvedRootCa(false) + .build()); + + client.get("https://www.reddit.com/"); + + verify(client, times(0)).getRootCaFromChainIfPossible(anyList()); + } + @Test void getRootCaFromChainIfPossibleReturnsEmptyListWhenNoCertificatesHaveBeenProvided() { - List rootCa = CertificateExtractorUtils.getInstance().getRootCaFromChainIfPossible(Collections.emptyList()); + List rootCa = CertificateExtractingClient.getInstance().getRootCaFromChainIfPossible(Collections.emptyList()); assertThat(rootCa).isEmpty(); } @Test void getRootCaFromAuthorityInfoAccessExtensionIfPresentReturnsEmptyListWhenCertificateIsNotInstanceOfX509CertImpl() { - List rootCa = CertificateExtractorUtils.getInstance().getRootCaFromAuthorityInfoAccessExtensionIfPresent(mock(X509Certificate.class)); + List rootCa = CertificateExtractingClient.getInstance().getRootCaFromAuthorityInfoAccessExtensionIfPresent(mock(X509Certificate.class)); assertThat(rootCa).isEmpty(); } @Test void throwsGenericCertificateExceptionWhenGetCertificatesFromRemoteFileFails() throws MalformedURLException { - CertificateExtractorUtils victim = CertificateExtractorUtils.getInstance(); + CertificateExtractingClient victim = CertificateExtractingClient.getInstance(); URI uri = mock(URI.class); doThrow(new MalformedURLException("KABOOM!!!")) @@ -140,20 +152,23 @@ void reUseExistingUnsafeSslSocketFactory() throws CertificateException, NoSuchAl X509Certificate intermediateCertificate = mock(X509Certificate.class); doNothing().when(intermediateCertificate).verify(any()); - List certificatesFromRemoteFile = CertificateExtractorUtils.getInstance().getCertificatesFromRemoteFile(uri, intermediateCertificate); + List certificatesFromRemoteFile = CertificateExtractingClient.getInstance().getCertificatesFromRemoteFile(uri, intermediateCertificate); assertThat(certificatesFromRemoteFile).isNotEmpty(); } @Test void extractCertificatesWithProxyAndAuthentication() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { - CertificateExtractorUtils certificateExtractorUtilsWithoutProxy = CertificateExtractorUtils.getInstance(); - List certificates = certificateExtractorUtilsWithoutProxy.getCertificateFromExternalSource("https://google.com"); + CertificateExtractingClient certificateExtractingClientWithoutProxy = CertificateExtractingClient.getInstance(); + List certificates = certificateExtractingClientWithoutProxy.get("https://google.com"); assertThat(certificates).isNotEmpty(); Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("my-custom-host", 8081)); - CertificateExtractorUtils certificateExtractorUtilsWithProxy = new CertificateExtractorUtils(proxy); + CertificateExtractingClient certificateExtractingClientWithProxy = CertificateExtractingClient.builder() + .withProxy(proxy) + .withResolvedRootCa(true) + .build(); - assertThatThrownBy(() -> certificateExtractorUtilsWithProxy.getCertificateFromExternalSource("https://google.com")) + assertThatThrownBy(() -> certificateExtractingClientWithProxy.get("https://google.com")) .isInstanceOf(GenericIOException.class) .hasMessage("Failed getting certificate from: [https://google.com]") .hasRootCauseInstanceOf(UnknownHostException.class) @@ -163,9 +178,13 @@ void extractCertificatesWithProxyAndAuthentication() throws NoSuchMethodExceptio ArgumentCaptor authenticatorCaptor = ArgumentCaptor.forClass(Authenticator.class); PasswordAuthentication passwordAuthentication = new PasswordAuthentication("foo", "bar".toCharArray()); - CertificateExtractorUtils certificateExtractorUtilsWithProxyAndAuthentication = new CertificateExtractorUtils(proxy, passwordAuthentication); + CertificateExtractingClient certificateExtractingClientWithProxyAndAuthentication = CertificateExtractingClient.builder() + .withProxy(proxy) + .withProxyPasswordAuthentication(passwordAuthentication) + .withResolvedRootCa(true) + .build(); - assertThatThrownBy(() -> certificateExtractorUtilsWithProxyAndAuthentication.getCertificateFromExternalSource("https://google.com")) + assertThatThrownBy(() -> certificateExtractingClientWithProxyAndAuthentication.get("https://google.com")) .isInstanceOf(GenericIOException.class) .hasMessage("Failed getting certificate from: [https://google.com]") .hasRootCauseInstanceOf(UnknownHostException.class) diff --git a/sslcontext-kickstart/src/test/java/nl/altindag/ssl/util/CertificateUtilsShould.java b/sslcontext-kickstart/src/test/java/nl/altindag/ssl/util/CertificateUtilsShould.java index 88e23413..cd09b53f 100644 --- a/sslcontext-kickstart/src/test/java/nl/altindag/ssl/util/CertificateUtilsShould.java +++ b/sslcontext-kickstart/src/test/java/nl/altindag/ssl/util/CertificateUtilsShould.java @@ -195,213 +195,213 @@ void loadOneLinerContainingMultipleCertificate() { @Test void useExistingInstanceOfCertificateExtractorUtilsWhenOnlyUsingUrl() { - CertificateExtractorUtils certificateExtractorUtils = mock(CertificateExtractorUtils.class); - when(certificateExtractorUtils.getCertificateFromExternalSource(anyString())).thenReturn(Collections.emptyList()); + CertificateExtractingClient certificateExtractingClient = mock(CertificateExtractingClient.class); + when(certificateExtractingClient.get(anyString())).thenReturn(Collections.emptyList()); - try (MockedStatic mockedStatic = mockStatic(CertificateExtractorUtils.class, invocationOnMock -> { + try (MockedStatic mockedStatic = mockStatic(CertificateExtractingClient.class, invocationOnMock -> { if ("getInstance".equals(invocationOnMock.getMethod().getName())) { - return certificateExtractorUtils; + return certificateExtractingClient; } else { return invocationOnMock.callRealMethod(); } })) { CertificateUtils.getCertificatesFromExternalSourceAsPem("https://github.com"); - mockedStatic.verify(CertificateExtractorUtils::getInstance, times(1)); + mockedStatic.verify(CertificateExtractingClient::getInstance, times(1)); } } @Test void createAnInstanceOfCertificateExtractorUtilsWithProxyDetailsWhenGetCertificatesFromExternalSource() { - Map> constructorArgs = new HashMap<>(); - try (MockedStatic mockedStatic = mockStatic(CertificateExtractorUtils.class, InvocationOnMock::callRealMethod); - MockedConstruction mockedConstruction = mockConstruction(CertificateExtractorUtils.class, + Map> constructorArgs = new HashMap<>(); + try (MockedStatic mockedStatic = mockStatic(CertificateExtractingClient.class, InvocationOnMock::callRealMethod); + MockedConstruction mockedConstruction = mockConstruction(CertificateExtractingClient.class, (mock, context) -> constructorArgs.put(mock, new ArrayList<>(context.arguments())))) { Proxy proxy = mock(Proxy.class); CertificateUtils.getCertificatesFromExternalSource(proxy, "https://github.com"); - List constructed = mockedConstruction.constructed(); + List constructed = mockedConstruction.constructed(); assertThat(constructed).hasSize(1); - CertificateExtractorUtils certificateExtractorUtils = constructed.get(0); - assertThat(constructorArgs.get(certificateExtractorUtils)).containsExactly(proxy); - mockedStatic.verify(CertificateExtractorUtils::getInstance, times(0)); + CertificateExtractingClient certificateExtractingClient = constructed.get(0); + assertThat(constructorArgs.get(certificateExtractingClient)).contains(true, proxy, null); + mockedStatic.verify(CertificateExtractingClient::getInstance, times(0)); } } @Test void createAnInstanceOfCertificateExtractorUtilsWithProxyDetailsAndPasswordAuthenticationWhenGetCertificatesFromExternalSource() { - Map> constructorArgs = new HashMap<>(); - try (MockedStatic mockedStatic = mockStatic(CertificateExtractorUtils.class, InvocationOnMock::callRealMethod); - MockedConstruction mockedConstruction = mockConstruction(CertificateExtractorUtils.class, + Map> constructorArgs = new HashMap<>(); + try (MockedStatic mockedStatic = mockStatic(CertificateExtractingClient.class, InvocationOnMock::callRealMethod); + MockedConstruction mockedConstruction = mockConstruction(CertificateExtractingClient.class, (mock, context) -> constructorArgs.put(mock, new ArrayList<>(context.arguments())))) { Proxy proxy = mock(Proxy.class); PasswordAuthentication passwordAuthentication = mock(PasswordAuthentication.class); CertificateUtils.getCertificatesFromExternalSource(proxy, passwordAuthentication, "https://github.com"); - List constructed = mockedConstruction.constructed(); + List constructed = mockedConstruction.constructed(); assertThat(constructed).hasSize(1); - CertificateExtractorUtils certificateExtractorUtils = constructed.get(0); - assertThat(constructorArgs.get(certificateExtractorUtils)).containsExactly(proxy, passwordAuthentication); - mockedStatic.verify(CertificateExtractorUtils::getInstance, times(0)); + CertificateExtractingClient certificateExtractingClient = constructed.get(0); + assertThat(constructorArgs.get(certificateExtractingClient)).contains(true, proxy, passwordAuthentication); + mockedStatic.verify(CertificateExtractingClient::getInstance, times(0)); } } @Test void createAnInstanceOfCertificateExtractorUtilsWithProxyDetailsWhenGetCertificatesFromExternalSourceAsPem() { - Map> constructorArgs = new HashMap<>(); - try (MockedStatic mockedStatic = mockStatic(CertificateExtractorUtils.class, InvocationOnMock::callRealMethod); - MockedConstruction mockedConstruction = mockConstruction(CertificateExtractorUtils.class, + Map> constructorArgs = new HashMap<>(); + try (MockedStatic mockedStatic = mockStatic(CertificateExtractingClient.class, InvocationOnMock::callRealMethod); + MockedConstruction mockedConstruction = mockConstruction(CertificateExtractingClient.class, (mock, context) -> constructorArgs.put(mock, new ArrayList<>(context.arguments())))) { Proxy proxy = mock(Proxy.class); CertificateUtils.getCertificatesFromExternalSourceAsPem(proxy, "https://github.com"); - List constructed = mockedConstruction.constructed(); + List constructed = mockedConstruction.constructed(); assertThat(constructed).hasSize(1); - CertificateExtractorUtils certificateExtractorUtils = constructed.get(0); - assertThat(constructorArgs.get(certificateExtractorUtils)).containsExactly(proxy); - mockedStatic.verify(CertificateExtractorUtils::getInstance, times(0)); + CertificateExtractingClient certificateExtractingClient = constructed.get(0); + assertThat(constructorArgs.get(certificateExtractingClient)).contains(true, proxy, null); + mockedStatic.verify(CertificateExtractingClient::getInstance, times(0)); } } @Test void createAnInstanceOfCertificateExtractorUtilsWithProxyDetailsAndPasswordAuthenticationWhenGetCertificatesFromExternalSourceAsPem() { - Map> constructorArgs = new HashMap<>(); - try (MockedStatic mockedStatic = mockStatic(CertificateExtractorUtils.class, InvocationOnMock::callRealMethod); - MockedConstruction mockedConstruction = mockConstruction(CertificateExtractorUtils.class, + Map> constructorArgs = new HashMap<>(); + try (MockedStatic mockedStatic = mockStatic(CertificateExtractingClient.class, InvocationOnMock::callRealMethod); + MockedConstruction mockedConstruction = mockConstruction(CertificateExtractingClient.class, (mock, context) -> constructorArgs.put(mock, new ArrayList<>(context.arguments())))) { Proxy proxy = mock(Proxy.class); PasswordAuthentication passwordAuthentication = mock(PasswordAuthentication.class); CertificateUtils.getCertificatesFromExternalSourceAsPem(proxy, passwordAuthentication, "https://github.com"); - List constructed = mockedConstruction.constructed(); + List constructed = mockedConstruction.constructed(); assertThat(constructed).hasSize(1); - CertificateExtractorUtils certificateExtractorUtils = constructed.get(0); - assertThat(constructorArgs.get(certificateExtractorUtils)).containsExactly(proxy, passwordAuthentication); - mockedStatic.verify(CertificateExtractorUtils::getInstance, times(0)); + CertificateExtractingClient certificateExtractingClient = constructed.get(0); + assertThat(constructorArgs.get(certificateExtractingClient)).contains(true, proxy, passwordAuthentication); + mockedStatic.verify(CertificateExtractingClient::getInstance, times(0)); } } @Test void createAnInstanceOfCertificateExtractorUtilsWithProxyDetailsWhenGetCertificatesFromExternalSources() { - Map> constructorArgs = new HashMap<>(); - try (MockedStatic mockedStatic = mockStatic(CertificateExtractorUtils.class, InvocationOnMock::callRealMethod); - MockedConstruction mockedConstruction = mockConstruction(CertificateExtractorUtils.class, + Map> constructorArgs = new HashMap<>(); + try (MockedStatic mockedStatic = mockStatic(CertificateExtractingClient.class, InvocationOnMock::callRealMethod); + MockedConstruction mockedConstruction = mockConstruction(CertificateExtractingClient.class, (mock, context) -> constructorArgs.put(mock, new ArrayList<>(context.arguments())))) { Proxy proxy = mock(Proxy.class); CertificateUtils.getCertificatesFromExternalSources(proxy, "https://github.com", "https://stackoverflow.com"); - List constructed = mockedConstruction.constructed(); + List constructed = mockedConstruction.constructed(); assertThat(constructed).hasSize(1); - CertificateExtractorUtils certificateExtractorUtils = constructed.get(0); - assertThat(constructorArgs.get(certificateExtractorUtils)).containsExactly(proxy); - mockedStatic.verify(CertificateExtractorUtils::getInstance, times(0)); + CertificateExtractingClient certificateExtractingClient = constructed.get(0); + assertThat(constructorArgs.get(certificateExtractingClient)).contains(true, proxy, null); + mockedStatic.verify(CertificateExtractingClient::getInstance, times(0)); } } @Test void createAnInstanceOfCertificateExtractorUtilsWithProxyDetailsAndPasswordAuthenticationWhenGetCertificatesFromExternalSources() { - Map> constructorArgs = new HashMap<>(); - try (MockedStatic mockedStatic = mockStatic(CertificateExtractorUtils.class, InvocationOnMock::callRealMethod); - MockedConstruction mockedConstruction = mockConstruction(CertificateExtractorUtils.class, + Map> constructorArgs = new HashMap<>(); + try (MockedStatic mockedStatic = mockStatic(CertificateExtractingClient.class, InvocationOnMock::callRealMethod); + MockedConstruction mockedConstruction = mockConstruction(CertificateExtractingClient.class, (mock, context) -> constructorArgs.put(mock, new ArrayList<>(context.arguments())))) { Proxy proxy = mock(Proxy.class); PasswordAuthentication passwordAuthentication = mock(PasswordAuthentication.class); CertificateUtils.getCertificatesFromExternalSources(proxy, passwordAuthentication, "https://github.com", "https://stackoverflow.com"); - List constructed = mockedConstruction.constructed(); + List constructed = mockedConstruction.constructed(); assertThat(constructed).hasSize(1); - CertificateExtractorUtils certificateExtractorUtils = constructed.get(0); - assertThat(constructorArgs.get(certificateExtractorUtils)).containsExactly(proxy, passwordAuthentication); - mockedStatic.verify(CertificateExtractorUtils::getInstance, times(0)); + CertificateExtractingClient certificateExtractingClient = constructed.get(0); + assertThat(constructorArgs.get(certificateExtractingClient)).contains(true, proxy, passwordAuthentication); + mockedStatic.verify(CertificateExtractingClient::getInstance, times(0)); } } @Test void createAnInstanceOfCertificateExtractorUtilsWithProxyDetailsWhenGetCertificatesFromExternalSourcesAsPem() { - Map> constructorArgs = new HashMap<>(); - try (MockedStatic mockedStatic = mockStatic(CertificateExtractorUtils.class, InvocationOnMock::callRealMethod); - MockedConstruction mockedConstruction = mockConstruction(CertificateExtractorUtils.class, + Map> constructorArgs = new HashMap<>(); + try (MockedStatic mockedStatic = mockStatic(CertificateExtractingClient.class, InvocationOnMock::callRealMethod); + MockedConstruction mockedConstruction = mockConstruction(CertificateExtractingClient.class, (mock, context) -> constructorArgs.put(mock, new ArrayList<>(context.arguments())))) { Proxy proxy = mock(Proxy.class); CertificateUtils.getCertificatesFromExternalSourcesAsPem(proxy, "https://github.com", "https://stackoverflow.com"); - List constructed = mockedConstruction.constructed(); + List constructed = mockedConstruction.constructed(); assertThat(constructed).hasSize(1); - CertificateExtractorUtils certificateExtractorUtils = constructed.get(0); - assertThat(constructorArgs.get(certificateExtractorUtils)).containsExactly(proxy); - mockedStatic.verify(CertificateExtractorUtils::getInstance, times(0)); + CertificateExtractingClient certificateExtractingClient = constructed.get(0); + assertThat(constructorArgs.get(certificateExtractingClient)).contains(true, proxy, null); + mockedStatic.verify(CertificateExtractingClient::getInstance, times(0)); } } @Test void createAnInstanceOfCertificateExtractorUtilsWithProxyDetailsWhenGetCertificatesFromExternalSourcesAsPemAndUrlsAsList() { - Map> constructorArgs = new HashMap<>(); - try (MockedStatic mockedStatic = mockStatic(CertificateExtractorUtils.class, InvocationOnMock::callRealMethod); - MockedConstruction mockedConstruction = mockConstruction(CertificateExtractorUtils.class, + Map> constructorArgs = new HashMap<>(); + try (MockedStatic mockedStatic = mockStatic(CertificateExtractingClient.class, InvocationOnMock::callRealMethod); + MockedConstruction mockedConstruction = mockConstruction(CertificateExtractingClient.class, (mock, context) -> constructorArgs.put(mock, new ArrayList<>(context.arguments())))) { Proxy proxy = mock(Proxy.class); CertificateUtils.getCertificatesFromExternalSourcesAsPem(proxy, Arrays.asList("https://github.com", "https://stackoverflow.com")); - List constructed = mockedConstruction.constructed(); + List constructed = mockedConstruction.constructed(); assertThat(constructed).hasSize(1); - CertificateExtractorUtils certificateExtractorUtils = constructed.get(0); - assertThat(constructorArgs.get(certificateExtractorUtils)).containsExactly(proxy); - mockedStatic.verify(CertificateExtractorUtils::getInstance, times(0)); + CertificateExtractingClient certificateExtractingClient = constructed.get(0); + assertThat(constructorArgs.get(certificateExtractingClient)).contains(true, proxy, null); + mockedStatic.verify(CertificateExtractingClient::getInstance, times(0)); } } @Test void createAnInstanceOfCertificateExtractorUtilsWithProxyDetailsAndPasswordAuthenticationWhenGetCertificatesFromExternalSourcesAsPem() { - Map> constructorArgs = new HashMap<>(); - try (MockedStatic mockedStatic = mockStatic(CertificateExtractorUtils.class, InvocationOnMock::callRealMethod); - MockedConstruction mockedConstruction = mockConstruction(CertificateExtractorUtils.class, + Map> constructorArgs = new HashMap<>(); + try (MockedStatic mockedStatic = mockStatic(CertificateExtractingClient.class, InvocationOnMock::callRealMethod); + MockedConstruction mockedConstruction = mockConstruction(CertificateExtractingClient.class, (mock, context) -> constructorArgs.put(mock, new ArrayList<>(context.arguments())))) { Proxy proxy = mock(Proxy.class); PasswordAuthentication passwordAuthentication = mock(PasswordAuthentication.class); CertificateUtils.getCertificatesFromExternalSourcesAsPem(proxy, passwordAuthentication, "https://github.com", "https://stackoverflow.com"); - List constructed = mockedConstruction.constructed(); + List constructed = mockedConstruction.constructed(); assertThat(constructed).hasSize(1); - CertificateExtractorUtils certificateExtractorUtils = constructed.get(0); - assertThat(constructorArgs.get(certificateExtractorUtils)).containsExactly(proxy, passwordAuthentication); - mockedStatic.verify(CertificateExtractorUtils::getInstance, times(0)); + CertificateExtractingClient certificateExtractingClient = constructed.get(0); + assertThat(constructorArgs.get(certificateExtractingClient)).contains(true, proxy, passwordAuthentication); + mockedStatic.verify(CertificateExtractingClient::getInstance, times(0)); } } @Test void createAnInstanceOfCertificateExtractorUtilsWithProxyDetailsAndPasswordAuthenticationWhenGetCertificatesFromExternalSourcesAsPemAndUrlsAsList() { - Map> constructorArgs = new HashMap<>(); - try (MockedStatic mockedStatic = mockStatic(CertificateExtractorUtils.class, InvocationOnMock::callRealMethod); - MockedConstruction mockedConstruction = mockConstruction(CertificateExtractorUtils.class, + Map> constructorArgs = new HashMap<>(); + try (MockedStatic mockedStatic = mockStatic(CertificateExtractingClient.class, InvocationOnMock::callRealMethod); + MockedConstruction mockedConstruction = mockConstruction(CertificateExtractingClient.class, (mock, context) -> constructorArgs.put(mock, new ArrayList<>(context.arguments())))) { Proxy proxy = mock(Proxy.class); PasswordAuthentication passwordAuthentication = mock(PasswordAuthentication.class); CertificateUtils.getCertificatesFromExternalSourcesAsPem(proxy, passwordAuthentication, Arrays.asList("https://github.com", "https://stackoverflow.com")); - List constructed = mockedConstruction.constructed(); + List constructed = mockedConstruction.constructed(); assertThat(constructed).hasSize(1); - CertificateExtractorUtils certificateExtractorUtils = constructed.get(0); - assertThat(constructorArgs.get(certificateExtractorUtils)).containsExactly(proxy, passwordAuthentication); - mockedStatic.verify(CertificateExtractorUtils::getInstance, times(0)); + CertificateExtractingClient certificateExtractingClient = constructed.get(0); + assertThat(constructorArgs.get(certificateExtractingClient)).contains(true, proxy, passwordAuthentication); + mockedStatic.verify(CertificateExtractingClient::getInstance, times(0)); } }