Tentative self signed ssl support #141
@ -144,6 +144,7 @@ class LoginActivity : AppCompatActivity(), DIAware {
|
||||
repository.refreshLoginInformation(url, login, password)
|
||||
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
repository.updateApiInformation()
|
||||
AmineB marked this conversation as resolved
Outdated
|
||||
val result = repository.login()
|
||||
if (result) {
|
||||
val (errorFetching, displaySelfossOnly) = repository.shouldBeSelfossInstance()
|
||||
|
@ -29,12 +29,16 @@ kotlin {
|
||||
sourceSets {
|
||||
val commonMain by getting {
|
||||
dependencies {
|
||||
implementation("io.ktor:ktor-client-core:2.2.4")
|
||||
AmineB
commented
Please revert this Please revert this
davidoskky
commented
Do you mean the whole version upgrade? Do you mean the whole version upgrade?
AmineB
commented
Yes please Yes please
|
||||
implementation("io.ktor:ktor-client-content-negotiation:2.2.4")
|
||||
implementation("io.ktor:ktor-serialization-kotlinx-json:2.2.4")
|
||||
implementation("io.ktor:ktor-client-logging:2.2.4")
|
||||
val ktorVersion = "2.3.2"
|
||||
|
||||
implementation("io.ktor:ktor-client-core:$ktorVersion")
|
||||
implementation("io.ktor:ktor-client-content-negotiation:$ktorVersion")
|
||||
implementation("io.ktor:ktor-serialization-kotlinx-json:$ktorVersion")
|
||||
implementation("io.ktor:ktor-client-logging:$ktorVersion")
|
||||
implementation("io.ktor:ktor-client-auth:$ktorVersion")
|
||||
implementation("io.ktor:ktor-client-cio:$ktorVersion")
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0")
|
||||
implementation("io.ktor:ktor-client-auth:2.2.4")
|
||||
|
||||
implementation("org.jsoup:jsoup:1.15.4")
|
||||
|
||||
//Dependency Injection
|
||||
|
@ -0,0 +1,17 @@
|
||||
package bou.amine.apps.readerforselfossv2.rest
|
||||
|
||||
import io.ktor.client.engine.cio.CIOEngineConfig
|
||||
import java.security.cert.X509Certificate
|
||||
import javax.net.ssl.X509TrustManager
|
||||
|
||||
class NaiveTrustManager : X509TrustManager {
|
||||
override fun checkClientTrusted(chain: Array<out X509Certificate>?, authType: String?) {}
|
||||
|
||||
override fun checkServerTrusted(chain: Array<out X509Certificate>?, authType: String?) {}
|
||||
|
||||
override fun getAcceptedIssuers(): Array<out X509Certificate> = arrayOf()
|
||||
}
|
||||
|
||||
actual fun setupInsecureHTTPEngine(config: CIOEngineConfig) {
|
||||
config.https.trustManager = NaiveTrustManager()
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
package bou.amine.apps.readerforselfossv2.rest
|
||||
|
||||
import bou.amine.apps.readerforselfossv2.service.AppSettingsService
|
||||
import io.github.aakira.napier.Napier
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.engine.okhttp.OkHttp
|
||||
import io.ktor.client.plugins.HttpRequestRetry
|
||||
import io.ktor.client.plugins.HttpTimeout
|
||||
import io.ktor.client.plugins.cache.HttpCache
|
||||
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
|
||||
import io.ktor.client.plugins.cookies.HttpCookies
|
||||
import io.ktor.client.plugins.logging.LogLevel
|
||||
import io.ktor.client.plugins.logging.Logger
|
||||
import io.ktor.client.plugins.logging.Logging
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.serialization.kotlinx.json.json
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.serialization.json.Json
|
||||
import okhttp3.OkHttpClient
|
||||
import org.apache.http.conn.ssl.AllowAllHostnameVerifier
|
||||
import java.security.cert.X509Certificate
|
||||
import javax.net.ssl.SSLContext
|
||||
import javax.net.ssl.X509TrustManager
|
||||
|
||||
class NaiveTrustManager : X509TrustManager {
|
||||
override fun checkClientTrusted(chain: Array<out X509Certificate>?, authType: String?) {}
|
||||
|
||||
override fun checkServerTrusted(chain: Array<out X509Certificate>?, authType: String?) {}
|
||||
|
||||
override fun getAcceptedIssuers(): Array<out X509Certificate> = arrayOf()
|
||||
}
|
||||
|
||||
actual fun createHttpClient(
|
||||
appSettingsService: AppSettingsService,
|
||||
api: SelfossApi
|
||||
) =
|
||||
HttpClient(OkHttp) {
|
||||
if (appSettingsService.getSelfSigned()) {
|
||||
engine {
|
||||
val trustManager = NaiveTrustManager()
|
||||
val sslContext = SSLContext.getInstance("TLS").apply {
|
||||
init(null, arrayOf(trustManager), null)
|
||||
}
|
||||
preconfigured = OkHttpClient().newBuilder()
|
||||
.sslSocketFactory(
|
||||
sslSocketFactory = sslContext.socketFactory,
|
||||
trustManager = trustManager
|
||||
)
|
||||
.hostnameVerifier(AllowAllHostnameVerifier())
|
||||
.build()
|
||||
}
|
||||
}
|
||||
install(ContentNegotiation) {
|
||||
install(HttpCache)
|
||||
json(Json {
|
||||
prettyPrint = true
|
||||
isLenient = true
|
||||
ignoreUnknownKeys = true
|
||||
})
|
||||
}
|
||||
install(Logging) {
|
||||
logger = object : Logger {
|
||||
override fun log(message: String) {
|
||||
Napier.d(message, tag = "LogApiCalls")
|
||||
}
|
||||
}
|
||||
level = LogLevel.INFO
|
||||
}
|
||||
install(HttpTimeout) {
|
||||
requestTimeoutMillis = appSettingsService.getApiTimeout()
|
||||
}
|
||||
install(HttpCookies)
|
||||
install(HttpRequestRetry) {
|
||||
maxRetries = 2
|
||||
retryIf { _, response ->
|
||||
response.status == HttpStatusCode.Forbidden && api.shouldHavePostLogin() && api.hasLoginInfo()
|
||||
}
|
||||
modifyRequest {
|
||||
Napier.i("Will modify", tag = "HttpSend")
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
Napier.i("Will login", tag = "HttpSend")
|
||||
api.login()
|
||||
Napier.i("Did login", tag = "HttpSend")
|
||||
}
|
||||
}
|
||||
}
|
||||
expectSuccess = false
|
||||
}
|
@ -4,22 +4,83 @@ import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
||||
import bou.amine.apps.readerforselfossv2.model.StatusAndData
|
||||
import bou.amine.apps.readerforselfossv2.model.SuccessResponse
|
||||
import bou.amine.apps.readerforselfossv2.service.AppSettingsService
|
||||
import io.github.aakira.napier.Napier
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.engine.cio.CIO
|
||||
import io.ktor.client.engine.cio.CIOEngineConfig
|
||||
import io.ktor.client.plugins.HttpRequestRetry
|
||||
import io.ktor.client.plugins.HttpTimeout
|
||||
import io.ktor.client.plugins.auth.providers.BasicAuthCredentials
|
||||
import io.ktor.client.plugins.cache.HttpCache
|
||||
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
|
||||
import io.ktor.client.plugins.cookies.HttpCookies
|
||||
import io.ktor.client.plugins.logging.LogLevel
|
||||
import io.ktor.client.plugins.logging.Logger
|
||||
import io.ktor.client.plugins.logging.Logging
|
||||
import io.ktor.client.request.get
|
||||
import io.ktor.client.request.headers
|
||||
import io.ktor.client.request.parameter
|
||||
import io.ktor.client.statement.HttpResponse
|
||||
import io.ktor.http.HttpHeaders
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.http.Parameters
|
||||
import io.ktor.serialization.kotlinx.json.json
|
||||
import io.ktor.util.encodeBase64
|
||||
import io.ktor.utils.io.charsets.Charsets
|
||||
import io.ktor.utils.io.core.toByteArray
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.serialization.json.Json
|
||||
|
||||
expect fun createHttpClient(
|
||||
expect fun setupInsecureHTTPEngine(config: CIOEngineConfig)
|
||||
|
||||
fun createHttpClient(
|
||||
appSettingsService: AppSettingsService,
|
||||
api: SelfossApi
|
||||
AmineB
commented
Why is this needed ? Can't it be replaced by Why is this needed ? Can't it be replaced by `this` ?
|
||||
): HttpClient
|
||||
) =
|
||||
HttpClient(CIO) {
|
||||
if (appSettingsService.getSelfSigned()) {
|
||||
engine {
|
||||
setupInsecureHTTPEngine(this)
|
||||
}
|
||||
}
|
||||
install(ContentNegotiation) {
|
||||
install(HttpCache)
|
||||
json(Json {
|
||||
prettyPrint = true
|
||||
isLenient = true
|
||||
ignoreUnknownKeys = true
|
||||
})
|
||||
}
|
||||
install(Logging) {
|
||||
logger = object : Logger {
|
||||
override fun log(message: String) {
|
||||
Napier.d(message, tag = "LogApiCalls")
|
||||
}
|
||||
}
|
||||
level = LogLevel.INFO
|
||||
}
|
||||
install(HttpTimeout) {
|
||||
requestTimeoutMillis = appSettingsService.getApiTimeout()
|
||||
}
|
||||
install(HttpCookies)
|
||||
install(HttpRequestRetry) {
|
||||
maxRetries = 2
|
||||
retryIf { _, response ->
|
||||
response.status == HttpStatusCode.Forbidden && api.shouldHavePostLogin() && api.hasLoginInfo()
|
||||
}
|
||||
modifyRequest {
|
||||
Napier.i("Will modify", tag = "HttpSend")
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
Napier.i("Will login", tag = "HttpSend")
|
||||
api.login()
|
||||
Napier.i("Did login", tag = "HttpSend")
|
||||
}
|
||||
}
|
||||
}
|
||||
expectSuccess = false
|
||||
}
|
||||
|
||||
class SelfossApi(private val appSettingsService: AppSettingsService) {
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user
repository.updateApiInformation()
is called ingoToMain
which is called at line 152. This should not be needed.Updating the api information is required for the following login call. This can probably be fixed by restructuring the code of the login page.