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

Commit f447141c authored by Jonathan Klee's avatar Jonathan Klee
Browse files

Introduce AuthDataProvider

parent 97280082
Loading
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -122,6 +122,18 @@ lintRelease:
      - app/build/reports/
      - build/reports/


publish-authdatalib:
  stage: publish
  needs: ["buildRelease"]
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
      when: manual
  script:
    - ./gradlew :auth-data-lib:build
    - ./gradlew :auth-data-lib:publish


pushToPrebuilt:
  stage: publish
  needs: ["buildRelease"]
+3 −1
Original line number Diff line number Diff line
@@ -159,7 +159,9 @@ allOpen {

dependencies {

    implementation project(':auth-data-lib')
    implementation project(':parental-control-data')

    // TODO: Add splitinstall-lib to a repo https://gitlab.e.foundation/e/os/backlog/-/issues/628
    api files('libs/splitinstall-lib.jar')

+11 −0
Original line number Diff line number Diff line
@@ -20,6 +20,10 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <permission
        android:name="foundation.e.apps.permission.AUTH_DATA_PROVIDER"
        android:protectionLevel="signature" />

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.GET_TASKS" />
@@ -167,6 +171,13 @@
        <receiver
            android:name=".install.splitinstall.SplitInstallBinder$SignInReceiver"
            android:exported="false" />

        <provider
            android:name="${applicationId}.microg.AuthDataProvider"
            android:authorities="${applicationId}.authdata.provider"
            android:readPermission="${applicationId}.permission.AUTH_DATA_PROVIDER"
            android:exported="true"/>

    </application>

</manifest>
 No newline at end of file
+119 −0
Original line number Diff line number Diff line
/*
 * Apps  Quickly and easily install Android apps onto your device!
 * Copyright (C) 2024  E FOUNDATION
 *
 * 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 foundation.e.apps.microg

import android.content.ContentProvider
import android.content.ContentValues
import android.content.pm.PackageManager
import android.database.Cursor
import android.database.MatrixCursor
import android.net.Uri
import dagger.hilt.EntryPoint
import dagger.hilt.InstallIn
import dagger.hilt.android.EntryPointAccessors
import dagger.hilt.components.SingletonComponent
import foundation.e.apps.authdata.AuthDataContract
import foundation.e.apps.data.preference.DataStoreManager

/**
 * Content provider dedicated to share the Google auth data with
 * other applications. Other applications need to own the following permission:
 * `foundation.e.apps.permission.AUTH_DATA_PROVIDER`
 */
class AuthDataProvider : ContentProvider() {

    @EntryPoint
    @InstallIn(SingletonComponent::class)
    interface DataStoreManagerEntryPoint {
        fun provideDataStoreManager(): DataStoreManager
    }

    private lateinit var dataStoreManager: DataStoreManager

    override fun onCreate(): Boolean {
        val context = context ?: return false

        val dataStoreEntryPoint = EntryPointAccessors.fromApplication(
            context.applicationContext,
            DataStoreManagerEntryPoint::class.java
        )

        dataStoreManager = dataStoreEntryPoint.provideDataStoreManager()
        return true
    }

    override fun query(uri: Uri, projection: Array<String>?, selection: String?,
                              selectionArgs: Array<String>?, sortOrder: String?): Cursor {

        if (context?.checkCallingOrSelfPermission(
                AUTH_DATA_PROVIDER_PERMISSION
        ) != PackageManager.PERMISSION_GRANTED) {
            throw SecurityException("Permission denied: $AUTH_DATA_PROVIDER_PERMISSION required")
        }

        val cursor = MatrixCursor(
            arrayOf(
                AuthDataContract.EMAIL_KEY,
                AuthDataContract.AUTH_TOKEN_KEY,
                AuthDataContract.GSF_ID_KEY,
                AuthDataContract.CONSISTENCY_TOKEN_KEY,
                AuthDataContract.DEVICE_CONFIG_TOKEN_KEY,
                AuthDataContract.EXPERIMENTS_CONFIG_TOKEN_KEY,
                AuthDataContract.DFE_COOKIE_KEY
            )
        )

        val row = cursor.newRow()
        dataStoreManager.getAuthData().let {
            row.add(AuthDataContract.EMAIL_KEY, it.email)
            row.add(AuthDataContract.AUTH_TOKEN_KEY, it.authToken)
            row.add(AuthDataContract.GSF_ID_KEY, it.gsfId)
            row.add(AuthDataContract.CONSISTENCY_TOKEN_KEY, it.deviceCheckInConsistencyToken)
            row.add(AuthDataContract.DEVICE_CONFIG_TOKEN_KEY, it.deviceConfigToken)
            row.add(AuthDataContract.EXPERIMENTS_CONFIG_TOKEN_KEY, it.experimentsConfigToken)
            row.add(AuthDataContract.DFE_COOKIE_KEY, it.dfeCookie)
        }

        cursor.setNotificationUri(context?.contentResolver, uri)

        return cursor
    }

    override fun update(uri: Uri, values: ContentValues?, selection: String?,
                               selectionArgs: Array<String>?): Int {
        throw UnsupportedOperationException("Update operation is not supported by the provider")
    }

    override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int {
        throw UnsupportedOperationException("Delete operation is not supported by the provider")
    }

    override fun getType(uri: Uri): String? {
        return "vnd.android.cursor.dir/vnd.foundation.e.apps.authdata.provider.strings";
    }

    override fun insert(uri: Uri, values: ContentValues?): Uri {
        throw UnsupportedOperationException("Insert operation is not supported by the provider")
    }

    companion object {
        const val AUTH_DATA_PROVIDER_PERMISSION = "foundation.e.apps.permission.AUTH_DATA_PROVIDER"
    }
}
+1 −0
Original line number Diff line number Diff line
/build
 No newline at end of file
Loading