Separate cookie jars by username

pull/2298/head
Alex Baker 3 years ago
parent df2a7f8857
commit 1d58292a07

@ -127,7 +127,7 @@ class MicrosoftAuthenticationActivity : ComponentActivity() {
)
val userInfo = withContext(Dispatchers.IO) {
httpClientFactory
.newClient()
.newClient(foreground = false)
.newCall(
Request.Builder()
.url(discovery.userinfoEndpoint!!.toString())

@ -41,6 +41,7 @@ import org.tasks.data.CaldavDao
import org.tasks.databinding.ActivityCaldavAccountSettingsBinding
import org.tasks.dialogs.DialogBuilder
import org.tasks.dialogs.Linkify
import org.tasks.extensions.Context.cookiePersistor
import org.tasks.extensions.Context.openUri
import org.tasks.injection.ThemedInjectingAppCompatActivity
import org.tasks.security.KeyStoreEncryption
@ -59,7 +60,6 @@ abstract class BaseCaldavAccountSettingsActivity : ThemedInjectingAppCompatActiv
@Inject lateinit var taskDeleter: TaskDeleter
@Inject lateinit var inventory: Inventory
@Inject lateinit var firebase: Firebase
@Inject lateinit var cookiePersistor: CookiePersistor
protected var caldavAccount: CaldavAccount? = null
protected lateinit var binding: ActivityCaldavAccountSettingsBinding
@ -350,7 +350,7 @@ abstract class BaseCaldavAccountSettingsActivity : ThemedInjectingAppCompatActiv
}
protected open suspend fun removeAccount() {
cookiePersistor.clearSession(caldavAccount?.url)
cookiePersistor(caldavAccount?.username).clearSession(caldavAccount?.url)
taskDeleter.delete(caldavAccount!!)
setResult(Activity.RESULT_OK)
finish()

@ -74,7 +74,14 @@ class CaldavClientProvider @Inject constructor(
auth: Interceptor?,
foreground: Boolean = false,
): OkHttpClient {
return httpClientFactory.newClient(foreground = foreground) { builder ->
return httpClientFactory.newClient(
foreground = foreground,
cookieKey = when (auth) {
is BasicDigestAuthHandler -> auth.username
is TasksBasicAuth -> auth.user
else -> null
}
) { builder ->
builder
.connectTimeout(15, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)

@ -6,7 +6,7 @@ import okhttp3.Response
import org.tasks.billing.Inventory
class TasksBasicAuth(
user: String,
val user: String,
token: String,
private val inventory: Inventory
) : Interceptor {

@ -31,7 +31,7 @@ class EtebaseClientProvider @Inject constructor(
@Throws(KeyManagementException::class, NoSuchAlgorithmException::class)
suspend fun forUrl(url: String, username: String, password: String?, session: String? = null, foreground: Boolean = false): EtebaseClient = withContext(Dispatchers.IO) {
val httpClient = createHttpClient(foreground)
val httpClient = createHttpClient(foreground, username)
val client = Client.create(httpClient, url)
val etebase = session
?.let { Account.restore(client, it, null) }
@ -39,8 +39,11 @@ class EtebaseClientProvider @Inject constructor(
EtebaseClient(context, username, etebase, caldavDao)
}
private suspend fun createHttpClient(foreground: Boolean): OkHttpClient {
return httpClientFactory.newClient(foreground = foreground) { builder ->
private suspend fun createHttpClient(foreground: Boolean, cookieKey: String): OkHttpClient {
return httpClientFactory.newClient(
foreground = foreground,
cookieKey = cookieKey,
) { builder ->
builder
.connectTimeout(15, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)

@ -3,12 +3,14 @@ package org.tasks.extensions
import android.content.ActivityNotFoundException
import android.content.ContentResolver
import android.content.Context
import android.content.Context.MODE_PRIVATE
import android.content.Intent
import android.content.Intent.ACTION_VIEW
import android.net.Uri
import android.widget.Toast
import androidx.annotation.AnyRes
import androidx.browser.customtabs.CustomTabsIntent
import com.franmontiel.persistentcookiejar.persistence.SharedPrefsCookiePersistor
import org.tasks.R
object Context {
@ -55,4 +57,12 @@ object Context {
.authority(packageName)
.path(res.toString())
.build()
fun Context.cookiePersistor(key: String? = null) =
SharedPrefsCookiePersistor(
getSharedPreferences(
"CookiePersistence${key?.let { "_$it" } ?: ""}",
MODE_PRIVATE
)
)
}

@ -3,7 +3,6 @@ package org.tasks.http
import android.content.Context
import at.bitfire.cert4android.CustomCertManager
import at.bitfire.dav4jvm.BasicDigestAuthHandler
import com.franmontiel.persistentcookiejar.persistence.CookiePersistor
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
@ -14,6 +13,7 @@ import okhttp3.internal.tls.OkHostnameVerifier
import org.tasks.DebugNetworkInterceptor
import org.tasks.caldav.TasksCookieJar
import org.tasks.data.CaldavAccount
import org.tasks.extensions.Context.cookiePersistor
import org.tasks.preferences.Preferences
import org.tasks.security.KeyStoreEncryption
import org.tasks.sync.microsoft.MicrosoftService
@ -28,15 +28,20 @@ class HttpClientFactory @Inject constructor(
private val preferences: Preferences,
private val interceptor: DebugNetworkInterceptor,
private val encryption: KeyStoreEncryption,
private val cookiePersistor: CookiePersistor,
) {
suspend fun newClient(foreground: Boolean) = newClient(
foreground = foreground,
cookieKey = null,
block = {},
)
suspend fun newClient(
foreground: Boolean = false,
username: String? = null,
encryptedPassword: String? = null
): OkHttpClient {
val decrypted = encryptedPassword?.let { encryption.decrypt(it) }
return newClient(foreground = foreground) { builder ->
return newClient(foreground = foreground, cookieKey = username) { builder ->
if (!username.isNullOrBlank() && !decrypted.isNullOrBlank()) {
val auth = BasicDigestAuthHandler(null, username, decrypted)
builder.addNetworkInterceptor(auth)
@ -47,6 +52,7 @@ class HttpClientFactory @Inject constructor(
suspend fun newClient(
foreground: Boolean = false,
cookieKey: String? = null,
block: (OkHttpClient.Builder) -> Unit = {}
): OkHttpClient {
val customCertManager = withContext(Dispatchers.Default) {
@ -63,7 +69,7 @@ class HttpClientFactory @Inject constructor(
.sslSocketFactory(sslContext.socketFactory, customCertManager)
.hostnameVerifier(hostnameVerifier)
.addInterceptor(UserAgentInterceptor)
.cookieJar(TasksCookieJar(persistor = cookiePersistor))
.cookieJar(TasksCookieJar(persistor = context.cookiePersistor(cookieKey)))
block(builder)
@ -86,7 +92,7 @@ class HttpClientFactory @Inject constructor(
if (!authState.isAuthorized) {
throw RuntimeException("Needs authentication")
}
val client = newClient {
val client = newClient(cookieKey = account.username) {
it.addInterceptor { chain ->
chain.proceed(
chain.request().newBuilder()
@ -107,4 +113,4 @@ class HttpClientFactory @Inject constructor(
const val URL_MICROSOFT = "https://graph.microsoft.com"
val MEDIA_TYPE_JSON = "application/json".toMediaType()
}
}
}

@ -3,8 +3,6 @@ package org.tasks.injection
import android.app.NotificationManager
import android.content.Context
import androidx.appcompat.app.AppCompatDelegate
import com.franmontiel.persistentcookiejar.persistence.CookiePersistor
import com.franmontiel.persistentcookiejar.persistence.SharedPrefsCookiePersistor
import com.todoroo.astrid.dao.Database
import dagger.Module
import dagger.Provides
@ -123,8 +121,4 @@ class ApplicationModule {
@Provides
fun providesNotificationManager(@ApplicationContext context: Context) =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
@Provides
fun cookiePersistor(@ApplicationContext context: Context): CookiePersistor =
SharedPrefsCookiePersistor(context)
}
Loading…
Cancel
Save