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:
parent
6e27fe5c84
commit
f2ce1fe344
@ -232,6 +232,10 @@ class Account(override val uuid: String) : BaseAccount {
|
|||||||
@set:Synchronized
|
@set:Synchronized
|
||||||
var useCompression = true
|
var useCompression = true
|
||||||
|
|
||||||
|
@get:Synchronized
|
||||||
|
@set:Synchronized
|
||||||
|
var isSendClientIdEnabled = true
|
||||||
|
|
||||||
@get:Synchronized
|
@get:Synchronized
|
||||||
@set:Synchronized
|
@set:Synchronized
|
||||||
var searchableFolders = Searchable.ALL
|
var searchableFolders = Searchable.ALL
|
||||||
|
@ -140,6 +140,7 @@ class AccountPreferenceSerializer(
|
|||||||
isReplyAfterQuote = storage.getBoolean("$accountUuid.replyAfterQuote", DEFAULT_REPLY_AFTER_QUOTE)
|
isReplyAfterQuote = storage.getBoolean("$accountUuid.replyAfterQuote", DEFAULT_REPLY_AFTER_QUOTE)
|
||||||
isStripSignature = storage.getBoolean("$accountUuid.stripSignature", DEFAULT_STRIP_SIGNATURE)
|
isStripSignature = storage.getBoolean("$accountUuid.stripSignature", DEFAULT_STRIP_SIGNATURE)
|
||||||
useCompression = storage.getBoolean("$accountUuid.useCompression", true)
|
useCompression = storage.getBoolean("$accountUuid.useCompression", true)
|
||||||
|
isSendClientIdEnabled = storage.getBoolean("$accountUuid.sendClientId", true)
|
||||||
|
|
||||||
importedAutoExpandFolder = storage.getString("$accountUuid.autoExpandFolderName", null)
|
importedAutoExpandFolder = storage.getString("$accountUuid.autoExpandFolderName", null)
|
||||||
|
|
||||||
@ -364,6 +365,7 @@ class AccountPreferenceSerializer(
|
|||||||
editor.putLong("$accountUuid.lastFolderListRefreshTime", lastFolderListRefreshTime)
|
editor.putLong("$accountUuid.lastFolderListRefreshTime", lastFolderListRefreshTime)
|
||||||
editor.putBoolean("$accountUuid.isFinishedSetup", isFinishedSetup)
|
editor.putBoolean("$accountUuid.isFinishedSetup", isFinishedSetup)
|
||||||
editor.putBoolean("$accountUuid.useCompression", useCompression)
|
editor.putBoolean("$accountUuid.useCompression", useCompression)
|
||||||
|
editor.putBoolean("$accountUuid.sendClientId", isSendClientIdEnabled)
|
||||||
editor.putBoolean("$accountUuid.migrateToOAuth", shouldMigrateToOAuth)
|
editor.putBoolean("$accountUuid.migrateToOAuth", shouldMigrateToOAuth)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -483,6 +485,7 @@ class AccountPreferenceSerializer(
|
|||||||
editor.remove("$accountUuid.lastFolderListRefreshTime")
|
editor.remove("$accountUuid.lastFolderListRefreshTime")
|
||||||
editor.remove("$accountUuid.isFinishedSetup")
|
editor.remove("$accountUuid.isFinishedSetup")
|
||||||
editor.remove("$accountUuid.useCompression")
|
editor.remove("$accountUuid.useCompression")
|
||||||
|
editor.remove("$accountUuid.sendClientId")
|
||||||
editor.remove("$accountUuid.migrateToOAuth")
|
editor.remove("$accountUuid.migrateToOAuth")
|
||||||
|
|
||||||
deleteIdentities(account, storage, editor)
|
deleteIdentities(account, storage, editor)
|
||||||
|
@ -276,6 +276,9 @@ public class AccountSettingsDescriptions {
|
|||||||
s.put("useCompression", Settings.versions(
|
s.put("useCompression", Settings.versions(
|
||||||
new V(81, new BooleanSetting(true))
|
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
|
// note that there is no setting for openPgpProvider, because this will have to be set up together
|
||||||
// with the actual provider after import anyways.
|
// with the actual provider after import anyways.
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ public class Settings {
|
|||||||
*
|
*
|
||||||
* @see SettingsExporter
|
* @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,
|
static Map<String, Object> validate(int version, Map<String, TreeMap<Integer, SettingsDescription>> settings,
|
||||||
Map<String, String> importedSettings, boolean useDefaultValues) {
|
Map<String, String> importedSettings, boolean useDefaultValues) {
|
||||||
|
@ -57,6 +57,8 @@ android {
|
|||||||
"fy",
|
"fy",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
buildConfigField("String", "CLIENT_ID_APP_NAME", "\"K-9 Mail\"")
|
||||||
}
|
}
|
||||||
|
|
||||||
signingConfigs {
|
signingConfigs {
|
||||||
|
@ -2,6 +2,7 @@ package com.fsck.k9.backends
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.fsck.k9.Account
|
import com.fsck.k9.Account
|
||||||
|
import com.fsck.k9.BuildConfig
|
||||||
import com.fsck.k9.backend.BackendFactory
|
import com.fsck.k9.backend.BackendFactory
|
||||||
import com.fsck.k9.backend.api.Backend
|
import com.fsck.k9.backend.api.Backend
|
||||||
import com.fsck.k9.backend.imap.ImapBackend
|
import com.fsck.k9.backend.imap.ImapBackend
|
||||||
@ -69,6 +70,9 @@ class ImapBackendFactory(
|
|||||||
override fun isSubscribedFoldersOnly() = account.isSubscribedFoldersOnly
|
override fun isSubscribedFoldersOnly() = account.isSubscribedFoldersOnly
|
||||||
|
|
||||||
override fun useCompression() = account.useCompression
|
override fun useCompression() = account.useCompression
|
||||||
|
override fun clientIdAppName(): String? {
|
||||||
|
return BuildConfig.CLIENT_ID_APP_NAME.takeIf { account.isSendClientIdEnabled }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,6 +86,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
|
|||||||
private Account mAccount;
|
private Account mAccount;
|
||||||
private boolean mMakeDefault;
|
private boolean mMakeDefault;
|
||||||
private CheckBox useCompressionCheckBox;
|
private CheckBox useCompressionCheckBox;
|
||||||
|
private CheckBox isSendClientIdEnabledCheckBox;
|
||||||
private CheckBox mSubscribedFoldersOnly;
|
private CheckBox mSubscribedFoldersOnly;
|
||||||
private AuthTypeAdapter mAuthTypeAdapter;
|
private AuthTypeAdapter mAuthTypeAdapter;
|
||||||
private ConnectionSecurity[] mConnectionSecurityChoices = ConnectionSecurity.values();
|
private ConnectionSecurity[] mConnectionSecurityChoices = ConnectionSecurity.values();
|
||||||
@ -134,6 +135,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
|
|||||||
mWebdavMailboxPathView = findViewById(R.id.webdav_mailbox_path);
|
mWebdavMailboxPathView = findViewById(R.id.webdav_mailbox_path);
|
||||||
mNextButton = findViewById(R.id.next);
|
mNextButton = findViewById(R.id.next);
|
||||||
useCompressionCheckBox = findViewById(R.id.use_compression);
|
useCompressionCheckBox = findViewById(R.id.use_compression);
|
||||||
|
isSendClientIdEnabledCheckBox = findViewById(R.id.is_send_client_id_enabled);
|
||||||
mSubscribedFoldersOnly = findViewById(R.id.subscribed_folders_only);
|
mSubscribedFoldersOnly = findViewById(R.id.subscribed_folders_only);
|
||||||
mAllowClientCertificateView = findViewById(R.id.account_allow_client_certificate);
|
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_owa_path_section).setVisibility(View.GONE);
|
||||||
findViewById(R.id.webdav_auth_path_section).setVisibility(View.GONE);
|
findViewById(R.id.webdav_auth_path_section).setVisibility(View.GONE);
|
||||||
useCompressionCheckBox.setVisibility(View.GONE);
|
useCompressionCheckBox.setVisibility(View.GONE);
|
||||||
|
isSendClientIdEnabledCheckBox.setVisibility(View.GONE);
|
||||||
mSubscribedFoldersOnly.setVisibility(View.GONE);
|
mSubscribedFoldersOnly.setVisibility(View.GONE);
|
||||||
} else if (settings.type.equals(Protocols.IMAP)) {
|
} else if (settings.type.equals(Protocols.IMAP)) {
|
||||||
serverLayoutView.setHint(getString(R.string.account_setup_incoming_imap_server_label));
|
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_label).setVisibility(View.GONE);
|
||||||
findViewById(R.id.account_auth_type).setVisibility(View.GONE);
|
findViewById(R.id.account_auth_type).setVisibility(View.GONE);
|
||||||
useCompressionCheckBox.setVisibility(View.GONE);
|
useCompressionCheckBox.setVisibility(View.GONE);
|
||||||
|
isSendClientIdEnabledCheckBox.setVisibility(View.GONE);
|
||||||
mSubscribedFoldersOnly.setVisibility(View.GONE);
|
mSubscribedFoldersOnly.setVisibility(View.GONE);
|
||||||
|
|
||||||
String path = WebDavStoreSettings.getPath(settings);
|
String path = WebDavStoreSettings.getPath(settings);
|
||||||
@ -294,6 +298,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
|
|||||||
updateViewFromSecurity();
|
updateViewFromSecurity();
|
||||||
|
|
||||||
useCompressionCheckBox.setChecked(mAccount.useCompression());
|
useCompressionCheckBox.setChecked(mAccount.useCompression());
|
||||||
|
isSendClientIdEnabledCheckBox.setChecked(mAccount.isSendClientIdEnabled());
|
||||||
|
|
||||||
if (settings.host != null) {
|
if (settings.host != null) {
|
||||||
mServerView.setText(settings.host);
|
mServerView.setText(settings.host);
|
||||||
@ -623,6 +628,7 @@ public class AccountSetupIncoming extends K9Activity implements OnClickListener
|
|||||||
mAccount.setIncomingServerSettings(settings);
|
mAccount.setIncomingServerSettings(settings);
|
||||||
|
|
||||||
mAccount.setUseCompression(useCompressionCheckBox.isChecked());
|
mAccount.setUseCompression(useCompressionCheckBox.isChecked());
|
||||||
|
mAccount.setSendClientIdEnabled(isSendClientIdEnabledCheckBox.isChecked());
|
||||||
mAccount.setSubscribedFoldersOnly(mSubscribedFoldersOnly.isChecked());
|
mAccount.setSubscribedFoldersOnly(mSubscribedFoldersOnly.isChecked());
|
||||||
|
|
||||||
AccountSetupCheckSettings.actionCheckSettings(this, mAccount, CheckDirection.INCOMING);
|
AccountSetupCheckSettings.actionCheckSettings(this, mAccount, CheckDirection.INCOMING);
|
||||||
|
@ -253,6 +253,12 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:text="@string/account_setup_incoming_use_compression" />
|
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
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dip"
|
android:layout_height="0dip"
|
||||||
|
@ -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_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_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_label">Erase deleted messages on server</string>
|
||||||
<string name="account_setup_expunge_policy_immediately">Immediately</string>
|
<string name="account_setup_expunge_policy_immediately">Immediately</string>
|
||||||
|
@ -13,6 +13,7 @@ class Capabilities {
|
|||||||
public static final String LOGINDISABLED = "LOGINDISABLED";
|
public static final String LOGINDISABLED = "LOGINDISABLED";
|
||||||
public static final String NAMESPACE = "NAMESPACE";
|
public static final String NAMESPACE = "NAMESPACE";
|
||||||
public static final String COMPRESS_DEFLATE = "COMPRESS=DEFLATE";
|
public static final String COMPRESS_DEFLATE = "COMPRESS=DEFLATE";
|
||||||
|
public static final String ID = "ID";
|
||||||
public static final String STARTTLS = "STARTTLS";
|
public static final String STARTTLS = "STARTTLS";
|
||||||
public static final String SPECIAL_USE = "SPECIAL-USE";
|
public static final String SPECIAL_USE = "SPECIAL-USE";
|
||||||
public static final String UID_PLUS = "UIDPLUS";
|
public static final String UID_PLUS = "UIDPLUS";
|
||||||
|
@ -15,6 +15,7 @@ internal interface ImapSettings {
|
|||||||
val password: String?
|
val password: String?
|
||||||
val clientCertificateAlias: String?
|
val clientCertificateAlias: String?
|
||||||
val useCompression: Boolean
|
val useCompression: Boolean
|
||||||
|
val clientIdAppName: String?
|
||||||
|
|
||||||
var pathPrefix: String?
|
var pathPrefix: String?
|
||||||
var pathDelimiter: String?
|
var pathDelimiter: String?
|
||||||
|
@ -4,4 +4,5 @@ interface ImapStoreConfig {
|
|||||||
val logLabel: String
|
val logLabel: String
|
||||||
fun isSubscribedFoldersOnly(): Boolean
|
fun isSubscribedFoldersOnly(): Boolean
|
||||||
fun useCompression(): Boolean
|
fun useCompression(): Boolean
|
||||||
|
fun clientIdAppName(): String?
|
||||||
}
|
}
|
||||||
|
@ -96,6 +96,7 @@ internal class RealImapConnection(
|
|||||||
extractOrRequestCapabilities(responses)
|
extractOrRequestCapabilities(responses)
|
||||||
|
|
||||||
enableCompressionIfRequested()
|
enableCompressionIfRequested()
|
||||||
|
sendClientIdIfSupported()
|
||||||
|
|
||||||
retrievePathPrefixIfNecessary()
|
retrievePathPrefixIfNecessary()
|
||||||
retrievePathDelimiterIfNecessary()
|
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() {
|
private fun enableCompression() {
|
||||||
try {
|
try {
|
||||||
executeSimpleCommand(Commands.COMPRESS_DEFLATE)
|
executeSimpleCommand(Commands.COMPRESS_DEFLATE)
|
||||||
|
@ -299,6 +299,9 @@ internal open class RealImapStore(
|
|||||||
override val useCompression: Boolean
|
override val useCompression: Boolean
|
||||||
get() = this@RealImapStore.config.useCompression()
|
get() = this@RealImapStore.config.useCompression()
|
||||||
|
|
||||||
|
override val clientIdAppName: String?
|
||||||
|
get() = this@RealImapStore.config.clientIdAppName()
|
||||||
|
|
||||||
override var pathPrefix: String?
|
override var pathPrefix: String?
|
||||||
get() = this@RealImapStore.pathPrefix
|
get() = this@RealImapStore.pathPrefix
|
||||||
set(value) {
|
set(value) {
|
||||||
|
@ -1037,6 +1037,7 @@ class RealImapConnectionTest {
|
|||||||
connectionSecurity: ConnectionSecurity = ConnectionSecurity.NONE,
|
connectionSecurity: ConnectionSecurity = ConnectionSecurity.NONE,
|
||||||
authType: AuthType = AuthType.PLAIN,
|
authType: AuthType = AuthType.PLAIN,
|
||||||
useCompression: Boolean = false,
|
useCompression: Boolean = false,
|
||||||
|
clientIdAppName: String? = null,
|
||||||
): ImapConnection {
|
): ImapConnection {
|
||||||
server.start()
|
server.start()
|
||||||
|
|
||||||
@ -1048,6 +1049,7 @@ class RealImapConnectionTest {
|
|||||||
username = USERNAME,
|
username = USERNAME,
|
||||||
password = PASSWORD,
|
password = PASSWORD,
|
||||||
useCompression = useCompression,
|
useCompression = useCompression,
|
||||||
|
clientIdAppName = clientIdAppName,
|
||||||
)
|
)
|
||||||
|
|
||||||
return createImapConnection(settings, socketFactory, oAuth2TokenProvider)
|
return createImapConnection(settings, socketFactory, oAuth2TokenProvider)
|
||||||
|
@ -392,20 +392,26 @@ class RealImapStoreTest {
|
|||||||
private fun createTestImapStore(
|
private fun createTestImapStore(
|
||||||
isSubscribedFoldersOnly: Boolean = false,
|
isSubscribedFoldersOnly: Boolean = false,
|
||||||
useCompression: Boolean = false,
|
useCompression: Boolean = false,
|
||||||
|
clientIdAppName: String? = null,
|
||||||
): TestImapStore {
|
): TestImapStore {
|
||||||
return TestImapStore(
|
return TestImapStore(
|
||||||
serverSettings = createServerSettings(),
|
serverSettings = createServerSettings(),
|
||||||
config = createImapStoreConfig(isSubscribedFoldersOnly, useCompression),
|
config = createImapStoreConfig(isSubscribedFoldersOnly, useCompression, clientIdAppName),
|
||||||
trustedSocketFactory = mock(),
|
trustedSocketFactory = mock(),
|
||||||
oauth2TokenProvider = null,
|
oauth2TokenProvider = null,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createImapStoreConfig(isSubscribedFoldersOnly: Boolean, useCompression: Boolean): ImapStoreConfig {
|
private fun createImapStoreConfig(
|
||||||
|
isSubscribedFoldersOnly: Boolean,
|
||||||
|
useCompression: Boolean,
|
||||||
|
clientIdAppName: String?,
|
||||||
|
): ImapStoreConfig {
|
||||||
return object : ImapStoreConfig {
|
return object : ImapStoreConfig {
|
||||||
override val logLabel: String = "irrelevant"
|
override val logLabel: String = "irrelevant"
|
||||||
override fun isSubscribedFoldersOnly(): Boolean = isSubscribedFoldersOnly
|
override fun isSubscribedFoldersOnly(): Boolean = isSubscribedFoldersOnly
|
||||||
override fun useCompression(): Boolean = useCompression
|
override fun useCompression(): Boolean = useCompression
|
||||||
|
override fun clientIdAppName(): String? = clientIdAppName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package com.fsck.k9.mail.store.imap
|
|||||||
import com.fsck.k9.mail.AuthType
|
import com.fsck.k9.mail.AuthType
|
||||||
import com.fsck.k9.mail.ConnectionSecurity
|
import com.fsck.k9.mail.ConnectionSecurity
|
||||||
|
|
||||||
|
@Suppress("LongParameterList")
|
||||||
internal class SimpleImapSettings(
|
internal class SimpleImapSettings(
|
||||||
override val host: String,
|
override val host: String,
|
||||||
override val port: Int = 0,
|
override val port: Int = 0,
|
||||||
@ -11,6 +12,7 @@ internal class SimpleImapSettings(
|
|||||||
override val username: String,
|
override val username: String,
|
||||||
override val password: String? = null,
|
override val password: String? = null,
|
||||||
override val useCompression: Boolean = false,
|
override val useCompression: Boolean = false,
|
||||||
|
override val clientIdAppName: String? = null,
|
||||||
) : ImapSettings {
|
) : ImapSettings {
|
||||||
override val clientCertificateAlias: String? = null
|
override val clientCertificateAlias: String? = null
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user