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

Commit 3dc5f710 authored by Jonathan Klee's avatar Jonathan Klee
Browse files

feat(auth): add Google and Yahoo account flows

parent 1396f0fc
Loading
Loading
Loading
Loading
Loading
+167 −1
Original line number Diff line number Diff line
@@ -234,6 +234,172 @@
                android:resource="@xml/contacts"/>
        </service>

        <!-- account type "Google" -->
        <service
            android:name=".sync.account.GoogleAccountAuthenticatorService"
            android:exported="false">
            <intent-filter>
                <action android:name="android.accounts.AccountAuthenticator"/>
            </intent-filter>
            <meta-data
                android:name="android.accounts.AccountAuthenticator"
                android:resource="@xml/google_account_authenticator"/>
        </service>
        <service
            android:name=".sync.adapter.GoogleCalendarsSyncAdapterService"
            android:exported="true"
            tools:ignore="ExportedService">
            <intent-filter>
                <action android:name="android.content.SyncAdapter"/>
            </intent-filter>
            <meta-data
                android:name="android.content.SyncAdapter"
                android:resource="@xml/google_sync_calendars"/>
        </service>
        <service
            android:name=".sync.adapter.GoogleJtxSyncAdapterService"
            android:exported="true"
            tools:ignore="ExportedService">
            <intent-filter>
                <action android:name="android.content.SyncAdapter"/>
            </intent-filter>
            <meta-data
                android:name="android.content.SyncAdapter"
                android:resource="@xml/google_sync_notes"/>
        </service>
        <service
            android:name=".sync.adapter.GoogleOpenTasksSyncAdapterService"
            android:exported="true"
            tools:ignore="ExportedService">
            <intent-filter>
                <action android:name="android.content.SyncAdapter"/>
            </intent-filter>
            <meta-data
                android:name="android.content.SyncAdapter"
                android:resource="@xml/google_sync_opentasks"/>
        </service>
        <service
            android:name=".sync.adapter.GoogleTasksOrgSyncAdapterService"
            android:exported="true"
            tools:ignore="ExportedService">
            <intent-filter>
                <action android:name="android.content.SyncAdapter"/>
            </intent-filter>
            <meta-data
                android:name="android.content.SyncAdapter"
                android:resource="@xml/google_sync_tasks_org"/>
        </service>

        <!-- account type "Google Address book" -->
        <service
            android:name=".sync.account.GoogleAddressBookAuthenticatorService"
            android:exported="true"
            tools:ignore="ExportedService">
            <intent-filter>
                <action android:name="android.accounts.AccountAuthenticator"/>
            </intent-filter>
            <meta-data
                android:name="android.accounts.AccountAuthenticator"
                android:resource="@xml/account_authenticator_google_address_book"/>
        </service>
        <service
            android:name=".sync.adapter.GoogleContactsSyncAdapterService"
            android:exported="true"
            tools:ignore="ExportedService">
            <intent-filter>
                <action android:name="android.content.SyncAdapter"/>
            </intent-filter>
            <meta-data
                android:name="android.content.SyncAdapter"
                android:resource="@xml/google_sync_contacts"/>
            <meta-data
                android:name="android.provider.CONTACTS_STRUCTURE"
                android:resource="@xml/contacts"/>
        </service>

        <!-- account type "Yahoo" -->
        <service
            android:name=".sync.account.YahooAccountAuthenticatorService"
            android:exported="false">
            <intent-filter>
                <action android:name="android.accounts.AccountAuthenticator"/>
            </intent-filter>
            <meta-data
                android:name="android.accounts.AccountAuthenticator"
                android:resource="@xml/yahoo_account_authenticator"/>
        </service>
        <service
            android:name=".sync.adapter.YahooCalendarsSyncAdapterService"
            android:exported="true"
            tools:ignore="ExportedService">
            <intent-filter>
                <action android:name="android.content.SyncAdapter"/>
            </intent-filter>
            <meta-data
                android:name="android.content.SyncAdapter"
                android:resource="@xml/yahoo_sync_calendars"/>
        </service>
        <service
            android:name=".sync.adapter.YahooJtxSyncAdapterService"
            android:exported="true"
            tools:ignore="ExportedService">
            <intent-filter>
                <action android:name="android.content.SyncAdapter"/>
            </intent-filter>
            <meta-data
                android:name="android.content.SyncAdapter"
                android:resource="@xml/yahoo_sync_notes"/>
        </service>
        <service
            android:name=".sync.adapter.YahooOpenTasksSyncAdapterService"
            android:exported="true"
            tools:ignore="ExportedService">
            <intent-filter>
                <action android:name="android.content.SyncAdapter"/>
            </intent-filter>
            <meta-data
                android:name="android.content.SyncAdapter"
                android:resource="@xml/yahoo_sync_opentasks"/>
        </service>
        <service
            android:name=".sync.adapter.YahooTasksOrgSyncAdapterService"
            android:exported="true"
            tools:ignore="ExportedService">
            <intent-filter>
                <action android:name="android.content.SyncAdapter"/>
            </intent-filter>
            <meta-data
                android:name="android.content.SyncAdapter"
                android:resource="@xml/yahoo_sync_tasks_org"/>
        </service>

        <!-- account type "Yahoo Address book" -->
        <service
            android:name=".sync.account.YahooAddressBookAuthenticatorService"
            android:exported="true"
            tools:ignore="ExportedService">
            <intent-filter>
                <action android:name="android.accounts.AccountAuthenticator"/>
            </intent-filter>
            <meta-data
                android:name="android.accounts.AccountAuthenticator"
                android:resource="@xml/account_authenticator_yahoo_address_book"/>
        </service>
        <service
            android:name=".sync.adapter.YahooContactsSyncAdapterService"
            android:exported="true"
            tools:ignore="ExportedService">
            <intent-filter>
                <action android:name="android.content.SyncAdapter"/>
            </intent-filter>
            <meta-data
                android:name="android.content.SyncAdapter"
                android:resource="@xml/yahoo_sync_contacts"/>
            <meta-data
                android:name="android.provider.CONTACTS_STRUCTURE"
                android:resource="@xml/contacts"/>
        </service>

        <!-- UnifiedPush -->
        <service android:exported="false" android:name=".push.UnifiedPushService">
            <intent-filter>
