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

Commit 979ce799 authored by Fahim M. Choudhury's avatar Fahim M. Choudhury Committed by Mohammed Althaf T
Browse files

mail: Configure Microsoft account integration for official, community, and test platforms

The redirect URI generated by Microsoft Azure portal is different
for each platform keystore: official, community and test. So, the
value needs to be updated at runtime based on the release type found in system properties.
parent 2193f462
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
@@ -15,6 +15,17 @@ if (testCoverageEnabled) {
    apply(plugin = "jacoco")
}

fun getProperty(property: String): String {
    return System.getenv(property) ?: run {
        val properties = Properties()
        val propertiesFile = project.rootProject.file("local.properties")
        if (propertiesFile.exists()) {
            propertiesFile.inputStream().use { properties.load(it) }
        }
        properties.getProperty(property)
    } ?: ""
}

android {
    namespace = "net.thunderbird.android"

@@ -140,6 +151,20 @@ android {
        )

        buildConfigField("String", "CLIENT_INFO_APP_NAME", "\"Thunderbird for Android\"")

        // Microsoft OAuth
        buildConfigField("String", "OAUTH_MICROSOFT_CLIENT_ID",
            "\"${getProperty("MICROSOFT_CLIENT_ID")}\"")

        buildConfigField("String", "MICROSOFT_REDIRECT_URI_SUFFIX_COMMUNITY",
            "\"${getProperty("MICROSOFT_REDIRECT_URI_SUFFIX_COMMUNITY")}\"",
        )
        buildConfigField("String", "MICROSOFT_REDIRECT_URI_SUFFIX_OFFICIAL",
            "\"${getProperty("MICROSOFT_REDIRECT_URI_SUFFIX_OFFICIAL")}\"",
        )
        buildConfigField("String", "MICROSOFT_REDIRECT_URI_SUFFIX_TEST",
            "\"${getProperty("MICROSOFT_REDIRECT_URI_SUFFIX_TEST")}\"",
        )
    }

    signingConfigs {
+2 −2
Original line number Diff line number Diff line
@@ -80,7 +80,7 @@ class EOAuthConfigurationFactory : OAuthConfigurationFactory {
            "outlook.office365.com",
            "smtp.office365.com",
        ) to OAuthConfiguration(
            clientId = "e6f8716e-299d-4ed9-bbf3-453f192f44e5",
            clientId = BuildConfig.OAUTH_MICROSOFT_CLIENT_ID,
            scopes = listOf(
                "https://outlook.office.com/IMAP.AccessAsUser.All",
                "https://outlook.office.com/SMTP.Send",
@@ -88,7 +88,7 @@ class EOAuthConfigurationFactory : OAuthConfigurationFactory {
            ),
            authorizationEndpoint = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize",
            tokenEndpoint = "https://login.microsoftonline.com/common/oauth2/v2.0/token",
            redirectUri = "msauth://net.thunderbird.android/S9nqeF27sTJcEfaInpC%2BDHzHuCY%3D",
            redirectUri = MicrosoftRedirectUriGenerator.generate(),
        )
    }

+37 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 MURENA SAS
 *
 * 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 net.thunderbird.android.auth

import net.thunderbird.android.BuildConfig

object MicrosoftRedirectUriGenerator {
    fun generate(): String {
        val releaseType = ReleaseTypeHelper.getReleaseType()
        val redirectUriSuffix = when (releaseType) {
            ReleaseType.Community -> BuildConfig.MICROSOFT_REDIRECT_URI_SUFFIX_COMMUNITY
            ReleaseType.Official -> BuildConfig.MICROSOFT_REDIRECT_URI_SUFFIX_OFFICIAL
            ReleaseType.Test, ReleaseType.Unavailable -> BuildConfig.MICROSOFT_REDIRECT_URI_SUFFIX_TEST
        }

        // For debug build (foundation.e.mail.debug), update the hash of your debug keystore in Microsoft Azure portal,
        // and based on that, set the redirectUriSuffix as it is a combination of both
        // the applicationId and signature hash of the keystore.

        return "msauth://${BuildConfig.APPLICATION_ID}/$redirectUriSuffix"
    }
}
+57 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 MURENA SAS
 *
 * 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 net.thunderbird.android.auth

import android.annotation.SuppressLint
import com.fsck.k9.logging.Timber

object ReleaseTypeHelper {

    private const val KEY_SYSTEM_PROPERTY_RELEASE_TYPE = "ro.lineage.releasetype"

    fun getReleaseType(): ReleaseType {
        val property = getSystemProperty(KEY_SYSTEM_PROPERTY_RELEASE_TYPE)

        return when (property) {
            ReleaseType.Community.value -> ReleaseType.Community
            ReleaseType.Official.value -> ReleaseType.Official
            ReleaseType.Test.value -> ReleaseType.Test
            else -> ReleaseType.Unavailable
        }
    }
}

enum class ReleaseType(val value: String) {
    Community("community"),
    Official("official"),
    Test("test"),
    Unavailable("")
}

@SuppressLint("PrivateApi")
private fun getSystemProperty(key: String): String {
    return try {
        Class.forName("android.os.SystemProperties")
            .getMethod("get", String::class.java)
            .invoke(null, key) as String
    } catch (e: Exception) {
        Timber.e("Unable to determine system property for $key", e)
        ReleaseType.Unavailable.value
    }
}