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

Commit dacf43d8 authored by Nihar Thakkar's avatar Nihar Thakkar
Browse files

Use Android AccountManager to manage OAuth tokens, create mock /e/ account for testing

parent 0911c736
Loading
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -15,4 +15,6 @@ object Constants {
    const val DEFAULT_CALENDAR_SYNC_INTERVAL = 2 * 60L // 2 minutes
    const val DEFAULT_CONTACTS_SYNC_INTERVAL = 15 * 60L // 15 minutes

    const val AUTH_TOKEN_TYPE = "oauth2-access-token"

}
+33 −1
Original line number Diff line number Diff line
@@ -13,11 +13,14 @@ import android.content.Context
import android.content.Intent
import android.database.DatabaseUtils
import android.os.Bundle
import at.bitfire.davdroid.AccountSettings
import at.bitfire.davdroid.R
import at.bitfire.davdroid.log.Logger
import at.bitfire.davdroid.model.ServiceDB
import at.bitfire.davdroid.resource.LocalAddressBook
import at.bitfire.davdroid.ui.setup.LoginActivity
import net.openid.appauth.AuthState
import net.openid.appauth.AuthorizationService
import java.util.*
import java.util.logging.Level

@@ -117,7 +120,36 @@ class EeloAccountAuthenticatorService : Service(), OnAccountsUpdateListener {
        override fun getAuthTokenLabel(p0: String?) = null
        override fun confirmCredentials(p0: AccountAuthenticatorResponse?, p1: Account?, p2: Bundle?) = null
        override fun updateCredentials(p0: AccountAuthenticatorResponse?, p1: Account?, p2: String?, p3: Bundle?) = null
        override fun getAuthToken(p0: AccountAuthenticatorResponse?, p1: Account?, p2: String?, p3: Bundle?) = null
        override fun getAuthToken(response: AccountAuthenticatorResponse?, account: Account?, authTokenType: String?, options: Bundle?): Bundle {
            val accountManager = AccountManager.get(context)
            val authState = AuthState.jsonDeserialize(accountManager.getUserData(account, AccountSettings.KEY_AUTH_STATE))

            if (authState != null) {
                if (authState.needsTokenRefresh) {
                    val tokenRequest = authState.createTokenRefreshRequest()

                    AuthorizationService(context).performTokenRequest(tokenRequest) { tokenResponse, ex ->
                        authState.update(tokenResponse, ex)
                        val result = Bundle()
                        result.putString(AccountManager.KEY_ACCOUNT_NAME, account!!.name)
                        result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type)
                        result.putString(AccountManager.KEY_AUTHTOKEN, authState.accessToken)
                        response?.onResult(result)
                    }
                }
                else {
                    val result = Bundle()
                    result.putString(AccountManager.KEY_ACCOUNT_NAME, account!!.name)
                    result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type)
                    result.putString(AccountManager.KEY_AUTHTOKEN, authState.accessToken)
                    return result
                }
            }

            val result = Bundle()
            result.putInt(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION)
            return result
        }
        override fun hasFeatures(p0: AccountAuthenticatorResponse?, p1: Account?, p2: Array<out String>?) = null

    }
+34 −1
Original line number Diff line number Diff line
@@ -20,6 +20,10 @@ import at.bitfire.davdroid.resource.LocalAddressBook
import at.bitfire.davdroid.ui.setup.LoginActivity
import java.util.*
import java.util.logging.Level
import android.accounts.AccountManager
import at.bitfire.davdroid.AccountSettings
import net.openid.appauth.AuthState
import net.openid.appauth.AuthorizationService


/**
@@ -117,7 +121,36 @@ class GoogleAccountAuthenticatorService : Service(), OnAccountsUpdateListener {
        override fun getAuthTokenLabel(p0: String?) = null
        override fun confirmCredentials(p0: AccountAuthenticatorResponse?, p1: Account?, p2: Bundle?) = null
        override fun updateCredentials(p0: AccountAuthenticatorResponse?, p1: Account?, p2: String?, p3: Bundle?) = null
        override fun getAuthToken(p0: AccountAuthenticatorResponse?, p1: Account?, p2: String?, p3: Bundle?) = null
        override fun getAuthToken(response: AccountAuthenticatorResponse?, account: Account?, authTokenType: String?, options: Bundle?): Bundle {
            val accountManager = AccountManager.get(context)
            val authState = AuthState.jsonDeserialize(accountManager.getUserData(account, AccountSettings.KEY_AUTH_STATE))

            if (authState != null) {
                if (authState.needsTokenRefresh) {
                    val tokenRequest = authState.createTokenRefreshRequest()

                    AuthorizationService(context).performTokenRequest(tokenRequest) { tokenResponse, ex ->
                                authState.update(tokenResponse, ex)
                                val result = Bundle()
                                result.putString(AccountManager.KEY_ACCOUNT_NAME, account!!.name)
                                result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type)
                                result.putString(AccountManager.KEY_AUTHTOKEN, authState.accessToken)
                                response?.onResult(result)
                            }
                }
                else {
                    val result = Bundle()
                    result.putString(AccountManager.KEY_ACCOUNT_NAME, account!!.name)
                    result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type)
                    result.putString(AccountManager.KEY_AUTHTOKEN, authState.accessToken)
                    return result
                }
            }

            val result = Bundle()
            result.putInt(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION)
            return result
        }
        override fun hasFeatures(p0: AccountAuthenticatorResponse?, p1: Account?, p2: Array<out String>?) = null

    }
+3 −0
Original line number Diff line number Diff line
@@ -166,6 +166,9 @@ class AccountDetailsFragment : Fragment(), LoaderManager.LoaderCallbacks<CreateS
        val accountManager = AccountManager.get(activity)
        if (!accountManager.addAccountExplicitly(account, config.credentials.password, userData))
            return false
        if (!config.credentials.authState?.accessToken.isNullOrEmpty()) {
            accountManager.setAuthToken(account, Constants.AUTH_TOKEN_TYPE, config.credentials.authState!!.accessToken)
        }

        // add entries for account to service DB
        Logger.log.log(Level.INFO, "Writing account configuration to database", config)
+17 −0
Original line number Diff line number Diff line
package at.bitfire.davdroid.ui.setup


import android.accounts.Account
import android.accounts.AccountManager
import android.app.Activity
import android.app.PendingIntent
import android.content.Context
@@ -29,6 +31,8 @@ import java.util.HashMap
import java.util.logging.Level
import android.net.ConnectivityManager
import android.widget.Toast
import at.bitfire.davdroid.AccountSettings
import at.bitfire.davdroid.model.Credentials
import kotlinx.android.synthetic.main.fragment_eelo_authenticator.*


@@ -190,6 +194,19 @@ class EeloAuthenticatorFragment : Fragment(), AuthorizationService.TokenResponse
        progress_bar.visibility = View.GONE
        successful_oauth_text_view.visibility = View.VISIBLE

        val account = Account("user1@e.email", getString(R.string.eelo_account_type))

        val userData = AccountSettings.initialUserData(Credentials("user1@e.email",
                null, AuthState(), null))

        val accountManager = AccountManager.get(activity)
        if (!accountManager.addAccountExplicitly(account, null, userData)) {
            Toast.makeText(context, "Failed to create test account", Toast.LENGTH_LONG).show()
        }
        else {
            Toast.makeText(context, "Successfully created test account", Toast.LENGTH_LONG).show()
        }

        // TODO Get the userId for future requests
        //getAccountInfo()
    }