+53 −0
Original line number Diff line number Diff line
/*
 * Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
 */

package at.bitfire.davdroid.network

import androidx.core.net.toUri
import net.openid.appauth.AuthorizationRequest
import net.openid.appauth.AuthorizationServiceConfiguration
import net.openid.appauth.ResponseTypeValues
import java.net.URI
import javax.inject.Inject

class OAuthYahoo @Inject constructor(
    private val oAuthIntegration: OAuthIntegration
) {

    private val SCOPES = arrayOf(
        "openid",
        "openid2",
        "profile",
        "email",
        "mail-w",
        "sdct-w",
        "ycal-w"
    )

    private val serviceConfig = AuthorizationServiceConfiguration(
        "https://api.login.yahoo.com/oauth2/request_auth".toUri(),
        "https://api.login.yahoo.com/oauth2/get_token".toUri()
    )

    fun baseUri(email: String): URI =
        URI("https", "caldav.calendar.yahoo.com", "/dav/$email", null)

    fun signIn(email: String?, locale: String?): AuthorizationRequest {
        val builder = AuthorizationRequest.Builder(
            serviceConfig,
            CLIENT_ID,
            ResponseTypeValues.CODE,
            oAuthIntegration.redirectUri
        )
        return builder
            .setScopes(*SCOPES)
            .setLoginHint(email)
            .setUiLocales(locale)
            .build()
    }

    companion object {
        private const val CLIENT_ID = "dj0yJmk9VEVzMWRyNHNtbzByJmQ9WVdrOWNHUklaalZKTXpJbWNHbzlORFkzTWpRNU9EZ3hPVFE0TXpBek1URXhNQT09JnM9Y29uc3VtZXJzZWNyZXQmeD04OQ--"
    }
}
+53 −0
Original line number Diff line number Diff line
/*
 * Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
 */
package at.bitfire.davdroid.sync.account

import android.accounts.AbstractAccountAuthenticator
import android.accounts.Account
import android.accounts.AccountAuthenticatorResponse
import android.accounts.AccountManager
import android.app.Service
import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.core.os.bundleOf
import at.bitfire.davdroid.ui.setup.LoginActivity

