diff --git a/coreexample/build.gradle.kts b/coreexample/build.gradle.kts index 63e58cfde..f8a997987 100644 --- a/coreexample/build.gradle.kts +++ b/coreexample/build.gradle.kts @@ -17,6 +17,7 @@ */ import com.android.build.gradle.TestedExtension +import configuration.extensions.protonEnvironment import studio.forface.easygradle.dsl.* import studio.forface.easygradle.dsl.android.* import java.io.FileNotFoundException @@ -25,6 +26,7 @@ import java.util.Properties plugins { protonAndroidApp protonDagger + id("me.proton.core.gradle-plugins.environment-config") kotlin("plugin.serialization") } @@ -90,11 +92,6 @@ android { fun setupFlavors(testedExtension: TestedExtension) { testedExtension.apply { val buildConfigFieldKeys = object { - val PROXY_TOKEN = "PROXY_TOKEN" - val API_HOST = "API_HOST" - val HV3_HOST = "HV3_HOST" - val QUARK_HOST = "QUARK_HOST" - val USE_DEFAULT_PINS = "USE_DEFAULT_PINS" val CAN_USE_DOH = "USE_DOH" val KEY_TRANSPARENCY_ENV = "KEY_TRANSPARENCY_ENV" val SENTRY_DSN = "SENTRY_DSN" @@ -107,8 +104,6 @@ fun setupFlavors(testedExtension: TestedExtension) { flavorDimensions(flavorDimensions.env) defaultConfig { - buildConfigField("String", buildConfigFieldKeys.PROXY_TOKEN, null.toBuildConfigValue()) - buildConfigField("Boolean", buildConfigFieldKeys.USE_DEFAULT_PINS, true.toBuildConfigValue()) buildConfigField("Boolean", buildConfigFieldKeys.CAN_USE_DOH, false.toBuildConfigValue()) buildConfigField("String", buildConfigFieldKeys.KEY_TRANSPARENCY_ENV, null.toBuildConfigValue()) buildConfigField("String", buildConfigFieldKeys.SENTRY_DSN, null.toBuildConfigValue()) @@ -118,19 +113,22 @@ fun setupFlavors(testedExtension: TestedExtension) { productFlavors.register("dev") { dimension = flavorDimensions.env applicationIdSuffix = ".dev" - buildConfigField("String", buildConfigFieldKeys.API_HOST, "api.proton.black".toBuildConfigValue()) - buildConfigField("String", buildConfigFieldKeys.HV3_HOST, "verify.proton.black".toBuildConfigValue()) - buildConfigField("String", buildConfigFieldKeys.QUARK_HOST, "proton.black".toBuildConfigValue()) - buildConfigField("Boolean", buildConfigFieldKeys.USE_DEFAULT_PINS, false.toBuildConfigValue()) + + protonEnvironment { + host = "proton.black" + } + buildConfigField("String", buildConfigFieldKeys.KEY_TRANSPARENCY_ENV, "black".toBuildConfigValue()) buildConfigField("String", buildConfigFieldKeys.SENTRY_DSN, null.toBuildConfigValue()) buildConfigField("String", buildConfigFieldKeys.ACCOUNT_SENTRY_DSN, null.toBuildConfigValue()) } productFlavors.register("prod") { dimension = flavorDimensions.env - buildConfigField("String", buildConfigFieldKeys.API_HOST, "mail-api.proton.me".toBuildConfigValue()) - buildConfigField("String", buildConfigFieldKeys.HV3_HOST, "verify.proton.me".toBuildConfigValue()) - buildConfigField("String", buildConfigFieldKeys.QUARK_HOST, "".toBuildConfigValue()) + + protonEnvironment { + apiPrefix = "mail-api" + } + buildConfigField("Boolean", buildConfigFieldKeys.CAN_USE_DOH, true.toBuildConfigValue()) buildConfigField("String", buildConfigFieldKeys.KEY_TRANSPARENCY_ENV, "production".toBuildConfigValue()) buildConfigField("String", buildConfigFieldKeys.SENTRY_DSN, null.toBuildConfigValue()) @@ -146,21 +144,17 @@ fun setupFlavors(testedExtension: TestedExtension) { logger.warn("No local.properties found") } } - val proxyToken: String? = localProperties.getProperty(buildConfigFieldKeys.PROXY_TOKEN) - val host: String = localProperties.getProperty("HOST") ?: "proton.me" - val apiHost = localProperties.getProperty(buildConfigFieldKeys.API_HOST) ?: "mail-api.$host" - val hv3Host = localProperties.getProperty(buildConfigFieldKeys.HV3_HOST) ?: "verify.$host" - val quarkHost = localProperties.getProperty(buildConfigFieldKeys.QUARK_HOST) ?: host - val useDefaultPins: String = localProperties.getProperty(buildConfigFieldKeys.USE_DEFAULT_PINS) ?: "false" + + val atlasHost: String = localProperties.getProperty("HOST") ?: "proton.me" val keyTransparencyEnv: String? = localProperties.getProperty(buildConfigFieldKeys.KEY_TRANSPARENCY_ENV) val sentryDsn: String? = localProperties.getProperty(buildConfigFieldKeys.SENTRY_DSN) val accountSentryDsn: String? = localProperties.getProperty(buildConfigFieldKeys.ACCOUNT_SENTRY_DSN) - buildConfigField("Boolean", buildConfigFieldKeys.USE_DEFAULT_PINS, useDefaultPins.toBoolean().toBuildConfigValue()) - buildConfigField("String", buildConfigFieldKeys.PROXY_TOKEN, proxyToken.toBuildConfigValue()) - buildConfigField("String", buildConfigFieldKeys.API_HOST, apiHost.toBuildConfigValue()) - buildConfigField("String", buildConfigFieldKeys.HV3_HOST, hv3Host.toBuildConfigValue()) - buildConfigField("String", buildConfigFieldKeys.QUARK_HOST, quarkHost.toBuildConfigValue()) + protonEnvironment { + useProxy = true + host = atlasHost + } + buildConfigField( "String", buildConfigFieldKeys.KEY_TRANSPARENCY_ENV, @@ -170,10 +164,10 @@ fun setupFlavors(testedExtension: TestedExtension) { buildConfigField("String", buildConfigFieldKeys.ACCOUNT_SENTRY_DSN, accountSentryDsn.toBuildConfigValue()) } productFlavors.register("mock") { - buildConfigField("String", buildConfigFieldKeys.API_HOST, "api.mock".toBuildConfigValue()) - buildConfigField("String", buildConfigFieldKeys.HV3_HOST, "verify.mock".toBuildConfigValue()) - buildConfigField("String", buildConfigFieldKeys.QUARK_HOST, "quark.mock".toBuildConfigValue()) - buildConfigField("Boolean", buildConfigFieldKeys.USE_DEFAULT_PINS, false.toBuildConfigValue()) + protonEnvironment { + host = "mock" + } + buildConfigField("String", buildConfigFieldKeys.KEY_TRANSPARENCY_ENV, null.toBuildConfigValue()) buildConfigField("String", buildConfigFieldKeys.SENTRY_DSN, null.toBuildConfigValue()) buildConfigField("String", buildConfigFieldKeys.ACCOUNT_SENTRY_DSN, null.toBuildConfigValue()) diff --git a/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/accountrecovery/AccountRecoveryNotificationTest.kt b/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/accountrecovery/AccountRecoveryNotificationTest.kt index 18da587c2..0aa40ff98 100644 --- a/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/accountrecovery/AccountRecoveryNotificationTest.kt +++ b/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/accountrecovery/AccountRecoveryNotificationTest.kt @@ -25,7 +25,6 @@ import androidx.compose.ui.test.junit4.createAndroidComposeRule import androidx.test.rule.GrantPermissionRule import dagger.hilt.android.testing.HiltAndroidRule import dagger.hilt.android.testing.HiltAndroidTest -import me.proton.android.core.coreexample.BuildConfig import me.proton.android.core.coreexample.Constants import me.proton.android.core.coreexample.MainActivity import me.proton.core.accountmanager.data.AccountStateHandler @@ -76,7 +75,7 @@ class AccountRecoveryNotificationTest : MinimalAccountRecoveryNotificationTest { @Inject override lateinit var waitForPrimaryAccount: WaitForPrimaryAccount - override val quark = Quark.fromDefaultResources(Constants.QUARK_HOST, BuildConfig.PROXY_TOKEN) + override val quark = Quark.fromDefaultResources(Constants.QUARK_HOST, Constants.PROXY_TOKEN) @BeforeTest override fun prepare() { diff --git a/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/login/ConvertExternalToInternalAccountTests.kt b/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/login/ConvertExternalToInternalAccountTests.kt index be43d74f5..0a8fb37da 100644 --- a/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/login/ConvertExternalToInternalAccountTests.kt +++ b/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/login/ConvertExternalToInternalAccountTests.kt @@ -5,7 +5,6 @@ import dagger.hilt.android.testing.HiltAndroidRule import dagger.hilt.android.testing.HiltAndroidTest import dagger.hilt.android.testing.UninstallModules import kotlinx.coroutines.runBlocking -import me.proton.android.core.coreexample.BuildConfig import me.proton.android.core.coreexample.Constants import me.proton.android.core.coreexample.MainActivity import me.proton.android.core.coreexample.api.CoreExampleApiClient @@ -33,8 +32,7 @@ import kotlin.time.Duration.Companion.seconds @UninstallModules(ApplicationModule::class) class ConvertExternalToInternalAccountTests : BaseConvertExternalToInternalAccountTests, ProtonTest(MainActivity::class.java) { - override val quark: Quark = - Quark.fromDefaultResources(Constants.QUARK_HOST, BuildConfig.PROXY_TOKEN) + override val quark: Quark = Quark.fromDefaultResources(Constants.QUARK_HOST, Constants.PROXY_TOKEN) override lateinit var testUser: User override lateinit var testUsername: String diff --git a/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/login/ExternalAccountSupportedLoginTests.kt b/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/login/ExternalAccountSupportedLoginTests.kt index 138d65281..b1e0f724a 100644 --- a/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/login/ExternalAccountSupportedLoginTests.kt +++ b/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/login/ExternalAccountSupportedLoginTests.kt @@ -24,7 +24,6 @@ import dagger.hilt.android.testing.HiltAndroidTest import dagger.hilt.android.testing.UninstallModules import kotlinx.coroutines.flow.first import kotlinx.coroutines.runBlocking -import me.proton.android.core.coreexample.BuildConfig import me.proton.android.core.coreexample.Constants import me.proton.android.core.coreexample.MainActivity import me.proton.android.core.coreexample.api.CoreExampleApiClient @@ -270,6 +269,6 @@ class ExternalAccountSupportedLoginTests : ProtonTest(MainActivity::class.java, } companion object { - private val quark = Quark.fromDefaultResources(Constants.QUARK_HOST, BuildConfig.PROXY_TOKEN) + private val quark = Quark.fromDefaultResources(Constants.QUARK_HOST, Constants.PROXY_TOKEN) } } diff --git a/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/login/ExternalAccountUnsupportedLoginTests.kt b/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/login/ExternalAccountUnsupportedLoginTests.kt index db1a758d8..82f1ddfad 100644 --- a/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/login/ExternalAccountUnsupportedLoginTests.kt +++ b/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/login/ExternalAccountUnsupportedLoginTests.kt @@ -23,7 +23,6 @@ import dagger.hilt.android.testing.BindValue import dagger.hilt.android.testing.HiltAndroidRule import dagger.hilt.android.testing.HiltAndroidTest import dagger.hilt.android.testing.UninstallModules -import me.proton.android.core.coreexample.BuildConfig import me.proton.android.core.coreexample.Constants import me.proton.android.core.coreexample.MainActivity import me.proton.android.core.coreexample.api.CoreExampleApiClient @@ -91,6 +90,6 @@ class ExternalAccountUnsupportedLoginTests : ProtonTest(MainActivity::class.java } companion object { - val quark = Quark.fromDefaultResources(Constants.QUARK_HOST, BuildConfig.PROXY_TOKEN) + val quark = Quark.fromDefaultResources(Constants.QUARK_HOST, Constants.PROXY_TOKEN) } } diff --git a/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/login/InternalLoginWithAccountSetupTests.kt b/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/login/InternalLoginWithAccountSetupTests.kt index c3f04e311..5443a59b2 100644 --- a/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/login/InternalLoginWithAccountSetupTests.kt +++ b/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/login/InternalLoginWithAccountSetupTests.kt @@ -25,7 +25,6 @@ import dagger.hilt.android.testing.HiltAndroidTest import dagger.hilt.android.testing.UninstallModules import kotlinx.coroutines.flow.first import kotlinx.coroutines.runBlocking -import me.proton.android.core.coreexample.BuildConfig import me.proton.android.core.coreexample.Constants import me.proton.android.core.coreexample.MainActivity import me.proton.android.core.coreexample.api.CoreExampleApiClient @@ -174,6 +173,6 @@ class InternalLoginWithAccountSetupTests : ProtonTest(MainActivity::class.java, } companion object { - private val quark = Quark.fromDefaultResources(Constants.QUARK_HOST, BuildConfig.PROXY_TOKEN) + private val quark = Quark.fromDefaultResources(Constants.QUARK_HOST, Constants.PROXY_TOKEN) } } diff --git a/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/login/VpnUsernameAccountLoginTests.kt b/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/login/VpnUsernameAccountLoginTests.kt index 995a2087d..518055e7a 100644 --- a/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/login/VpnUsernameAccountLoginTests.kt +++ b/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/login/VpnUsernameAccountLoginTests.kt @@ -22,7 +22,6 @@ import dagger.hilt.android.testing.BindValue import dagger.hilt.android.testing.HiltAndroidRule import dagger.hilt.android.testing.HiltAndroidTest import dagger.hilt.android.testing.UninstallModules -import me.proton.android.core.coreexample.BuildConfig import me.proton.android.core.coreexample.Constants import me.proton.android.core.coreexample.MainActivity import me.proton.android.core.coreexample.api.CoreExampleApiClient @@ -43,7 +42,7 @@ import kotlin.test.BeforeTest @HiltAndroidTest @UninstallModules(ApplicationModule::class) class VpnUsernameAccountLoginTests : BaseUsernameAccountLoginTests, ProtonTest(MainActivity::class.java) { - override val quark: Quark = Quark.fromDefaultResources(Constants.QUARK_HOST, BuildConfig.PROXY_TOKEN) + override val quark: Quark = Quark.fromDefaultResources(Constants.QUARK_HOST, Constants.PROXY_TOKEN) override val internalUsers: User.Users = User.Users.fromDefaultResources() override val vpnUsers: User.Users = User.Users.fromJavaResources( User::class.java.classLoader!!, diff --git a/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/signup/DriveExternalAccountSignupTests.kt b/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/signup/DriveExternalAccountSignupTests.kt index 736352e15..5a1e19c98 100644 --- a/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/signup/DriveExternalAccountSignupTests.kt +++ b/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/signup/DriveExternalAccountSignupTests.kt @@ -22,7 +22,6 @@ import dagger.hilt.android.testing.BindValue import dagger.hilt.android.testing.HiltAndroidRule import dagger.hilt.android.testing.HiltAndroidTest import dagger.hilt.android.testing.UninstallModules -import me.proton.android.core.coreexample.BuildConfig import me.proton.android.core.coreexample.Constants import me.proton.android.core.coreexample.api.CoreExampleApiClient import me.proton.android.core.coreexample.di.ApplicationModule @@ -44,7 +43,7 @@ import kotlin.test.BeforeTest class DriveExternalAccountSignupTests : BaseExternalAccountSignupTests { override lateinit var testUser: User - override val quark = Quark.fromDefaultResources(Constants.QUARK_HOST, BuildConfig.PROXY_TOKEN) + override val quark = Quark.fromDefaultResources(Constants.QUARK_HOST, Constants.PROXY_TOKEN) @get:Rule val hiltRule = HiltAndroidRule(this) diff --git a/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/signup/ExternalAccountChooseUsernameTest.kt b/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/signup/ExternalAccountChooseUsernameTest.kt index d7a853cca..6fe325d30 100644 --- a/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/signup/ExternalAccountChooseUsernameTest.kt +++ b/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/signup/ExternalAccountChooseUsernameTest.kt @@ -24,7 +24,6 @@ import dagger.hilt.android.testing.BindValue import dagger.hilt.android.testing.HiltAndroidRule import dagger.hilt.android.testing.HiltAndroidTest import dagger.hilt.android.testing.UninstallModules -import me.proton.android.core.coreexample.BuildConfig import me.proton.android.core.coreexample.Constants import me.proton.android.core.coreexample.api.CoreExampleApiClient import me.proton.android.core.coreexample.di.ApplicationModule @@ -92,7 +91,8 @@ open class ExternalAccountChooseUsernameTest { private companion object { - private val quark = Quark.fromDefaultResources(Constants.QUARK_HOST, BuildConfig.PROXY_TOKEN) + private val quark = Quark.fromDefaultResources(Constants.QUARK_HOST, Constants.PROXY_TOKEN) + private fun launchSignupActivity(accountType: AccountType): ActivityScenario = ActivityScenario.launch( StartSignup().createIntent( diff --git a/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/signup/VpnUsernameAccountSignupTests.kt b/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/signup/VpnUsernameAccountSignupTests.kt index 37db08908..262c13128 100644 --- a/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/signup/VpnUsernameAccountSignupTests.kt +++ b/coreexample/hilt-tests/src/main/kotlin/me/proton/android/core/coreexample/hilttests/signup/VpnUsernameAccountSignupTests.kt @@ -24,7 +24,6 @@ import dagger.hilt.android.testing.BindValue import dagger.hilt.android.testing.HiltAndroidRule import dagger.hilt.android.testing.HiltAndroidTest import dagger.hilt.android.testing.UninstallModules -import me.proton.android.core.coreexample.BuildConfig import me.proton.android.core.coreexample.Constants import me.proton.android.core.coreexample.MainActivity import me.proton.android.core.coreexample.api.CoreExampleApiClient @@ -48,7 +47,7 @@ import kotlin.test.BeforeTest @UninstallModules(ApplicationModule::class) class VpnUsernameAccountSignupTests : BaseUsernameAccountSignupTests, ProtonTest(MainActivity::class.java, defaultTimeout = 20_000) { - override val quark: Quark = Quark.fromDefaultResources(Constants.QUARK_HOST, BuildConfig.PROXY_TOKEN) + override val quark: Quark = Quark.fromDefaultResources(Constants.QUARK_HOST, Constants.PROXY_TOKEN) override val vpnUsers: User.Users = User.Users.fromJavaResources( User::class.java.classLoader!!, "sensitive/users-vpn-username.json" diff --git a/coreexample/src/androidTest/kotlin/me/proton/core/test/android/uitests/tests/BaseTest.kt b/coreexample/src/androidTest/kotlin/me/proton/core/test/android/uitests/tests/BaseTest.kt index 8419c5b3d..7472c3706 100644 --- a/coreexample/src/androidTest/kotlin/me/proton/core/test/android/uitests/tests/BaseTest.kt +++ b/coreexample/src/androidTest/kotlin/me/proton/core/test/android/uitests/tests/BaseTest.kt @@ -23,19 +23,18 @@ import android.util.Log import androidx.test.core.app.ApplicationProvider import dagger.hilt.android.EntryPointAccessors import kotlinx.coroutines.runBlocking -import me.proton.android.core.coreexample.BuildConfig import me.proton.android.core.coreexample.Constants import me.proton.android.core.coreexample.MainActivity import me.proton.core.auth.presentation.testing.ProtonTestEntryPoint import me.proton.core.payment.domain.usecase.PaymentProvider import me.proton.core.test.android.instrumented.ProtonTest import me.proton.core.test.android.instrumented.utils.Shell.setupDeviceForAutomation -import me.proton.core.test.quark.data.User.Users import me.proton.core.test.android.robots.auth.AddAccountRobot import me.proton.core.test.android.uitests.robot.CoreexampleRobot import me.proton.core.test.quark.Quark import me.proton.core.test.quark.data.Plan import me.proton.core.test.quark.data.User +import me.proton.core.test.quark.data.User.Users import org.junit.After import org.junit.BeforeClass @@ -61,7 +60,11 @@ open class BaseTest( companion object { val users = Users.fromDefaultResources() - val quark = Quark.fromDefaultResources(Constants.QUARK_HOST, BuildConfig.PROXY_TOKEN) + val quark = Quark.fromDefaultResources( + Constants.QUARK_HOST, + Constants.PROXY_TOKEN + ) + val authHelper by lazy { protonTestEntryPoint.loginTestHelper } private val protonTestEntryPoint by lazy { diff --git a/coreexample/src/main/kotlin/me/proton/android/core/coreexample/Constants.kt b/coreexample/src/main/kotlin/me/proton/android/core/coreexample/Constants.kt index ae48998fe..e3842c0c6 100644 --- a/coreexample/src/main/kotlin/me/proton/android/core/coreexample/Constants.kt +++ b/coreexample/src/main/kotlin/me/proton/android/core/coreexample/Constants.kt @@ -18,11 +18,13 @@ package me.proton.android.core.coreexample +import me.proton.core.configuration.EnvironmentConfigurationDefaults + object Constants { - const val API_HOST = BuildConfig.API_HOST - const val HV3_HOST = BuildConfig.HV3_HOST - const val BASE_URL = "https://$API_HOST" - const val QUARK_HOST = BuildConfig.QUARK_HOST + const val HV3_HOST = EnvironmentConfigurationDefaults.hv3Host + const val BASE_URL = EnvironmentConfigurationDefaults.baseUrl + const val QUARK_HOST = EnvironmentConfigurationDefaults.host + const val PROXY_TOKEN = EnvironmentConfigurationDefaults.proxyToken } const val PLAN_PLUS_ID = diff --git a/coreexample/src/main/kotlin/me/proton/android/core/coreexample/di/NetworkModule.kt b/coreexample/src/main/kotlin/me/proton/android/core/coreexample/di/NetworkModule.kt index 6c5ac170f..8ae0c6b25 100644 --- a/coreexample/src/main/kotlin/me/proton/android/core/coreexample/di/NetworkModule.kt +++ b/coreexample/src/main/kotlin/me/proton/android/core/coreexample/di/NetworkModule.kt @@ -23,9 +23,9 @@ import dagger.Module import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent -import me.proton.android.core.coreexample.BuildConfig import me.proton.android.core.coreexample.Constants import me.proton.android.core.coreexample.api.CoreExampleApiClient +import me.proton.core.configuration.EnvironmentConfigurationDefaults import me.proton.core.network.data.client.ExtraHeaderProviderImpl import me.proton.core.network.data.di.AlternativeApiPins import me.proton.core.network.data.di.BaseProtonApiUrl @@ -46,7 +46,7 @@ class NetworkModule { @Provides @Singleton fun provideExtraHeaderProvider(): ExtraHeaderProvider = ExtraHeaderProviderImpl().apply { - BuildConfig.PROXY_TOKEN?.takeIfNotBlank()?.let { addHeaders("X-atlas-secret" to it) } + Constants.PROXY_TOKEN.takeIfNotBlank()?.let { addHeaders("X-atlas-secret" to it) } } } @@ -63,7 +63,7 @@ class NetworkConstantsModule { @CertificatePins @Provides - fun provideCertificatePins() = if (BuildConfig.USE_DEFAULT_PINS) { + fun provideCertificatePins() = if (EnvironmentConfigurationDefaults.useDefaultPins) { NetWorkDataConstants.DEFAULT_SPKI_PINS } else { emptyArray() @@ -71,7 +71,7 @@ class NetworkConstantsModule { @AlternativeApiPins @Provides - fun provideAlternativeApiPins() = if (BuildConfig.USE_DEFAULT_PINS) { + fun provideAlternativeApiPins() = if (EnvironmentConfigurationDefaults.useDefaultPins) { NetWorkDataConstants.ALTERNATIVE_API_SPKI_PINS } else { emptyList() diff --git a/plugins/README.md b/plugins/README.md index 5d300ec93..be6eb75eb 100644 --- a/plugins/README.md +++ b/plugins/README.md @@ -87,7 +87,7 @@ coverage report: - ./build/reports/cobertura-coverage.xml ``` -It also allows for further customization. See the [plugin's README](./jacoco/README.md) for more info. +It also allows for further customization. See the [plugin's README](jacoco/README.md) for more info. ## Include Core Build plugin - Plugin id: `me.proton.core.gradle-plugins.include-core-build` @@ -128,29 +128,92 @@ includeCoreBuild { ``` Override include with local: -```kotlin +``` gradle.properties local.git.proton-libs=../proton-libs ``` -**Note: This plugin in based on [IncludeGit Gradle Plugin](https://melix.github.io/includegit-gradle-plugin).** +**Note: This plugin in based +on [IncludeGit Gradle Plugin](https://melix.github.io/includegit-gradle-plugin).** ## Publish-core-libraries plugin + - Plugin id: `publish-core-libraries` - Not published on MavenCentral. Use internally in core project to orchestrate [core libraries publication](../README.md#release). +## Environment configuration plugin + +- Plugin id: `me.proton.core.gradle-plugins.environment-config` +- Published on MavenCentral. + +This plugin should be applied to either build flavor or application build type android extension +in `build.gradle.kts` file. + +* + +Generates `build/generated/source/envConfig/{flavor}/{buildType}/EnvironmentConfigurationDefaults.java` +similarly to `BuildConfig.java`. +Generated class is then added to source directories and can be accessed at runtime + +* Automatically obtains and sets proxy token if `useProxy` is set to `true` +* By default (if no configuration provided in build.gradle.kts) generates a default production + config (`api.proton.me`) + +```kotlin +build.gradle.kts + +plugins { + id("me.proton.core.gradle-plugins.environment-config") +} + +android { + buildTypes { + debug { + environmentConfig { + useProxy = true // use proxy on all debug builds. Defaults to 'false' + } + } + } + + defaultConfig { + environmentConfig { + apiPrefix = "mail-api" // will result in base url https://mail-api.proton.me + } + } + + productFlavors.register("dev") { + environmentConfig { + host = "proton.black" // will result in base url https://mail-api.proton.black + } + } + + productFlavors.register("atlas") { + environmentConfig { + apiPrefix = "test" + baseUrl = "https://special.url" // will result in base url https://test.special.url + } + } +} +``` + ## Tests + - Plugin id: `me.proton.core.gradle-plugins.tests` - Published on MavenCentral. -This plugin should be applied to the root `build.gradle` file. It adds an `allTest` task which run all unit tests in jvm and Android subprojects. +This plugin should be applied to the root `build.gradle` file. It adds an `allTest` task which run +all unit tests in jvm and Android subprojects. # Release -Release process is based on [trunk branch for release process](https://trunkbaseddevelopment.com/branch-for-release/). -Release is done by the CI. To trigger a release for version `X.Y.Z`, just push a branch named `release/gradle-plugins/X.Y.Z`. -When the release is successfully done, a tag `release/gradle-plugins/X.Y.Z` is created from the commit used to do the release. -Release implementation is orchestrated by project [publish-core-plugins](./publish-core-plugins). +Release process is based +on [trunk branch for release process](https://trunkbaseddevelopment.com/branch-for-release/). +Release is done by the CI. To trigger a release for version `X.Y.Z`, just push a branch +named `release/gradle-plugins/X.Y.Z`. +When the release is successfully done, a tag `release/gradle-plugins/X.Y.Z` is created from the +commit used to do the release. + +Release implementation is orchestrated by project [publish-core-plugins](publish-core-plugins). diff --git a/plugins/environment-configuration/build.gradle.kts b/plugins/environment-configuration/build.gradle.kts new file mode 100644 index 000000000..71c7261f2 --- /dev/null +++ b/plugins/environment-configuration/build.gradle.kts @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2021 Proton Technologies AG + * This file is part of Proton Technologies AG and ProtonCore. + * + * ProtonCore 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. + * + * ProtonCore 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 ProtonCore. If not, see . + */ + +plugins { + `kotlin-dsl` + kotlin("jvm") + `java-gradle-plugin` +} + +publishOption.shouldBePublishedAsPlugin = true + +gradlePlugin { + plugins { + create("protonEnvironment") { + id = "me.proton.core.gradle-plugins.environment-config" + displayName = "Proton environment configuration plugin" + description = "Generates build/generated/source/envConfig/{flavor}/{buildType}/" + + "EnvironmentConfigurationDefaults.java" + implementationClass = "configuration.ProtonEnvironmentConfigurationPlugin" + } + } +} + +repositories { + google() + mavenCentral() + maven("https://plugins.gradle.org/m2/") +} + +dependencies { + implementation(gradleApi()) + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin") + compileOnly(libs.android.gradle) + api(libs.easyGradle.androidDsl) +} diff --git a/plugins/environment-configuration/src/main/kotlin/configuration/EnvironmentConfig.kt b/plugins/environment-configuration/src/main/kotlin/configuration/EnvironmentConfig.kt new file mode 100644 index 000000000..3bc97ba18 --- /dev/null +++ b/plugins/environment-configuration/src/main/kotlin/configuration/EnvironmentConfig.kt @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 Proton Technologies AG + * This file is part of Proton AG and ProtonCore. + * + * ProtonCore 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. + * + * ProtonCore 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 ProtonCore. If not, see . + */ + +package configuration + +@SuppressWarnings("LongParameterList") +open class EnvironmentConfig( + open val host: String? = null, + open val proxyToken: String? = null, + open val apiPrefix: String? = null, + open val baseUrl: String? = null, + open val apiHost: String? = null, + open val hv3Host: String? = null, + open val hv3Url: String? = null, + open val useDefaultPins: Boolean? = host == "proton.me" +) diff --git a/plugins/environment-configuration/src/main/kotlin/configuration/EnvironmentConfigSettings.kt b/plugins/environment-configuration/src/main/kotlin/configuration/EnvironmentConfigSettings.kt new file mode 100644 index 000000000..08f4c16a1 --- /dev/null +++ b/plugins/environment-configuration/src/main/kotlin/configuration/EnvironmentConfigSettings.kt @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2022 Proton Technologies AG + * This file is part of Proton AG and ProtonCore. + * + * ProtonCore 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. + * + * ProtonCore 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 ProtonCore. If not, see . + */ + +package configuration + +import configuration.util.getTokenFromCurl + +open class EnvironmentConfigSettings : EnvironmentConfig() { + private var _host: String? = null + override var host: String + get() = _host ?: "proton.me" + set(value) { + _host = value + } + + private var _apiPrefix: String? = null + override var apiPrefix: String + get() = _apiPrefix ?: "api" + set(value) { + _apiPrefix = value + } + + private var _apiHost: String? = null + override var apiHost: String + get() = _apiHost ?: "$apiPrefix.$host" + set(value) { + _apiHost = value + } + + private var _baseUrl: String? = null + override var baseUrl: String + get() = _baseUrl ?: "https://$apiHost" + set(value) { + _baseUrl = value + } + + private var _hv3Host: String? = null + override var hv3Host: String + get() = _hv3Host ?: "verify.$host" + set(value) { + _hv3Host = value + } + + private var _hv3Url: String? = null + override var hv3Url: String + get() = _hv3Url ?: "https://$hv3Host" + set(value) { + _hv3Url = value + } + + private var _useDefaultPins: Boolean? = null + final override var useDefaultPins: Boolean + get() = _useDefaultPins ?: true + private set(value) { + _useDefaultPins = value + } + + private var _useProxy: Boolean? = null + var useProxy: Boolean + get() = _useProxy ?: false + set(value) { + _useProxy = value + } + + private var _proxyToken: String? = null + final override var proxyToken: String? + get() = proxyTokenFromCurl.takeIf { useProxy } ?: "" + private set(value) { + _proxyToken = value + } +} + +private val proxyTokenFromCurl: String by lazy { + val atlasProxyUrl: String? = System.getenv("ATLAS_PROXY_URL") + if (atlasProxyUrl.isNullOrEmpty()) { + println("ATLAS_PROXY_URL is not set. skipping proxy token setting") + return@lazy "" + } + + getTokenFromCurl(atlasProxyUrl) +} diff --git a/plugins/environment-configuration/src/main/kotlin/configuration/ProtonEnvironmentConfigurationPlugin.kt b/plugins/environment-configuration/src/main/kotlin/configuration/ProtonEnvironmentConfigurationPlugin.kt new file mode 100644 index 000000000..d100d581e --- /dev/null +++ b/plugins/environment-configuration/src/main/kotlin/configuration/ProtonEnvironmentConfigurationPlugin.kt @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2022 Proton Technologies AG + * This file is part of Proton AG and ProtonCore. + * + * ProtonCore 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. + * + * ProtonCore 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 ProtonCore. If not, see . + */ +package configuration + +import com.android.build.api.dsl.ApplicationBuildType +import com.android.build.api.dsl.DefaultConfig +import com.android.build.api.dsl.ProductFlavor +import com.android.build.gradle.AppExtension +import configuration.extensions.environmentConfiguration +import configuration.extensions.mergeWith +import configuration.extensions.printEnvironmentConfigDetails +import configuration.extensions.sourceClassContent +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.configurationcache.extensions.capitalized + +class ProtonEnvironmentConfigurationPlugin : Plugin { + + override fun apply(target: Project) { + target.logger.info("Applying Proton environment configurations") + + target.afterEvaluate { + handleConfigurations(target) + } + } + + /** + * Handles the configurations for the given project. + * + * Goes through all the product flavors and build types of the project, + * merges their configurations, and then creates the necessary directories and files. + * + * @param project The project for which the configurations are being handled. + */ + private fun handleConfigurations(project: Project) { + project.extensions.getByType(AppExtension::class.java).apply { + productFlavors.all { flavor -> + buildTypes.all { buildType -> + val mergedConfig = mergeConfigurations(defaultConfig, buildType, flavor) + val variantName = flavor.name + buildType.name.capitalized() + + project.logger.debug("environment configuration :$variantName") + project.printEnvironmentConfigDetails(mergedConfig) + + project.createJavaFileInDir(flavor, buildType, mergedConfig.sourceClassContent()) + true + } + } + } + } + + /** + * Creates a [javaClassName].java file in [generatedSourceLocation]/[flavor].name/[buildType].name/[packagePath] + * adds flavor directories to source sets + * + * @param flavor The product flavor. + * @param buildType The build type. + * @param sourceClassContent The content to be written to the source class file. + * @param generatedSourceLocation Generated files dir + * @param javaClassName Java class name to be generated + * @param packagePath Package directory + */ + @Suppress("LongParameterList") + private fun Project.createJavaFileInDir( + flavor: ProductFlavor, + buildType: ApplicationBuildType, + sourceClassContent: String, + generatedSourceLocation: String = ENV_CONFIG_LOCATION, + javaClassName: String = DEFAULTS_CLASS_NAME, + packagePath: String = PACKAGE_NAME.replace(".", "/") + ) { + val variantLocation = "$generatedSourceLocation/${flavor.name}/${buildType.name}" + val variantName = flavor.name + buildType.name.capitalized() + val configDirectory = project.buildDir.resolve("$variantLocation/$packagePath") + val variantDirectory = project.buildDir.resolve(variantLocation) + + configDirectory.mkdirs() + + val environmentConfigFile = configDirectory + .resolve("$javaClassName.java").apply { + writeText(sourceClassContent) + } + + project.logger.info("generated ${environmentConfigFile.path}") + + project.extensions.getByType(AppExtension::class.java).sourceSets + .findByName(variantName) + ?.java?.apply { + // avoid duplicate content roots + if (!srcDirs.contains(variantDirectory)) { + srcDir(variantDirectory) + } + } + } + + private fun mergeConfigurations( + defaultConfig: DefaultConfig, + buildType: ApplicationBuildType, + flavor: ProductFlavor + ): EnvironmentConfig = defaultConfig.environmentConfiguration + .mergeWith(buildType.environmentConfiguration) + .mergeWith(flavor.environmentConfiguration) + + companion object { + const val ENV_CONFIG_LOCATION: String = "generated/source/envConfig" + const val PACKAGE_NAME: String = "me.proton.core.configuration" + const val DEFAULTS_CLASS_NAME: String = "EnvironmentConfigurationDefaults" + } +} diff --git a/plugins/environment-configuration/src/main/kotlin/configuration/extensions/ApplicationBuildType.kt b/plugins/environment-configuration/src/main/kotlin/configuration/extensions/ApplicationBuildType.kt new file mode 100644 index 000000000..6772ac2aa --- /dev/null +++ b/plugins/environment-configuration/src/main/kotlin/configuration/extensions/ApplicationBuildType.kt @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 Proton Technologies AG + * This file is part of Proton AG and ProtonCore. + * + * ProtonCore 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. + * + * ProtonCore 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 ProtonCore. If not, see . + */ + +package configuration.extensions + +import com.android.build.api.dsl.ApplicationBuildType +import configuration.EnvironmentConfig +import configuration.EnvironmentConfigSettings +import org.jetbrains.kotlin.gradle.plugin.extraProperties + +var ApplicationBuildType.environmentConfiguration: EnvironmentConfig + get() = extraProperties.getEnvironmentConfigurationByName(name) + private set(config) = extraProperties.setEnvironmentConfigurationByName(name, config) + +fun ApplicationBuildType.protonEnvironment(action: EnvironmentConfigSettings.() -> Unit) { + environmentConfiguration = EnvironmentConfigSettings().apply(action) +} diff --git a/plugins/environment-configuration/src/main/kotlin/configuration/extensions/BaseFlavor.kt b/plugins/environment-configuration/src/main/kotlin/configuration/extensions/BaseFlavor.kt new file mode 100644 index 000000000..ad3d45a60 --- /dev/null +++ b/plugins/environment-configuration/src/main/kotlin/configuration/extensions/BaseFlavor.kt @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 Proton Technologies AG + * This file is part of Proton AG and ProtonCore. + * + * ProtonCore 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. + * + * ProtonCore 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 ProtonCore. If not, see . + */ + +package configuration.extensions + +import com.android.build.api.dsl.BaseFlavor +import configuration.EnvironmentConfig +import configuration.EnvironmentConfigSettings +import org.jetbrains.kotlin.gradle.plugin.extraProperties + +var BaseFlavor.environmentConfiguration: EnvironmentConfig + get() = extraProperties.getEnvironmentConfigurationByName(getName()) + private set(config) = extraProperties.setEnvironmentConfigurationByName(getName(), config) + +fun BaseFlavor.protonEnvironment(action: EnvironmentConfigSettings.() -> Unit) { + environmentConfiguration = EnvironmentConfigSettings().apply(action) +} diff --git a/plugins/environment-configuration/src/main/kotlin/configuration/extensions/EnvironmentConfig.kt b/plugins/environment-configuration/src/main/kotlin/configuration/extensions/EnvironmentConfig.kt new file mode 100644 index 000000000..865d14232 --- /dev/null +++ b/plugins/environment-configuration/src/main/kotlin/configuration/extensions/EnvironmentConfig.kt @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2022 Proton Technologies AG + * This file is part of Proton AG and ProtonCore. + * + * ProtonCore 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. + * + * ProtonCore 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 ProtonCore. If not, see . + */ + +package configuration.extensions + +import configuration.EnvironmentConfig +import configuration.ProtonEnvironmentConfigurationPlugin.Companion.DEFAULTS_CLASS_NAME +import configuration.ProtonEnvironmentConfigurationPlugin.Companion.PACKAGE_NAME +import configuration.util.toBuildConfigValue + +fun EnvironmentConfig.mergeWith(other: EnvironmentConfig) = EnvironmentConfig( + host = other.host ?: host, + apiPrefix = other.apiPrefix ?: apiPrefix, + baseUrl = other.baseUrl ?: baseUrl, + apiHost = other.apiHost ?: apiHost, + hv3Host = other.hv3Host ?: hv3Host, + hv3Url = other.hv3Url ?: hv3Url, + proxyToken = other.proxyToken.takeIf { it?.isNotEmpty()!! } ?: proxyToken, +) + +fun EnvironmentConfig.sourceClassContent( + namespace: String = PACKAGE_NAME, + className: String = DEFAULTS_CLASS_NAME, + fields: String = configData.joinToString("\n") +): String = """package $namespace; + +public class $className { +$fields +} +""" + +private val EnvironmentConfig.configData: List + get() = EnvironmentConfig::class.java.declaredFields.map { + it.trySetAccessible() + + val (type, name) = it.type.simpleName to it.name + val value = it.get(this).toBuildConfigValue() + + " public static final $type $name = $value;" + } diff --git a/plugins/environment-configuration/src/main/kotlin/configuration/extensions/ExtraPropertiesExtension.kt b/plugins/environment-configuration/src/main/kotlin/configuration/extensions/ExtraPropertiesExtension.kt new file mode 100644 index 000000000..0c2d6f4c7 --- /dev/null +++ b/plugins/environment-configuration/src/main/kotlin/configuration/extensions/ExtraPropertiesExtension.kt @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2022 Proton Technologies AG + * This file is part of Proton AG and ProtonCore. + * + * ProtonCore 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. + * + * ProtonCore 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 ProtonCore. If not, see . + */ + +package configuration.extensions + +import configuration.EnvironmentConfig +import configuration.EnvironmentConfigSettings +import org.gradle.api.plugins.ExtraPropertiesExtension + +private const val PROP_SUFFIX = "ProtonEnvironmentConfig" + +fun ExtraPropertiesExtension.getEnvironmentConfigurationByName( + name: String, + fallbackSettings: EnvironmentConfigSettings = EnvironmentConfigSettings() +): EnvironmentConfig = + if (properties.contains(name + PROP_SUFFIX)) + this[name + PROP_SUFFIX] as? EnvironmentConfigSettings ?: fallbackSettings + else + fallbackSettings + +fun ExtraPropertiesExtension.setEnvironmentConfigurationByName( + name: String, + config: EnvironmentConfig +) { + this[name + PROP_SUFFIX] = config +} diff --git a/plugins/environment-configuration/src/main/kotlin/configuration/extensions/Project.kt b/plugins/environment-configuration/src/main/kotlin/configuration/extensions/Project.kt new file mode 100644 index 000000000..f36f60261 --- /dev/null +++ b/plugins/environment-configuration/src/main/kotlin/configuration/extensions/Project.kt @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 Proton Technologies AG + * This file is part of Proton AG and ProtonCore. + * + * ProtonCore 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. + * + * ProtonCore 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 ProtonCore. If not, see . + */ + +package configuration.extensions + +import configuration.EnvironmentConfig +import org.gradle.api.Project + +fun Project.printEnvironmentConfigDetails(config: EnvironmentConfig) { + logger.debug(" host: ${config.host}") + logger.debug(" api prefix: ${config.apiPrefix}") + logger.debug(" api host: ${config.apiHost}") + logger.debug(" base url: ${config.baseUrl}") + logger.debug(" hv3 host: ${config.hv3Host}") + logger.debug(" hv3 url: ${config.hv3Url}}") + logger.debug(" proxy token: ${config.proxyToken}") +} diff --git a/plugins/environment-configuration/src/main/kotlin/configuration/util/Helpers.kt b/plugins/environment-configuration/src/main/kotlin/configuration/util/Helpers.kt new file mode 100644 index 000000000..face7eb3e --- /dev/null +++ b/plugins/environment-configuration/src/main/kotlin/configuration/util/Helpers.kt @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2022 Proton Technologies AG + * This file is part of Proton AG and ProtonCore. + * + * ProtonCore 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. + * + * ProtonCore 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 ProtonCore. If not, see . + */ + +package configuration.util + +import java.util.concurrent.TimeUnit + +fun getTokenFromCurl(proxyUrl: String): String { + + val process = ProcessBuilder("curl", proxyUrl) + .redirectOutput(ProcessBuilder.Redirect.PIPE) + .redirectError(ProcessBuilder.Redirect.PIPE) + .start() + + try { + val error: String = process.errorStream.bufferedReader().readText() + val output = process.inputStream.bufferedReader().readText() + + // Avoid potential hangs + require(process.waitFor(1, TimeUnit.SECONDS)) { + "Curl process timed out." + } + + require(process.exitValue() == 0) { + "Could not obtain proxy token with exit code ${process.exitValue()}: $error" + } + + require(Regex("^[a-zA-Z0-9]+$").matches(output)) { + "Invalid token format. Expected a single word, got: $output" + } + + return output.trim() + } finally { + process.destroy() + } +} + + +fun Any?.toBuildConfigValue(): String { + return when (this) { + null -> "null" + is Boolean -> "$this" + is String -> "\"$this\"" + else -> throw IllegalArgumentException("Unknown build field conversion for type ${this::class.java.simpleName}") + } +} diff --git a/plugins/settings.gradle.kts b/plugins/settings.gradle.kts index f6bcf329f..639cad52e 100644 --- a/plugins/settings.gradle.kts +++ b/plugins/settings.gradle.kts @@ -27,7 +27,8 @@ include( "jacoco", "tests", "include-core-build", - "publish-core-libraries" + "publish-core-libraries", + "environment-configuration" ) pluginManagement {