From 622aa88f864ab9f170c4b617a00b02c46302474b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 5 May 2023 15:59:36 +0200 Subject: [PATCH] Remove LegacySessionImporter, and the dialog which explains that Riot is now Element. --- changelog.d/8402.misc | 1 + .../matrix/android/sdk/common/TestMatrix.kt | 6 - .../java/org/matrix/android/sdk/api/Matrix.kt | 7 - .../sdk/api/legacy/LegacySessionImporter.kt | 26 - .../android/sdk/internal/auth/AuthModule.kt | 5 - .../legacy/DefaultLegacySessionImporter.kt | 231 ------ .../sdk/internal/legacy/riot/Credentials.java | 110 --- .../sdk/internal/legacy/riot/Fingerprint.java | 94 --- .../riot/HomeServerConnectionConfig.java | 674 ------------------ .../internal/legacy/riot/LoginStorage.java | 206 ------ .../sdk/internal/legacy/riot/WellKnown.kt | 96 --- .../legacy/riot/WellKnownBaseConfig.kt | 37 - .../legacy/riot/WellKnownManagerConfig.kt | 24 - .../legacy/riot/WellKnownPreferredConfig.kt | 37 - .../java/im/vector/app/VectorApplication.kt | 11 - .../im/vector/app/core/di/SingletonModule.kt | 6 - .../features/disclaimer/DisclaimerDialog.kt | 62 -- .../vector/app/features/home/HomeActivity.kt | 4 - .../features/settings/VectorPreferences.kt | 4 - vector/src/main/res/drawable/ic_riot_icon.xml | 26 - .../res/layout/dialog_disclaimer_content.xml | 69 -- 21 files changed, 1 insertion(+), 1735 deletions(-) create mode 100644 changelog.d/8402.misc delete mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/legacy/LegacySessionImporter.kt delete mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/DefaultLegacySessionImporter.kt delete mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/Credentials.java delete mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/Fingerprint.java delete mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/HomeServerConnectionConfig.java delete mode 100755 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/LoginStorage.java delete mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnown.kt delete mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnownBaseConfig.kt delete mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnownManagerConfig.kt delete mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnownPreferredConfig.kt delete mode 100644 vector/src/main/java/im/vector/app/features/disclaimer/DisclaimerDialog.kt delete mode 100644 vector/src/main/res/drawable/ic_riot_icon.xml delete mode 100644 vector/src/main/res/layout/dialog_disclaimer_content.xml diff --git a/changelog.d/8402.misc b/changelog.d/8402.misc new file mode 100644 index 0000000000..c493b6bf92 --- /dev/null +++ b/changelog.d/8402.misc @@ -0,0 +1 @@ +Remove ability to migrate session from Riot to Element. diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/TestMatrix.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/TestMatrix.kt index 5864a801e6..60201b34c7 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/TestMatrix.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/TestMatrix.kt @@ -28,7 +28,6 @@ import org.matrix.android.sdk.BuildConfig import org.matrix.android.sdk.api.MatrixConfiguration import org.matrix.android.sdk.api.auth.AuthenticationService import org.matrix.android.sdk.api.auth.HomeServerHistoryService -import org.matrix.android.sdk.api.legacy.LegacySessionImporter import org.matrix.android.sdk.api.network.ApiInterceptorListener import org.matrix.android.sdk.api.network.ApiPath import org.matrix.android.sdk.api.raw.RawService @@ -46,7 +45,6 @@ import javax.inject.Inject */ internal class TestMatrix(context: Context, matrixConfiguration: MatrixConfiguration) { - @Inject internal lateinit var legacySessionImporter: LegacySessionImporter @Inject internal lateinit var authenticationService: AuthenticationService @Inject internal lateinit var rawService: RawService @Inject internal lateinit var userAgentHolder: UserAgentHolder @@ -88,10 +86,6 @@ internal class TestMatrix(context: Context, matrixConfiguration: MatrixConfigura fun homeServerHistoryService() = homeServerHistoryService - fun legacySessionImporter(): LegacySessionImporter { - return legacySessionImporter - } - fun registerApiInterceptorListener(path: ApiPath, listener: ApiInterceptorListener) { apiInterceptor.addListener(path, listener) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt index 953ebddcbf..8893229a76 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt @@ -28,7 +28,6 @@ import org.matrix.android.sdk.BuildConfig import org.matrix.android.sdk.api.auth.AuthenticationService import org.matrix.android.sdk.api.auth.HomeServerHistoryService import org.matrix.android.sdk.api.debug.DebugService -import org.matrix.android.sdk.api.legacy.LegacySessionImporter import org.matrix.android.sdk.api.network.ApiInterceptorListener import org.matrix.android.sdk.api.network.ApiPath import org.matrix.android.sdk.api.raw.RawService @@ -55,7 +54,6 @@ import javax.inject.Inject */ class Matrix(context: Context, matrixConfiguration: MatrixConfiguration) { - @Inject internal lateinit var legacySessionImporter: LegacySessionImporter @Inject internal lateinit var authenticationService: AuthenticationService @Inject internal lateinit var rawService: RawService @Inject internal lateinit var debugService: DebugService @@ -118,11 +116,6 @@ class Matrix(context: Context, matrixConfiguration: MatrixConfiguration) { */ fun homeServerHistoryService() = homeServerHistoryService - /** - * Return the legacy session importer, useful if you want to migrate an app, which was using the legacy Matrix Android Sdk. - */ - fun legacySessionImporter() = legacySessionImporter - /** * Returns the SecureStorageService used to encrypt and decrypt sensitive data. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/legacy/LegacySessionImporter.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/legacy/LegacySessionImporter.kt deleted file mode 100644 index 57de3f5ac0..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/legacy/LegacySessionImporter.kt +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.api.legacy - -interface LegacySessionImporter { - - /** - * Will eventually import a session created by the legacy app. - * @return true if a session has been imported - */ - fun process(): Boolean -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/AuthModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/AuthModule.kt index b1f65194f1..c43bef8697 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/AuthModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/AuthModule.kt @@ -23,7 +23,6 @@ import dagger.Provides import io.realm.RealmConfiguration import org.matrix.android.sdk.api.auth.AuthenticationService import org.matrix.android.sdk.api.auth.HomeServerHistoryService -import org.matrix.android.sdk.api.legacy.LegacySessionImporter import org.matrix.android.sdk.internal.auth.db.AuthRealmMigration import org.matrix.android.sdk.internal.auth.db.AuthRealmModule import org.matrix.android.sdk.internal.auth.db.RealmPendingSessionStore @@ -34,7 +33,6 @@ import org.matrix.android.sdk.internal.auth.login.DirectLoginTask import org.matrix.android.sdk.internal.auth.login.QrLoginTokenTask import org.matrix.android.sdk.internal.database.RealmKeysUtils import org.matrix.android.sdk.internal.di.AuthDatabase -import org.matrix.android.sdk.internal.legacy.DefaultLegacySessionImporter import org.matrix.android.sdk.internal.wellknown.WellknownModule import java.io.File @@ -70,9 +68,6 @@ internal abstract class AuthModule { } } - @Binds - abstract fun bindLegacySessionImporter(importer: DefaultLegacySessionImporter): LegacySessionImporter - @Binds abstract fun bindSessionParamsStore(store: RealmSessionParamsStore): SessionParamsStore diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/DefaultLegacySessionImporter.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/DefaultLegacySessionImporter.kt deleted file mode 100644 index 3ce3d1df0c..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/DefaultLegacySessionImporter.kt +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.legacy - -import android.content.Context -import io.realm.Realm -import io.realm.RealmConfiguration -import kotlinx.coroutines.runBlocking -import org.matrix.android.sdk.api.auth.LoginType -import org.matrix.android.sdk.api.auth.data.Credentials -import org.matrix.android.sdk.api.auth.data.DiscoveryInformation -import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig -import org.matrix.android.sdk.api.auth.data.SessionParams -import org.matrix.android.sdk.api.auth.data.WellKnownBaseConfig -import org.matrix.android.sdk.api.legacy.LegacySessionImporter -import org.matrix.android.sdk.api.network.ssl.Fingerprint -import org.matrix.android.sdk.api.util.md5 -import org.matrix.android.sdk.internal.auth.SessionParamsStore -import org.matrix.android.sdk.internal.crypto.store.db.RealmCryptoStoreMigration -import org.matrix.android.sdk.internal.crypto.store.db.RealmCryptoStoreModule -import org.matrix.android.sdk.internal.database.RealmKeysUtils -import org.matrix.android.sdk.internal.legacy.riot.LoginStorage -import org.matrix.android.sdk.internal.util.time.Clock -import timber.log.Timber -import java.io.File -import javax.inject.Inject -import org.matrix.android.sdk.internal.legacy.riot.Fingerprint as LegacyFingerprint -import org.matrix.android.sdk.internal.legacy.riot.HomeServerConnectionConfig as LegacyHomeServerConnectionConfig - -internal class DefaultLegacySessionImporter @Inject constructor( - private val context: Context, - private val sessionParamsStore: SessionParamsStore, - private val realmKeysUtils: RealmKeysUtils, - private val clock: Clock, -) : LegacySessionImporter { - - private val loginStorage = LoginStorage(context) - - companion object { - // During development, set to false to play several times the migration - private var DELETE_PREVIOUS_DATA = true - } - - override fun process(): Boolean { - Timber.d("Migration: Importing legacy session") - - val list = loginStorage.credentialsList - - Timber.d("Migration: found ${list.size} session(s).") - - val legacyConfig = list.firstOrNull() ?: return false - - runBlocking { - Timber.d("Migration: importing a session") - try { - importCredentials(legacyConfig) - } catch (t: Throwable) { - // It can happen in case of partial migration. To test, do not return - Timber.e(t, "Migration: Error importing credential") - } - - Timber.d("Migration: importing crypto DB") - try { - importCryptoDb(legacyConfig) - } catch (t: Throwable) { - // It can happen in case of partial migration. To test, do not return - Timber.e(t, "Migration: Error importing crypto DB") - } - - if (DELETE_PREVIOUS_DATA) { - try { - Timber.d("Migration: clear file system") - clearFileSystem(legacyConfig) - } catch (t: Throwable) { - Timber.e(t, "Migration: Error clearing filesystem") - } - try { - Timber.d("Migration: clear shared prefs") - clearSharedPrefs() - } catch (t: Throwable) { - Timber.e(t, "Migration: Error clearing shared prefs") - } - } else { - Timber.d("Migration: clear file system - DEACTIVATED") - Timber.d("Migration: clear shared prefs - DEACTIVATED") - } - } - - // A session has been imported - return true - } - - private suspend fun importCredentials(legacyConfig: LegacyHomeServerConnectionConfig) { - @Suppress("DEPRECATION") - val sessionParams = SessionParams( - credentials = Credentials( - userId = legacyConfig.credentials.userId, - accessToken = legacyConfig.credentials.accessToken, - refreshToken = legacyConfig.credentials.refreshToken, - homeServer = legacyConfig.credentials.homeServer, - deviceId = legacyConfig.credentials.deviceId, - discoveryInformation = legacyConfig.credentials.wellKnown?.let { wellKnown -> - // Note credentials.wellKnown is not serialized in the LoginStorage, so this code is a bit useless... - if (wellKnown.homeServer?.baseURL != null || wellKnown.identityServer?.baseURL != null) { - DiscoveryInformation( - homeServer = wellKnown.homeServer?.baseURL?.let { WellKnownBaseConfig(baseURL = it) }, - identityServer = wellKnown.identityServer?.baseURL?.let { WellKnownBaseConfig(baseURL = it) } - ) - } else { - null - } - } - ), - homeServerConnectionConfig = HomeServerConnectionConfig( - homeServerUri = legacyConfig.homeserverUri, - identityServerUri = legacyConfig.identityServerUri, - antiVirusServerUri = legacyConfig.antiVirusServerUri, - allowedFingerprints = legacyConfig.allowedFingerprints.map { - Fingerprint( - bytes = it.bytes, - hashType = when (it.type) { - LegacyFingerprint.HashType.SHA1, - null -> Fingerprint.HashType.SHA1 - LegacyFingerprint.HashType.SHA256 -> Fingerprint.HashType.SHA256 - } - ) - }, - shouldPin = legacyConfig.shouldPin(), - tlsVersions = legacyConfig.acceptedTlsVersions, - tlsCipherSuites = legacyConfig.acceptedTlsCipherSuites, - shouldAcceptTlsExtensions = legacyConfig.shouldAcceptTlsExtensions(), - allowHttpExtension = false, // TODO - forceUsageTlsVersions = legacyConfig.forceUsageOfTlsVersions() - ), - // If token is not valid, this boolean will be updated later - isTokenValid = true, - loginType = LoginType.UNKNOWN, - ) - - Timber.d("Migration: save session") - sessionParamsStore.save(sessionParams) - } - - private fun importCryptoDb(legacyConfig: LegacyHomeServerConnectionConfig) { - // Here we migrate the DB, we copy the crypto DB to the location specific to Matrix SDK2, and we encrypt it. - val userMd5 = legacyConfig.credentials.userId.md5() - - val sessionId = legacyConfig.credentials.let { (if (it.deviceId.isNullOrBlank()) it.userId else "${it.userId}|${it.deviceId}").md5() } - val newLocation = File(context.filesDir, sessionId) - - val keyAlias = "crypto_module_$userMd5" - - // Ensure newLocation does not exist (can happen in case of partial migration) - newLocation.deleteRecursively() - newLocation.mkdirs() - - val realmCryptoStoreMigration = RealmCryptoStoreMigration(clock) - - Timber.d("Migration: create legacy realm configuration") - - val realmConfiguration = RealmConfiguration.Builder() - .directory(File(context.filesDir, userMd5)) - .name("crypto_store.realm") - .modules(RealmCryptoStoreModule()) - .schemaVersion(realmCryptoStoreMigration.schemaVersion) - .migration(realmCryptoStoreMigration) - .build() - - Timber.d("Migration: copy DB to encrypted DB") - Realm.getInstance(realmConfiguration).use { - // Move the DB to the new location, handled by Matrix SDK2 - it.writeEncryptedCopyTo(File(newLocation, realmConfiguration.realmFileName), realmKeysUtils.getRealmEncryptionKey(keyAlias)) - } - } - - // Delete all the files created by Riot Android which will not be used anymore by Element - private fun clearFileSystem(legacyConfig: LegacyHomeServerConnectionConfig) { - val cryptoFolder = legacyConfig.credentials.userId.md5() - - listOf( - // Where session store was saved (we do not care about migrating that, an initial sync will be performed) - File(context.filesDir, "MXFileStore"), - // Previous (and very old) file crypto store - File(context.filesDir, "MXFileCryptoStore"), - // Draft. They will be lost, this is sad but we assume it - File(context.filesDir, "MXLatestMessagesStore"), - // Media storage - File(context.filesDir, "MXMediaStore"), - File(context.filesDir, "MXMediaStore2"), - File(context.filesDir, "MXMediaStore3"), - // Ext folder - File(context.filesDir, "ext_share"), - // Crypto store - File(context.filesDir, cryptoFolder) - ).forEach { file -> - try { - file.deleteRecursively() - } catch (t: Throwable) { - Timber.e(t, "Migration: unable to delete $file") - } - } - } - - private fun clearSharedPrefs() { - // Shared Pref. Note that we do not delete the default preferences, as it should be nearly the same (TODO check that) - listOf( - "Vector.LoginStorage", - "GcmRegistrationManager", - "IntegrationManager.Storage" - ).forEach { prefName -> - context.getSharedPreferences(prefName, Context.MODE_PRIVATE) - .edit() - .clear() - .apply() - } - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/Credentials.java b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/Credentials.java deleted file mode 100644 index bbed159e3c..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/Credentials.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.matrix.android.sdk.internal.legacy.riot; - -import android.text.TextUtils; - -import org.jetbrains.annotations.Nullable; -import org.json.JSONException; -import org.json.JSONObject; - -/** - * IMPORTANT: This class is imported from Riot-Android to be able to perform a migration. Do not use it for any other purpose - * - * The user's credentials. - */ -public class Credentials { - public String userId; - - // This is the server name and not a URI, e.g. "matrix.org". Spec says it's now deprecated - @Deprecated - public String homeServer; - - public String accessToken; - - public String refreshToken; - - public String deviceId; - - // Optional data that may contain info to override homeserver and/or identity server - public WellKnown wellKnown; - - public JSONObject toJson() throws JSONException { - JSONObject json = new JSONObject(); - - json.put("user_id", userId); - json.put("home_server", homeServer); - json.put("access_token", accessToken); - json.put("refresh_token", TextUtils.isEmpty(refreshToken) ? JSONObject.NULL : refreshToken); - json.put("device_id", deviceId); - - return json; - } - - public static Credentials fromJson(JSONObject obj) throws JSONException { - Credentials creds = new Credentials(); - creds.userId = obj.getString("user_id"); - creds.homeServer = obj.getString("home_server"); - creds.accessToken = obj.getString("access_token"); - - if (obj.has("device_id")) { - creds.deviceId = obj.getString("device_id"); - } - - // refresh_token is mandatory - if (obj.has("refresh_token")) { - try { - creds.refreshToken = obj.getString("refresh_token"); - } catch (Exception e) { - creds.refreshToken = null; - } - } else { - throw new RuntimeException("refresh_token is required."); - } - - return creds; - } - - @Override - public String toString() { - return "Credentials{" + - "userId='" + userId + '\'' + - ", homeServer='" + homeServer + '\'' + - ", refreshToken.length='" + (refreshToken != null ? refreshToken.length() : "null") + '\'' + - ", accessToken.length='" + (accessToken != null ? accessToken.length() : "null") + '\'' + - '}'; - } - - @Nullable - public String getUserId() { - return userId; - } - - @Nullable - public String getHomeServer() { - return homeServer; - } - - @Nullable - public String getAccessToken() { - return accessToken; - } - - @Nullable - public String getDeviceId() { - return deviceId; - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/Fingerprint.java b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/Fingerprint.java deleted file mode 100644 index 82541d38f6..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/Fingerprint.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.legacy.riot; - -import android.util.Base64; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.Arrays; - -/** - * IMPORTANT: This class is imported from Riot-Android to be able to perform a migration. Do not use it for any other purpose - * - * Represents a X509 Certificate fingerprint. - */ -public class Fingerprint { - public enum HashType { - SHA1, - SHA256 - } - - private final HashType mHashType; - private final byte[] mBytes; - - public Fingerprint(HashType hashType, byte[] bytes) { - mHashType = hashType; - mBytes = bytes; - } - - public HashType getType() { - return mHashType; - } - - public byte[] getBytes() { - return mBytes; - } - - public JSONObject toJson() throws JSONException { - JSONObject obj = new JSONObject(); - obj.put("bytes", Base64.encodeToString(getBytes(), Base64.DEFAULT)); - obj.put("hash_type", mHashType.toString()); - return obj; - } - - public static Fingerprint fromJson(JSONObject obj) throws JSONException { - String hashTypeStr = obj.getString("hash_type"); - byte[] fingerprintBytes = Base64.decode(obj.getString("bytes"), Base64.DEFAULT); - - final HashType hashType; - if ("SHA256".equalsIgnoreCase(hashTypeStr)) { - hashType = HashType.SHA256; - } else if ("SHA1".equalsIgnoreCase(hashTypeStr)) { - hashType = HashType.SHA1; - } else { - throw new JSONException("Unrecognized hash type: " + hashTypeStr); - } - - return new Fingerprint(hashType, fingerprintBytes); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Fingerprint that = (Fingerprint) o; - - if (!Arrays.equals(mBytes, that.mBytes)) return false; - return mHashType == that.mHashType; - - } - - @Override - public int hashCode() { - int result = mBytes != null ? Arrays.hashCode(mBytes) : 0; - result = 31 * result + (mHashType != null ? mHashType.hashCode() : 0); - return result; - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/HomeServerConnectionConfig.java b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/HomeServerConnectionConfig.java deleted file mode 100644 index b2bb852cd1..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/HomeServerConnectionConfig.java +++ /dev/null @@ -1,674 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.legacy.riot; - -import android.net.Uri; -import android.text.TextUtils; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.net.InetSocketAddress; -import java.net.Proxy; -import java.util.ArrayList; -import java.util.List; - -import okhttp3.CipherSuite; -import okhttp3.TlsVersion; -import timber.log.Timber; - -/** - * IMPORTANT: This class is imported from Riot-Android to be able to perform a migration. Do not use it for any other purpose - * - * Represents how to connect to a specific Homeserver, may include credentials to use. - */ -public class HomeServerConnectionConfig { - - // the homeserver URI - private Uri mHomeServerUri; - // the jitsi server URI. Can be null - @Nullable - private Uri mJitsiServerUri; - // the identity server URI. Can be null - @Nullable - private Uri mIdentityServerUri; - // the anti-virus server URI - private Uri mAntiVirusServerUri; - // allowed fingerprints - private List mAllowedFingerprints = new ArrayList<>(); - // the credentials - private Credentials mCredentials; - // tell whether we should reject X509 certs that were issued by trusts CAs and only trustcerts with matching fingerprints. - private boolean mPin; - // the accepted TLS versions - private List mTlsVersions; - // the accepted TLS cipher suites - private List mTlsCipherSuites; - // should accept TLS extensions - private boolean mShouldAcceptTlsExtensions = true; - // Force usage of TLS versions - private boolean mForceUsageTlsVersions; - // the proxy hostname - private String mProxyHostname; - // the proxy port - private int mProxyPort = -1; - - - /** - * Private constructor. Please use the Builder - */ - private HomeServerConnectionConfig() { - // Private constructor - } - - /** - * Update the homeserver URI. - * - * @param uri the new HS uri - */ - public void setHomeserverUri(Uri uri) { - mHomeServerUri = uri; - } - - /** - * @return the homeserver uri - */ - public Uri getHomeserverUri() { - return mHomeServerUri; - } - - /** - * @return the jitsi server uri - */ - public Uri getJitsiServerUri() { - return mJitsiServerUri; - } - - /** - * @return the identity server uri, or null if not defined - */ - @Nullable - public Uri getIdentityServerUri() { - return mIdentityServerUri; - } - - /** - * @return the anti-virus server uri - */ - public Uri getAntiVirusServerUri() { - if (null != mAntiVirusServerUri) { - return mAntiVirusServerUri; - } - // Else consider the HS uri by default. - return mHomeServerUri; - } - - /** - * @return the allowed fingerprints. - */ - public List getAllowedFingerprints() { - return mAllowedFingerprints; - } - - /** - * @return the credentials - */ - public Credentials getCredentials() { - return mCredentials; - } - - /** - * Update the credentials. - * - * @param credentials the new credentials - */ - public void setCredentials(Credentials credentials) { - mCredentials = credentials; - - // Override homeserver url and/or identity server url if provided - if (credentials.wellKnown != null) { - if (credentials.wellKnown.homeServer != null) { - String homeServerUrl = credentials.wellKnown.homeServer.baseURL; - - if (!TextUtils.isEmpty(homeServerUrl)) { - // remove trailing "/" - if (homeServerUrl.endsWith("/")) { - homeServerUrl = homeServerUrl.substring(0, homeServerUrl.length() - 1); - } - - Timber.d("Overriding homeserver url to " + homeServerUrl); - mHomeServerUri = Uri.parse(homeServerUrl); - } - } - - if (credentials.wellKnown.identityServer != null) { - String identityServerUrl = credentials.wellKnown.identityServer.baseURL; - - if (!TextUtils.isEmpty(identityServerUrl)) { - // remove trailing "/" - if (identityServerUrl.endsWith("/")) { - identityServerUrl = identityServerUrl.substring(0, identityServerUrl.length() - 1); - } - - Timber.d("Overriding identity server url to " + identityServerUrl); - mIdentityServerUri = Uri.parse(identityServerUrl); - } - } - - if (credentials.wellKnown.jitsiServer != null) { - String jitsiServerUrl = credentials.wellKnown.jitsiServer.preferredDomain; - - if (!TextUtils.isEmpty(jitsiServerUrl)) { - // add trailing "/" - if (!jitsiServerUrl.endsWith("/")) { - jitsiServerUrl = jitsiServerUrl + "/"; - } - - Timber.d("Overriding jitsi server url to " + jitsiServerUrl); - mJitsiServerUri = Uri.parse(jitsiServerUrl); - } - } - } - } - - /** - * @return whether we should reject X509 certs that were issued by trusts CAs and only trust - * certs with matching fingerprints. - */ - public boolean shouldPin() { - return mPin; - } - - /** - * TLS versions accepted for TLS connections with the homeserver. - */ - @Nullable - public List getAcceptedTlsVersions() { - return mTlsVersions; - } - - /** - * TLS cipher suites accepted for TLS connections with the homeserver. - */ - @Nullable - public List getAcceptedTlsCipherSuites() { - return mTlsCipherSuites; - } - - /** - * @return whether we should accept TLS extensions. - */ - public boolean shouldAcceptTlsExtensions() { - return mShouldAcceptTlsExtensions; - } - - /** - * @return true if the usage of TlsVersions has to be forced - */ - public boolean forceUsageOfTlsVersions() { - return mForceUsageTlsVersions; - } - - - /** - * @return proxy config if available - */ - @Nullable - public Proxy getProxyConfig() { - if (mProxyHostname == null || mProxyHostname.length() == 0 || mProxyPort == -1) { - return null; - } - - return new Proxy(Proxy.Type.HTTP, - new InetSocketAddress(mProxyHostname, mProxyPort)); - } - - - @Override - public String toString() { - return "HomeserverConnectionConfig{" + - "mHomeServerUri=" + mHomeServerUri + - ", mJitsiServerUri=" + mJitsiServerUri + - ", mIdentityServerUri=" + mIdentityServerUri + - ", mAntiVirusServerUri=" + mAntiVirusServerUri + - ", mAllowedFingerprints size=" + mAllowedFingerprints.size() + - ", mCredentials=" + mCredentials + - ", mPin=" + mPin + - ", mShouldAcceptTlsExtensions=" + mShouldAcceptTlsExtensions + - ", mProxyHostname=" + (null == mProxyHostname ? "" : mProxyHostname) + - ", mProxyPort=" + (-1 == mProxyPort ? "" : mProxyPort) + - ", mTlsVersions=" + (null == mTlsVersions ? "" : mTlsVersions.size()) + - ", mTlsCipherSuites=" + (null == mTlsCipherSuites ? "" : mTlsCipherSuites.size()) + - '}'; - } - - /** - * Convert the object instance into a JSon object - * - * @return the JSon representation - * @throws JSONException the JSON conversion failure reason - */ - public JSONObject toJson() throws JSONException { - JSONObject json = new JSONObject(); - - json.put("home_server_url", mHomeServerUri.toString()); - Uri jitsiServerUri = getJitsiServerUri(); - if (jitsiServerUri != null) { - json.put("jitsi_server_url", jitsiServerUri.toString()); - } - Uri identityServerUri = getIdentityServerUri(); - if (identityServerUri != null) { - json.put("identity_server_url", identityServerUri.toString()); - } - - if (mAntiVirusServerUri != null) { - json.put("antivirus_server_url", mAntiVirusServerUri.toString()); - } - - json.put("pin", mPin); - - if (mCredentials != null) json.put("credentials", mCredentials.toJson()); - if (mAllowedFingerprints != null) { - List fingerprints = new ArrayList<>(mAllowedFingerprints.size()); - - for (Fingerprint fingerprint : mAllowedFingerprints) { - fingerprints.add(fingerprint.toJson()); - } - - json.put("fingerprints", new JSONArray(fingerprints)); - } - - json.put("tls_extensions", mShouldAcceptTlsExtensions); - - if (mTlsVersions != null) { - List tlsVersions = new ArrayList<>(mTlsVersions.size()); - - for (TlsVersion tlsVersion : mTlsVersions) { - tlsVersions.add(tlsVersion.javaName()); - } - - json.put("tls_versions", new JSONArray(tlsVersions)); - } - - json.put("force_usage_of_tls_versions", mForceUsageTlsVersions); - - if (mTlsCipherSuites != null) { - List tlsCipherSuites = new ArrayList<>(mTlsCipherSuites.size()); - - for (CipherSuite tlsCipherSuite : mTlsCipherSuites) { - tlsCipherSuites.add(tlsCipherSuite.javaName()); - } - - json.put("tls_cipher_suites", new JSONArray(tlsCipherSuites)); - } - - if (mProxyPort != -1) { - json.put("proxy_port", mProxyPort); - } - - if (mProxyHostname != null && mProxyHostname.length() > 0) { - json.put("proxy_hostname", mProxyHostname); - } - - return json; - } - - /** - * Create an object instance from the json object. - * - * @param jsonObject the json object - * @return a HomeServerConnectionConfig instance - * @throws JSONException the conversion failure reason - */ - public static HomeServerConnectionConfig fromJson(JSONObject jsonObject) throws JSONException { - JSONObject credentialsObj = jsonObject.optJSONObject("credentials"); - Credentials creds = credentialsObj != null ? Credentials.fromJson(credentialsObj) : null; - - Builder builder = new Builder() - .withHomeServerUri(Uri.parse(jsonObject.getString("home_server_url"))) - .withJitsiServerUri(jsonObject.has("jitsi_server_url") ? Uri.parse(jsonObject.getString("jitsi_server_url")) : null) - .withIdentityServerUri(jsonObject.has("identity_server_url") ? Uri.parse(jsonObject.getString("identity_server_url")) : null) - .withCredentials(creds) - .withPin(jsonObject.optBoolean("pin", false)); - - JSONArray fingerprintArray = jsonObject.optJSONArray("fingerprints"); - if (fingerprintArray != null) { - for (int i = 0; i < fingerprintArray.length(); i++) { - builder.addAllowedFingerPrint(Fingerprint.fromJson(fingerprintArray.getJSONObject(i))); - } - } - - // Set the anti-virus server uri if any - if (jsonObject.has("antivirus_server_url")) { - builder.withAntiVirusServerUri(Uri.parse(jsonObject.getString("antivirus_server_url"))); - } - - builder.withShouldAcceptTlsExtensions(jsonObject.optBoolean("tls_extensions", true)); - - // Set the TLS versions if any - if (jsonObject.has("tls_versions")) { - JSONArray tlsVersionsArray = jsonObject.optJSONArray("tls_versions"); - if (tlsVersionsArray != null) { - for (int i = 0; i < tlsVersionsArray.length(); i++) { - builder.addAcceptedTlsVersion(TlsVersion.forJavaName(tlsVersionsArray.getString(i))); - } - } - } - - builder.forceUsageOfTlsVersions(jsonObject.optBoolean("force_usage_of_tls_versions", false)); - - // Set the TLS cipher suites if any - if (jsonObject.has("tls_cipher_suites")) { - JSONArray tlsCipherSuitesArray = jsonObject.optJSONArray("tls_cipher_suites"); - if (tlsCipherSuitesArray != null) { - for (int i = 0; i < tlsCipherSuitesArray.length(); i++) { - builder.addAcceptedTlsCipherSuite(CipherSuite.forJavaName(tlsCipherSuitesArray.getString(i))); - } - } - } - - // Set the proxy options right if any - if (jsonObject.has("proxy_hostname") && jsonObject.has("proxy_port")) { - builder.withProxy(jsonObject.getString("proxy_hostname"), jsonObject.getInt("proxy_port")); - } - - return builder.build(); - } - - /** - * Builder - */ - public static class Builder { - private HomeServerConnectionConfig mHomeServerConnectionConfig; - - /** - * Builder constructor - */ - public Builder() { - mHomeServerConnectionConfig = new HomeServerConnectionConfig(); - } - - /** - * create a Builder from an existing HomeServerConnectionConfig - */ - public Builder(HomeServerConnectionConfig from) { - try { - mHomeServerConnectionConfig = HomeServerConnectionConfig.fromJson(from.toJson()); - } catch (JSONException e) { - // Should not happen - throw new RuntimeException("Unable to create a HomeServerConnectionConfig", e); - } - } - - /** - * @param homeServerUri The URI to use to connect to the homeserver. Cannot be null - * @return this builder - */ - public Builder withHomeServerUri(final Uri homeServerUri) { - if (homeServerUri == null || (!"http".equals(homeServerUri.getScheme()) && !"https".equals(homeServerUri.getScheme()))) { - throw new RuntimeException("Invalid homeserver URI: " + homeServerUri); - } - - // remove trailing / - if (homeServerUri.toString().endsWith("/")) { - try { - String url = homeServerUri.toString(); - mHomeServerConnectionConfig.mHomeServerUri = Uri.parse(url.substring(0, url.length() - 1)); - } catch (Exception e) { - throw new RuntimeException("Invalid homeserver URI: " + homeServerUri); - } - } else { - mHomeServerConnectionConfig.mHomeServerUri = homeServerUri; - } - - return this; - } - - /** - * @param jitsiServerUri The URI to use to manage identity. Can be null - * @return this builder - */ - public Builder withJitsiServerUri(@Nullable final Uri jitsiServerUri) { - if (jitsiServerUri != null - && !jitsiServerUri.toString().isEmpty() - && !"http".equals(jitsiServerUri.getScheme()) - && !"https".equals(jitsiServerUri.getScheme())) { - throw new RuntimeException("Invalid jitsi server URI: " + jitsiServerUri); - } - - // add trailing / - if ((null != jitsiServerUri) && !jitsiServerUri.toString().endsWith("/")) { - try { - String url = jitsiServerUri.toString(); - mHomeServerConnectionConfig.mJitsiServerUri = Uri.parse(url + "/"); - } catch (Exception e) { - throw new RuntimeException("Invalid jitsi server URI: " + jitsiServerUri); - } - } else { - if (jitsiServerUri != null && jitsiServerUri.toString().isEmpty()) { - mHomeServerConnectionConfig.mJitsiServerUri = null; - } else { - mHomeServerConnectionConfig.mJitsiServerUri = jitsiServerUri; - } - } - - return this; - } - - /** - * @param identityServerUri The URI to use to manage identity. Can be null - * @return this builder - */ - public Builder withIdentityServerUri(@Nullable final Uri identityServerUri) { - if (identityServerUri != null - && !identityServerUri.toString().isEmpty() - && !"http".equals(identityServerUri.getScheme()) - && !"https".equals(identityServerUri.getScheme())) { - throw new RuntimeException("Invalid identity server URI: " + identityServerUri); - } - - // remove trailing / - if ((null != identityServerUri) && identityServerUri.toString().endsWith("/")) { - try { - String url = identityServerUri.toString(); - mHomeServerConnectionConfig.mIdentityServerUri = Uri.parse(url.substring(0, url.length() - 1)); - } catch (Exception e) { - throw new RuntimeException("Invalid identity server URI: " + identityServerUri); - } - } else { - if (identityServerUri != null && identityServerUri.toString().isEmpty()) { - mHomeServerConnectionConfig.mIdentityServerUri = null; - } else { - mHomeServerConnectionConfig.mIdentityServerUri = identityServerUri; - } - } - - return this; - } - - /** - * @param credentials The credentials to use, if needed. Can be null. - * @return this builder - */ - public Builder withCredentials(@Nullable Credentials credentials) { - mHomeServerConnectionConfig.mCredentials = credentials; - return this; - } - - /** - * @param allowedFingerprint If using SSL, allow server certs that match this fingerprint. - * @return this builder - */ - public Builder addAllowedFingerPrint(@Nullable Fingerprint allowedFingerprint) { - if (allowedFingerprint != null) { - mHomeServerConnectionConfig.mAllowedFingerprints.add(allowedFingerprint); - } - - return this; - } - - /** - * @param pin If true only allow certs matching given fingerprints, otherwise fallback to - * standard X509 checks. - * @return this builder - */ - public Builder withPin(boolean pin) { - mHomeServerConnectionConfig.mPin = pin; - - return this; - } - - /** - * @param shouldAcceptTlsExtension - * @return this builder - */ - public Builder withShouldAcceptTlsExtensions(boolean shouldAcceptTlsExtension) { - mHomeServerConnectionConfig.mShouldAcceptTlsExtensions = shouldAcceptTlsExtension; - - return this; - } - - /** - * Add an accepted TLS version for TLS connections with the homeserver. - * - * @param tlsVersion the tls version to add to the set of TLS versions accepted. - * @return this builder - */ - public Builder addAcceptedTlsVersion(@NonNull TlsVersion tlsVersion) { - if (mHomeServerConnectionConfig.mTlsVersions == null) { - mHomeServerConnectionConfig.mTlsVersions = new ArrayList<>(); - } - - mHomeServerConnectionConfig.mTlsVersions.add(tlsVersion); - - return this; - } - - /** - * Force the usage of TlsVersion. This can be usefull for device on Android version < 20 - * - * @param forceUsageOfTlsVersions set to true to force the usage of specified TlsVersions (with {@link #addAcceptedTlsVersion(TlsVersion)} - * @return this builder - */ - public Builder forceUsageOfTlsVersions(boolean forceUsageOfTlsVersions) { - mHomeServerConnectionConfig.mForceUsageTlsVersions = forceUsageOfTlsVersions; - - return this; - } - - /** - * Add a TLS cipher suite to the list of accepted TLS connections with the homeserver. - * - * @param tlsCipherSuite the tls cipher suite to add. - * @return this builder - */ - public Builder addAcceptedTlsCipherSuite(@NonNull CipherSuite tlsCipherSuite) { - if (mHomeServerConnectionConfig.mTlsCipherSuites == null) { - mHomeServerConnectionConfig.mTlsCipherSuites = new ArrayList<>(); - } - - mHomeServerConnectionConfig.mTlsCipherSuites.add(tlsCipherSuite); - - return this; - } - - /** - * Update the anti-virus server URI. - * - * @param antivirusServerUri the new anti-virus uri. Can be null - * @return this builder - */ - public Builder withAntiVirusServerUri(@Nullable Uri antivirusServerUri) { - if ((null != antivirusServerUri) && (!"http".equals(antivirusServerUri.getScheme()) && !"https".equals(antivirusServerUri.getScheme()))) { - throw new RuntimeException("Invalid antivirus server URI: " + antivirusServerUri); - } - - mHomeServerConnectionConfig.mAntiVirusServerUri = antivirusServerUri; - - return this; - } - - /** - * Convenient method to limit the TLS versions and cipher suites for this Builder - * Ref: - * - https://www.ssi.gouv.fr/uploads/2017/02/security-recommendations-for-tls_v1.1.pdf - * - https://developer.android.com/reference/javax/net/ssl/SSLEngine - * - * @param tlsLimitations true to use Tls limitations - * @param enableCompatibilityMode set to true for Android < 20 - * @return this builder - */ - public Builder withTlsLimitations(boolean tlsLimitations, boolean enableCompatibilityMode) { - if (tlsLimitations) { - withShouldAcceptTlsExtensions(false); - - // Tls versions - addAcceptedTlsVersion(TlsVersion.TLS_1_2); - addAcceptedTlsVersion(TlsVersion.TLS_1_3); - - forceUsageOfTlsVersions(enableCompatibilityMode); - - // Cipher suites - addAcceptedTlsCipherSuite(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256); - addAcceptedTlsCipherSuite(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256); - addAcceptedTlsCipherSuite(CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256); - addAcceptedTlsCipherSuite(CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256); - addAcceptedTlsCipherSuite(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384); - addAcceptedTlsCipherSuite(CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384); - addAcceptedTlsCipherSuite(CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256); - addAcceptedTlsCipherSuite(CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256); - - if (enableCompatibilityMode) { - // Adopt some preceding cipher suites for Android < 20 to be able to negotiate - // a TLS session. - addAcceptedTlsCipherSuite(CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA); - addAcceptedTlsCipherSuite(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA); - } - } - - return this; - } - - /** - * @param proxyHostname Proxy Hostname - * @param proxyPort Proxy Port - * @return this builder - */ - public Builder withProxy(@Nullable String proxyHostname, int proxyPort) { - mHomeServerConnectionConfig.mProxyHostname = proxyHostname; - mHomeServerConnectionConfig.mProxyPort = proxyPort; - return this; - } - - /** - * @return the {@link HomeServerConnectionConfig} - */ - public HomeServerConnectionConfig build() { - // Check mandatory parameters - if (mHomeServerConnectionConfig.mHomeServerUri == null) { - throw new RuntimeException("Homeserver URI not set"); - } - - return mHomeServerConnectionConfig; - } - - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/LoginStorage.java b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/LoginStorage.java deleted file mode 100755 index 924bd461ed..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/LoginStorage.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.legacy.riot; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.content.SharedPreferences; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; -import java.util.List; - -import timber.log.Timber; - -/** - * IMPORTANT: This class is imported from Riot-Android to be able to perform a migration. Do not use it for any other purpose - * - * Stores login credentials in SharedPreferences. - */ -public class LoginStorage { - private static final String PREFS_LOGIN = "Vector.LoginStorage"; - - // multi accounts + homeserver config - private static final String PREFS_KEY_CONNECTION_CONFIGS = "PREFS_KEY_CONNECTION_CONFIGS"; - - private final Context mContext; - - public LoginStorage(Context appContext) { - mContext = appContext.getApplicationContext(); - - } - - /** - * @return the list of homeserver configurations. - */ - public List getCredentialsList() { - SharedPreferences prefs = mContext.getSharedPreferences(PREFS_LOGIN, Context.MODE_PRIVATE); - - String connectionConfigsString = prefs.getString(PREFS_KEY_CONNECTION_CONFIGS, null); - - Timber.d("Got connection json: "); - - if (connectionConfigsString == null) { - return new ArrayList<>(); - } - - try { - JSONArray connectionConfigsStrings = new JSONArray(connectionConfigsString); - - List configList = new ArrayList<>( - connectionConfigsStrings.length() - ); - - for (int i = 0; i < connectionConfigsStrings.length(); i++) { - configList.add( - HomeServerConnectionConfig.fromJson(connectionConfigsStrings.getJSONObject(i)) - ); - } - - return configList; - } catch (JSONException e) { - Timber.e(e, "Failed to deserialize accounts"); - throw new RuntimeException("Failed to deserialize accounts"); - } - } - - /** - * Add a credentials to the credentials list - * - * @param config the homeserver config to add. - */ - public void addCredentials(HomeServerConnectionConfig config) { - if (null != config && config.getCredentials() != null) { - SharedPreferences prefs = mContext.getSharedPreferences(PREFS_LOGIN, Context.MODE_PRIVATE); - SharedPreferences.Editor editor = prefs.edit(); - - List configs = getCredentialsList(); - - configs.add(config); - - List serialized = new ArrayList<>(configs.size()); - - try { - for (HomeServerConnectionConfig c : configs) { - serialized.add(c.toJson()); - } - } catch (JSONException e) { - throw new RuntimeException("Failed to serialize connection config"); - } - - String ser = new JSONArray(serialized).toString(); - - Timber.d("Storing " + serialized.size() + " credentials"); - - editor.putString(PREFS_KEY_CONNECTION_CONFIGS, ser); - editor.apply(); - } - } - - /** - * Remove the credentials from credentials list - * - * @param config the credentials to remove - */ - public void removeCredentials(HomeServerConnectionConfig config) { - if (null != config && config.getCredentials() != null) { - Timber.d("Removing account: " + config.getCredentials().userId); - - SharedPreferences prefs = mContext.getSharedPreferences(PREFS_LOGIN, Context.MODE_PRIVATE); - SharedPreferences.Editor editor = prefs.edit(); - - List configs = getCredentialsList(); - List serialized = new ArrayList<>(configs.size()); - - boolean found = false; - try { - for (HomeServerConnectionConfig c : configs) { - if (c.getCredentials().userId.equals(config.getCredentials().userId)) { - found = true; - } else { - serialized.add(c.toJson()); - } - } - } catch (JSONException e) { - throw new RuntimeException("Failed to serialize connection config"); - } - - if (!found) return; - - String ser = new JSONArray(serialized).toString(); - - Timber.d("Storing " + serialized.size() + " credentials"); - - editor.putString(PREFS_KEY_CONNECTION_CONFIGS, ser); - editor.apply(); - } - } - - /** - * Replace the credential from credentials list, based on credentials.userId. - * If it does not match an existing credential it does *not* insert the new credentials. - * - * @param config the credentials to insert - */ - public void replaceCredentials(HomeServerConnectionConfig config) { - if (null != config && config.getCredentials() != null) { - SharedPreferences prefs = mContext.getSharedPreferences(PREFS_LOGIN, Context.MODE_PRIVATE); - SharedPreferences.Editor editor = prefs.edit(); - - List configs = getCredentialsList(); - List serialized = new ArrayList<>(configs.size()); - - boolean found = false; - try { - for (HomeServerConnectionConfig c : configs) { - if (c.getCredentials().userId.equals(config.getCredentials().userId)) { - serialized.add(config.toJson()); - found = true; - } else { - serialized.add(c.toJson()); - } - } - } catch (JSONException e) { - throw new RuntimeException("Failed to serialize connection config"); - } - - if (!found) return; - - String ser = new JSONArray(serialized).toString(); - - Timber.d("Storing " + serialized.size() + " credentials"); - - editor.putString(PREFS_KEY_CONNECTION_CONFIGS, ser); - editor.apply(); - } - } - - /** - * Clear the stored values - */ - @SuppressLint("ApplySharedPref") - public void clear() { - SharedPreferences prefs = mContext.getSharedPreferences(PREFS_LOGIN, Context.MODE_PRIVATE); - SharedPreferences.Editor editor = prefs.edit(); - editor.remove(PREFS_KEY_CONNECTION_CONFIGS); - //Need to commit now because called before forcing an app restart - editor.commit(); - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnown.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnown.kt deleted file mode 100644 index a754a0da96..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnown.kt +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.matrix.android.sdk.internal.legacy.riot - -import com.squareup.moshi.Json -import com.squareup.moshi.JsonClass - -/** - * IMPORTANT: This class is imported from Riot-Android to be able to perform a migration. Do not use it for any other purpose - * - * https://matrix.org/docs/spec/client_server/r0.4.0.html#server-discovery - *
- * {
- *     "m.homeserver": {
- *         "base_url": "https://matrix.org"
- *     },
- *     "m.identity_server": {
- *         "base_url": "https://vector.im"
- *     }
- *     "m.integrations": {
- *          "managers": [
- *              {
- *                  "api_url": "https://integrations.example.org",
- *                  "ui_url": "https://integrations.example.org/ui"
- *              },
- *              {
- *                  "api_url": "https://bots.example.org"
- *              }
- *          ]
- *    }
- *     "im.vector.riot.jitsi": {
- *         "preferredDomain": "https://jitsi.riot.im/"
- *     }
- * }
- * 
- */ -@JsonClass(generateAdapter = true) -class WellKnown { - - @JvmField - @Json(name = "m.homeserver") - var homeServer: WellKnownBaseConfig? = null - - @JvmField - @Json(name = "m.identity_server") - var identityServer: WellKnownBaseConfig? = null - - @JvmField - @Json(name = "m.integrations") - var integrations: Map? = null - - /** - * Returns the list of integration managers proposed. - */ - fun getIntegrationManagers(): List { - val managers = ArrayList() - integrations?.get("managers")?.let { - (it as? ArrayList<*>)?.let { configs -> - configs.forEach { config -> - (config as? Map<*, *>)?.let { map -> - val apiUrl = map["api_url"] as? String - val uiUrl = map["ui_url"] as? String ?: apiUrl - if (apiUrl != null && - apiUrl.startsWith("https://") && - uiUrl!!.startsWith("https://")) { - managers.add( - WellKnownManagerConfig( - apiUrl = apiUrl, - uiUrl = uiUrl - ) - ) - } - } - } - } - } - return managers - } - - @JvmField - @Json(name = "im.vector.riot.jitsi") - var jitsiServer: WellKnownPreferredConfig? = null -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnownBaseConfig.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnownBaseConfig.kt deleted file mode 100644 index 2a4ae295fd..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnownBaseConfig.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.matrix.android.sdk.internal.legacy.riot - -import com.squareup.moshi.Json -import com.squareup.moshi.JsonClass - -/** - * IMPORTANT: This class is imported from Riot-Android to be able to perform a migration. Do not use it for any other purpose - * - * https://matrix.org/docs/spec/client_server/r0.4.0.html#server-discovery - *
- * {
- *     "base_url": "https://vector.im"
- * }
- * 
- */ -@JsonClass(generateAdapter = true) -class WellKnownBaseConfig { - - @JvmField - @Json(name = "base_url") - var baseURL: String? = null -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnownManagerConfig.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnownManagerConfig.kt deleted file mode 100644 index 6b1c67f7cb..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnownManagerConfig.kt +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.matrix.android.sdk.internal.legacy.riot - -/** - * IMPORTANT: This class is imported from Riot-Android to be able to perform a migration. Do not use it for any other purpose - */ -data class WellKnownManagerConfig( - val apiUrl: String, - val uiUrl: String -) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnownPreferredConfig.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnownPreferredConfig.kt deleted file mode 100644 index beb95a1d6f..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnownPreferredConfig.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.matrix.android.sdk.internal.legacy.riot - -import com.squareup.moshi.Json -import com.squareup.moshi.JsonClass - -/** - * IMPORTANT: This class is imported from Riot-Android to be able to perform a migration. Do not use it for any other purpose - * - * https://matrix.org/docs/spec/client_server/r0.4.0.html#server-discovery - *
- * {
- *     "preferredDomain": "https://jitsi.riot.im/"
- * }
- * 
- */ -@JsonClass(generateAdapter = true) -class WellKnownPreferredConfig { - - @JvmField - @Json(name = "preferredDomain") - var preferredDomain: String? = null -} diff --git a/vector-app/src/main/java/im/vector/app/VectorApplication.kt b/vector-app/src/main/java/im/vector/app/VectorApplication.kt index 5bc6750acc..8d12292524 100644 --- a/vector-app/src/main/java/im/vector/app/VectorApplication.kt +++ b/vector-app/src/main/java/im/vector/app/VectorApplication.kt @@ -54,7 +54,6 @@ import im.vector.app.core.resources.BuildMeta import im.vector.app.features.analytics.VectorAnalytics import im.vector.app.features.call.webrtc.WebRtcCallManager import im.vector.app.features.configuration.VectorConfiguration -import im.vector.app.features.disclaimer.DisclaimerDialog import im.vector.app.features.invite.InvitesAcceptor import im.vector.app.features.lifecycle.VectorActivityLifecycleCallbacks import im.vector.app.features.notifications.NotificationDrawerManager @@ -71,7 +70,6 @@ import im.vector.application.R import org.jitsi.meet.sdk.log.JitsiMeetDefaultLogHandler import org.matrix.android.sdk.api.Matrix import org.matrix.android.sdk.api.auth.AuthenticationService -import org.matrix.android.sdk.api.legacy.LegacySessionImporter import timber.log.Timber import java.text.SimpleDateFormat import java.util.Date @@ -86,7 +84,6 @@ class VectorApplication : WorkConfiguration.Provider { lateinit var appContext: Context - @Inject lateinit var legacySessionImporter: LegacySessionImporter @Inject lateinit var authenticationService: AuthenticationService @Inject lateinit var vectorConfiguration: VectorConfiguration @Inject lateinit var emojiCompatFontProvider: EmojiCompatFontProvider @@ -111,7 +108,6 @@ class VectorApplication : @Inject lateinit var buildMeta: BuildMeta @Inject lateinit var leakDetector: LeakDetector @Inject lateinit var vectorLocale: VectorLocale - @Inject lateinit var disclaimerDialog: DisclaimerDialog // font thread handler private var fontThreadHandler: Handler? = null @@ -170,13 +166,6 @@ class VectorApplication : notificationUtils.createNotificationChannels() - // It can takes time, but do we care? - val sessionImported = legacySessionImporter.process() - if (!sessionImported) { - // Do not display the name change popup - disclaimerDialog.doNotShowDisclaimerDialog() - } - ProcessLifecycleOwner.get().lifecycle.addObserver(object : DefaultLifecycleObserver { override fun onResume(owner: LifecycleOwner) { Timber.i("App entered foreground") diff --git a/vector-app/src/main/java/im/vector/app/core/di/SingletonModule.kt b/vector-app/src/main/java/im/vector/app/core/di/SingletonModule.kt index 385f0f584b..2a917593d8 100644 --- a/vector-app/src/main/java/im/vector/app/core/di/SingletonModule.kt +++ b/vector-app/src/main/java/im/vector/app/core/di/SingletonModule.kt @@ -73,7 +73,6 @@ import org.matrix.android.sdk.api.MatrixConfiguration import org.matrix.android.sdk.api.SyncConfig import org.matrix.android.sdk.api.auth.AuthenticationService import org.matrix.android.sdk.api.auth.HomeServerHistoryService -import org.matrix.android.sdk.api.legacy.LegacySessionImporter import org.matrix.android.sdk.api.raw.RawService import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.sync.filter.SyncFilterParams @@ -176,11 +175,6 @@ import javax.inject.Singleton return activeSessionHolder.getActiveSession() } - @Provides - fun providesLegacySessionImporter(matrix: Matrix): LegacySessionImporter { - return matrix.legacySessionImporter() - } - @Provides fun providesAuthenticationService(matrix: Matrix): AuthenticationService { return matrix.authenticationService() diff --git a/vector/src/main/java/im/vector/app/features/disclaimer/DisclaimerDialog.kt b/vector/src/main/java/im/vector/app/features/disclaimer/DisclaimerDialog.kt deleted file mode 100644 index 8214ab7120..0000000000 --- a/vector/src/main/java/im/vector/app/features/disclaimer/DisclaimerDialog.kt +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2019 New Vector Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package im.vector.app.features.disclaimer - -import android.app.Activity -import android.content.SharedPreferences -import androidx.core.content.edit -import com.google.android.material.dialog.MaterialAlertDialogBuilder -import im.vector.app.R -import im.vector.app.core.di.DefaultPreferences -import im.vector.app.core.utils.openUrlInChromeCustomTab -import im.vector.app.features.settings.VectorSettingsUrls -import javax.inject.Inject - -// Increase this value to show again the disclaimer dialog after an upgrade of the application -private const val CURRENT_DISCLAIMER_VALUE = 2 - -const val SHARED_PREF_KEY = "LAST_DISCLAIMER_VERSION_VALUE" - -class DisclaimerDialog @Inject constructor( - @DefaultPreferences - private val sharedPrefs: SharedPreferences, -) { - fun showDisclaimerDialog(activity: Activity) { - if (sharedPrefs.getInt(SHARED_PREF_KEY, 0) < CURRENT_DISCLAIMER_VALUE) { - sharedPrefs.edit { - putInt(SHARED_PREF_KEY, CURRENT_DISCLAIMER_VALUE) - } - - val dialogLayout = activity.layoutInflater.inflate(R.layout.dialog_disclaimer_content, null) - - MaterialAlertDialogBuilder(activity) - .setView(dialogLayout) - .setCancelable(false) - .setNegativeButton(R.string.disclaimer_negative_button, null) - .setPositiveButton(R.string.disclaimer_positive_button) { _, _ -> - openUrlInChromeCustomTab(activity, null, VectorSettingsUrls.DISCLAIMER_URL) - } - .show() - } - } - - fun doNotShowDisclaimerDialog() { - sharedPrefs.edit { - putInt(SHARED_PREF_KEY, CURRENT_DISCLAIMER_VALUE) - } - } -} diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt index 4b42903d32..872f3f6dd5 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt @@ -56,7 +56,6 @@ import im.vector.app.features.analytics.accountdata.AnalyticsAccountDataViewMode import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.analytics.plan.ViewRoom import im.vector.app.features.crypto.recover.SetupMode -import im.vector.app.features.disclaimer.DisclaimerDialog import im.vector.app.features.home.room.list.actions.RoomListSharedAction import im.vector.app.features.home.room.list.actions.RoomListSharedActionViewModel import im.vector.app.features.home.room.list.home.layout.HomeLayoutSettingBottomDialogFragment @@ -140,7 +139,6 @@ class HomeActivity : @Inject lateinit var spaceStateHandler: SpaceStateHandler @Inject lateinit var unifiedPushHelper: UnifiedPushHelper @Inject lateinit var nightlyProxy: NightlyProxy - @Inject lateinit var disclaimerDialog: DisclaimerDialog @Inject lateinit var notificationPermissionManager: NotificationPermissionManager private var isNewAppLayoutEnabled: Boolean = false // delete once old app layout is removed @@ -588,8 +586,6 @@ class HomeActivity : .setPositiveButton(R.string.yes) { _, _ -> bugReporter.openBugReportScreen(this) } .setNegativeButton(R.string.no) { _, _ -> bugReporter.deleteCrashFile() } .show() - } else { - disclaimerDialog.showDisclaimerDialog(this) } // Force remote backup state update to update the banner if needed diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt b/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt index 56c25da0fd..f915395a42 100755 --- a/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt @@ -28,7 +28,6 @@ import im.vector.app.core.di.DefaultPreferences import im.vector.app.core.resources.BuildMeta import im.vector.app.core.resources.StringProvider import im.vector.app.features.VectorFeatures -import im.vector.app.features.disclaimer.SHARED_PREF_KEY import im.vector.app.features.home.ShortcutsHandler import im.vector.app.features.homeserver.ServerUrlsRepository import im.vector.app.features.themes.ThemeUtils @@ -334,9 +333,6 @@ class VectorPreferences @Inject constructor( // theme keysToKeep.add(ThemeUtils.APPLICATION_THEME_KEY) - // Disclaimer dialog - keysToKeep.add(SHARED_PREF_KEY) - // get all the existing keys val keys = defaultPrefs.all.keys diff --git a/vector/src/main/res/drawable/ic_riot_icon.xml b/vector/src/main/res/drawable/ic_riot_icon.xml deleted file mode 100644 index 51db35b239..0000000000 --- a/vector/src/main/res/drawable/ic_riot_icon.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - diff --git a/vector/src/main/res/layout/dialog_disclaimer_content.xml b/vector/src/main/res/layout/dialog_disclaimer_content.xml deleted file mode 100644 index 38f376e7eb..0000000000 --- a/vector/src/main/res/layout/dialog_disclaimer_content.xml +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file