class GoogleAccountAuthenticatorService: Service() {

    private lateinit var accountAuthenticator: AccountAuthenticator

    override fun onCreate() {
        accountAuthenticator = AccountAuthenticator(this)
    }

    override fun onBind(intent: Intent?) =
        accountAuthenticator.iBinder.takeIf { intent?.action == AccountManager.ACTION_AUTHENTICATOR_INTENT }

    private class AccountAuthenticator(
        val context: Context
    ): AbstractAccountAuthenticator(context) {

        override fun addAccount(
            response: AccountAuthenticatorResponse?,
            accountType: String?,
            authTokenType: String?,
            requiredFeatures: Array<out String>?,
            options: Bundle?
        ): Bundle {
            val intent = Intent(context, LoginActivity::class.java)
            intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response)
            intent.putExtra(LoginActivity.EXTRA_GOOGLE_LOGIN_FLOW, true)
            return bundleOf(AccountManager.KEY_INTENT to intent)
        }

        override fun editProperties(response: AccountAuthenticatorResponse?, accountType: String?) = null
        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 hasFeatures(p0: AccountAuthenticatorResponse?, p1: Account?, p2: Array<out String>?) = null

    }
}
+46 −0
Original line number Diff line number Diff line
/*
 * Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
 */
package at.bitfire.davdroid.sync.account

import android.accounts.AbstractAccountAuthenticator
import android.accounts.Account
import android.accounts.AccountAuthenticatorResponse
import android.accounts.AccountManager
import android.app.Service
import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.core.os.bundleOf
import at.bitfire.davdroid.ui.AccountsActivity

class GoogleAddressBookAuthenticatorService: Service() {

    private lateinit var accountAuthenticator: AccountAuthenticator

    override fun onCreate() {
        accountAuthenticator = AccountAuthenticator(this)
    }

    override fun onBind(intent: Intent?) =
        accountAuthenticator.iBinder.takeIf { intent?.action == AccountManager.ACTION_AUTHENTICATOR_INTENT }

    private class AccountAuthenticator(
        val context: Context
    ): AbstractAccountAuthenticator(context) {

        override fun addAccount(response: AccountAuthenticatorResponse?, accountType: String?, authTokenType: String?, requiredFeatures: Array<String>?, options: Bundle?): Bundle {
            val intent = Intent(context, AccountsActivity::class.java)
            intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response)
            return bundleOf(AccountManager.KEY_INTENT to intent)
        }

        override fun editProperties(response: AccountAuthenticatorResponse?, accountType: String?) = null
        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 hasFeatures(p0: AccountAuthenticatorResponse?, p1: Account?, p2: Array<out String>?) = null

    }
}
+53 −0
Original line number Diff line number Diff line
/*
 * Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
 */
package at.bitfire.davdroid.sync.account

import android.accounts.AbstractAccountAuthenticator
import android.accounts.Account
import android.accounts.AccountAuthenticatorResponse
import android.accounts.AccountManager
import android.app.Service
import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.core.os.bundleOf
import at.bitfire.davdroid.ui.setup.LoginActivity

class YahooAccountAuthenticatorService: Service() {

    private lateinit var accountAuthenticator: AccountAuthenticator

    override fun onCreate() {
        accountAuthenticator = AccountAuthenticator(this)
    }

    override fun onBind(intent: Intent?) =
        accountAuthenticator.iBinder.takeIf { intent?.action == AccountManager.ACTION_AUTHENTICATOR_INTENT }

    private class AccountAuthenticator(
        val context: Context
    ): AbstractAccountAuthenticator(context) {

        override fun addAccount(
            response: AccountAuthenticatorResponse?,
            accountType: String?,
            authTokenType: String?,
            requiredFeatures: Array<out String>?,
            options: Bundle?
        ): Bundle {
            val intent = Intent(context, LoginActivity::class.java)
            intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response)
            intent.putExtra(LoginActivity.EXTRA_YAHOO_LOGIN_FLOW, true)
            return bundleOf(AccountManager.KEY_INTENT to intent)
        }

        override fun editProperties(response: AccountAuthenticatorResponse?, accountType: String?) = null
        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 hasFeatures(p0: AccountAuthenticatorResponse?, p1: Account?, p2: Array<out String>?) = null

    }
}
Loading