Merge pull request #7007 from thundernest/refactor_oauth_setup
Refactor OAuth setup
This commit is contained in:
commit
3699e7d68d
71 changed files with 364 additions and 160 deletions
|
@ -9,6 +9,32 @@ android {
|
|||
applicationId = "net.thunderbird.feature.preview"
|
||||
versionCode = 1
|
||||
versionName = "1.0"
|
||||
|
||||
buildConfigField(
|
||||
"String",
|
||||
"OAUTH_GMAIL_CLIENT_ID",
|
||||
"\"262622259280-5qb3vtj68d5dtudmaif4g9vd3cpar8r3.apps.googleusercontent.com\"",
|
||||
)
|
||||
buildConfigField(
|
||||
"String",
|
||||
"OAUTH_YAHOO_CLIENT_ID",
|
||||
"\"dj0yJmk9ejRCRU1ybmZjQlVBJmQ9WVdrOVVrZEViak4xYmxZbWNHbzlNQT09JnM9Y29uc3VtZXJzZWNyZXQmc3Y9MCZ4PTZj\"",
|
||||
)
|
||||
buildConfigField(
|
||||
"String",
|
||||
"OAUTH_AOL_CLIENT_ID",
|
||||
"\"dj0yJmk9cHYydkJkTUxHcXlYJmQ9WVdrOWVHZHhVVXN4VVV3bWNHbzlNQT09JnM9Y29uc3VtZXJzZWNyZXQmc3Y9MCZ4PTdm\"",
|
||||
)
|
||||
buildConfigField(
|
||||
"String",
|
||||
"OAUTH_MICROSOFT_CLIENT_ID",
|
||||
"\"e647013a-ada4-4114-b419-e43d250f99c5\"",
|
||||
)
|
||||
buildConfigField(
|
||||
"String",
|
||||
"OAUTH_MICROSOFT_REDIRECT_URI_ID",
|
||||
"\"VZF2DYuLYAu4TurFd6usQB2JPts%3D\"",
|
||||
)
|
||||
}
|
||||
|
||||
packaging {
|
||||
|
@ -19,6 +45,17 @@ android {
|
|||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
getByName("release") {
|
||||
isMinifyEnabled = false
|
||||
proguardFiles(
|
||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||
"proguard-rules.pro",
|
||||
)
|
||||
signingConfig = signingConfigs.getByName("debug")
|
||||
}
|
||||
}
|
||||
|
||||
lint {
|
||||
baseline = file("lint-baseline.xml")
|
||||
}
|
||||
|
@ -26,6 +63,7 @@ android {
|
|||
|
||||
dependencies {
|
||||
implementation(projects.core.ui.compose.designsystem)
|
||||
implementation(projects.core.common)
|
||||
|
||||
implementation(projects.feature.onboarding)
|
||||
implementation(projects.feature.account.setup)
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package app.k9mail.feature.preview
|
||||
|
||||
import app.k9mail.core.common.oauth.OAuthConfigurationFactory
|
||||
import app.k9mail.feature.account.setup.featureAccountSetupModule
|
||||
import app.k9mail.feature.preview.auth.AppOAuthConfigurationFactory
|
||||
import okhttp3.OkHttpClient
|
||||
import org.koin.core.module.Module
|
||||
import org.koin.dsl.module
|
||||
|
@ -12,5 +14,7 @@ val featureModule: Module = module {
|
|||
OkHttpClient()
|
||||
}
|
||||
|
||||
single<OAuthConfigurationFactory> { AppOAuthConfigurationFactory() }
|
||||
|
||||
includes(featureAccountSetupModule)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
package app.k9mail.feature.preview.auth
|
||||
|
||||
import app.k9mail.core.common.oauth.OAuthConfiguration
|
||||
import app.k9mail.core.common.oauth.OAuthConfigurationFactory
|
||||
import app.k9mail.feature.preview.BuildConfig
|
||||
|
||||
class AppOAuthConfigurationFactory : OAuthConfigurationFactory {
|
||||
override fun createConfigurations(): Map<List<String>, OAuthConfiguration> {
|
||||
return mapOf(
|
||||
createAolConfiguration(),
|
||||
createGmailConfiguration(),
|
||||
createMicrosoftConfiguration(),
|
||||
createYahooConfiguration(),
|
||||
)
|
||||
}
|
||||
|
||||
private fun createAolConfiguration(): Pair<List<String>, OAuthConfiguration> {
|
||||
return listOf("imap.aol.com", "smtp.aol.com") to OAuthConfiguration(
|
||||
clientId = BuildConfig.OAUTH_AOL_CLIENT_ID,
|
||||
scopes = listOf("mail-w"),
|
||||
authorizationEndpoint = "https://api.login.aol.com/oauth2/request_auth",
|
||||
tokenEndpoint = "https://api.login.aol.com/oauth2/get_token",
|
||||
redirectUri = "${BuildConfig.APPLICATION_ID}://oauth2redirect",
|
||||
)
|
||||
}
|
||||
|
||||
private fun createGmailConfiguration(): Pair<List<String>, OAuthConfiguration> {
|
||||
return listOf(
|
||||
"imap.gmail.com",
|
||||
"imap.googlemail.com",
|
||||
"smtp.gmail.com",
|
||||
"smtp.googlemail.com",
|
||||
) to OAuthConfiguration(
|
||||
clientId = BuildConfig.OAUTH_GMAIL_CLIENT_ID,
|
||||
scopes = listOf("https://mail.google.com/"),
|
||||
authorizationEndpoint = "https://accounts.google.com/o/oauth2/v2/auth",
|
||||
tokenEndpoint = "https://oauth2.googleapis.com/token",
|
||||
redirectUri = "${BuildConfig.APPLICATION_ID}:/oauth2redirect",
|
||||
)
|
||||
}
|
||||
|
||||
private fun createMicrosoftConfiguration(): Pair<List<String>, OAuthConfiguration> {
|
||||
return listOf(
|
||||
"imap.mail.yahoo.com",
|
||||
"smtp.mail.yahoo.com",
|
||||
) to OAuthConfiguration(
|
||||
clientId = BuildConfig.OAUTH_MICROSOFT_CLIENT_ID,
|
||||
scopes = listOf(
|
||||
"https://outlook.office.com/IMAP.AccessAsUser.All",
|
||||
"https://outlook.office.com/SMTP.Send",
|
||||
"offline_access",
|
||||
),
|
||||
authorizationEndpoint = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize",
|
||||
tokenEndpoint = "https://login.microsoftonline.com/common/oauth2/v2.0/token",
|
||||
redirectUri = "msauth://${BuildConfig.APPLICATION_ID}://${BuildConfig.OAUTH_MICROSOFT_REDIRECT_URI_ID}",
|
||||
)
|
||||
}
|
||||
|
||||
private fun createYahooConfiguration(): Pair<List<String>, OAuthConfiguration> {
|
||||
return listOf(
|
||||
"imap.mail.yahoo.com",
|
||||
"smtp.mail.yahoo.com",
|
||||
) to OAuthConfiguration(
|
||||
clientId = BuildConfig.OAUTH_YAHOO_CLIENT_ID,
|
||||
scopes = listOf("mail-w"),
|
||||
authorizationEndpoint = "https://api.login.yahoo.com/oauth2/request_auth",
|
||||
tokenEndpoint = "https://api.login.yahoo.com/oauth2/get_token",
|
||||
redirectUri = "${BuildConfig.APPLICATION_ID}://oauth2redirect",
|
||||
)
|
||||
}
|
||||
}
|
|
@ -28,6 +28,7 @@ dependencies {
|
|||
implementation(libs.mime4j.dom)
|
||||
|
||||
testApi(projects.core.testing)
|
||||
testApi(projects.core.android.testing)
|
||||
testImplementation(projects.mail.testing)
|
||||
testImplementation(projects.backend.imap)
|
||||
testImplementation(projects.mail.protocols.smtp)
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package com.fsck.k9.mailstore
|
||||
|
||||
import app.k9mail.core.common.mail.Protocols
|
||||
import com.fsck.k9.Account
|
||||
import com.fsck.k9.Account.SpecialFolderSelection
|
||||
import com.fsck.k9.Preferences
|
||||
import com.fsck.k9.mail.FolderClass
|
||||
import com.fsck.k9.preferences.Protocols
|
||||
|
||||
/**
|
||||
* Updates special folders in [Account] if they are marked as [SpecialFolderSelection.AUTOMATIC] or if they are marked
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package com.fsck.k9.mailstore
|
||||
|
||||
import app.k9mail.core.common.mail.Protocols
|
||||
import com.fsck.k9.Account
|
||||
import com.fsck.k9.Account.SpecialFolderSelection
|
||||
import com.fsck.k9.Preferences
|
||||
import com.fsck.k9.mail.FolderType
|
||||
import com.fsck.k9.preferences.Protocols
|
||||
import timber.log.Timber
|
||||
|
||||
class SpecialLocalFoldersCreator(
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
package com.fsck.k9.oauth
|
||||
|
||||
class OAuthConfigurationProvider(
|
||||
private val configurations: Map<List<String>, OAuthConfiguration>,
|
||||
private val googleConfiguration: OAuthConfiguration,
|
||||
) {
|
||||
private val hostnameMapping: Map<String, OAuthConfiguration> = buildMap {
|
||||
for ((hostnames, configuration) in configurations) {
|
||||
for (hostname in hostnames) {
|
||||
put(hostname.lowercase(), configuration)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getConfiguration(hostname: String): OAuthConfiguration? {
|
||||
return hostnameMapping[hostname.lowercase()]
|
||||
}
|
||||
|
||||
fun isGoogle(hostname: String): Boolean {
|
||||
return getConfiguration(hostname) == googleConfiguration
|
||||
}
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
package com.fsck.k9.preferences
|
||||
|
||||
import app.k9mail.core.common.mail.Protocols
|
||||
|
||||
object ServerTypeConverter {
|
||||
@JvmStatic
|
||||
fun toServerSettingsType(exportType: String): String = exportType.lowercase()
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.fsck.k9.setup
|
||||
|
||||
import com.fsck.k9.preferences.Protocols
|
||||
import app.k9mail.core.common.mail.Protocols
|
||||
|
||||
class ServerNameSuggester {
|
||||
fun suggestServerName(serverType: String, domainPart: String): String = when (serverType) {
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
package com.fsck.k9.autocrypt
|
||||
|
||||
import app.k9mail.core.android.testing.RobolectricTest
|
||||
import assertk.assertThat
|
||||
import assertk.assertions.isEqualTo
|
||||
import assertk.assertions.isFalse
|
||||
import assertk.assertions.isNotNull
|
||||
import assertk.assertions.isNull
|
||||
import assertk.assertions.isTrue
|
||||
import com.fsck.k9.RobolectricTest
|
||||
import org.junit.Test
|
||||
|
||||
class AutocryptDraftStateHeaderParserTest : RobolectricTest() {
|
||||
|
|
|
@ -5,7 +5,7 @@ import java.io.FileNotFoundException;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import com.fsck.k9.RobolectricTest;
|
||||
import app.k9mail.core.android.testing.RobolectricTest;
|
||||
import com.fsck.k9.mail.MessagingException;
|
||||
import com.fsck.k9.mail.internet.BinaryTempFileBody;
|
||||
import com.fsck.k9.mail.internet.MimeMessage;
|
||||
|
|
|
@ -33,7 +33,7 @@ import com.fsck.k9.mailstore.SendState;
|
|||
import com.fsck.k9.mailstore.SpecialLocalFoldersCreator;
|
||||
import com.fsck.k9.notification.NotificationController;
|
||||
import com.fsck.k9.notification.NotificationStrategy;
|
||||
import com.fsck.k9.preferences.Protocols;
|
||||
import app.k9mail.core.common.mail.Protocols;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package com.fsck.k9.helper
|
||||
|
||||
import app.k9mail.core.android.testing.RobolectricTest
|
||||
import assertk.assertThat
|
||||
import assertk.assertions.isEqualTo
|
||||
import com.fsck.k9.Account
|
||||
import com.fsck.k9.Identity
|
||||
import com.fsck.k9.RobolectricTest
|
||||
import com.fsck.k9.mail.Address
|
||||
import com.fsck.k9.mail.Message
|
||||
import com.fsck.k9.mail.Message.RecipientType
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package com.fsck.k9.helper;
|
||||
|
||||
|
||||
import com.fsck.k9.RobolectricTest;
|
||||
import app.k9mail.core.android.testing.RobolectricTest;
|
||||
import com.fsck.k9.mail.Address;
|
||||
import com.fsck.k9.mail.Message;
|
||||
import com.fsck.k9.mail.internet.MimeMessage;
|
||||
|
@ -10,7 +9,6 @@ import org.junit.Test;
|
|||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
|
||||
public class ListHeadersTest extends RobolectricTest {
|
||||
private static final String[] TEST_EMAIL_ADDRESSES = new String[] {
|
||||
"prettyandsimple@example.com",
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package com.fsck.k9.helper
|
||||
|
||||
import androidx.core.net.toUri
|
||||
import app.k9mail.core.android.testing.RobolectricTest
|
||||
import assertk.assertThat
|
||||
import assertk.assertions.isEqualTo
|
||||
import assertk.assertions.isNull
|
||||
import com.fsck.k9.RobolectricTest
|
||||
import com.fsck.k9.mail.internet.MimeMessage
|
||||
import org.junit.Test
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import java.util.List;
|
|||
|
||||
import android.net.Uri;
|
||||
|
||||
import com.fsck.k9.RobolectricTest;
|
||||
import app.k9mail.core.android.testing.RobolectricTest;
|
||||
import com.fsck.k9.helper.MailTo.CaseInsensitiveParamWrapper;
|
||||
import com.fsck.k9.mail.Address;
|
||||
import org.junit.Rule;
|
||||
|
|
|
@ -4,12 +4,12 @@ import android.graphics.Color
|
|||
import android.text.SpannableString
|
||||
import app.k9mail.core.android.common.contact.Contact
|
||||
import app.k9mail.core.android.common.contact.ContactRepository
|
||||
import app.k9mail.core.android.testing.RobolectricTest
|
||||
import app.k9mail.core.common.mail.EmailAddress
|
||||
import app.k9mail.core.common.mail.toEmailAddressOrThrow
|
||||
import assertk.assertThat
|
||||
import assertk.assertions.isEqualTo
|
||||
import assertk.assertions.isInstanceOf
|
||||
import com.fsck.k9.RobolectricTest
|
||||
import com.fsck.k9.helper.MessageHelper.Companion.toFriendly
|
||||
import com.fsck.k9.mail.Address
|
||||
import org.junit.Test
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
package com.fsck.k9.helper;
|
||||
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import app.k9mail.core.android.testing.RobolectricTest;
|
||||
import com.fsck.k9.Account;
|
||||
import com.fsck.k9.RobolectricTest;
|
||||
import com.fsck.k9.helper.ReplyToParser.ReplyToAddresses;
|
||||
import com.fsck.k9.mail.Address;
|
||||
import com.fsck.k9.mail.Message;
|
||||
|
|
|
@ -5,7 +5,7 @@ import java.util.Map;
|
|||
|
||||
import android.net.Uri;
|
||||
|
||||
import com.fsck.k9.RobolectricTest;
|
||||
import app.k9mail.core.android.testing.RobolectricTest;
|
||||
import com.fsck.k9.mail.BodyPart;
|
||||
import com.fsck.k9.mail.Multipart;
|
||||
import com.fsck.k9.mail.Part;
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package com.fsck.k9.message
|
||||
|
||||
import app.k9mail.core.android.testing.RobolectricTest
|
||||
import assertk.assertThat
|
||||
import assertk.assertions.isGreaterThan
|
||||
import com.fsck.k9.Account.QuoteStyle
|
||||
import com.fsck.k9.Identity
|
||||
import com.fsck.k9.RobolectricTest
|
||||
import com.fsck.k9.mail.internet.MimeHeaderChecker
|
||||
import com.fsck.k9.mail.internet.TextBody
|
||||
import org.junit.Test
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package com.fsck.k9.message
|
||||
|
||||
import app.k9mail.core.android.testing.RobolectricTest
|
||||
import assertk.assertThat
|
||||
import assertk.assertions.contains
|
||||
import com.fsck.k9.RobolectricTest
|
||||
import com.fsck.k9.helper.toCrLf
|
||||
import org.junit.Test
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package com.fsck.k9.message;
|
||||
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
|
@ -13,10 +12,10 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import app.k9mail.core.android.testing.RobolectricTest;
|
||||
import com.fsck.k9.Account.QuoteStyle;
|
||||
import com.fsck.k9.CoreResourceProvider;
|
||||
import com.fsck.k9.Identity;
|
||||
import com.fsck.k9.RobolectricTest;
|
||||
import com.fsck.k9.TestCoreResourceProvider;
|
||||
import com.fsck.k9.mail.Address;
|
||||
import com.fsck.k9.mail.BodyPart;
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
package com.fsck.k9.message.extractors;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.fsck.k9.RobolectricTest;
|
||||
import app.k9mail.core.android.testing.RobolectricTest;
|
||||
import com.fsck.k9.mail.Part;
|
||||
import com.fsck.k9.mail.internet.MimeBodyPart;
|
||||
import com.fsck.k9.mail.internet.MimeHeader;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package com.fsck.k9.message.quote
|
||||
|
||||
import app.k9mail.core.android.testing.RobolectricTest
|
||||
import assertk.assertThat
|
||||
import assertk.assertions.isEqualTo
|
||||
import com.fsck.k9.Account.QuoteStyle
|
||||
import com.fsck.k9.RobolectricTest
|
||||
import com.fsck.k9.TestCoreResourceProvider
|
||||
import com.fsck.k9.mail.Address
|
||||
import com.fsck.k9.mail.Message
|
||||
|
|
|
@ -5,8 +5,8 @@ import android.app.PendingIntent
|
|||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import app.k9mail.core.android.testing.RobolectricTest
|
||||
import com.fsck.k9.Account
|
||||
import com.fsck.k9.RobolectricTest
|
||||
import com.fsck.k9.testing.MockHelper.mockBuilder
|
||||
import org.junit.Test
|
||||
import org.mockito.Mockito.verify
|
||||
|
|
|
@ -5,8 +5,8 @@ import android.app.PendingIntent
|
|||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import app.k9mail.core.android.testing.RobolectricTest
|
||||
import com.fsck.k9.Account
|
||||
import com.fsck.k9.RobolectricTest
|
||||
import com.fsck.k9.testing.MockHelper.mockBuilder
|
||||
import org.junit.Test
|
||||
import org.mockito.Mockito.verify
|
||||
|
|
|
@ -2,8 +2,8 @@ package com.fsck.k9.notification
|
|||
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import app.k9mail.core.android.testing.RobolectricTest
|
||||
import com.fsck.k9.Account
|
||||
import com.fsck.k9.RobolectricTest
|
||||
import com.fsck.k9.testing.MockHelper.mockBuilder
|
||||
import org.junit.Test
|
||||
import org.mockito.Mockito.verify
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package com.fsck.k9.notification
|
||||
|
||||
import app.k9mail.core.android.common.contact.ContactRepository
|
||||
import app.k9mail.core.android.testing.RobolectricTest
|
||||
import assertk.assertThat
|
||||
import assertk.assertions.isEqualTo
|
||||
import com.fsck.k9.Account
|
||||
import com.fsck.k9.RobolectricTest
|
||||
import com.fsck.k9.controller.MessageReference
|
||||
import com.fsck.k9.mail.Address
|
||||
import com.fsck.k9.mail.Message.RecipientType
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.fsck.k9.notification
|
||||
|
||||
import app.k9mail.core.android.testing.RobolectricTest
|
||||
import assertk.assertThat
|
||||
import assertk.assertions.containsExactly
|
||||
import assertk.assertions.hasSize
|
||||
|
@ -12,7 +13,6 @@ import assertk.assertions.isNull
|
|||
import assertk.assertions.isSameAs
|
||||
import assertk.assertions.isTrue
|
||||
import com.fsck.k9.Account
|
||||
import com.fsck.k9.RobolectricTest
|
||||
import com.fsck.k9.controller.MessageReference
|
||||
import kotlin.test.assertNotNull
|
||||
import org.junit.Test
|
||||
|
|
|
@ -5,8 +5,8 @@ import android.app.PendingIntent
|
|||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import app.k9mail.core.android.testing.RobolectricTest
|
||||
import com.fsck.k9.Account
|
||||
import com.fsck.k9.RobolectricTest
|
||||
import com.fsck.k9.testing.MockHelper.mockBuilder
|
||||
import org.junit.Test
|
||||
import org.mockito.ArgumentMatchers.anyLong
|
||||
|
|
|
@ -5,8 +5,8 @@ import android.app.PendingIntent
|
|||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import app.k9mail.core.android.testing.RobolectricTest
|
||||
import com.fsck.k9.Account
|
||||
import com.fsck.k9.RobolectricTest
|
||||
import com.fsck.k9.mailstore.LocalFolder
|
||||
import com.fsck.k9.notification.NotificationIds.getFetchingMailNotificationId
|
||||
import com.fsck.k9.testing.MockHelper.mockBuilder
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.fsck.k9.setup;
|
||||
|
||||
|
||||
import com.fsck.k9.preferences.Protocols;
|
||||
import app.k9mail.core.common.mail.Protocols;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
package com.fsck.k9
|
||||
|
||||
import app.k9mail.core.common.oauth.OAuthConfigurationFactory
|
||||
import app.k9mail.ui.widget.list.messageListWidgetModule
|
||||
import com.fsck.k9.auth.createOAuthConfigurationProvider
|
||||
import com.fsck.k9.auth.AppOAuthConfigurationFactory
|
||||
import com.fsck.k9.backends.backendsModule
|
||||
import com.fsck.k9.controller.ControllerExtension
|
||||
import com.fsck.k9.crypto.EncryptionExtractor
|
||||
|
@ -29,7 +30,7 @@ private val mainAppModule = module {
|
|||
single(named("controllerExtensions")) { emptyList<ControllerExtension>() }
|
||||
single<EncryptionExtractor> { OpenPgpEncryptionExtractor.newInstance() }
|
||||
single<StoragePersister> { K9StoragePersister(get()) }
|
||||
single { createOAuthConfigurationProvider() }
|
||||
single<OAuthConfigurationFactory> { AppOAuthConfigurationFactory() }
|
||||
}
|
||||
|
||||
val appModules = listOf(
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
package com.fsck.k9.auth
|
||||
|
||||
import app.k9mail.core.common.oauth.OAuthConfiguration
|
||||
import app.k9mail.core.common.oauth.OAuthConfigurationFactory
|
||||
import com.fsck.k9.BuildConfig
|
||||
|
||||
class AppOAuthConfigurationFactory : OAuthConfigurationFactory {
|
||||
override fun createConfigurations(): Map<List<String>, OAuthConfiguration> {
|
||||
return mapOf(
|
||||
createAolConfiguration(),
|
||||
createGmailConfiguration(),
|
||||
createMicrosoftConfiguration(),
|
||||
createYahooConfiguration(),
|
||||
)
|
||||
}
|
||||
|
||||
private fun createAolConfiguration(): Pair<List<String>, OAuthConfiguration> {
|
||||
return listOf("imap.aol.com", "smtp.aol.com") to OAuthConfiguration(
|
||||
clientId = BuildConfig.OAUTH_AOL_CLIENT_ID,
|
||||
scopes = listOf("mail-w"),
|
||||
authorizationEndpoint = "https://api.login.aol.com/oauth2/request_auth",
|
||||
tokenEndpoint = "https://api.login.aol.com/oauth2/get_token",
|
||||
redirectUri = "${BuildConfig.APPLICATION_ID}://oauth2redirect",
|
||||
)
|
||||
}
|
||||
|
||||
private fun createGmailConfiguration(): Pair<List<String>, OAuthConfiguration> {
|
||||
return listOf(
|
||||
"imap.gmail.com",
|
||||
"imap.googlemail.com",
|
||||
"smtp.gmail.com",
|
||||
"smtp.googlemail.com",
|
||||
) to OAuthConfiguration(
|
||||
clientId = BuildConfig.OAUTH_GMAIL_CLIENT_ID,
|
||||
scopes = listOf("https://mail.google.com/"),
|
||||
authorizationEndpoint = "https://accounts.google.com/o/oauth2/v2/auth",
|
||||
tokenEndpoint = "https://oauth2.googleapis.com/token",
|
||||
redirectUri = "${BuildConfig.APPLICATION_ID}:/oauth2redirect",
|
||||
)
|
||||
}
|
||||
|
||||
private fun createMicrosoftConfiguration(): Pair<List<String>, OAuthConfiguration> {
|
||||
return listOf(
|
||||
"imap.mail.yahoo.com",
|
||||
"smtp.mail.yahoo.com",
|
||||
) to OAuthConfiguration(
|
||||
clientId = BuildConfig.OAUTH_MICROSOFT_CLIENT_ID,
|
||||
scopes = listOf(
|
||||
"https://outlook.office.com/IMAP.AccessAsUser.All",
|
||||
"https://outlook.office.com/SMTP.Send",
|
||||
"offline_access",
|
||||
),
|
||||
authorizationEndpoint = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize",
|
||||
tokenEndpoint = "https://login.microsoftonline.com/common/oauth2/v2.0/token",
|
||||
redirectUri = BuildConfig.OAUTH_MICROSOFT_REDIRECT_URI,
|
||||
)
|
||||
}
|
||||
|
||||
private fun createYahooConfiguration(): Pair<List<String>, OAuthConfiguration> {
|
||||
return listOf(
|
||||
"imap.mail.yahoo.com",
|
||||
"smtp.mail.yahoo.com",
|
||||
) to OAuthConfiguration(
|
||||
clientId = BuildConfig.OAUTH_YAHOO_CLIENT_ID,
|
||||
scopes = listOf("mail-w"),
|
||||
authorizationEndpoint = "https://api.login.yahoo.com/oauth2/request_auth",
|
||||
tokenEndpoint = "https://api.login.yahoo.com/oauth2/get_token",
|
||||
redirectUri = "${BuildConfig.APPLICATION_ID}://oauth2redirect",
|
||||
)
|
||||
}
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
package com.fsck.k9.auth
|
||||
|
||||
import com.fsck.k9.BuildConfig
|
||||
import com.fsck.k9.oauth.OAuthConfiguration
|
||||
import com.fsck.k9.oauth.OAuthConfigurationProvider
|
||||
|
||||
fun createOAuthConfigurationProvider(): OAuthConfigurationProvider {
|
||||
val redirectUriSlash = BuildConfig.APPLICATION_ID + ":/oauth2redirect"
|
||||
val redirectUriDoubleSlash = BuildConfig.APPLICATION_ID + "://oauth2redirect"
|
||||
|
||||
val googleConfig = OAuthConfiguration(
|
||||
clientId = BuildConfig.OAUTH_GMAIL_CLIENT_ID,
|
||||
scopes = listOf("https://mail.google.com/"),
|
||||
authorizationEndpoint = "https://accounts.google.com/o/oauth2/v2/auth",
|
||||
tokenEndpoint = "https://oauth2.googleapis.com/token",
|
||||
redirectUri = redirectUriSlash,
|
||||
)
|
||||
|
||||
return OAuthConfigurationProvider(
|
||||
configurations = mapOf(
|
||||
listOf("imap.gmail.com", "imap.googlemail.com", "smtp.gmail.com", "smtp.googlemail.com") to googleConfig,
|
||||
listOf("imap.mail.yahoo.com", "smtp.mail.yahoo.com") to OAuthConfiguration(
|
||||
clientId = BuildConfig.OAUTH_YAHOO_CLIENT_ID,
|
||||
scopes = listOf("mail-w"),
|
||||
authorizationEndpoint = "https://api.login.yahoo.com/oauth2/request_auth",
|
||||
tokenEndpoint = "https://api.login.yahoo.com/oauth2/get_token",
|
||||
redirectUri = redirectUriDoubleSlash,
|
||||
),
|
||||
listOf("imap.aol.com", "smtp.aol.com") to OAuthConfiguration(
|
||||
clientId = BuildConfig.OAUTH_AOL_CLIENT_ID,
|
||||
scopes = listOf("mail-w"),
|
||||
authorizationEndpoint = "https://api.login.aol.com/oauth2/request_auth",
|
||||
tokenEndpoint = "https://api.login.aol.com/oauth2/get_token",
|
||||
redirectUri = redirectUriDoubleSlash,
|
||||
),
|
||||
listOf("outlook.office365.com", "smtp.office365.com") to OAuthConfiguration(
|
||||
clientId = BuildConfig.OAUTH_MICROSOFT_CLIENT_ID,
|
||||
scopes = listOf(
|
||||
"https://outlook.office.com/IMAP.AccessAsUser.All",
|
||||
"https://outlook.office.com/SMTP.Send",
|
||||
"offline_access",
|
||||
),
|
||||
authorizationEndpoint = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize",
|
||||
tokenEndpoint = "https://login.microsoftonline.com/common/oauth2/v2.0/token",
|
||||
redirectUri = BuildConfig.OAUTH_MICROSOFT_REDIRECT_URI,
|
||||
),
|
||||
),
|
||||
googleConfiguration = googleConfig,
|
||||
)
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
package com.fsck.k9.preferences.migrations
|
||||
|
||||
import android.database.sqlite.SQLiteDatabase
|
||||
import app.k9mail.core.common.mail.Protocols
|
||||
import com.fsck.k9.ServerSettingsSerializer
|
||||
import com.fsck.k9.preferences.Protocols
|
||||
|
||||
/**
|
||||
* Rewrite 'folderPushMode' value of non-IMAP accounts to 'NONE'.
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package com.fsck.k9.storage.migrations
|
||||
|
||||
import android.database.sqlite.SQLiteDatabase
|
||||
import app.k9mail.core.common.mail.Protocols
|
||||
import com.fsck.k9.mailstore.MigrationsHelper
|
||||
import com.fsck.k9.preferences.Protocols
|
||||
|
||||
internal object MigrationTo65 {
|
||||
@JvmStatic
|
||||
|
|
|
@ -3,9 +3,9 @@ package com.fsck.k9.storage.migrations
|
|||
import android.content.ContentValues
|
||||
import android.database.sqlite.SQLiteDatabase
|
||||
import app.k9mail.core.android.common.database.map
|
||||
import app.k9mail.core.common.mail.Protocols
|
||||
import com.fsck.k9.Account
|
||||
import com.fsck.k9.mailstore.MigrationsHelper
|
||||
import com.fsck.k9.preferences.Protocols
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,8 +5,8 @@ plugins {
|
|||
dependencies {
|
||||
implementation(projects.app.core)
|
||||
|
||||
api(libs.junit)
|
||||
api(libs.robolectric)
|
||||
api(projects.core.android.testing)
|
||||
|
||||
api(libs.koin.core)
|
||||
api(libs.mockito.core)
|
||||
api(libs.mockito.kotlin)
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
package com.fsck.k9.account
|
||||
|
||||
import android.content.res.Resources
|
||||
import app.k9mail.core.common.mail.Protocols
|
||||
import com.fsck.k9.Account.DeletePolicy
|
||||
import com.fsck.k9.Preferences
|
||||
import com.fsck.k9.core.R
|
||||
import com.fsck.k9.mail.ConnectionSecurity
|
||||
import com.fsck.k9.preferences.Protocols
|
||||
|
||||
/**
|
||||
* Deals with logic surrounding account creation.
|
||||
|
|
|
@ -4,13 +4,13 @@ import android.content.Context
|
|||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import app.k9mail.core.common.mail.Protocols
|
||||
import com.fsck.k9.Account
|
||||
import com.fsck.k9.Preferences
|
||||
import com.fsck.k9.helper.EmailHelper.getDomainFromEmailAddress
|
||||
import com.fsck.k9.mail.ConnectionSecurity
|
||||
import com.fsck.k9.mail.ServerSettings
|
||||
import com.fsck.k9.mailstore.SpecialLocalFoldersCreator
|
||||
import com.fsck.k9.preferences.Protocols
|
||||
import com.fsck.k9.setup.ServerNameSuggester
|
||||
import com.fsck.k9.ui.R
|
||||
import com.fsck.k9.ui.base.K9Activity
|
||||
|
|
|
@ -38,7 +38,7 @@ import com.fsck.k9.mail.ConnectionSecurity;
|
|||
import com.fsck.k9.mail.MailServerDirection;
|
||||
import com.fsck.k9.mail.ServerSettings;
|
||||
import com.fsck.k9.mail.store.imap.ImapStoreSettings;
|
||||
import com.fsck.k9.preferences.Protocols;
|
||||
import app.k9mail.core.common.mail.Protocols;
|
||||
import com.fsck.k9.ui.R;
|
||||
import com.fsck.k9.ui.base.extensions.TextInputLayoutHelper;
|
||||
import com.fsck.k9.view.ClientCertificateSpinner;
|
||||
|
|
|
@ -28,7 +28,7 @@ import com.fsck.k9.Account;
|
|||
import com.fsck.k9.DI;
|
||||
import com.fsck.k9.LocalKeyStoreManager;
|
||||
import com.fsck.k9.Preferences;
|
||||
import com.fsck.k9.preferences.Protocols;
|
||||
import app.k9mail.core.common.mail.Protocols;
|
||||
import com.fsck.k9.ui.R;
|
||||
import com.fsck.k9.account.AccountCreator;
|
||||
import com.fsck.k9.ui.base.K9Activity;
|
||||
|
|
|
@ -14,9 +14,9 @@ import androidx.lifecycle.DefaultLifecycleObserver
|
|||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import app.k9mail.core.common.oauth.OAuthConfiguration
|
||||
import app.k9mail.core.common.oauth.OAuthConfigurationProvider
|
||||
import com.fsck.k9.Account
|
||||
import com.fsck.k9.oauth.OAuthConfiguration
|
||||
import com.fsck.k9.oauth.OAuthConfigurationProvider
|
||||
import com.fsck.k9.preferences.AccountManager
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
@ -72,7 +72,7 @@ class AuthViewModel(
|
|||
}
|
||||
|
||||
fun isUsingGoogle(account: Account): Boolean {
|
||||
return oAuthConfigurationProvider.isGoogle(account.incomingServerSettings.host!!)
|
||||
return GoogleOAuthHelper.isGoogle(account.incomingServerSettings.host!!)
|
||||
}
|
||||
|
||||
private fun getOrCreateAuthState(account: Account): AuthState {
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package com.fsck.k9.activity.setup
|
||||
|
||||
object GoogleOAuthHelper {
|
||||
fun isGoogle(hostname: String): Boolean {
|
||||
return hostname.lowercase().endsWith(".gmail.com") ||
|
||||
hostname.lowercase().endsWith(".googlemail.com")
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@ import com.fsck.k9.Account.DeletePolicy;
|
|||
import com.fsck.k9.Preferences;
|
||||
import com.fsck.k9.RobolectricTest;
|
||||
import com.fsck.k9.mail.ConnectionSecurity;
|
||||
import com.fsck.k9.preferences.Protocols;
|
||||
import app.k9mail.core.common.mail.Protocols;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
package com.fsck.k9.activity.compose
|
||||
|
||||
import android.os.Bundle
|
||||
import app.k9mail.core.android.testing.RobolectricTest
|
||||
import assertk.assertThat
|
||||
import assertk.assertions.isFalse
|
||||
import assertk.assertions.isSameAs
|
||||
import assertk.assertions.isTrue
|
||||
import com.fsck.k9.Identity
|
||||
import com.fsck.k9.RobolectricTest
|
||||
import com.fsck.k9.mail.Address
|
||||
import org.junit.Test
|
||||
import org.mockito.kotlin.doReturn
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package com.fsck.k9.contacts
|
||||
|
||||
import app.k9mail.core.android.testing.RobolectricTest
|
||||
import assertk.assertThat
|
||||
import assertk.assertions.isEqualTo
|
||||
import com.fsck.k9.RobolectricTest
|
||||
import com.fsck.k9.mail.Address
|
||||
import org.junit.Test
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package com.fsck.k9.ui
|
||||
|
||||
import app.k9mail.core.android.testing.RobolectricTest
|
||||
import assertk.assertThat
|
||||
import assertk.assertions.isEqualTo
|
||||
import assertk.assertions.size
|
||||
import com.fsck.k9.RobolectricTest
|
||||
import com.fsck.k9.core.R
|
||||
import org.junit.Test
|
||||
import org.robolectric.RuntimeEnvironment
|
||||
|
|
|
@ -2,10 +2,10 @@ package com.fsck.k9.ui.helper
|
|||
|
||||
import android.os.Build
|
||||
import android.os.SystemClock
|
||||
import app.k9mail.core.android.testing.RobolectricTest
|
||||
import app.k9mail.core.testing.TestClock
|
||||
import assertk.assertThat
|
||||
import assertk.assertions.isEqualTo
|
||||
import com.fsck.k9.RobolectricTest
|
||||
import java.time.LocalDate
|
||||
import java.time.LocalDateTime
|
||||
import java.time.ZoneId
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package com.fsck.k9.ui.helper
|
||||
|
||||
import app.k9mail.core.android.testing.RobolectricTest
|
||||
import assertk.assertThat
|
||||
import assertk.assertions.isEqualTo
|
||||
import com.fsck.k9.RobolectricTest
|
||||
import org.junit.Test
|
||||
import org.robolectric.RuntimeEnvironment
|
||||
import org.robolectric.annotation.Config
|
||||
|
|
|
@ -4,6 +4,7 @@ import android.graphics.Color
|
|||
import android.text.Spannable
|
||||
import android.text.style.ForegroundColorSpan
|
||||
import androidx.core.text.getSpans
|
||||
import app.k9mail.core.android.testing.RobolectricTest
|
||||
import assertk.assertThat
|
||||
import assertk.assertions.containsExactly
|
||||
import assertk.assertions.isEqualTo
|
||||
|
@ -12,7 +13,6 @@ import assertk.assertions.isNotNull
|
|||
import assertk.assertions.isNull
|
||||
import com.fsck.k9.Account
|
||||
import com.fsck.k9.Identity
|
||||
import com.fsck.k9.RobolectricTest
|
||||
import com.fsck.k9.helper.ContactNameProvider
|
||||
import com.fsck.k9.mail.Address
|
||||
import org.junit.Test
|
||||
|
|
|
@ -11,6 +11,7 @@ import android.widget.TextView
|
|||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.isGone
|
||||
import androidx.core.view.isVisible
|
||||
import app.k9mail.core.android.testing.RobolectricTest
|
||||
import app.k9mail.core.testing.TestClock
|
||||
import assertk.Assert
|
||||
import assertk.assertThat
|
||||
|
@ -21,7 +22,6 @@ import com.fsck.k9.Account
|
|||
import com.fsck.k9.FontSizes
|
||||
import com.fsck.k9.FontSizes.FONT_DEFAULT
|
||||
import com.fsck.k9.FontSizes.LARGE
|
||||
import com.fsck.k9.RobolectricTest
|
||||
import com.fsck.k9.UiDensity
|
||||
import com.fsck.k9.contacts.ContactPictureLoader
|
||||
import com.fsck.k9.mail.Address
|
||||
|
|
|
@ -4,13 +4,13 @@ import android.graphics.Color
|
|||
import android.text.Spannable
|
||||
import android.text.style.ForegroundColorSpan
|
||||
import androidx.core.text.getSpans
|
||||
import app.k9mail.core.android.testing.RobolectricTest
|
||||
import assertk.assertThat
|
||||
import assertk.assertions.containsExactly
|
||||
import assertk.assertions.isEqualTo
|
||||
import assertk.assertions.isInstanceOf
|
||||
import com.fsck.k9.Account
|
||||
import com.fsck.k9.Identity
|
||||
import com.fsck.k9.RobolectricTest
|
||||
import com.fsck.k9.helper.ContactNameProvider
|
||||
import com.fsck.k9.mail.Address
|
||||
import org.junit.Test
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package com.fsck.k9.ui.messageview
|
||||
|
||||
import app.k9mail.core.android.testing.RobolectricTest
|
||||
import assertk.assertThat
|
||||
import assertk.assertions.isEqualTo
|
||||
import assertk.assertions.isNull
|
||||
import com.fsck.k9.RobolectricTest
|
||||
import org.junit.Test
|
||||
|
||||
class RecipientLayoutCreatorTest : RobolectricTest() {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package app.k9mail.core.android.common
|
||||
|
||||
import app.k9mail.core.android.common.test.externalModule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.koin.android.ext.koin.androidContext
|
||||
|
@ -14,7 +15,10 @@ internal class CoreCommonAndroidModuleKtTest {
|
|||
@Test
|
||||
fun `should have a valid di module`() {
|
||||
koinApplication {
|
||||
modules(coreCommonAndroidModule)
|
||||
modules(
|
||||
externalModule,
|
||||
coreCommonAndroidModule,
|
||||
)
|
||||
androidContext(RuntimeEnvironment.getApplication())
|
||||
checkModules()
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package app.k9mail.core.android.common.contact
|
||||
|
||||
import app.k9mail.core.android.common.coreCommonAndroidModule
|
||||
import app.k9mail.core.android.common.test.externalModule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.koin.android.ext.koin.androidContext
|
||||
|
@ -11,13 +12,15 @@ import org.robolectric.RuntimeEnvironment
|
|||
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
internal class ContactKoinModuleKtTest {
|
||||
|
||||
@Test
|
||||
fun `should have a valid di module`() {
|
||||
koinApplication {
|
||||
modules(coreCommonAndroidModule)
|
||||
|
||||
modules(contactModule)
|
||||
|
||||
modules(
|
||||
externalModule,
|
||||
coreCommonAndroidModule,
|
||||
contactModule,
|
||||
)
|
||||
androidContext(RuntimeEnvironment.getApplication())
|
||||
checkModules()
|
||||
}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
package app.k9mail.core.android.common.test
|
||||
|
||||
import app.k9mail.core.common.oauth.OAuthConfigurationFactory
|
||||
import org.koin.dsl.module
|
||||
|
||||
internal val externalModule = module {
|
||||
single<OAuthConfigurationFactory> {
|
||||
OAuthConfigurationFactory { emptyMap() }
|
||||
}
|
||||
}
|
12
core/android/testing/build.gradle.kts
Normal file
12
core/android/testing/build.gradle.kts
Normal file
|
@ -0,0 +1,12 @@
|
|||
plugins {
|
||||
id(ThunderbirdPlugins.Library.android)
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "app.k9mail.core.android.testing"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(libs.junit)
|
||||
api(libs.robolectric)
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package com.fsck.k9
|
||||
package app.k9mail.core.android.testing
|
||||
|
||||
import android.app.Application
|
||||
import org.junit.runner.RunWith
|
||||
|
@ -6,9 +6,7 @@ import org.robolectric.RobolectricTestRunner
|
|||
import org.robolectric.annotation.Config
|
||||
|
||||
/**
|
||||
* A Robolectric test that does not create an instance of our [Application] class [K9].
|
||||
*
|
||||
* See also [K9RobolectricTest].
|
||||
* A Robolectric test that does not create an instance of our [Application].
|
||||
*/
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
@Config(application = EmptyApplication::class)
|
|
@ -1,9 +1,17 @@
|
|||
package app.k9mail.core.common
|
||||
|
||||
import app.k9mail.core.common.oauth.InMemoryOAuthConfigurationProvider
|
||||
import app.k9mail.core.common.oauth.OAuthConfigurationProvider
|
||||
import kotlinx.datetime.Clock
|
||||
import org.koin.core.module.Module
|
||||
import org.koin.dsl.module
|
||||
|
||||
val coreCommonModule: Module = module {
|
||||
single<Clock> { Clock.System }
|
||||
|
||||
single<OAuthConfigurationProvider> {
|
||||
InMemoryOAuthConfigurationProvider(
|
||||
configurationFactory = get(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package com.fsck.k9.preferences
|
||||
package app.k9mail.core.common.mail
|
||||
|
||||
object Protocols {
|
||||
const val IMAP = "imap"
|
|
@ -0,0 +1,18 @@
|
|||
package app.k9mail.core.common.oauth
|
||||
|
||||
internal class InMemoryOAuthConfigurationProvider(
|
||||
private val configurationFactory: OAuthConfigurationFactory,
|
||||
) : OAuthConfigurationProvider {
|
||||
|
||||
private val hostnameMapping: Map<String, OAuthConfiguration> = buildMap {
|
||||
for ((hostnames, configuration) in configurationFactory.createConfigurations()) {
|
||||
for (hostname in hostnames) {
|
||||
put(hostname.lowercase(), configuration)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getConfiguration(hostname: String): OAuthConfiguration? {
|
||||
return hostnameMapping[hostname.lowercase()]
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package com.fsck.k9.oauth
|
||||
package app.k9mail.core.common.oauth
|
||||
|
||||
data class OAuthConfiguration(
|
||||
val clientId: String,
|
|
@ -0,0 +1,5 @@
|
|||
package app.k9mail.core.common.oauth
|
||||
|
||||
fun interface OAuthConfigurationFactory {
|
||||
fun createConfigurations(): Map<List<String>, OAuthConfiguration>
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package app.k9mail.core.common.oauth
|
||||
|
||||
interface OAuthConfigurationProvider {
|
||||
|
||||
fun getConfiguration(hostname: String): OAuthConfiguration?
|
||||
}
|
|
@ -1,15 +1,32 @@
|
|||
package app.k9mail.core.common
|
||||
|
||||
import app.k9mail.core.common.oauth.OAuthConfigurationFactory
|
||||
import org.junit.Test
|
||||
import org.koin.core.annotation.KoinExperimentalAPI
|
||||
import org.koin.dsl.koinApplication
|
||||
import org.koin.dsl.module
|
||||
import org.koin.test.check.checkModules
|
||||
import org.koin.test.verify.verify
|
||||
|
||||
@OptIn(KoinExperimentalAPI::class)
|
||||
internal class CoreCommonModuleKtTest {
|
||||
|
||||
private val externalModule = module {
|
||||
single<OAuthConfigurationFactory> {
|
||||
OAuthConfigurationFactory { emptyMap() }
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should have a valid di module`() {
|
||||
coreCommonModule.verify(
|
||||
extraTypes = listOf(
|
||||
OAuthConfigurationFactory::class,
|
||||
),
|
||||
)
|
||||
|
||||
koinApplication {
|
||||
modules(coreCommonModule)
|
||||
modules(externalModule, coreCommonModule)
|
||||
checkModules()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,13 +3,13 @@ plugins {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
implementation(projects.app.core)
|
||||
implementation(projects.core.common)
|
||||
implementation(projects.mail.common)
|
||||
implementation(projects.feature.autodiscovery.api)
|
||||
|
||||
implementation(libs.timber)
|
||||
|
||||
testImplementation(projects.app.testing)
|
||||
testImplementation(projects.core.android.testing)
|
||||
testImplementation(projects.backend.imap)
|
||||
testImplementation(libs.robolectric)
|
||||
testImplementation(libs.androidx.test.core)
|
||||
|
|
|
@ -5,11 +5,11 @@ import android.net.Uri
|
|||
import app.k9mail.autodiscovery.api.ConnectionSettingsDiscovery
|
||||
import app.k9mail.autodiscovery.api.DiscoveredServerSettings
|
||||
import app.k9mail.autodiscovery.api.DiscoveryResults
|
||||
import app.k9mail.core.common.mail.Protocols
|
||||
import app.k9mail.core.common.oauth.OAuthConfigurationProvider
|
||||
import com.fsck.k9.helper.EmailHelper
|
||||
import com.fsck.k9.mail.AuthType
|
||||
import com.fsck.k9.mail.ConnectionSecurity
|
||||
import com.fsck.k9.oauth.OAuthConfigurationProvider
|
||||
import com.fsck.k9.preferences.Protocols
|
||||
import org.xmlpull.v1.XmlPullParser
|
||||
import timber.log.Timber
|
||||
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
package app.k9mail.autodiscovery.providersxml
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import app.k9mail.core.android.testing.RobolectricTest
|
||||
import app.k9mail.core.common.oauth.OAuthConfiguration
|
||||
import app.k9mail.core.common.oauth.OAuthConfigurationProvider
|
||||
import assertk.assertThat
|
||||
import assertk.assertions.isEqualTo
|
||||
import assertk.assertions.isNotNull
|
||||
import assertk.assertions.isNull
|
||||
import com.fsck.k9.RobolectricTest
|
||||
import com.fsck.k9.mail.AuthType
|
||||
import com.fsck.k9.mail.ConnectionSecurity
|
||||
import com.fsck.k9.oauth.OAuthConfiguration
|
||||
import com.fsck.k9.oauth.OAuthConfigurationProvider
|
||||
import org.junit.Test
|
||||
|
||||
class ProvidersXmlDiscoveryTest : RobolectricTest() {
|
||||
|
@ -46,19 +46,22 @@ class ProvidersXmlDiscoveryTest : RobolectricTest() {
|
|||
}
|
||||
|
||||
private fun createOAuthConfigurationProvider(): OAuthConfigurationProvider {
|
||||
val googleConfig = OAuthConfiguration(
|
||||
return object : OAuthConfigurationProvider {
|
||||
override fun getConfiguration(hostname: String): OAuthConfiguration? {
|
||||
return when (hostname) {
|
||||
"imap.gmail.com" -> oAuthConfiguration
|
||||
"smtp.gmail.com" -> oAuthConfiguration
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val oAuthConfiguration = OAuthConfiguration(
|
||||
clientId = "irrelevant",
|
||||
scopes = listOf("irrelevant"),
|
||||
authorizationEndpoint = "irrelevant",
|
||||
tokenEndpoint = "irrelevant",
|
||||
redirectUri = "irrelevant",
|
||||
)
|
||||
|
||||
return OAuthConfigurationProvider(
|
||||
configurations = mapOf(
|
||||
listOf("imap.gmail.com", "smtp.gmail.com") to googleConfig,
|
||||
),
|
||||
googleConfiguration = googleConfig,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@ include(
|
|||
":core:common",
|
||||
":core:testing",
|
||||
":core:android:common",
|
||||
":core:android:testing",
|
||||
":core:ui:compose:common",
|
||||
":core:ui:compose:designsystem",
|
||||
":core:ui:compose:theme",
|
||||
|
|
Loading…
Reference in a new issue