mirror of https://github.com/tasks/tasks
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
106 lines
3.9 KiB
Kotlin
106 lines
3.9 KiB
Kotlin
package org.tasks.caldav
|
|
|
|
import android.content.Context
|
|
import at.bitfire.cert4android.CustomCertManager
|
|
import at.bitfire.dav4jvm.BasicDigestAuthHandler
|
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
|
import kotlinx.coroutines.Dispatchers
|
|
import kotlinx.coroutines.withContext
|
|
import okhttp3.Authenticator
|
|
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
|
import okhttp3.Interceptor
|
|
import okhttp3.OkHttpClient
|
|
import okhttp3.internal.tls.OkHostnameVerifier
|
|
import org.tasks.DebugNetworkInterceptor
|
|
import org.tasks.billing.Inventory
|
|
import org.tasks.data.CaldavAccount
|
|
import org.tasks.preferences.Preferences
|
|
import org.tasks.security.KeyStoreEncryption
|
|
import java.util.concurrent.TimeUnit
|
|
import javax.inject.Inject
|
|
import javax.net.ssl.SSLContext
|
|
|
|
class CaldavClientProvider @Inject constructor(
|
|
@ApplicationContext private val context: Context,
|
|
private val encryption: KeyStoreEncryption,
|
|
private val preferences: Preferences,
|
|
private val interceptor: DebugNetworkInterceptor,
|
|
private val inventory: Inventory
|
|
) {
|
|
suspend fun forUrl(
|
|
url: String?,
|
|
username: String? = null,
|
|
password: String? = null,
|
|
token: String? = null): CaldavClient {
|
|
val auth = getAuthInterceptor(username = username, password = password, token = token)
|
|
val customCertManager = newCertManager()
|
|
return CaldavClient(
|
|
this,
|
|
customCertManager,
|
|
createHttpClient(auth, customCertManager),
|
|
url?.toHttpUrlOrNull()
|
|
)
|
|
}
|
|
|
|
suspend fun forAccount(account: CaldavAccount, url: String? = account.url): CaldavClient {
|
|
val auth = getAuthInterceptor(account)
|
|
val customCertManager = newCertManager()
|
|
return CaldavClient(
|
|
this,
|
|
customCertManager,
|
|
createHttpClient(auth, customCertManager),
|
|
url?.toHttpUrlOrNull()
|
|
)
|
|
}
|
|
|
|
private suspend fun newCertManager() = withContext(Dispatchers.Default) {
|
|
CustomCertManager(context)
|
|
}
|
|
|
|
private fun getAuthInterceptor(
|
|
account: CaldavAccount? = null,
|
|
username: String? = account?.username,
|
|
password: String? = account?.getPassword(encryption),
|
|
token: String? = null
|
|
): Interceptor? {
|
|
return when {
|
|
account?.isTasksOrg == true ->
|
|
account.password
|
|
?.let { encryption.decrypt(it) }
|
|
?.let { TokenInterceptor(it, inventory) }
|
|
username?.isNotBlank() == true && password?.isNotBlank() == true ->
|
|
BasicDigestAuthHandler(null, username, password)
|
|
token?.isNotBlank() == true ->
|
|
TokenInterceptor(token, inventory)
|
|
else -> null
|
|
}
|
|
}
|
|
|
|
private fun createHttpClient(auth: Interceptor?, customCertManager: CustomCertManager, foreground: Boolean = false): OkHttpClient {
|
|
customCertManager.appInForeground = foreground
|
|
val hostnameVerifier = customCertManager.hostnameVerifier(OkHostnameVerifier)
|
|
val sslContext = SSLContext.getInstance("TLS")
|
|
sslContext.init(null, arrayOf(customCertManager), null)
|
|
val builder = OkHttpClient()
|
|
.newBuilder()
|
|
.cookieJar(MemoryCookieStore())
|
|
.followRedirects(false)
|
|
.followSslRedirects(true)
|
|
.sslSocketFactory(sslContext.socketFactory, customCertManager)
|
|
.hostnameVerifier(hostnameVerifier)
|
|
.connectTimeout(15, TimeUnit.SECONDS)
|
|
.writeTimeout(30, TimeUnit.SECONDS)
|
|
.readTimeout(120, TimeUnit.SECONDS)
|
|
auth?.let {
|
|
builder.addNetworkInterceptor(it)
|
|
if (it is Authenticator) {
|
|
builder.authenticator(it)
|
|
}
|
|
}
|
|
if (preferences.isFlipperEnabled) {
|
|
interceptor.apply(builder)
|
|
}
|
|
|
|
return builder.build()
|
|
}
|
|
} |