diff --git a/app/src/demo/assets/user_list_success_2.json b/app/src/demo/assets/user_list_success_2.json index 5165c09..6933b49 100644 --- a/app/src/demo/assets/user_list_success_2.json +++ b/app/src/demo/assets/user_list_success_2.json @@ -6,8 +6,8 @@ "first": "Pablo", "last": "Garcia" }, - "email": "Pablogarcia.sg@gmail.com", - "phone": "618 42 69 62" + "email": "Pablo.Garcia@gmail.com", + "phone": "666 66 66 66" }, { "name": { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ceacb63..ff6d519 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -15,8 +15,8 @@ android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" - android:usesCleartextTraffic="true" android:theme="@style/Theme.Mocks" + android:networkSecurityConfig="@xml/network_security_config" tools:targetApi="31"> + + + + + + + + \ No newline at end of file diff --git a/mock/build.gradle b/mock/build.gradle index f86da0d..8bf8f84 100644 --- a/mock/build.gradle +++ b/mock/build.gradle @@ -34,6 +34,7 @@ android { dependencies { implementation "com.squareup.okhttp3:mockwebserver:4.9.3" + implementation "com.squareup.okhttp3:okhttp-tls:4.9.3" implementation "com.google.dagger:dagger:2.44" kapt "com.google.dagger:dagger-compiler:2.44" diff --git a/mock/src/main/java/com/telefonica/mock/MockApiClient.kt b/mock/src/main/java/com/telefonica/mock/MockApiClient.kt index 2d7d7f4..a7abe8d 100644 --- a/mock/src/main/java/com/telefonica/mock/MockApiClient.kt +++ b/mock/src/main/java/com/telefonica/mock/MockApiClient.kt @@ -8,6 +8,9 @@ import okhttp3.mockwebserver.MockResponse import okhttp3.mockwebserver.MockWebServer import okhttp3.mockwebserver.RecordedRequest import java.net.InetAddress +import okhttp3.tls.HandshakeCertificates +import okhttp3.tls.HeldCertificate +import java.net.InetAddress import java.util.concurrent.TimeUnit import javax.inject.Inject @@ -35,7 +38,7 @@ open class MockApiClient @Inject constructor( } } - suspend fun startServer(inetAddress: InetAddress = InetAddress.getByName("localhost"), port: Int = 0) { + internal suspend fun startServer(inetAddress: InetAddress, port: Int = 0) { withContext(coroutineDispatcher) { runCatching { mockWebServer.start(inetAddress = inetAddress, port = port) @@ -59,10 +62,25 @@ open class MockApiClient @Inject constructor( enqueuedAnswers.addAll(mocks) } - fun setUp() { + internal fun setUp(address: InetAddress, enableSsl: Boolean) { mockWebServer.dispatcher = dispatcher + if (enableSsl) { + enableHttpsFor(mockWebServer, address) + } + } + + private fun enableHttpsFor(mockWebServer: MockWebServer, address: InetAddress) { + val serverCertificates = HandshakeCertificates.Builder() + .heldCertificate(buildCertificate(address.canonicalHostName)) + .build() + mockWebServer.useHttps(serverCertificates.sslSocketFactory(), false) } + private fun buildCertificate(altName: String): HeldCertificate = HeldCertificate.Builder() + .addSubjectAlternativeName(altName) + .build() + + private fun getMockResponse(mockFiles: List): MockResponse = when (mockFiles.isEmpty()) { true -> MockResponse().setResponseCode(NOT_FOUND_ERROR) false -> { diff --git a/mock/src/main/java/com/telefonica/mock/MockHelper.kt b/mock/src/main/java/com/telefonica/mock/MockHelper.kt index bc2bc4e..1ed557c 100644 --- a/mock/src/main/java/com/telefonica/mock/MockHelper.kt +++ b/mock/src/main/java/com/telefonica/mock/MockHelper.kt @@ -28,8 +28,15 @@ class MockHelper(context: Context) { suspend fun getBaseUrl(): String = mockApiClient.getBaseUrl() - suspend fun setUp(inetAddress: InetAddress = InetAddress.getByName("localhost"), port: Int = 0) { - mockApiClient.setUp() + suspend fun setUp( + inetAddress: InetAddress = InetAddress.getByName("localhost"), + port: Int = 0, + enableSsl: Boolean = false, + ) { + mockApiClient.setUp( + address = inetAddress, + enableSsl = enableSsl, + ) mockApiClient.startServer(inetAddress, port) } diff --git a/mock/src/main/java/com/telefonica/mock/cert/AllCertsAllowedBuilderUpdater.kt b/mock/src/main/java/com/telefonica/mock/cert/AllCertsAllowedBuilderUpdater.kt new file mode 100644 index 0000000..e1f905d --- /dev/null +++ b/mock/src/main/java/com/telefonica/mock/cert/AllCertsAllowedBuilderUpdater.kt @@ -0,0 +1,47 @@ +package com.telefonica.mock.cert + +import android.annotation.SuppressLint +import okhttp3.OkHttpClient +import java.security.KeyManagementException +import java.security.NoSuchAlgorithmException +import java.security.cert.CertificateException +import javax.net.ssl.HostnameVerifier +import javax.net.ssl.SSLContext +import javax.net.ssl.TrustManager +import javax.net.ssl.X509TrustManager + +object AllCertsAllowedBuilderUpdater { + + @SuppressLint("CustomX509TrustManager") + @JvmStatic + fun update(builder: OkHttpClient.Builder) { + val trustAllCerts = arrayOf(object : X509TrustManager { + @SuppressLint("TrustAllX509TrustManager") + @Throws(CertificateException::class) + override fun checkClientTrusted(chain: Array, authType: String) { + } + + @SuppressLint("TrustAllX509TrustManager") + @Throws(CertificateException::class) + override fun checkServerTrusted(chain: Array, authType: String) { + } + + override fun getAcceptedIssuers(): Array { + return arrayOf() + } + }) + + try { + val sslContext = SSLContext.getInstance("SSL") + sslContext.init(null, trustAllCerts, java.security.SecureRandom()) + val sslSocketFactory = sslContext.socketFactory + builder.sslSocketFactory(sslSocketFactory, trustAllCerts[0] as X509TrustManager) + builder.hostnameVerifier(HostnameVerifier { _, _ -> true }) + } catch (e: NoSuchAlgorithmException) { + throw RuntimeException(e) + } catch (e: KeyManagementException) { + throw RuntimeException(e) + } + } + +}