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

Commit 5e8f56c8 authored by Mohammed Althaf T's avatar Mohammed Althaf T 😊
Browse files

Merge branch '3511-main-ose-murena_login3' into 'main-ose'

Add OAuth login and logout for Murena.

See merge request !171
parents 9aa59b88 de730672
Loading
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -5,6 +5,11 @@ stages:
  - build

before_script:
  - echo MURENA_CLIENT_ID=$MURENA_CLIENT_ID >> local.properties
  - echo MURENA_REDIRECT_URI=$MURENA_REDIRECT_URI >> local.properties
  - echo MURENA_LOGOUT_REDIRECT_URI=$MURENA_LOGOUT_REDIRECT_URI >> local.properties
  - echo MURENA_BASE_URL=$MURENA_BASE_URL_STAGING >> local.properties
  - echo MURENA_DISCOVERY_END_POINT=$MURENA_DISCOVERY_END_POINT_STAGING >> local.properties
  - export JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64
  - export GRADLE_USER_HOME=$(pwd)/.gradle
  - chmod +x ./gradlew
+23 −0
Original line number Diff line number Diff line
@@ -69,6 +69,19 @@ android {
            if (versionName != null) {
                setProperty("archivesBaseName", "AccountManager-$versionName")
            }

            buildConfigField("String", "MURENA_CLIENT_ID", "\"${retrieveKey("MURENA_CLIENT_ID")}\"")
            buildConfigField("String", "MURENA_REDIRECT_URI", "\"${retrieveKey("MURENA_REDIRECT_URI")}\"")
            buildConfigField("String", "MURENA_LOGOUT_REDIRECT_URI", "\"${retrieveKey("MURENA_LOGOUT_REDIRECT_URI")}\"")
            buildConfigField("String", "MURENA_BASE_URL", "\"${retrieveKey("MURENA_BASE_URL")}\"")
            buildConfigField("String", "MURENA_DISCOVERY_END_POINT", "\"${retrieveKey("MURENA_DISCOVERY_END_POINT")}\"")

            manifestPlaceholders.putAll(
                mapOf<String, Any>(
                    "murenaAuthRedirectScheme" to retrieveKey("MURENA_REDIRECT_URI"),
                    "murenaAuthLogoutRedirectScheme" to retrieveKey("MURENA_LOGOUT_REDIRECT_URI")
                )
            )
        }
    }

@@ -168,6 +181,15 @@ android {
    }
}

fun retrieveKey(keyName: String): String {
    val properties = Properties().apply {
        load(rootProject.file("local.properties").inputStream())
    }

    return properties.getProperty(keyName)
        ?: throw GradleException("$keyName property not found in local.properties file")
}

