Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e5c96011 authored by Fahim Salam Chowdhury's avatar Fahim Salam Chowdhury 👽
Browse files

feat: impl murena cookie store

to pass & reserve cookies for DAV requests of murena account
parent 172366e6
Loading
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
/*
 * Copyright MURENA SAS 2024
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

package at.bitfire.davdroid.network

import android.accounts.Account
import android.content.Context
import at.bitfire.davdroid.R
import okhttp3.CookieJar

fun createCookieStore(context: Context? = null, account: Account? = null): CookieJar {
    if (context == null || account == null) {
        return MemoryCookieStore()
    }

    val murenaAccountType = context.getString(R.string.eelo_account_type)
    val murenaAddressBookAccountType = context.getString(R.string.account_type_eelo_address_book)

    if (account.type in listOf(murenaAccountType, murenaAddressBookAccountType)) {
        return MurenaCookieStore(context, account)
    }

    return MemoryCookieStore()
}
+2 −0
Original line number Diff line number Diff line
@@ -175,6 +175,8 @@ class HttpClient private constructor(
                authStateCallback = { authState: AuthState ->
                    updateCredentials(accountSettings, authState, credential.clientSecret)
                })

            cookieStore = createCookieStore(context, accountSettings.account)
        }

        private fun updateCredentials(
+76 −0
Original line number Diff line number Diff line
/*
 * Copyright MURENA SAS 2024
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

package at.bitfire.davdroid.network

import android.accounts.Account
import android.accounts.AccountManager
import android.content.Context
import at.bitfire.davdroid.settings.AccountSettings
import okhttp3.Cookie
import okhttp3.CookieJar
import okhttp3.HttpUrl

class MurenaCookieStore(context: Context, private val account: Account): CookieJar {

    private val accountManager = AccountManager.get(context.applicationContext)

    override fun loadForRequest(url: HttpUrl): List<Cookie> {
        return getCookieMap(url).values.filter {
            it.matches(url)
        }
    }

    override fun saveFromResponse(url: HttpUrl, cookies: List<Cookie>) {
        val cookieList = cookies.filter {
            it.expiresAt > System.currentTimeMillis()
        }

        if (cookieList.isEmpty()) {
            return
        }

        val cookieMap = getCookieMap(url)

        // replace old cookie with new one
        cookieList.forEach {
            cookieMap[it.name] = it
        }

        val cookieString = cookieMap.values.joinToString(separator = AccountSettings.COOKIE_SEPARATOR)
        accountManager.setUserData(account, AccountSettings.MURENA_COOKIE_KEY, cookieString)
    }

    private fun getCookieMap(url: HttpUrl): HashMap<String, Cookie> {
        val result = HashMap<String, Cookie>()

            val cookiesString = accountManager.getUserData(account, AccountSettings.MURENA_COOKIE_KEY)
                ?: return HashMap()

            val cookies = cookiesString.split(AccountSettings.COOKIE_SEPARATOR.toRegex()).dropLastWhile { it.isEmpty() }
                .toTypedArray()

            cookies.forEach {
               val cookie = Cookie.parse(url, it) ?: return@forEach

                if (cookie.expiresAt > System.currentTimeMillis()) {
                    result[cookie.name] = cookie
                }
            }

        return result
    }
}