0
0
mirror of https://github.com/thunderbird/thunderbird-android.git synced 2024-09-20 12:12:15 +02:00

IMAP: Add support for sending ID command with app name

This commit is contained in:
Self Not Found 2023-04-23 12:35:37 +08:00 committed by cketti
parent 6e27fe5c84
commit f2ce1fe344
17 changed files with 56 additions and 3 deletions

View File

@ -232,6 +232,10 @@ class Account(override val uuid: String) : BaseAccount {
@set:Synchronized
var useCompression = true
@get:Synchronized
@set:Synchronized
var isSendClientIdEnabled = true
@get:Synchronized
@set:Synchronized
var searchableFolders = Searchable.ALL

View File

@ -140,6 +140,7 @@ class AccountPreferenceSerializer(
isReplyAfterQuote = storage.getBoolean("$accountUuid.replyAfterQuote", DEFAULT_REPLY_AFTER_QUOTE)
isStripSignature = storage.getBoolean("$accountUuid.stripSignature", DEFAULT_STRIP_SIGNATURE)
useCompression = storage.getBoolean("$accountUuid.useCompression", true)
isSendClientIdEnabled = storage.getBoolean("$accountUuid.sendClientId", true)
importedAutoExpandFolder = storage.getString("$accountUuid.autoExpandFolderName", null)
@ -364,6 +365,7 @@ class AccountPreferenceSerializer(
editor.putLong("$accountUuid.lastFolderListRefreshTime", lastFolderListRefreshTime)
editor.putBoolean("$accountUuid.isFinishedSetup", isFinishedSetup)
editor.putBoolean("$accountUuid.useCompression", useCompression)
editor.putBoolean("$accountUuid.sendClientId", isSendClientIdEnabled)
editor.putBoolean("$accountUuid.migrateToOAuth", shouldMigrateToOAuth)
}
@ -483,6 +485,7 @@ class AccountPreferenceSerializer(
editor.remove("$accountUuid.lastFolderListRefreshTime")
editor.remove("$accountUuid.isFinishedSetup")
editor.remove("$accountUuid.useCompression")
editor.remove("$accountUuid.sendClientId")
editor.remove("$accountUuid.migrateToOAuth")
deleteIdentities(account, storage, editor)

View File

@ -276,6 +276,9 @@ public class AccountSettingsDescriptions {
s.put("useCompression", Settings.versions(
new V(81, new BooleanSetting(true))
));
s.put("sendClientId", Settings.versions(
new V(88, new BooleanSetting(true))
));
// note that there is no setting for openPgpProvider, because this will have to be set up together
// with the actual provider after import anyways.

View File

@ -36,7 +36,7 @@ public class Settings {
*
* @see SettingsExporter
*/
public static final int VERSION = 87;
public static final int VERSION = 88;
static Map<String, Object> validate(int version, Map<String, TreeMap<Integer, SettingsDescription>> settings,
Map<String, String> importedSettings, boolean useDefaultValues) {

View File

@ -57,6 +57,8 @@ android {
"fy",
),
)
buildConfigField("String", "CLIENT_ID_APP_NAME", "\"K-9 Mail\"")
}
signingConfigs {

View File

@ -2,6 +2,7 @@ package com.fsck.k9.backends
import android.content.Context
import com.fsck.k9.Account
import com.fsck.k9.BuildConfig
import com.fsck.k9.backend.BackendFactory
import com.fsck.k9.backend.api.Backend
import com.fsck.k9.backend.imap.ImapBackend
@ -69,6 +70,9 @@ class ImapBackendFactory(
override fun isSubscribedFoldersOnly() = account.isSubscribedFoldersOnly
override fun useCompression() = account.useCompression
override fun clientIdAppName(): String? {
return BuildConfig.CLIENT_ID_APP_NAME.takeIf { account.isSendClientIdEnabled }
}
}
}

View File

@ -86,6 +86,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
private Account mAccount;
private boolean mMakeDefault;
private CheckBox useCompressionCheckBox;
private CheckBox isSendClientIdEnabledCheckBox;
private CheckBox mSubscribedFoldersOnly;
private AuthTypeAdapter mAuthTypeAdapter;
private ConnectionSecurity[] mConnectionSecurityChoices = ConnectionSecurity.values();
@ -134,6 +135,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
mWebdavMailboxPathView = findViewById(R.id.webdav_mailbox_path);
mNextButton = findViewById(R.id.next);
useCompressionCheckBox = findViewById(R.id.use_compression);
isSendClientIdEnabledCheckBox = findViewById(R.id.is_send_client_id_enabled);
mSubscribedFoldersOnly = findViewById(R.id.subscribed_folders_only);
mAllowClientCertificateView = findViewById(R.id.account_allow_client_certificate);
@ -213,6 +215,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
findViewById(R.id.webdav_owa_path_section).setVisibility(View.GONE);
findViewById(R.id.webdav_auth_path_section).setVisibility(View.GONE);
useCompressionCheckBox.setVisibility(View.GONE);
isSendClientIdEnabledCheckBox.setVisibility(View.GONE);
mSubscribedFoldersOnly.setVisibility(View.GONE);
} else if (settings.type.equals(Protocols.IMAP)) {
serverLayoutView.setHint(getString(R.string.account_setup_incoming_imap_server_label));
@ -244,6 +247,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
findViewById(R.id.account_auth_type_label).setVisibility(View.GONE);
findViewById(R.id.account_auth_type).setVisibility(View.GONE);
useCompressionCheckBox.setVisibility(View.GONE);
isSendClientIdEnabledCheckBox.setVisibility(View.GONE);
mSubscribedFoldersOnly.setVisibility(View.GONE);
String path = WebDavStoreSettings.getPath(settings);
@ -294,6 +298,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
updateViewFromSecurity();
useCompressionCheckBox.setChecked(mAccount.useCompression());
isSendClientIdEnabledCheckBox.setChecked(mAccount.isSendClientIdEnabled());
if (settings.host != null) {
mServerView.setText(settings.host);
@ -623,6 +628,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
mAccount.setIncomingServerSettings(settings);
mAccount.setUseCompression(useCompressionCheckBox.isChecked());
mAccount.setSendClientIdEnabled(isSendClientIdEnabledCheckBox.isChecked());
mAccount.setSubscribedFoldersOnly(mSubscribedFoldersOnly.isChecked());
AccountSetupCheckSettings.actionCheckSettings(this, mAccount, CheckDirection.INCOMING);

View File

@ -253,6 +253,12 @@
android:layout_width="wrap_content"
android:text="@string/account_setup_incoming_use_compression" />
<CheckBox
android:id="@+id/is_send_client_id_enabled"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="@string/account_setup_incoming_send_client_id" />
<View
android:layout_width="match_parent"
android:layout_height="0dip"

View File

@ -429,6 +429,7 @@ Please submit bug reports, contribute new features and ask questions at
<string name="account_setup_incoming_delete_policy_markread_label">Mark as read on server</string>
<string name="account_setup_incoming_use_compression">Use compression</string>
<string name="account_setup_incoming_send_client_id">Send client ID</string>
<string name="account_setup_expunge_policy_label">Erase deleted messages on server</string>
<string name="account_setup_expunge_policy_immediately">Immediately</string>

View File

@ -13,6 +13,7 @@ class Capabilities {
public static final String LOGINDISABLED = "LOGINDISABLED";
public static final String NAMESPACE = "NAMESPACE";
public static final String COMPRESS_DEFLATE = "COMPRESS=DEFLATE";
public static final String ID = "ID";
public static final String STARTTLS = "STARTTLS";
public static final String SPECIAL_USE = "SPECIAL-USE";
public static final String UID_PLUS = "UIDPLUS";

View File

@ -15,6 +15,7 @@ internal interface ImapSettings {
val password: String?
val clientCertificateAlias: String?
val useCompression: Boolean
val clientIdAppName: String?
var pathPrefix: String?
var pathDelimiter: String?

View File

@ -4,4 +4,5 @@ interface ImapStoreConfig {
val logLabel: String
fun isSubscribedFoldersOnly(): Boolean
fun useCompression(): Boolean
fun clientIdAppName(): String?
}

View File

@ -96,6 +96,7 @@ internal class RealImapConnection(
extractOrRequestCapabilities(responses)
enableCompressionIfRequested()
sendClientIdIfSupported()
retrievePathPrefixIfNecessary()
retrievePathDelimiterIfNecessary()
@ -561,6 +562,13 @@ internal class RealImapConnection(
}
}
private fun sendClientIdIfSupported() {
if (hasCapability(Capabilities.ID) && settings.clientIdAppName != null) {
val encodedAppName = ImapUtility.encodeString(settings.clientIdAppName)
executeSimpleCommand("""ID ("name" $encodedAppName)""")
}
}
private fun enableCompression() {
try {
executeSimpleCommand(Commands.COMPRESS_DEFLATE)

View File

@ -299,6 +299,9 @@ internal open class RealImapStore(
override val useCompression: Boolean
get() = this@RealImapStore.config.useCompression()
override val clientIdAppName: String?
get() = this@RealImapStore.config.clientIdAppName()
override var pathPrefix: String?
get() = this@RealImapStore.pathPrefix
set(value) {

View File

@ -1037,6 +1037,7 @@ class RealImapConnectionTest {
connectionSecurity: ConnectionSecurity = ConnectionSecurity.NONE,
authType: AuthType = AuthType.PLAIN,
useCompression: Boolean = false,
clientIdAppName: String? = null,
): ImapConnection {
server.start()
@ -1048,6 +1049,7 @@ class RealImapConnectionTest {
username = USERNAME,
password = PASSWORD,
useCompression = useCompression,
clientIdAppName = clientIdAppName,
)
return createImapConnection(settings, socketFactory, oAuth2TokenProvider)

View File

@ -392,20 +392,26 @@ class RealImapStoreTest {
private fun createTestImapStore(
isSubscribedFoldersOnly: Boolean = false,
useCompression: Boolean = false,
clientIdAppName: String? = null,
): TestImapStore {
return TestImapStore(
serverSettings = createServerSettings(),
config = createImapStoreConfig(isSubscribedFoldersOnly, useCompression),
config = createImapStoreConfig(isSubscribedFoldersOnly, useCompression, clientIdAppName),
trustedSocketFactory = mock(),
oauth2TokenProvider = null,
)
}
private fun createImapStoreConfig(isSubscribedFoldersOnly: Boolean, useCompression: Boolean): ImapStoreConfig {
private fun createImapStoreConfig(
isSubscribedFoldersOnly: Boolean,
useCompression: Boolean,
clientIdAppName: String?,
): ImapStoreConfig {
return object : ImapStoreConfig {
override val logLabel: String = "irrelevant"
override fun isSubscribedFoldersOnly(): Boolean = isSubscribedFoldersOnly
override fun useCompression(): Boolean = useCompression
override fun clientIdAppName(): String? = clientIdAppName
}
}

View File

@ -3,6 +3,7 @@ package com.fsck.k9.mail.store.imap
import com.fsck.k9.mail.AuthType
import com.fsck.k9.mail.ConnectionSecurity
@Suppress("LongParameterList")
internal class SimpleImapSettings(
override val host: String,
override val port: Int = 0,
@ -11,6 +12,7 @@ internal class SimpleImapSettings(
override val username: String,
override val password: String? = null,
override val useCompression: Boolean = false,
override val clientIdAppName: String? = null,
) : ImapSettings {
override val clientCertificateAlias: String? = null