ksp {
    arg("room.schemaLocation", "$projectDir/schemas")
}
@@ -257,6 +279,7 @@ dependencies {
    implementation(libs.commons.lang)

    // e-Specific dependencies
    implementation(libs.androidx.runtime.livedata)
    implementation(libs.elib)
    implementation(libs.ez.vcard)
    implementation(libs.synctools) {
+2 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import at.bitfire.vcard4android.GroupMethod
import dagger.Lazy
import dagger.hilt.android.qualifiers.ApplicationContext
import foundation.e.accountmanager.AccountTypes
import foundation.e.accountmanager.pref.AuthStatePrefUtils
import foundation.e.accountmanager.utils.AccountHelper
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.awaitClose
@@ -75,6 +76,7 @@ class AccountRepository @Inject constructor(

        // create Android account
        val userData = AccountSettings.initialUserData(credentials)
        AuthStatePrefUtils.saveAuthState(context, account, credentials?.authState?.jsonSerializeString())
        logger.log(Level.INFO, "Creating Android account with initial config", arrayOf(account, userData))

        if (!SystemAccountUtils.createAccount(context, account, userData, credentials?.password))
+6 −1
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import dagger.hilt.android.qualifiers.ApplicationContext
import foundation.e.accountmanager.AccountTypes
import foundation.e.accountmanager.pref.AuthStatePrefUtils
import net.openid.appauth.AuthState
import java.util.Collections
import java.util.logging.Level
@@ -72,7 +73,7 @@ class AccountSettings @AssistedInject constructor(
            *AccountTypes.getAccountTypes().toTypedArray(),
            "at.bitfire.davdroid.test"      // R.strings.account_type_test in androidTest
        )
        if (!allowedAccountTypes.contains(account.type))
        if (!allowedAccountTypes.any { it == account.type })
            throw IllegalArgumentException("Invalid account type for AccountSettings(): ${account.type}")

        // synchronize because account migration must only be run one time
@@ -131,6 +132,7 @@ class AccountSettings @AssistedInject constructor(

    fun updateAuthState(authState: AuthState) {
        accountManager.setAndVerifyUserData(account, KEY_AUTH_STATE, authState.jsonSerializeString())
        AuthStatePrefUtils.saveAuthState(context, account, authState.jsonSerializeString())
    }

    /**
@@ -156,6 +158,7 @@ class AccountSettings @AssistedInject constructor(
            SyncDataType.CONTACTS -> KEY_SYNC_INTERVAL_ADDRESSBOOKS
            SyncDataType.EVENTS -> KEY_SYNC_INTERVAL_CALENDARS
            SyncDataType.TASKS -> KEY_SYNC_INTERVAL_TASKS
            else -> KEY_SYNC_INTERVAL_DEFAULT
        }
        val seconds = accountManager.getUserData(account, key)?.toLong()
        return when (seconds) {
@@ -176,6 +179,7 @@ class AccountSettings @AssistedInject constructor(
            SyncDataType.CONTACTS -> KEY_SYNC_INTERVAL_ADDRESSBOOKS
            SyncDataType.EVENTS -> KEY_SYNC_INTERVAL_CALENDARS
            SyncDataType.TASKS -> KEY_SYNC_INTERVAL_TASKS
            else -> KEY_SYNC_INTERVAL_DEFAULT
        }
        val newValue = seconds ?: SYNC_INTERVAL_MANUALLY
        accountManager.setAndVerifyUserData(account, key, newValue.toString())
@@ -362,6 +366,7 @@ class AccountSettings @AssistedInject constructor(

        /** Stores the tasks sync interval (in seconds) so that it can be set again when the provider is switched */
        const val KEY_SYNC_INTERVAL_TASKS = "sync_interval_tasks"
        const val KEY_SYNC_INTERVAL_DEFAULT = "sync_interval_default"

        const val KEY_USERNAME = "user_name"
        const val KEY_CERTIFICATE_ALIAS = "certificate_alias"
+12 −1
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@ import at.bitfire.davdroid.resource.LocalAddressBookStore
import at.bitfire.davdroid.settings.AccountSettings
import at.bitfire.davdroid.sync.adapter.SyncFrameworkIntegration
import at.bitfire.davdroid.sync.worker.SyncWorkerManager
import foundation.e.accountmanager.Authority
import kotlinx.coroutines.runBlocking
import javax.inject.Inject
import javax.inject.Provider
@@ -92,6 +93,11 @@ class AutomaticSyncManager @Inject constructor(
                SyncDataType.CONTACTS -> throw IllegalStateException()  // handled above
                SyncDataType.EVENTS -> CalendarContract.AUTHORITY
                SyncDataType.TASKS -> tasksAppManager.get().currentProvider()?.authority
                SyncDataType.EMAIL -> Authority.Email.authority
                SyncDataType.MEDIA -> Authority.Media.authority
                SyncDataType.NOTES -> Authority.Notes.authority
                SyncDataType.APP_DATA -> Authority.AppData.authority
                SyncDataType.E_DRIVE -> Authority.MeteredEDrive.authority
            }
            if (authority != null && syncInterval != null) {
                // enable given authority, but completely disable all other possible authorities
@@ -132,7 +138,12 @@ class AutomaticSyncManager @Inject constructor(
        val serviceType = when (dataType) {
            SyncDataType.CONTACTS -> Service.TYPE_CARDDAV
            SyncDataType.EVENTS,
            SyncDataType.TASKS -> Service.TYPE_CALDAV
            SyncDataType.TASKS,
            SyncDataType.EMAIL,
            SyncDataType.MEDIA,
            SyncDataType.NOTES,
            SyncDataType.APP_DATA,
            SyncDataType.E_DRIVE -> Service.TYPE_CALDAV
        }
        val hasService = runBlocking { serviceRepository.getByAccountAndType(account.name, serviceType) != null }

Loading