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

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

6287-Finalize_OIDC_support_for_murena_account

parent ca79e5ca
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -9,6 +9,9 @@ before_script:
  - echo MURENA_CLIENT_ID=$MURENA_CLIENT_ID >> local.properties
  - echo MURENA_CLIENT_SECRET=$MURENA_CLIENT_SECRET >> 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 >> local.properties
  - echo MURENA_DISCOVERY_END_POINT=$MURENA_DISCOVERY_END_POINT >> local.properties
  - echo GOOGLE_CLIENT_ID=$GOOGLE_CLIENT_ID >> local.properties
  - echo GOOGLE_REDIRECT_URI=$GOOGLE_REDIRECT_URI >> local.properties
  - echo YAHOO_CLIENT_ID=$YAHOO_CLIENT_ID >> local.properties
+7 −2
Original line number Diff line number Diff line
@@ -111,6 +111,9 @@ android {
        buildConfigField "String", "MURENA_CLIENT_ID", "\"${retrieveKey("MURENA_CLIENT_ID")}\""
        buildConfigField "String", "MURENA_CLIENT_SECRET", "\"${retrieveKey("MURENA_CLIENT_SECRET")}\""
        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")}\""

        buildConfigField "String", "GOOGLE_CLIENT_ID", "\"${retrieveKey("GOOGLE_CLIENT_ID")}\""
        buildConfigField "String", "GOOGLE_REDIRECT_URI", "\"${retrieveKey("GOOGLE_REDIRECT_URI")}\""
@@ -120,7 +123,9 @@ android {
	    manifestPlaceholders = [
                'appAuthRedirectScheme':  applicationId,
                "googleAuthRedirectScheme": retrieveKey("GOOGLE_REDIRECT_URI"),
                "murenaAuthRedirectScheme": retrieveKey("MURENA_REDIRECT_URI")
                "murenaAuthRedirectScheme": retrieveKey("MURENA_REDIRECT_URI"),

                "murenaAuthLogoutRedirectScheme":retrieveKey("MURENA_LOGOUT_REDIRECT_URI")
        ]
    }

@@ -219,7 +224,7 @@ dependencies {
    implementation "commons-httpclient:commons-httpclient:3.1@jar" // remove after entire switch to lib v2
    implementation 'org.apache.jackrabbit:jackrabbit-webdav:2.13.5' // remove after entire switch to lib v2
    implementation 'com.google.code.gson:gson:2.10.1'
    implementation("foundation.e:Nextcloud-Android-Library:1.0.6-release") {
    implementation("foundation.e:Nextcloud-Android-Library:1.0.7-u2.17-release") {
        exclude group: 'com.gitlab.bitfireAT', module: 'dav4jvm'
        exclude group: 'org.ogce', module: 'xpp3' // unused in Android and brings wrong Junit version
        exclude group: 'com.squareup.okhttp3'
+12 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
    <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

    <!-- account management permissions not required for own accounts since API level 22 -->
    <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" android:maxSdkVersion="22"/>
@@ -682,6 +683,17 @@

        </activity>

        <activity android:name=".ui.signout.OpenIdEndSessionActivity"
            android:exported="true" >
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="${murenaAuthLogoutRedirectScheme}" />
            </intent-filter>
        </activity>

        <receiver
            android:name=".receiver.BootCompletedReceiver"
+51 −26
Original line number Diff line number Diff line
@@ -15,8 +15,10 @@
 */
package at.bitfire.davdroid.authorization

import android.content.Context
import android.net.Uri
import at.bitfire.davdroid.BuildConfig
import at.bitfire.davdroid.R
import net.openid.appauth.AuthorizationServiceConfiguration
import net.openid.appauth.AuthorizationServiceConfiguration.RetrieveConfigurationCallback

@@ -30,40 +32,59 @@ enum class IdentityProvider(
    clientId: String,
    clientSecret: String?,
    redirectUri: String,
    logoutRedirectUri: String?,
    scope: String,
    userInfoEndpoint: String?
    userInfoEndpoint: String?,
    baseUrl: String?
) {
    MURENA(
        "https://accounts.eeo.one/auth/realms/eeo.one/.well-known/openid-configuration",
        null,
        null,
        BuildConfig.MURENA_CLIENT_ID,
        BuildConfig.MURENA_CLIENT_SECRET,
        BuildConfig.MURENA_REDIRECT_URI + ":/redirect",
        "openid address profile email phone roles offline_access web-origins microprofile-jwt",
        null
        discoveryEndpoint = BuildConfig.MURENA_DISCOVERY_END_POINT,
        authEndpoint = null,
        tokenEndpoint = null,
        clientId = BuildConfig.MURENA_CLIENT_ID,
        clientSecret = BuildConfig.MURENA_CLIENT_SECRET,
        redirectUri = BuildConfig.MURENA_REDIRECT_URI + ":/redirect",
        logoutRedirectUri = BuildConfig.MURENA_LOGOUT_REDIRECT_URI + ":/redirect",
        scope = "openid address profile email phone roles offline_access web-origins microprofile-jwt",
        userInfoEndpoint = null,
        baseUrl = BuildConfig.MURENA_BASE_URL,
    ),
    GOOGLE(
        "https://accounts.google.com/.well-known/openid-configuration",
        null,
        null,
        BuildConfig.GOOGLE_CLIENT_ID,
        null,
        BuildConfig.GOOGLE_REDIRECT_URI + ":/oauth2redirect",
        "openid profile email https://www.googleapis.com/auth/carddav https://www.googleapis.com/auth/calendar https://mail.google.com/",
        null
        discoveryEndpoint = "https://accounts.google.com/.well-known/openid-configuration",
        authEndpoint = null,
        tokenEndpoint = null,
        clientId = BuildConfig.GOOGLE_CLIENT_ID,
        clientSecret = null,
        redirectUri = BuildConfig.GOOGLE_REDIRECT_URI + ":/oauth2redirect",
        logoutRedirectUri = null,
        scope = "openid profile email https://www.googleapis.com/auth/carddav https://www.googleapis.com/auth/calendar https://mail.google.com/",
        userInfoEndpoint = null,
        baseUrl = null
    ),
    YAHOO(
        "https://api.login.yahoo.com/.well-known/openid-configuration",
        null,
        null,
        BuildConfig.YAHOO_CLIENT_ID,
        null,
        BuildConfig.APPLICATION_ID + "://oauth2redirect",
        "openid openid2 profile email mail-w sdct-w ycal-w",
        null
        discoveryEndpoint = "https://api.login.yahoo.com/.well-known/openid-configuration",
        authEndpoint = null,
        tokenEndpoint = null,
        clientId = BuildConfig.YAHOO_CLIENT_ID,
        clientSecret = null,
        redirectUri = BuildConfig.APPLICATION_ID + "://oauth2redirect",
        logoutRedirectUri = null,
        scope = "openid openid2 profile email mail-w sdct-w ycal-w",
        userInfoEndpoint = null,
        baseUrl = null
    );

    companion object {
        fun retrieveByAccountType(context: Context, accountType: String): IdentityProvider? {
            return when(accountType) {
                context.getString(R.string.eelo_account_type) -> MURENA
                context.getString(R.string.google_account_type) -> GOOGLE
                context.getString(R.string.yahoo_account_type) -> YAHOO
                else -> null
            }
        }
    }

    private val mDiscoveryEndpoint: Uri?
    private val mAuthEndpoint: Uri?
    private val mTokenEndpoint: Uri?
@@ -71,8 +92,10 @@ enum class IdentityProvider(
    val clientId: String
    val clientSecret: String?
    val redirectUri: Uri
    val logoutRedirectUri: Uri?
    val scope: String
    val userInfoEndpoint: String?
    val baseUrl: String?

    init {
        require(
@@ -87,8 +110,10 @@ enum class IdentityProvider(
        this.clientSecret = clientSecret
        this.redirectUri =
            retrieveUri(redirectUri) ?: throw IllegalArgumentException("invalid redirect uri")
        this.logoutRedirectUri = retrieveUri(logoutRedirectUri)
        this.scope = scope
        this.userInfoEndpoint = userInfoEndpoint
        this.baseUrl = baseUrl
    }

    fun retrieveConfig(callback: RetrieveConfigurationCallback) {
+41 −5
Original line number Diff line number Diff line
@@ -20,17 +20,16 @@ import android.accounts.AccountManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import at.bitfire.davdroid.settings.AccountSettings
import at.bitfire.davdroid.syncadapter.AccountUtils
import at.bitfire.davdroid.ui.signout.OpenIdEndSessionActivity
import at.bitfire.davdroid.util.AuthStatePrefUtils
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory

class AccountRemovedReceiver : BroadcastReceiver() {

    companion object {
        private const val ACCOUNT_REMOVAL_ACTION = "android.accounts.action.ACCOUNT_REMOVED"
    }

    override fun onReceive(context: Context?, intent: Intent?) {
        if (context == null || intent == null || intent.action != ACCOUNT_REMOVAL_ACTION) {
        if (context == null || intent == null || intent.action != AccountManager.ACTION_ACCOUNT_REMOVED) {
            return
        }

@@ -38,6 +37,43 @@ class AccountRemovedReceiver : BroadcastReceiver() {

        val ownCloudClientManager = OwnCloudClientManagerFactory.getDefaultSingleton()
        ownCloudClientManager.removeClientForByName(accountName)

        clearOidcSession(
            intent = intent,
            context = context,
            accountName = accountName
        )
    }

    private fun clearOidcSession(
        intent: Intent,
        context: Context,
        accountName: String
    ) {
        intent.extras?.getString(AccountManager.KEY_ACCOUNT_TYPE)?.let { type ->
            val authStateString =
                AuthStatePrefUtils.loadAuthState(context, accountName, type) ?: return
            startOidcEndSessionActivity(
                context = context,
                authState = authStateString,
                accountType = type
            )
        }
    }

    private fun startOidcEndSessionActivity(
        context: Context,
        authState: String,
        accountType: String
    ) {
        val intent = Intent(context, OpenIdEndSessionActivity::class.java)
        intent.apply {
            putExtra(AccountSettings.KEY_AUTH_STATE, authState)
            putExtra(AccountManager.KEY_ACCOUNT_TYPE, accountType)
            addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        }

        context.applicationContext.startActivity(intent)
    }

    private fun getAccountName(context: Context, intent: Intent): String? {
Loading