diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser index 9d3f2013..4bf38514 100644 Binary files a/.idea/caches/build_file_checksums.ser and b/.idea/caches/build_file_checksums.ser differ diff --git a/app/src/main/java/im/vector/riotredesign/features/login/LoginActivity.kt b/app/src/main/java/im/vector/riotredesign/features/login/LoginActivity.kt index 31d8b37b..c280bb46 100644 --- a/app/src/main/java/im/vector/riotredesign/features/login/LoginActivity.kt +++ b/app/src/main/java/im/vector/riotredesign/features/login/LoginActivity.kt @@ -5,9 +5,9 @@ import android.view.View import android.widget.Toast import im.vector.matrix.android.api.Matrix import im.vector.matrix.android.api.MatrixCallback -import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig import im.vector.matrix.android.api.failure.Failure +import im.vector.matrix.android.api.session.Session import im.vector.riotredesign.R import im.vector.riotredesign.core.platform.RiotActivity import im.vector.riotredesign.features.home.HomeActivity @@ -17,7 +17,6 @@ import org.koin.android.ext.android.inject class LoginActivity : RiotActivity() { private val matrix by inject() - private val homeServerConnectionConfig = HomeServerConnectionConfig("https://matrix.org/") private val authenticator = matrix.authenticator() override fun onCreate(savedInstanceState: Bundle?) { @@ -30,6 +29,11 @@ class LoginActivity : RiotActivity() { val login = loginField.text.trim().toString() val password = passwordField.text.trim().toString() progressBar.visibility = View.VISIBLE + val homeServerConnectionConfig = HomeServerConnectionConfig.Builder() + .withHomeServerUri("https://matrix.org/") + .withIdentityServerUri("https://vector.im") + .build() + authenticator.authenticate(homeServerConnectionConfig, login, password, object : MatrixCallback { override fun onSuccess(data: Session?) { matrix.currentSession = data diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index 93a785c0..28361b0c 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -3,9 +3,6 @@ apply plugin: 'kotlin-android' apply plugin: 'kotlin-kapt' apply plugin: 'io.objectbox' -ext.support_version = '28.0.0' -ext.moshi_version = '1.7.0' - buildscript { repositories { @@ -43,6 +40,11 @@ android { } dependencies { + + def arrow_version = "0.7.3" + def support_version = '28.0.0' + def moshi_version = '1.7.0' + implementation fileTree(dir: 'libs', include: ['*.aar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" @@ -65,6 +67,8 @@ dependencies { // Paging implementation "android.arch.paging:runtime:1.0.1" + implementation "io.arrow-kt:arrow-core:$arrow_version" + // DI implementation "org.koin:koin-core:$koin_version" implementation "org.koin:koin-core-ext:$koin_version" diff --git a/matrix-sdk-android/objectbox-models/default.json b/matrix-sdk-android/objectbox-models/default.json index b4204c65..59e29086 100644 --- a/matrix-sdk-android/objectbox-models/default.json +++ b/matrix-sdk-android/objectbox-models/default.json @@ -4,50 +4,77 @@ "_note3": "If you have VCS merge conflicts, you must resolve them according to ObjectBox docs.", "entities": [ { - "id": "3:213989653016909134", - "lastPropertyId": "6:8192129106205548340", + "id": "6:5991986256653472999", + "lastPropertyId": "6:5675340775405504775", "name": "Credentials", "properties": [ { - "id": "1:3516672544602138732", + "id": "1:904844404428661340", "name": "id" }, { - "id": "2:8457998089049891725", - "indexId": "1:7573100044105293219", + "id": "2:4962733318674873893", "name": "userId" }, { - "id": "3:878535388660167894", + "id": "3:6496111157191804406", "name": "homeServer" }, { - "id": "4:7030303501035684102", + "id": "4:6583709765305423919", "name": "accessToken" }, { - "id": "5:7193051897929077560", + "id": "5:865976960498370870", "name": "refreshToken" }, { - "id": "6:8192129106205548340", + "id": "6:5675340775405504775", "name": "deviceId" } ], "relations": [] + }, + { + "id": "7:6920598293865885979", + "lastPropertyId": "3:5795529890406591571", + "name": "ObjectBoxSessionParams", + "properties": [ + { + "id": "1:7073183456619398402", + "name": "credentialsJson" + }, + { + "id": "2:8905537494398356078", + "name": "homeServerConnectionConfigJson" + }, + { + "id": "3:5795529890406591571", + "name": "id" + } + ], + "relations": [] } ], - "lastEntityId": "3:213989653016909134", - "lastIndexId": "1:7573100044105293219", + "lastEntityId": "7:6920598293865885979", + "lastIndexId": "4:1616715309690181473", "lastRelationId": "0:0", "lastSequenceId": "0:0", "modelVersion": 4, "modelVersionParserMinimum": 4, "retiredEntityUids": [ 637433444018824383, - 5577202525246066978 + 5577202525246066978, + 213989653016909134, + 826321009570992494, + 1775102368193732759 + ], + "retiredIndexUids": [ + 7573100044105293219, + 7664899561635023422, + 762622607983996029, + 1616715309690181473 ], - "retiredIndexUids": [], "retiredPropertyUids": [ 6211403495341530846, 1774175862476960436, @@ -60,7 +87,25 @@ 8258973118557394726, 4167129800901721265, 4654729568692986907, - 958528673818813300 + 958528673818813300, + 3516672544602138732, + 8457998089049891725, + 878535388660167894, + 7030303501035684102, + 7193051897929077560, + 8192129106205548340, + 7632656533038841948, + 1390065349267803135, + 6024884732066241356, + 3502558420506448922, + 3999645739247298623, + 8488502568193639300, + 594512591943458255, + 5113574037182501000, + 4929796643260285955, + 5690571528511905880, + 1811444397594387116, + 8817556524159529201 ], "retiredRelationUids": [], "version": 1 diff --git a/matrix-sdk-android/objectbox-models/default.json.bak b/matrix-sdk-android/objectbox-models/default.json.bak index 8866d88e..408532ff 100644 --- a/matrix-sdk-android/objectbox-models/default.json.bak +++ b/matrix-sdk-android/objectbox-models/default.json.bak @@ -4,49 +4,76 @@ "_note3": "If you have VCS merge conflicts, you must resolve them according to ObjectBox docs.", "entities": [ { - "id": "3:213989653016909134", - "lastPropertyId": "6:8192129106205548340", - "name": "Credentials", + "id": "4:1775102368193732759", + "lastPropertyId": "6:8817556524159529201", + "name": "SessionParams", "properties": [ { - "id": "1:3516672544602138732", + "id": "2:5690571528511905880", + "name": "homeServerConnectionConfig" + }, + { + "id": "3:1811444397594387116", "name": "id" }, { - "id": "2:8457998089049891725", + "id": "6:8817556524159529201", + "indexId": "4:1616715309690181473", + "name": "credentialsRelationId" + } + ], + "relations": [] + }, + { + "id": "6:5991986256653472999", + "lastPropertyId": "6:5675340775405504775", + "name": "Credentials", + "properties": [ + { + "id": "1:904844404428661340", + "name": "id" + }, + { + "id": "2:4962733318674873893", "name": "userId" }, { - "id": "3:878535388660167894", + "id": "3:6496111157191804406", "name": "homeServer" }, { - "id": "4:7030303501035684102", + "id": "4:6583709765305423919", "name": "accessToken" }, { - "id": "5:7193051897929077560", + "id": "5:865976960498370870", "name": "refreshToken" }, { - "id": "6:8192129106205548340", + "id": "6:5675340775405504775", "name": "deviceId" } ], "relations": [] } ], - "lastEntityId": "3:213989653016909134", - "lastIndexId": "0:0", + "lastEntityId": "6:5991986256653472999", + "lastIndexId": "4:1616715309690181473", "lastRelationId": "0:0", "lastSequenceId": "0:0", "modelVersion": 4, "modelVersionParserMinimum": 4, "retiredEntityUids": [ 637433444018824383, - 5577202525246066978 + 5577202525246066978, + 213989653016909134, + 826321009570992494 + ], + "retiredIndexUids": [ + 7573100044105293219, + 7664899561635023422, + 762622607983996029 ], - "retiredIndexUids": [], "retiredPropertyUids": [ 6211403495341530846, 1774175862476960436, @@ -59,7 +86,22 @@ 8258973118557394726, 4167129800901721265, 4654729568692986907, - 958528673818813300 + 958528673818813300, + 3516672544602138732, + 8457998089049891725, + 878535388660167894, + 7030303501035684102, + 7193051897929077560, + 8192129106205548340, + 7632656533038841948, + 1390065349267803135, + 6024884732066241356, + 3502558420506448922, + 3999645739247298623, + 8488502568193639300, + 594512591943458255, + 5113574037182501000, + 4929796643260285955 ], "retiredRelationUids": [], "version": 1 diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/CredentialsStore.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/CredentialsStore.kt deleted file mode 100644 index fd74d89d..00000000 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/CredentialsStore.kt +++ /dev/null @@ -1,11 +0,0 @@ -package im.vector.matrix.android.api.auth - -import im.vector.matrix.android.internal.auth.data.Credentials - -interface CredentialsStore { - - fun get(): Credentials? - - fun save(credentials: Credentials) - -} \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/SessionParamsStore.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/SessionParamsStore.kt new file mode 100644 index 00000000..908a69c9 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/SessionParamsStore.kt @@ -0,0 +1,11 @@ +package im.vector.matrix.android.api.auth + +import im.vector.matrix.android.internal.auth.data.SessionParams + +interface SessionParamsStore { + + fun get(): SessionParams? + + fun save(sessionParams: SessionParams) + +} \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/data/HomeServerConnectionConfig.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/data/HomeServerConnectionConfig.kt index 89d26bb5..164a502a 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/data/HomeServerConnectionConfig.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/auth/data/HomeServerConnectionConfig.kt @@ -1,9 +1,225 @@ package im.vector.matrix.android.api.auth.data +import android.net.Uri import com.squareup.moshi.JsonClass +import im.vector.matrix.android.internal.network.ssl.Fingerprint +import okhttp3.CipherSuite +import okhttp3.TlsVersion @JsonClass(generateAdapter = true) data class HomeServerConnectionConfig( - // the home server URI - val hsUri: String -) \ No newline at end of file + val homeServerUri: Uri, + val identityServerUri: Uri, + val antiVirusServerUri: Uri? = null, + val allowedFingerprints: MutableList = ArrayList(), + val shouldPin: Boolean = false, + val tlsVersions: MutableList? = null, + val tlsCipherSuites: MutableList? = null, + val shouldAcceptTlsExtensions: Boolean = true, + val allowHttpExtension: Boolean = false, + val forceUsageTlsVersions: Boolean = false +) { + + class Builder { + + private lateinit var homeServerUri: Uri + private lateinit var identityServerUri: Uri + private var antiVirusServerUri: Uri? = null + private val allowedFingerprints: MutableList = ArrayList() + private var shouldPin: Boolean = false + private val tlsVersions: MutableList = ArrayList() + private val tlsCipherSuites: MutableList = ArrayList() + private var shouldAcceptTlsExtensions: Boolean = true + private var allowHttpExtension: Boolean = false + private var forceUsageTlsVersions: Boolean = false + + fun withHomeServerUri(hsUriString: String): Builder { + return withHomeServerUri(Uri.parse(hsUriString)) + } + + /** + * @param hsUri The URI to use to connect to the homeserver. + * @return this builder + */ + fun withHomeServerUri(hsUri: Uri): Builder { + if (hsUri.scheme != "http" && hsUri.scheme != "https") { + throw RuntimeException("Invalid home server URI: " + hsUri!!) + } + // remove trailing / + homeServerUri = if (hsUri.toString().endsWith("/")) { + try { + val url = hsUri.toString() + Uri.parse(url.substring(0, url.length - 1)) + } catch (e: Exception) { + throw RuntimeException("Invalid home server URI: $hsUri") + } + } else { + hsUri + } + return this + } + + fun withIdentityServerUri(identityServerUriString: String): Builder { + return withIdentityServerUri(Uri.parse(identityServerUriString)) + } + + /** + * @param identityServerUri The URI to use to manage identity. + * @return this builder + */ + fun withIdentityServerUri(identityServerUri: Uri): Builder { + if (identityServerUri.scheme != "http" && identityServerUri.scheme != "https") { + throw RuntimeException("Invalid identity server URI: $identityServerUri") + } + // remove trailing / + if (identityServerUri.toString().endsWith("/")) { + try { + val url = identityServerUri.toString() + this.identityServerUri = Uri.parse(url.substring(0, url.length - 1)) + } catch (e: Exception) { + throw RuntimeException("Invalid identity server URI: $identityServerUri") + } + } else { + this.identityServerUri = identityServerUri + } + return this + } + + /** + * @param allowedFingerprints If using SSL, allow server certs that match these fingerprints. + * @return this builder + */ + fun withAllowedFingerPrints(allowedFingerprints: List?): Builder { + if (allowedFingerprints != null) { + this.allowedFingerprints.addAll(allowedFingerprints) + } + return this + } + + /** + * @param pin If true only allow certs matching given fingerprints, otherwise fallback to + * standard X509 checks. + * @return this builder + */ + fun withPin(pin: Boolean): Builder { + this.shouldPin = pin + return this + } + + /** + * @param shouldAcceptTlsExtension + * @return this builder + */ + fun withShouldAcceptTlsExtensions(shouldAcceptTlsExtension: Boolean): Builder { + this.shouldAcceptTlsExtensions = shouldAcceptTlsExtension + return this + } + + /** + * Add an accepted TLS version for TLS connections with the home server. + * + * @param tlsVersion the tls version to add to the set of TLS versions accepted. + * @return this builder + */ + fun addAcceptedTlsVersion(tlsVersion: TlsVersion): Builder { + this.tlsVersions.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 [.addAcceptedTlsVersion] + * @return this builder + */ + fun forceUsageOfTlsVersions(forceUsageOfTlsVersions: Boolean): Builder { + this.forceUsageTlsVersions = forceUsageOfTlsVersions + return this + } + + /** + * Add a TLS cipher suite to the list of accepted TLS connections with the home server. + * + * @param tlsCipherSuite the tls cipher suite to add. + * @return this builder + */ + fun addAcceptedTlsCipherSuite(tlsCipherSuite: CipherSuite): Builder { + this.tlsCipherSuites.add(tlsCipherSuite) + return this + } + + /** + * Update the anti-virus server URI. + * + * @param antivirusServerUri the new anti-virus uri. Can be null + * @return this builder + */ + fun withAntiVirusServerUri(antivirusServerUri: Uri?): Builder { + if (null != antivirusServerUri && "http" != antivirusServerUri.scheme && "https" != antivirusServerUri.scheme) { + throw RuntimeException("Invalid antivirus server URI: $antivirusServerUri") + } + this.antiVirusServerUri = 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 + */ + fun withTlsLimitations(tlsLimitations: Boolean, enableCompatibilityMode: Boolean): Builder { + 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 + } + + fun withAllowHttpConnection(allowHttpExtension: Boolean): Builder { + this.allowHttpExtension = allowHttpExtension + return this + } + + /** + * @return the [HomeServerConnectionConfig] + */ + fun build(): HomeServerConnectionConfig { + return HomeServerConnectionConfig(homeServerUri, identityServerUri, antiVirusServerUri, allowedFingerprints, shouldPin, tlsVersions, tlsCipherSuites, shouldAcceptTlsExtensions, allowHttpExtension, forceUsageTlsVersions) + } + + } + + +} + + + + + diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/events/Event.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/events/Event.kt index e230e31f..9f897a53 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/events/Event.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/events/Event.kt @@ -1,7 +1,9 @@ package im.vector.matrix.android.api.events +import com.google.gson.JsonObject import com.squareup.moshi.Json import com.squareup.moshi.JsonClass +import im.vector.matrix.android.internal.legacy.util.JsonUtils @JsonClass(generateAdapter = true) data class Event( @@ -14,4 +16,14 @@ data class Event( @Json(name = "state_key") val stateKey: String? = null, @Json(name = "room_id") val roomId: String? = null, @Json(name = "unsigned_data") val unsignedData: UnsignedData? = null -) +){ + + fun contentAsJsonObject(): JsonObject? { + return JsonUtils.toJson(content) + } + + + +} + + diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/events/EventType.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/events/EventType.kt index efc34a95..20671195 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/events/EventType.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/events/EventType.kt @@ -1,43 +1,42 @@ package im.vector.matrix.android.api.events -import com.squareup.moshi.Json +object EventType { -enum class EventType { - - @Json(name ="m.presence") PRESENCE, - @Json(name ="m.room.message") MESSAGE, - @Json(name ="m.sticker") STICKER, - @Json(name ="m.room.encrypted") ENCRYPTED, - @Json(name ="m.room.encryption") ENCRYPTION, - @Json(name ="m.room.message.feedback") FEEDBACK, - @Json(name ="m.typing") TYPING, - @Json(name ="m.room.redaction") REDACTION, - @Json(name ="m.receipt") RECEIPT, - @Json(name ="m.tag") TAG, - @Json(name ="m.room_key") ROOM_KEY, - @Json(name ="m.fully_read") FULLY_READ, - @Json(name ="m.room.plumbing") PLUMBING, - @Json(name ="m.room.bot.options") BOT_OPTIONS, - @Json(name ="m.room_key_request") KEY_REQUEST, - @Json(name ="m.forwarded_room_key") FORWARDED_ROOM_KEY, - @Json(name ="org.matrix.room.preview_urls") PREVIEW_URLS, + const val PRESENCE = "m.presence" + const val MESSAGE = "m.room.message" + const val STICKER = "m.sticker" + const val ENCRYPTED = "m.room.encrypted" + const val ENCRYPTION = "m.room.encryption" + const val FEEDBACK = "m.room.message.feedback" + const val TYPING = "m.typing" + const val REDACTION = "m.room.redaction" + const val RECEIPT = "m.receipt" + const val TAG = "m.tag" + const val ROOM_KEY = "m.room_key" + const val FULLY_READ = "m.fully_read" + const val PLUMBING = "m.room.plumbing" + const val BOT_OPTIONS = "m.room.bot.options" + const val KEY_REQUEST = "m.room_key_request" + const val FORWARDED_ROOM_KEY = "m.forwarded_room_key" + const val PREVIEW_URLS = "org.matrix.room.preview_urls" // State Events - @Json(name ="m.room.name") STATE_ROOM_NAME, - @Json(name ="m.room.topic") STATE_ROOM_TOPIC, - @Json(name ="m.room.avatar") STATE_ROOM_AVATAR, - @Json(name ="m.room.member") STATE_ROOM_MEMBER, - @Json(name ="m.room.third_party_invite") STATE_ROOM_THIRD_PARTY_INVITE, - @Json(name ="m.room.create") STATE_ROOM_CREATE, - @Json(name ="m.room.join_rules") STATE_ROOM_JOIN_RULES, - @Json(name ="m.room.guest_access") STATE_ROOM_GUEST_ACCESS, - @Json(name ="m.room.power_levels") STATE_ROOM_POWER_LEVELS, - @Json(name ="m.room.aliases") STATE_ROOM_ALIASES, - @Json(name ="m.room.tombstone") STATE_ROOM_TOMBSTONE, - @Json(name ="m.room.canonical_alias") STATE_CANONICAL_ALIAS, - @Json(name ="m.room.history_visibility") STATE_HISTORY_VISIBILITY, - @Json(name ="m.room.related_groups") STATE_RELATED_GROUPS, - @Json(name ="m.room.pinned_events") STATE_PINNED_EVENT + + const val STATE_ROOM_NAME = "m.room.name" + const val STATE_ROOM_TOPIC = "m.room.topic" + const val STATE_ROOM_AVATAR = "m.room.avatar" + const val STATE_ROOM_MEMBER = "m.room.member" + const val STATE_ROOM_THIRD_PARTY_INVITE = "m.room.third_party_invite" + const val STATE_ROOM_CREATE = "m.room.create" + const val STATE_ROOM_JOIN_RULES = "m.room.join_rules" + const val STATE_ROOM_GUEST_ACCESS = "m.room.guest_access" + const val STATE_ROOM_POWER_LEVELS = "m.room.power_levels" + const val STATE_ROOM_ALIASES = "m.room.aliases" + const val STATE_ROOM_TOMBSTONE = "m.room.tombstone" + const val STATE_CANONICAL_ALIAS = "m.room.canonical_alias" + const val STATE_HISTORY_VISIBILITY = "m.room.history_visibility" + const val STATE_RELATED_GROUPS = "m.room.related_groups" + const val STATE_PINNED_EVENT = "m.room.pinned_events" } \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/rooms/Invite.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/rooms/Invite.kt index de1d4046..79b9fa84 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/rooms/Invite.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/rooms/Invite.kt @@ -1,7 +1,9 @@ package im.vector.matrix.android.api.rooms import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass +@JsonClass(generateAdapter = true) data class Invite( @Json(name = "display_name") val displayName: String, @Json(name = "signed") val signed: Signed diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/rooms/RoomMember.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/rooms/RoomMember.kt index 7083cb24..7cbfb441 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/rooms/RoomMember.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/rooms/RoomMember.kt @@ -1,12 +1,15 @@ package im.vector.matrix.android.api.rooms +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass import im.vector.matrix.android.api.events.UnsignedData +@JsonClass(generateAdapter = true) data class RoomMember( - val membership: Membership, - val displayDame: String? = null, - val avatarUrl: String? = null, - val isDirect: Boolean = false, - val thirdPartyInvite: Invite? = null, - val unsignedData: UnsignedData? = null + @Json(name = "membership") val membership: Membership, + @Json(name = "display_name") val displayDame: String? = null, + @Json(name = "avatar_url") val avatarUrl: String? = null, + @Json(name = "is_direct") val isDirect: Boolean = false, + @Json(name = "third_party_invite") val thirdPartyInvite: Invite? = null, + @Json(name = "unsigned_data") val unsignedData: UnsignedData? = null ) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/AuthModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/AuthModule.kt index 46ec1655..b9fe0410 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/AuthModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/AuthModule.kt @@ -2,10 +2,10 @@ package im.vector.matrix.android.internal.auth import android.content.Context import im.vector.matrix.android.api.auth.Authenticator -import im.vector.matrix.android.api.auth.CredentialsStore -import im.vector.matrix.android.internal.auth.data.Credentials -import im.vector.matrix.android.internal.auth.data.MyObjectBox -import im.vector.matrix.android.internal.auth.db.ObjectBoxCredentialsStore +import im.vector.matrix.android.api.auth.SessionParamsStore +import im.vector.matrix.android.internal.auth.db.ObjectBoxSessionParams +import im.vector.matrix.android.internal.auth.db.ObjectBoxSessionParamsMapper +import im.vector.matrix.android.internal.auth.db.ObjectBoxSessionParamsStore import io.objectbox.Box import io.objectbox.BoxStore import org.koin.dsl.context.ModuleDefinition @@ -26,13 +26,14 @@ class AuthModule(private val context: Context) : Module { MyObjectBox.builder().androidContext(context).build() } + single { val boxStore = get(name = AUTH_BOX_STORE) as BoxStore - boxStore.boxFor(Credentials::class.java) as Box + boxStore.boxFor(ObjectBoxSessionParams::class.java) as Box } single { - ObjectBoxCredentialsStore(get()) as CredentialsStore + ObjectBoxSessionParamsStore(ObjectBoxSessionParamsMapper((get())), get()) as SessionParamsStore } }.invoke() diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/DefaultAuthenticator.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/DefaultAuthenticator.kt index a1ea3068..b804c7c6 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/DefaultAuthenticator.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/DefaultAuthenticator.kt @@ -1,19 +1,21 @@ package im.vector.matrix.android.internal.auth +import arrow.core.leftIfNull import com.squareup.moshi.Moshi import im.vector.matrix.android.api.MatrixCallback -import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.auth.Authenticator -import im.vector.matrix.android.api.auth.CredentialsStore +import im.vector.matrix.android.api.auth.SessionParamsStore import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig +import im.vector.matrix.android.api.failure.Failure +import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.util.Cancelable -import im.vector.matrix.android.internal.session.DefaultSession import im.vector.matrix.android.internal.auth.data.Credentials import im.vector.matrix.android.internal.auth.data.PasswordLoginParams +import im.vector.matrix.android.internal.auth.data.SessionParams import im.vector.matrix.android.internal.network.executeRequest +import im.vector.matrix.android.internal.session.DefaultSession import im.vector.matrix.android.internal.util.CancelableCoroutine import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers -import im.vector.matrix.android.internal.util.map import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import retrofit2.Retrofit @@ -21,28 +23,34 @@ import retrofit2.Retrofit class DefaultAuthenticator(private val retrofitBuilder: Retrofit.Builder, private val jsonMapper: Moshi, private val coroutineDispatchers: MatrixCoroutineDispatchers, - private val credentialsStore: CredentialsStore) : Authenticator { + private val sessionParamsStore: SessionParamsStore) : Authenticator { override fun authenticate(homeServerConnectionConfig: HomeServerConnectionConfig, login: String, password: String, callback: MatrixCallback): Cancelable { val authAPI = buildAuthAPI(homeServerConnectionConfig) + val job = GlobalScope.launch(coroutineDispatchers.main) { val loginParams = PasswordLoginParams.userIdentifier(login, password, "Mobile") - val loginResult = executeRequest { + executeRequest { apiCall = authAPI.login(loginParams) moshi = jsonMapper dispatcher = coroutineDispatchers.io + }.leftIfNull { + Failure.Unknown(IllegalArgumentException("Credentials shouldn't not be null")) }.map { - it?.apply { credentialsStore.save(it) } + val sessionParams = SessionParams(it, homeServerConnectionConfig) + sessionParamsStore.save(sessionParams) + sessionParams }.map { - DefaultSession(homeServerConnectionConfig) - } - loginResult.either({ callback.onFailure(it) }, { callback.onSuccess(it) }) + DefaultSession(it) + }.bimap( + { callback.onFailure(it) }, { callback.onSuccess(it) } + ) } return CancelableCoroutine(job) } private fun buildAuthAPI(homeServerConnectionConfig: HomeServerConnectionConfig): AuthAPI { - val retrofit = retrofitBuilder.baseUrl(homeServerConnectionConfig.hsUri).build() + val retrofit = retrofitBuilder.baseUrl(homeServerConnectionConfig.homeServerUri.toString()).build() return retrofit.create(AuthAPI::class.java) } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/data/Credentials.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/data/Credentials.kt index 150c0341..dc27befd 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/data/Credentials.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/data/Credentials.kt @@ -4,13 +4,12 @@ import com.squareup.moshi.Json import com.squareup.moshi.JsonClass import io.objectbox.annotation.Entity import io.objectbox.annotation.Id -import io.objectbox.annotation.Index -@Entity @JsonClass(generateAdapter = true) +@Entity data class Credentials( @Id var id: Long = 0, - @Index @Json(name = "user_id") val userId: String, + @Json(name = "user_id") val userId: String, @Json(name = "home_server") val homeServer: String, @Json(name = "access_token") val accessToken: String, @Json(name = "refresh_token") val refreshToken: String?, diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/data/SessionParams.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/data/SessionParams.kt new file mode 100644 index 00000000..1c36cf64 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/data/SessionParams.kt @@ -0,0 +1,8 @@ +package im.vector.matrix.android.internal.auth.data + +import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig + +data class SessionParams( + val credentials: Credentials, + val homeServerConnectionConfig: HomeServerConnectionConfig +) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/db/ObjectBoxCredentialsStore.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/db/ObjectBoxCredentialsStore.kt deleted file mode 100644 index 104e7060..00000000 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/db/ObjectBoxCredentialsStore.kt +++ /dev/null @@ -1,17 +0,0 @@ -package im.vector.matrix.android.internal.auth.db - -import im.vector.matrix.android.api.auth.CredentialsStore -import im.vector.matrix.android.internal.auth.data.Credentials -import io.objectbox.Box - -class ObjectBoxCredentialsStore(private val box: Box) : CredentialsStore { - - override fun save(credentials: Credentials) { - box.put(credentials) - } - - override fun get(): Credentials? { - return box.all.lastOrNull() - } - -} \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/db/ObjectBoxSessionParams.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/db/ObjectBoxSessionParams.kt new file mode 100644 index 00000000..3539ec77 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/db/ObjectBoxSessionParams.kt @@ -0,0 +1,11 @@ +package im.vector.matrix.android.internal.auth.db + +import io.objectbox.annotation.Entity +import io.objectbox.annotation.Id + +@Entity +data class ObjectBoxSessionParams( + val credentialsJson: String, + val homeServerConnectionConfigJson: String, + @Id var id: Long = 0 +) \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/db/ObjectBoxSessionParamsMapper.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/db/ObjectBoxSessionParamsMapper.kt new file mode 100644 index 00000000..ee6ba19b --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/db/ObjectBoxSessionParamsMapper.kt @@ -0,0 +1,38 @@ +package im.vector.matrix.android.internal.auth.db + +import com.squareup.moshi.Moshi +import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig +import im.vector.matrix.android.internal.auth.data.Credentials +import im.vector.matrix.android.internal.auth.data.SessionParams + +class ObjectBoxSessionParamsMapper(moshi: Moshi) { + + private val credentialsAdapter = moshi.adapter(Credentials::class.java) + private val homeServerConnectionConfigAdapter = moshi.adapter(HomeServerConnectionConfig::class.java) + + fun map(objectBoxSessionParams: ObjectBoxSessionParams?): SessionParams? { + if (objectBoxSessionParams == null) { + return null + } + val credentials = credentialsAdapter.fromJson(objectBoxSessionParams.credentialsJson) + val homeServerConnectionConfig = homeServerConnectionConfigAdapter.fromJson(objectBoxSessionParams.homeServerConnectionConfigJson) + if (credentials == null || homeServerConnectionConfig == null) { + return null + } + return SessionParams(credentials, homeServerConnectionConfig) + } + + fun map(sessionParams: SessionParams?): ObjectBoxSessionParams? { + if (sessionParams == null) { + return null + } + val credentialsJson = credentialsAdapter.toJson(sessionParams.credentials) + val homeServerConnectionConfigJson = homeServerConnectionConfigAdapter.toJson(sessionParams.homeServerConnectionConfig) + if (credentialsJson == null || homeServerConnectionConfigJson == null) { + return null + } + return ObjectBoxSessionParams(credentialsJson, homeServerConnectionConfigJson) + } + + +} \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/db/ObjectBoxSessionParamsStore.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/db/ObjectBoxSessionParamsStore.kt new file mode 100644 index 00000000..19b31c06 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/auth/db/ObjectBoxSessionParamsStore.kt @@ -0,0 +1,21 @@ +package im.vector.matrix.android.internal.auth.db + +import im.vector.matrix.android.api.auth.SessionParamsStore +import im.vector.matrix.android.internal.auth.data.SessionParams +import io.objectbox.Box + +class ObjectBoxSessionParamsStore(private val mapper: ObjectBoxSessionParamsMapper, + private val box: Box) : SessionParamsStore { + + override fun save(sessionParams: SessionParams) { + val objectBoxSessionParams = mapper.map(sessionParams) + objectBoxSessionParams?.let { + box.put(it) + } + } + + override fun get(): SessionParams? { + return box.all.map { mapper.map(it) }.lastOrNull() + } + +} \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MatrixModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MatrixModule.kt index c2abfcd8..f3d0aebe 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MatrixModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MatrixModule.kt @@ -14,6 +14,10 @@ class MatrixModule(private val options: MatrixOptions) : Module { override fun invoke(): ModuleDefinition = module { + single { + options.context + } + single { MatrixCoroutineDispatchers(io = Dispatchers.IO, computation = Dispatchers.IO, main = options.mainExecutor.asCoroutineDispatcher()) } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MoshiProvider.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MoshiProvider.kt new file mode 100644 index 00000000..b8f52338 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/MoshiProvider.kt @@ -0,0 +1,13 @@ +package im.vector.matrix.android.internal.di + +import com.squareup.moshi.Moshi + +object MoshiProvider { + + private val moshi: Moshi = Moshi.Builder().build() + + fun providesMoshi(): Moshi { + return moshi + } + +} \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/NetworkModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/NetworkModule.kt index 1435aa92..9504b7b0 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/NetworkModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/NetworkModule.kt @@ -1,7 +1,6 @@ package im.vector.matrix.android.internal.di import com.jakewharton.retrofit2.adapter.kotlin.coroutines.CoroutineCallAdapterFactory -import com.squareup.moshi.Moshi import im.vector.matrix.android.internal.network.AccessTokenInterceptor import okhttp3.OkHttpClient import okhttp3.logging.HttpLoggingInterceptor @@ -25,7 +24,7 @@ class NetworkModule : Module { single { val logger = HttpLoggingInterceptor.Logger { message -> Timber.v(message) } - HttpLoggingInterceptor(logger).apply { level = HttpLoggingInterceptor.Level.BODY } + HttpLoggingInterceptor(logger).apply { level = HttpLoggingInterceptor.Level.BASIC } } single { @@ -39,7 +38,7 @@ class NetworkModule : Module { } single { - Moshi.Builder().build() + MoshiProvider.providesMoshi() } single { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/SessionModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/SessionModule.kt index e40d018e..0997947d 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/SessionModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/di/SessionModule.kt @@ -1,20 +1,32 @@ package im.vector.matrix.android.internal.di -import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig +import im.vector.matrix.android.internal.auth.data.SessionParams +import im.vector.matrix.android.internal.legacy.MXDataHandler +import im.vector.matrix.android.internal.legacy.MXSession +import im.vector.matrix.android.internal.legacy.data.store.MXFileStore import im.vector.matrix.android.internal.session.DefaultSession import org.koin.dsl.context.ModuleDefinition import org.koin.dsl.module.Module import org.koin.dsl.module.module import retrofit2.Retrofit -class SessionModule(private val connectionConfig: HomeServerConnectionConfig) : Module { +class SessionModule(private val sessionParams: SessionParams) : Module { override fun invoke(): ModuleDefinition = module(override = true) { scope(DefaultSession.SCOPE) { val retrofitBuilder = get() as Retrofit.Builder retrofitBuilder - .baseUrl(connectionConfig.hsUri) + .baseUrl(sessionParams.homeServerConnectionConfig?.homeServerUri.toString()) .build() } + + scope(DefaultSession.SCOPE) { + val store = MXFileStore(sessionParams.credentials, false, get()) + val dataHandler = MXDataHandler(store, sessionParams.credentials) + MXSession.Builder(sessionParams, dataHandler, get()).build() + } + }.invoke() + + } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/SyncModule.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/SyncModule.kt index 386dc2d2..01b95e26 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/SyncModule.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/SyncModule.kt @@ -16,7 +16,11 @@ class SyncModule : Module { } scope(DefaultSession.SCOPE) { - Synchronizer(get(), get(), get()) + SyncResponseHandler(get(), get()) + } + + scope(DefaultSession.SCOPE) { + Synchronizer(get(), get(), get(), get()) } }.invoke() diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/SyncResponseHandler.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/SyncResponseHandler.kt new file mode 100644 index 00000000..d3ab929d --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/SyncResponseHandler.kt @@ -0,0 +1,523 @@ +package im.vector.matrix.android.internal.events.sync + +import android.text.TextUtils +import im.vector.matrix.android.api.events.Event +import im.vector.matrix.android.internal.events.sync.data.SyncResponse +import im.vector.matrix.android.internal.legacy.MXDataHandler +import im.vector.matrix.android.internal.legacy.data.Room +import im.vector.matrix.android.internal.legacy.data.store.IMXStore +import im.vector.matrix.android.internal.legacy.data.store.MXMemoryStore +import im.vector.matrix.android.internal.legacy.rest.client.AccountDataRestClient +import im.vector.matrix.android.internal.legacy.rest.model.RoomMember +import im.vector.matrix.android.internal.legacy.rest.model.bingrules.PushRulesResponse +import im.vector.matrix.android.internal.legacy.util.JsonUtils +import timber.log.Timber +import java.util.ArrayList +import kotlin.collections.HashMap +import kotlin.collections.List +import kotlin.collections.Map +import kotlin.collections.MutableList +import kotlin.collections.MutableMap +import kotlin.collections.emptyList +import kotlin.collections.isNotEmpty +import kotlin.collections.set + +class SyncResponseHandler(private val dataHandler: MXDataHandler, + private val store: IMXStore) { + + private val leftRoomsStore = MXMemoryStore() + private var isStartingCryptoWithInitialSync = false + private var areLeftRoomsSynced = false + + fun handleResponse(syncResponse: SyncResponse?, fromToken: String?, isCatchingUp: Boolean) { + if (syncResponse == null) { + return + } + Timber.v("Handle sync response") + val isInitialSync = null == fromToken + var isEmptyResponse = true + + // Handle the to device events before the room ones + // to ensure to decrypt them properly + if (syncResponse.toDevice?.events != null) { + for (toDeviceEvent in syncResponse.toDevice.events) { + handleToDeviceEvent(toDeviceEvent) + } + } + // Handle account data before the room events + // to be able to update direct chats dictionary during invites handling. + if (syncResponse.accountData != null) { + manageAccountData(syncResponse.accountData, isInitialSync) + } + + // sanity check + if (syncResponse.rooms != null) { + // joined rooms events + if (syncResponse.rooms.join.isNotEmpty()) { + val roomIds = syncResponse.rooms.join.keys + // Handle first joined rooms + for (roomId in roomIds) { + if (null != leftRoomsStore.getRoom(roomId)) { + leftRoomsStore.deleteRoom(roomId) + } + // TODO handle joined room + //getRoom(roomId).handleJoinedRoomSync(syncResponse.rooms.join[roomId], isInitialSync) + } + isEmptyResponse = false + } + + // invited room management + if (syncResponse.rooms.invite.isNotEmpty()) { + val roomIds = syncResponse.rooms.invite.keys + + var updatedDirectChatRoomsDict: MutableMap>? = null + var hasChanged = false + + for (roomId in roomIds) { + if (null != leftRoomsStore.getRoom(roomId)) { + leftRoomsStore.deleteRoom(roomId) + } + val room = getRoom(roomId) + val invitedRoomSync = syncResponse.rooms.invite[roomId] + // TODO handle invited room + //room.handleInvitedRoomSync(invitedRoomSync) + + // Handle here the invites to a direct chat. + if (room.isDirectChatInvitation) { + // Retrieve the inviter user id. + var participantUserId: String? = null + for (event in invitedRoomSync?.inviteState?.events ?: emptyList()) { + if (event.sender != null) { + participantUserId = event.sender + break + } + } + + if (participantUserId != null) { + // Prepare the updated dictionary. + if (updatedDirectChatRoomsDict == null) updatedDirectChatRoomsDict = if (null != store.directChatRoomsDict) { + // Consider the current dictionary. + HashMap(store.directChatRoomsDict) + } else { + java.util.HashMap() + } + + val roomIdsList: MutableList = if (updatedDirectChatRoomsDict.containsKey(participantUserId)) { + ArrayList(updatedDirectChatRoomsDict[participantUserId]) + } else { + ArrayList() + } + + // Check whether the room was not yet seen as direct chat + if (roomIdsList.indexOf(roomId) < 0) { + + roomIdsList.add(roomId) // update room list with the new room + updatedDirectChatRoomsDict[participantUserId] = roomIdsList + hasChanged = true + } + } + } + + } + + isEmptyResponse = false + + if (hasChanged) { + // Update account data to add new direct chat room(s) + /* mAccountDataRestClient.setAccountData(mCredentials.userId, AccountDataRestClient.ACCOUNT_DATA_TYPE_DIRECT_MESSAGES, + updatedDirectChatRoomsDict, object : ApiCallback { + override fun onSuccess(info: Void) { + } + + override fun onNetworkError(e: Exception) { + // TODO: we should try again. + } + + override fun onMatrixError(e: MatrixError) { + } + + override fun onUnexpectedError(e: Exception) { + } + })*/ + } + } + + // left room management + // it should be done at the end but it seems there is a server issue + // when inviting after leaving a room, the room is defined in the both leave & invite rooms list. + if (syncResponse.rooms.leave.isNotEmpty()) { + val roomIds = syncResponse.rooms.leave.keys + for (roomId in roomIds) { + // RoomSync leftRoomSync = syncResponse.rooms.leave.get(roomId); + + // Presently we remove the existing room from the rooms list. + // FIXME SYNC V2 Archive/Display the left rooms! + // For that create 'handleArchivedRoomSync' method + + var membership = RoomMember.MEMBERSHIP_LEAVE + val room = getRoom(roomId) + + // Retrieve existing room + // The room will then be able to notify its listeners. + // TODO handle + // room.handleJoinedRoomSync(syncResponse.rooms.leave[roomId], isInitialSync) + + val member = room.getMember(dataHandler.userId) + if (null != member) { + membership = member.membership + } + if (!TextUtils.equals(membership, RoomMember.MEMBERSHIP_KICK) && !TextUtils.equals(membership, RoomMember.MEMBERSHIP_BAN)) { + // ensure that the room data are properly deleted + store.deleteRoom(roomId) + dataHandler.onLeaveRoom(roomId) + } else { + dataHandler.onRoomKick(roomId) + } + // don't add to the left rooms if the user has been kicked / banned + if (areLeftRoomsSynced && TextUtils.equals(membership, RoomMember.MEMBERSHIP_LEAVE)) { + val leftRoom = getRoom(leftRoomsStore, roomId, true) + //Todo handle + //leftRoom.handleJoinedRoomSync(syncResponse.rooms.leave[roomId], isInitialSync) + } + } + isEmptyResponse = false + } + } + + // groups + if (null != syncResponse.groups) { + // Handle invited groups + if (null != syncResponse.groups.invite && !syncResponse.groups.invite.isEmpty()) { + // Handle invited groups + for (groupId in syncResponse.groups.invite.keys) { + val invitedGroupSync = syncResponse.groups.invite[groupId] + dataHandler.groupsManager.onNewGroupInvitation(groupId, invitedGroupSync?.profile, invitedGroupSync?.inviter, !isInitialSync) + } + } + + // Handle joined groups + if (null != syncResponse.groups.join && !syncResponse.groups.join.isEmpty()) { + for (groupId in syncResponse.groups.join.keys) { + dataHandler.groupsManager.onJoinGroup(groupId, !isInitialSync) + } + } + // Handle left groups + if (null != syncResponse.groups.leave && !syncResponse.groups.leave.isEmpty()) { + // Handle joined groups + for (groupId in syncResponse.groups.leave.keys) { + dataHandler.groupsManager.onLeaveGroup(groupId, !isInitialSync) + } + } + } + + // Handle presence of other users + if (syncResponse.presence?.events != null) { + for (presenceEvent in syncResponse.presence.events) { + handlePresenceEvent(presenceEvent) + } + } + dataHandler.crypto?.onSyncCompleted(syncResponse, fromToken, isCatchingUp) + if (!isEmptyResponse) { + store.eventStreamToken = syncResponse.nextBatch + store.commit() + } + + if (isInitialSync) { + if (!isCatchingUp) { + dataHandler.startCrypto(true) + } else { + // the events thread sends a dummy initial sync event + // when the application is restarted. + isStartingCryptoWithInitialSync = !isEmptyResponse + } + + dataHandler.onInitialSyncComplete(syncResponse?.nextBatch) + } else { + + if (!isCatchingUp) { + dataHandler.startCrypto(isStartingCryptoWithInitialSync) + } + + dataHandler.onLiveEventsChunkProcessed(fromToken, syncResponse.nextBatch) + dataHandler.callsManager?.checkPendingIncomingCalls() + + } + } + + private fun manageAccountData(accountData: Map, isInitialSync: Boolean) { + if (accountData.containsKey("events")) { + val events = accountData["events"] as List> + if (!events.isEmpty()) { + // ignored users list + manageIgnoredUsers(events, isInitialSync) + // push rules + managePushRulesUpdate(events) + // direct messages rooms + manageDirectChatRooms(events, isInitialSync) + // URL preview + manageUrlPreview(events) + // User widgets + manageUserWidgets(events) + } + } + } + + /** + * Refresh the push rules from the account data events list + * + * @param events the account data events. + */ + private fun managePushRulesUpdate(events: List>) { + for (event in events) { + val type = event["type"] as String + + if (TextUtils.equals(type, "m.push_rules")) { + if (event.containsKey("content")) { + val gson = JsonUtils.getGson(false) + + // convert the data to PushRulesResponse + // because BingRulesManager supports only PushRulesResponse + val element = gson.toJsonTree(event["content"]) + dataHandler.bingRulesManager?.buildRules(gson.fromJson(element, PushRulesResponse::class.java)) + + // warn the client that the push rules have been updated + dataHandler.onBingRulesUpdate() + } + + return + } + } + } + + /** + * Check if the ignored users list is updated + * + * @param events the account data events list + */ + private fun manageIgnoredUsers(events: List>, isInitialSync: Boolean) { + val newIgnoredUsers = dataHandler.ignoredUsers(events) + + if (null != newIgnoredUsers) { + val curIgnoredUsers = dataHandler.ignoredUserIds + // the both lists are not empty + if (0 != newIgnoredUsers.size || 0 != curIgnoredUsers.size) { + // check if the ignored users list has been updated + if (newIgnoredUsers.size != curIgnoredUsers.size || !newIgnoredUsers.containsAll(curIgnoredUsers)) { + // update the store + store.setIgnoredUserIdsList(newIgnoredUsers) + if (!isInitialSync) { + // warn there is an update + dataHandler.onIgnoredUsersListUpdate() + } + } + } + } + } + + + /** + * Extract the direct chat rooms list from the dedicated events. + * + * @param events the account data events list. + */ + private fun manageDirectChatRooms(events: List>, isInitialSync: Boolean) { + if (events.isNotEmpty()) { + for (event in events) { + val type = event["type"] as String + + if (TextUtils.equals(type, AccountDataRestClient.ACCOUNT_DATA_TYPE_DIRECT_MESSAGES)) { + if (event.containsKey("content")) { + val contentDict = event["content"] as Map> + store.directChatRoomsDict = contentDict + // reset the current list of the direct chat roomIDs + // to update it + if (!isInitialSync) { + // warn there is an update + dataHandler.onDirectMessageChatRoomsListUpdate() + } + } + } + } + } + } + + /** + * Manage the URL preview flag + * + * @param events the events list + */ + private fun manageUrlPreview(events: List>) { + if (0 != events.size) { + for (event in events) { + val type = event["type"] as String + + if (TextUtils.equals(type, AccountDataRestClient.ACCOUNT_DATA_TYPE_PREVIEW_URLS)) { + if (event.containsKey("content")) { + val contentDict = event["content"] as Map + var enable = true + if (contentDict.containsKey(AccountDataRestClient.ACCOUNT_DATA_KEY_URL_PREVIEW_DISABLE)) { + enable = !(contentDict[AccountDataRestClient.ACCOUNT_DATA_KEY_URL_PREVIEW_DISABLE] as Boolean) + } + + store.setURLPreviewEnabled(enable) + } + } + } + } + } + + /** + * Manage the user widgets + * + * @param events the events list + */ + private fun manageUserWidgets(events: List>) { + if (0 != events.size) { + for (event in events) { + val type = event["type"] as String + + if (TextUtils.equals(type, AccountDataRestClient.ACCOUNT_DATA_TYPE_WIDGETS)) { + if (event.containsKey("content")) { + val contentDict = event["content"] as Map + store.setUserWidgets(contentDict) + } + } + } + } + } + + /** + * Handle a presence event. + * + * @param presenceEvent the presence event. + */ + private fun handlePresenceEvent(presenceEvent: Event) { + /* // Presence event + if (EventType.PRESENCE == presenceEvent.type) { + val userPresence = JsonUtils.toUser(presenceEvent.getContent()) + + // use the sender by default + if (!TextUtils.isEmpty(presenceEvent.getSender())) { + userPresence.user_id = presenceEvent.getSender() + } + var user: User? = store.getUser(userPresence.user_id) + + if (user == null) { + user = userPresence + user!!.setDataHandler(dataHandler) + } else { + user.currently_active = userPresence.currently_active + user.presence = userPresence.presence + user.lastActiveAgo = userPresence.lastActiveAgo + } + user.latestPresenceTs = System.currentTimeMillis() + // check if the current user has been updated + if (mCredentials.userId == user.user_id) { + // always use the up-to-date information + getMyUser().displayname = user.displayname + getMyUser().avatar_url = user.avatarUrl + + store.setAvatarURL(user.avatarUrl, presenceEvent.getOriginServerTs()) + store.setDisplayName(user.displayname, presenceEvent.getOriginServerTs()) + } + store.storeUser(user) + onPresenceUpdate(presenceEvent, user) + }*/ + } + + private fun handleToDeviceEvent(event: Event) { + // Decrypt event if necessary + /* + decryptEvent(event, null) + if (TextUtils.equals(event.getType(), Event.EVENT_TYPE_MESSAGE) + && null != event.getContent() + && TextUtils.equals(JsonUtils.getMessageMsgType(event.getContent()), "m.bad.encrypted")) { + Timber.e("## handleToDeviceEvent() : Warning: Unable to decrypt to-device event : %s", event.getContent()) + } else { + //onToDeviceEvent(event) + } + */ + } + + /** + * Decrypt an encrypted event + * + * @param event the event to decrypt + * @param timelineId the timeline identifier + * @return true if the event has been decrypted + */ + fun decryptEvent(event: Event?, timelineId: String?): Boolean { + /* + if (null != event && TextUtils.equals(event.getType(), Event.EVENT_TYPE_MESSAGE_ENCRYPTED)) { + if (null != getCrypto()) { + var result: MXEventDecryptionResult? = null + try { + result = getCrypto().decryptEvent(event, timelineId) + } catch (exception: MXDecryptionException) { + event.cryptoError = exception.cryptoError + } + if (null != result) { + event.setClearData(result) + return true + } + } else { + event.cryptoError = MXCryptoError(MXCryptoError.ENCRYPTING_NOT_ENABLED_ERROR_CODE, MXCryptoError.ENCRYPTING_NOT_ENABLED_REASON, null) + } + } + */ + return false + } + + /** + * Get the room object for the corresponding room id. Creates and initializes the object if there is none. + * + * @param roomId the room id + * @return the corresponding room + */ + fun getRoom(roomId: String): Room { + return getRoom(roomId, true) + } + + /** + * Get the room object for the corresponding room id. + * The left rooms are not included. + * + * @param roomId the room id + * @param create create the room it does not exist. + * @return the corresponding room + */ + fun getRoom(roomId: String, create: Boolean): Room { + return getRoom(store, roomId, create) + } + + /** + * Get the room object for the corresponding room id. + * By default, the left rooms are not included. + * + * @param roomId the room id + * @param testLeftRooms true to test if the room is a left room + * @param create create the room it does not exist. + * @return the corresponding room + */ + fun getRoom(roomId: String, testLeftRooms: Boolean, create: Boolean): Room { + var room = store.getRoom(roomId) + if (room == null && testLeftRooms) { + room = leftRoomsStore.getRoom(roomId) + } + if (room == null && create) { + room = getRoom(store, roomId, create) + } + return room + } + + fun getRoom(store: IMXStore, roomId: String, create: Boolean): Room { + var room = store.getRoom(roomId) + if (room == null && create) { + room = Room(dataHandler, store, roomId) + store.storeRoom(room) + } + return room + } + + +} \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/Synchronizer.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/Synchronizer.kt index 65456a8c..53733814 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/Synchronizer.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/Synchronizer.kt @@ -14,7 +14,8 @@ import kotlinx.coroutines.launch class Synchronizer(private val syncAPI: SyncAPI, private val coroutineDispatchers: MatrixCoroutineDispatchers, - private val jsonMapper: Moshi) { + private val jsonMapper: Moshi, + private val syncResponseHandler: SyncResponseHandler) { fun synchronize(callback: MatrixCallback): Cancelable { val job = GlobalScope.launch(coroutineDispatchers.main) { @@ -27,8 +28,11 @@ class Synchronizer(private val syncAPI: SyncAPI, apiCall = syncAPI.sync(params) moshi = jsonMapper dispatcher = coroutineDispatchers.io + }.map { + syncResponseHandler.handleResponse(it, null, false) + it } - syncResponse.either({ callback.onFailure(it) }, { callback.onSuccess(it) }) + syncResponse.bimap({ callback.onFailure(it) }, { callback.onSuccess(it) }) } return CancelableCoroutine(job) } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/data/DeviceOneTimeKeysCountSyncResponse.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/data/DeviceOneTimeKeysCountSyncResponse.kt index 13fd8263..de7d9497 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/data/DeviceOneTimeKeysCountSyncResponse.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/data/DeviceOneTimeKeysCountSyncResponse.kt @@ -1,9 +1,10 @@ package im.vector.matrix.android.internal.events.sync.data +import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = true) data class DeviceOneTimeKeysCountSyncResponse( - val signed_curve25519: Int? = null + @Json(name = "signed_curve25519") val signedCurve25519: Int? = null ) \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/data/GroupSyncProfile.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/data/GroupSyncProfile.kt new file mode 100644 index 00000000..bf7360b7 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/data/GroupSyncProfile.kt @@ -0,0 +1,17 @@ +package im.vector.matrix.android.internal.events.sync.data + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +data class GroupSyncProfile( + /** + * The name of the group, if any. May be nil. + */ + @Json(name = "name") var name: String? = null, + + /** + * The URL for the group's avatar. May be nil. + */ + @Json(name = "avatar_url") var avatarUrl: String? = null +) \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/data/GroupsSyncResponse.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/data/GroupsSyncResponse.kt new file mode 100644 index 00000000..3934d58e --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/data/GroupsSyncResponse.kt @@ -0,0 +1,22 @@ +package im.vector.matrix.android.internal.events.sync.data + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +data class GroupsSyncResponse( + /** + * Joined groups: An array of groups ids. + */ + @Json(name = "join") val join: Map = emptyMap(), + + /** + * Invitations. The groups that the user has been invited to: keys are groups ids. + */ + @Json(name = "invite") val invite: Map = emptyMap(), + + /** + * Left groups. An array of groups ids: the groups that the user has left or been banned from. + */ + @Json(name = "leave") val leave: Map = emptyMap() +) \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/data/InvitedGroupSync.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/data/InvitedGroupSync.kt new file mode 100644 index 00000000..7de27e71 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/data/InvitedGroupSync.kt @@ -0,0 +1,17 @@ +package im.vector.matrix.android.internal.events.sync.data + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +data class InvitedGroupSync( + /** + * The identifier of the inviter. + */ + @Json(name = "inviter") val inviter: String? = null, + + /** + * The group profile. + */ + @Json(name = "profile") val profile: GroupSyncProfile? = null +) \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/data/SyncResponse.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/data/SyncResponse.kt index 19f97128..7c66f4c1 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/data/SyncResponse.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/events/sync/data/SyncResponse.kt @@ -2,11 +2,11 @@ package im.vector.matrix.android.internal.events.sync.data import com.squareup.moshi.Json import com.squareup.moshi.JsonClass +import im.vector.matrix.android.internal.legacy.rest.model.group.GroupsSyncResponse // SyncResponse represents the request response for server sync v2. @JsonClass(generateAdapter = true) data class SyncResponse( - /** * The user private data. */ @@ -40,6 +40,13 @@ data class SyncResponse( /** * One time keys management */ - @Json(name = "device_one_time_keys_count") val deviceOneTimeKeysCount: DeviceOneTimeKeysCountSyncResponse? = null + @Json(name = "device_one_time_keys_count") val deviceOneTimeKeysCount: DeviceOneTimeKeysCountSyncResponse? = null, + + + /** + * List of groups. + */ + @Json(name = "groups") val groups: GroupsSyncResponse? = null + ) \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/HomeServerConnectionConfig.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/HomeServerConnectionConfig.java deleted file mode 100644 index cc928ef0..00000000 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/HomeServerConnectionConfig.java +++ /dev/null @@ -1,532 +0,0 @@ -/* - * Copyright 2016 OpenMarket Ltd - * Copyright 2018 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.matrix.android.internal.legacy; - -import android.net.Uri; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.support.annotation.VisibleForTesting; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import im.vector.matrix.android.internal.legacy.rest.model.login.Credentials; -import im.vector.matrix.android.internal.legacy.ssl.Fingerprint; - -import java.util.ArrayList; -import java.util.List; - -import okhttp3.CipherSuite; -import okhttp3.TlsVersion; - -/** - * Represents how to connect to a specific Homeserver, may include credentials to use. - */ -public class HomeServerConnectionConfig { - - // the home server URI - private Uri mHsUri; - // the identity server URI - 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; - // allow Http connection - private boolean mAllowHttpExtension; - // Force usage of TLS versions - private boolean mForceUsageTlsVersions; - - /** - * Private constructor. Please use the Builder - */ - private HomeServerConnectionConfig() { - // Private constructor - } - - /** - * Update the home server URI. - * - * @param uri the new HS uri - */ - public void setHomeserverUri(Uri uri) { - mHsUri = uri; - } - - /** - * @return the home server uri - */ - public Uri getHomeserverUri() { - return mHsUri; - } - - /** - * @return the identity server uri - */ - public Uri getIdentityServerUri() { - if (null != mIdentityServerUri) { - return mIdentityServerUri; - } - // Else consider the HS uri by default. - return mHsUri; - } - - /** - * @return the anti-virus server uri - */ - public Uri getAntiVirusServerUri() { - if (null != mAntiVirusServerUri) { - return mAntiVirusServerUri; - } - // Else consider the HS uri by default. - return mHsUri; - } - - /** - * @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; - } - - /** - * @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 home server. - */ - @Nullable - public List getAcceptedTlsVersions() { - return mTlsVersions; - } - - /** - * TLS cipher suites accepted for TLS connections with the home server. - */ - @Nullable - public List getAcceptedTlsCipherSuites() { - return mTlsCipherSuites; - } - - /** - * @return whether we should accept TLS extensions. - */ - public boolean shouldAcceptTlsExtensions() { - return mShouldAcceptTlsExtensions; - } - - /** - * @return true if Http connection is allowed (false by default). - */ - public boolean isHttpConnectionAllowed() { - return mAllowHttpExtension; - } - - /** - * @return true if the usage of TlsVersions has to be forced - */ - public boolean forceUsageOfTlsVersions() { - return mForceUsageTlsVersions; - } - - @Override - public String toString() { - return "HomeserverConnectionConfig{" + - "mHsUri=" + mHsUri + - ", mIdentityServerUri=" + mIdentityServerUri + - ", mAntiVirusServerUri=" + mAntiVirusServerUri + - ", mAllowedFingerprints size=" + mAllowedFingerprints.size() + - ", mCredentials=" + mCredentials + - ", mPin=" + mPin + - ", mShouldAcceptTlsExtensions=" + mShouldAcceptTlsExtensions + - ", 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", mHsUri.toString()); - json.put("identity_server_url", getIdentityServerUri().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)); - } - - 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 { - JSONArray fingerprintArray = jsonObject.optJSONArray("fingerprints"); - List fingerprints = new ArrayList<>(); - if (fingerprintArray != null) { - for (int i = 0; i < fingerprintArray.length(); i++) { - fingerprints.add(Fingerprint.fromJson(fingerprintArray.getJSONObject(i))); - } - } - - 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"))) - .withIdentityServerUri(jsonObject.has("identity_server_url") ? Uri.parse(jsonObject.getString("identity_server_url")) : null) - .withCredentials(creds) - .withAllowedFingerPrints(fingerprints) - .withPin(jsonObject.optBoolean("pin", false)); - - // 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))); - } - } - } - - return builder.build(); - } - - /** - * Builder - */ - public static class Builder { - private HomeServerConnectionConfig mHomeServerConnectionConfig; - - /** - * Builder constructor - */ - public Builder() { - mHomeServerConnectionConfig = new HomeServerConnectionConfig(); - } - - /** - * @param hsUri The URI to use to connect to the homeserver. Cannot be null - * @return this builder - */ - public Builder withHomeServerUri(final Uri hsUri) { - if (hsUri == null || (!"http".equals(hsUri.getScheme()) && !"https".equals(hsUri.getScheme()))) { - throw new RuntimeException("Invalid home server URI: " + hsUri); - } - - // remove trailing / - if (hsUri.toString().endsWith("/")) { - try { - String url = hsUri.toString(); - mHomeServerConnectionConfig.mHsUri = Uri.parse(url.substring(0, url.length() - 1)); - } catch (Exception e) { - throw new RuntimeException("Invalid home server URI: " + hsUri); - } - } else { - mHomeServerConnectionConfig.mHsUri = hsUri; - } - - 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 ((null != identityServerUri) && (!"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 { - 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 allowedFingerprints If using SSL, allow server certs that match these fingerprints. - * @return this builder - */ - public Builder withAllowedFingerPrints(@Nullable List allowedFingerprints) { - if (allowedFingerprints != null) { - mHomeServerConnectionConfig.mAllowedFingerprints.addAll(allowedFingerprints); - } - - 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 home server. - * - * @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 home server. - * - * @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; - } - - /** - * For test only: allow Http connection - */ - @VisibleForTesting - public Builder withAllowHttpConnection() { - mHomeServerConnectionConfig.mAllowHttpExtension = true; - 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; - } - - /** - * @return the {@link HomeServerConnectionConfig} - */ - public HomeServerConnectionConfig build() { - // Check mandatory parameters - if (mHomeServerConnectionConfig.mHsUri == null) { - throw new RuntimeException("Home server URI not set"); - } - - return mHomeServerConnectionConfig; - } - - } -} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/MXDataHandler.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/MXDataHandler.java index 6235bc50..db9cf585 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/MXDataHandler.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/MXDataHandler.java @@ -25,6 +25,7 @@ import android.text.TextUtils; import com.google.gson.Gson; import com.google.gson.JsonElement; +import im.vector.matrix.android.internal.auth.data.Credentials; import im.vector.matrix.android.internal.legacy.call.MXCallsManager; import im.vector.matrix.android.internal.legacy.crypto.MXCrypto; import im.vector.matrix.android.internal.legacy.crypto.MXCryptoError; @@ -62,13 +63,12 @@ import im.vector.matrix.android.internal.legacy.rest.model.bingrules.BingRule; import im.vector.matrix.android.internal.legacy.rest.model.bingrules.PushRuleSet; import im.vector.matrix.android.internal.legacy.rest.model.bingrules.PushRulesResponse; import im.vector.matrix.android.internal.legacy.rest.model.group.InvitedGroupSync; -import im.vector.matrix.android.internal.legacy.rest.model.login.Credentials; import im.vector.matrix.android.internal.legacy.rest.model.sync.InvitedRoomSync; import im.vector.matrix.android.internal.legacy.rest.model.sync.SyncResponse; -import im.vector.matrix.android.internal.legacy.ssl.UnrecognizedCertificateException; import im.vector.matrix.android.internal.legacy.util.BingRulesManager; import im.vector.matrix.android.internal.legacy.util.JsonUtils; import im.vector.matrix.android.internal.legacy.util.Log; +import im.vector.matrix.android.internal.network.ssl.UnrecognizedCertificateException; import java.util.ArrayList; import java.util.Collection; @@ -173,7 +173,7 @@ public class MXDataHandler { * Default constructor. * * @param store the data storage implementation. - * @param credentials the credentials + * @param credentials the getCredentials */ public MXDataHandler(IMXStore store, Credentials credentials) { mStore = store; @@ -208,8 +208,12 @@ public class MXDataHandler { mMetricsListener = metricsListener; } + public GroupsManager getGroupsManager() { + return mGroupsManager; + } + /** - * @return the credentials + * @return the getCredentials */ public Credentials getCredentials() { return mCredentials; @@ -426,7 +430,7 @@ public class MXDataHandler { // MyUser is initialized as late as possible to have a better chance at having the info in storage, // which should be the case if this is called after the initial sync if (mMyUser == null) { - mMyUser = new MyUser(store.getUser(mCredentials.userId)); + mMyUser = new MyUser(store.getUser(mCredentials.getUserId())); mMyUser.setDataHandler(this); // assume the profile is not yet initialized @@ -441,7 +445,7 @@ public class MXDataHandler { } // Handle the case where the user is null by loading the user information from the server - mMyUser.user_id = mCredentials.userId; + mMyUser.user_id = mCredentials.getUserId(); } else if (null != store) { // assume the profile is not yet initialized if ((null == store.displayName()) && (null != mMyUser.displayname)) { @@ -634,7 +638,7 @@ public class MXDataHandler { */ public String getUserId() { if (isAlive()) { - return mCredentials.userId; + return mCredentials.getUserId(); } else { return "dummy"; } @@ -934,7 +938,7 @@ public class MXDataHandler { RoomSummary summary = mStore.getSummary(event.roomId); if (null == summary) { - summary = new RoomSummary(null, lastEvent, beforeLiveRoomState, mCredentials.userId); + summary = new RoomSummary(null, lastEvent, beforeLiveRoomState, mCredentials.getUserId()); } else { summary.setLatestReceivedEvent(lastEvent, beforeLiveRoomState); } @@ -1069,7 +1073,7 @@ public class MXDataHandler { * @param events the account data events list. * @return the ignored users list. null means that there is no defined user ids list. */ - private List ignoredUsers(List> events) { + public List ignoredUsers(List> events) { List ignoredUsers = null; if (0 != events.size()) { @@ -1212,7 +1216,7 @@ public class MXDataHandler { user.setLatestPresenceTs(System.currentTimeMillis()); // check if the current user has been updated - if (mCredentials.userId.equals(user.user_id)) { + if (mCredentials.getUserId().equals(user.user_id)) { // always use the up-to-date information getMyUser().displayname = user.displayname; getMyUser().avatar_url = user.getAvatarUrl(); @@ -1420,7 +1424,7 @@ public class MXDataHandler { if (hasChanged) { // Update account data to add new direct chat room(s) - mAccountDataRestClient.setAccountData(mCredentials.userId, AccountDataRestClient.ACCOUNT_DATA_TYPE_DIRECT_MESSAGES, + mAccountDataRestClient.setAccountData(mCredentials.getUserId(), AccountDataRestClient.ACCOUNT_DATA_TYPE_DIRECT_MESSAGES, updatedDirectChatRoomsDict, new ApiCallback() { @Override public void onSuccess(Void info) { @@ -1532,10 +1536,6 @@ public class MXDataHandler { } } - if (null != mCrypto) { - mCrypto.onSyncCompleted(syncResponse, fromToken, isCatchingUp); - } - IMXStore store = getStore(); if (!isEmptyResponse && (null != store)) { @@ -1890,7 +1890,7 @@ public class MXDataHandler { /** * Start the crypto */ - private void startCrypto(final boolean isInitialSync) { + public void startCrypto(final boolean isInitialSync) { if ((null != getCrypto()) && !getCrypto().isStarted() && !getCrypto().isStarting()) { getCrypto().setNetworkConnectivityReceiver(mNetworkConnectivityReceiver); getCrypto().start(isInitialSync, new ApiCallback() { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/MXSession.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/MXSession.java index 4ce70572..ac0be7bb 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/MXSession.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/MXSession.java @@ -30,8 +30,24 @@ import android.text.TextUtils; import com.google.gson.JsonObject; -import im.vector.matrix.android.BuildConfig; -import im.vector.matrix.android.R; +import org.matrix.olm.OlmManager; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig; +import im.vector.matrix.android.internal.auth.data.Credentials; +import im.vector.matrix.android.internal.auth.data.SessionParams; import im.vector.matrix.android.internal.legacy.call.MXCallsManager; import im.vector.matrix.android.internal.legacy.crypto.MXCrypto; import im.vector.matrix.android.internal.legacy.crypto.MXCryptoConfig; @@ -79,7 +95,6 @@ import im.vector.matrix.android.internal.legacy.rest.model.Versions; import im.vector.matrix.android.internal.legacy.rest.model.bingrules.BingRule; import im.vector.matrix.android.internal.legacy.rest.model.filter.FilterBody; import im.vector.matrix.android.internal.legacy.rest.model.filter.FilterResponse; -import im.vector.matrix.android.internal.legacy.rest.model.login.Credentials; import im.vector.matrix.android.internal.legacy.rest.model.login.LoginFlow; import im.vector.matrix.android.internal.legacy.rest.model.login.RegistrationFlowResponse; import im.vector.matrix.android.internal.legacy.rest.model.message.MediaMessage; @@ -101,21 +116,6 @@ import im.vector.matrix.android.internal.legacy.util.JsonUtils; import im.vector.matrix.android.internal.legacy.util.Log; import im.vector.matrix.android.internal.legacy.util.UnsentEventsManager; import im.vector.matrix.android.internal.legacy.util.VersionsUtil; -import org.matrix.olm.OlmManager; - -import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.regex.Pattern; /** * Class that represents one user's session with a particular home server. @@ -192,38 +192,38 @@ public class MXSession { /** * Create a basic session for direct API calls. * - * @param hsConfig the home server connection config + * @param sessionParams the session connection data */ - private MXSession(HomeServerConnectionConfig hsConfig) { - mCredentials = hsConfig.getCredentials(); - mHsConfig = hsConfig; + private MXSession(final SessionParams sessionParams) { + mCredentials = sessionParams.getCredentials(); + mHsConfig = sessionParams.getHomeServerConnectionConfig(); - mEventsRestClient = new EventsRestClient(hsConfig); - mProfileRestClient = new ProfileRestClient(hsConfig); - mPresenceRestClient = new PresenceRestClient(hsConfig); - mRoomsRestClient = new RoomsRestClient(hsConfig); - mPushRulesRestClient = new PushRulesRestClient(hsConfig); - mPushersRestClient = new PushersRestClient(hsConfig); - mThirdPidRestClient = new ThirdPidRestClient(hsConfig); - mCallRestClient = new CallRestClient(hsConfig); - mAccountDataRestClient = new AccountDataRestClient(hsConfig); - mCryptoRestClient = new CryptoRestClient(hsConfig); - mLoginRestClient = new LoginRestClient(hsConfig); - mGroupsRestClient = new GroupsRestClient(hsConfig); - mMediaScanRestClient = new MediaScanRestClient(hsConfig); - mFilterRestClient = new FilterRestClient(hsConfig); + mEventsRestClient = new EventsRestClient(sessionParams); + mProfileRestClient = new ProfileRestClient(sessionParams); + mPresenceRestClient = new PresenceRestClient(sessionParams); + mRoomsRestClient = new RoomsRestClient(sessionParams); + mPushRulesRestClient = new PushRulesRestClient(sessionParams); + mPushersRestClient = new PushersRestClient(sessionParams); + mThirdPidRestClient = new ThirdPidRestClient(sessionParams); + mCallRestClient = new CallRestClient(sessionParams); + mAccountDataRestClient = new AccountDataRestClient(sessionParams); + mCryptoRestClient = new CryptoRestClient(sessionParams); + mLoginRestClient = new LoginRestClient(sessionParams); + mGroupsRestClient = new GroupsRestClient(sessionParams); + mMediaScanRestClient = new MediaScanRestClient(sessionParams); + mFilterRestClient = new FilterRestClient(sessionParams); } /** * Create a user session with a data handler. * Private, please use the MxSession.Builder now * - * @param hsConfig the home server connection config - * @param dataHandler the data handler - * @param appContext the application context + * @param sessionParams the session connection data + * @param dataHandler the data handler + * @param appContext the application context */ - private MXSession(HomeServerConnectionConfig hsConfig, MXDataHandler dataHandler, Context appContext) { - this(hsConfig); + private MXSession(final SessionParams sessionParams, MXDataHandler dataHandler, Context appContext) { + this(sessionParams); mDataHandler = dataHandler; mDataHandler.getStore().addMXStoreListener(new MXStoreListener() { @@ -300,7 +300,7 @@ public class MXSession { mUnsentEventsManager = new UnsentEventsManager(mNetworkConnectivityReceiver, mDataHandler); - mContentManager = new ContentManager(hsConfig, mUnsentEventsManager); + mContentManager = new ContentManager(mHsConfig, mCredentials, mUnsentEventsManager); // mCallsManager = new MXCallsManager(this, mAppContent); @@ -321,8 +321,8 @@ public class MXSession { mGroupsRestClient.setUnsentEventsManager(mUnsentEventsManager); // return the default cache manager - mLatestChatMessageCache = new MXLatestChatMessageCache(mCredentials.userId); - mMediasCache = new MXMediasCache(mContentManager, mNetworkConnectivityReceiver, mCredentials.userId, appContext); + mLatestChatMessageCache = new MXLatestChatMessageCache(mCredentials.getUserId()); + mMediasCache = new MXMediasCache(mContentManager, mNetworkConnectivityReceiver, mCredentials.getUserId(), appContext); mDataHandler.setMediasCache(mMediasCache); mMediaScanRestClient.setMxStore(mDataHandler.getStore()); @@ -380,9 +380,9 @@ public class MXSession { } /** - * Get the user credentials. + * Get the user getCredentials. * - * @return the credentials + * @return the getCredentials */ public Credentials getCredentials() { checkIfAlive(); @@ -842,7 +842,7 @@ public class MXSession { mEventsThread.setFailureCallback(mFailureCallback); } - if (mCredentials.accessToken != null && !mEventsThread.isAlive()) { + if (mCredentials.getAccessToken() != null && !mEventsThread.isAlive()) { // GA issue try { mEventsThread.start(); @@ -860,35 +860,6 @@ public class MXSession { } } - /** - * Refresh the access token - */ - public void refreshToken() { - checkIfAlive(); - - mProfileRestClient.refreshTokens(new ApiCallback() { - @Override - public void onSuccess(Credentials info) { - Log.d(LOG_TAG, "refreshToken : succeeds."); - } - - @Override - public void onNetworkError(Exception e) { - Log.e(LOG_TAG, "refreshToken : onNetworkError " + e.getMessage(), e); - } - - @Override - public void onMatrixError(MatrixError e) { - Log.e(LOG_TAG, "refreshToken : onMatrixError " + e.getMessage()); - } - - @Override - public void onUnexpectedError(Exception e) { - Log.e(LOG_TAG, "refreshToken : onMatrixError " + e.getMessage(), e); - } - }); - } - /** * Update the online status * @@ -1246,7 +1217,7 @@ public class MXSession { params.addCryptoAlgorithm(algorithm); params.setDirectMessage(); - params.addParticipantIds(mHsConfig, Arrays.asList(aParticipantUserId)); + params.addParticipantIds(mHsConfig, mCredentials, Arrays.asList(aParticipantUserId)); createRoom(params, aCreateRoomCallBack); } @@ -2436,7 +2407,7 @@ public class MXSession { DeleteDeviceParams params = new DeleteDeviceParams(); params.auth = new DeleteDeviceAuth(); params.auth.session = registrationFlowResponse.session; - params.auth.user = mCredentials.userId; + params.auth.user = mCredentials.getUserId(); params.auth.password = password; Log.d(LOG_TAG, "## deleteDevice() : supported stages " + stages); @@ -2512,10 +2483,12 @@ public class MXSession { * ========================================================================================== */ public static class Builder { - private MXSession mxSession; - public Builder(HomeServerConnectionConfig hsConfig, MXDataHandler dataHandler, Context context) { - mxSession = new MXSession(hsConfig, dataHandler, context); + private MXSession mxSession; + private SessionParams sessionParams; + + public Builder(SessionParams sessionParams, MXDataHandler dataHandler, Context context) { + mxSession = new MXSession(sessionParams, dataHandler, context); } public Builder withFileEncryption(boolean enableFileEncryption) { @@ -2538,9 +2511,8 @@ public class MXSession { try { HomeServerConnectionConfig alteredHsConfig = new HomeServerConnectionConfig.Builder() .withHomeServerUri(Uri.parse(pushServerUrl)) - .withCredentials(mxSession.mHsConfig.getCredentials()) .build(); - pushersRestClient = new PushersRestClient(alteredHsConfig); + pushersRestClient = new PushersRestClient(new SessionParams(sessionParams.getCredentials(), alteredHsConfig)); } catch (Exception e) { Log.e(LOG_TAG, "## withPushServerUrl() failed " + e.getMessage(), e); } @@ -2562,7 +2534,6 @@ public class MXSession { */ public Builder withMetricsListener(@Nullable MetricsListener metricsListener) { mxSession.mMetricsListener = metricsListener; - return this; } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/RestClient.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/RestClient.java index 70b8b3a2..0c42394a 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/RestClient.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/RestClient.java @@ -36,15 +36,16 @@ import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.X509TrustManager; import im.vector.matrix.android.BuildConfig; +import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig; +import im.vector.matrix.android.internal.auth.data.Credentials; +import im.vector.matrix.android.internal.auth.data.SessionParams; import im.vector.matrix.android.internal.legacy.listeners.IMXNetworkEventListener; import im.vector.matrix.android.internal.legacy.network.NetworkConnectivityReceiver; import im.vector.matrix.android.internal.legacy.rest.client.MXRestExecutorService; -import im.vector.matrix.android.internal.legacy.rest.model.login.Credentials; -import im.vector.matrix.android.internal.legacy.ssl.CertUtil; import im.vector.matrix.android.internal.legacy.util.JsonUtils; -import im.vector.matrix.android.internal.legacy.util.Log; import im.vector.matrix.android.internal.legacy.util.PolymorphicRequestBodyConverter; import im.vector.matrix.android.internal.legacy.util.UnsentEventsManager; +import im.vector.matrix.android.internal.network.ssl.CertUtil; import okhttp3.Dispatcher; import okhttp3.Interceptor; import okhttp3.OkHttpClient; @@ -53,12 +54,12 @@ import okhttp3.Response; import okhttp3.logging.HttpLoggingInterceptor; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; +import timber.log.Timber; /** * Class for making Matrix API calls. */ public class RestClient { - private static final String LOG_TAG = RestClient.class.getSimpleName(); public static final String URI_API_PREFIX_PATH_MEDIA_R0 = "_matrix/media/r0/"; public static final String URI_API_PREFIX_PATH_MEDIA_PROXY_UNSTABLE = "_matrix/media_proxy/unstable/"; @@ -103,38 +104,37 @@ public class RestClient { // http client private OkHttpClient mOkHttpClient = new OkHttpClient(); - public RestClient(HomeServerConnectionConfig hsConfig, Class type, String uriPrefix, boolean withNullSerialization) { - this(hsConfig, type, uriPrefix, withNullSerialization, EndPointServer.HOME_SERVER); + public RestClient(SessionParams sessionParams, Class type, String uriPrefix, boolean withNullSerialization) { + this(sessionParams, type, uriPrefix, withNullSerialization, EndPointServer.HOME_SERVER); } /** * Public constructor. * - * @param hsConfig the home server configuration. + * @param sessionParams the session data * @param type the REST type * @param uriPrefix the URL request prefix * @param withNullSerialization true to serialise class member with null value * @param useIdentityServer true to use the identity server URL as base request */ - public RestClient(HomeServerConnectionConfig hsConfig, Class type, String uriPrefix, boolean withNullSerialization, boolean useIdentityServer) { - this(hsConfig, type, uriPrefix, withNullSerialization, useIdentityServer ? EndPointServer.IDENTITY_SERVER : EndPointServer.HOME_SERVER); + public RestClient(SessionParams sessionParams, Class type, String uriPrefix, boolean withNullSerialization, boolean useIdentityServer) { + this(sessionParams, type, uriPrefix, withNullSerialization, useIdentityServer ? EndPointServer.IDENTITY_SERVER : EndPointServer.HOME_SERVER); } /** * Public constructor. * - * @param hsConfig the home server configuration. + * @param sessionParams the session data * @param type the REST type * @param uriPrefix the URL request prefix * @param withNullSerialization true to serialise class member with null value * @param endPointServer tell which server is used to define the base url */ - public RestClient(HomeServerConnectionConfig hsConfig, Class type, String uriPrefix, boolean withNullSerialization, EndPointServer endPointServer) { + public RestClient(SessionParams sessionParams, Class type, String uriPrefix, boolean withNullSerialization, EndPointServer endPointServer) { // The JSON -> object mapper gson = JsonUtils.getGson(withNullSerialization); - - mHsConfig = hsConfig; - mCredentials = hsConfig.getCredentials(); + mHsConfig = sessionParams.getHomeServerConnectionConfig(); + mCredentials = sessionParams.getCredentials(); Interceptor authentInterceptor = new Interceptor() { @@ -146,12 +146,10 @@ public class RestClient { // set a custom user agent newRequestBuilder.addHeader("User-Agent", sUserAgent); } - // Add the access token to all requests if it is set - if ((mCredentials != null) && (mCredentials.accessToken != null)) { - newRequestBuilder.addHeader("Authorization", "Bearer " + mCredentials.accessToken); + if (mCredentials != null) { + newRequestBuilder.addHeader("Authorization", "Bearer " + mCredentials.getAccessToken()); } - request = newRequestBuilder.build(); return chain.proceed(request); @@ -191,17 +189,15 @@ public class RestClient { } try { - Pair pair = CertUtil.newPinnedSSLSocketFactory(hsConfig); + Pair pair = CertUtil.INSTANCE.newPinnedSSLSocketFactory(mHsConfig); okHttpClientBuilder.sslSocketFactory(pair.first, pair.second); - okHttpClientBuilder.hostnameVerifier(CertUtil.newHostnameVerifier(hsConfig)); - okHttpClientBuilder.connectionSpecs(CertUtil.newConnectionSpecs(hsConfig)); + okHttpClientBuilder.hostnameVerifier(CertUtil.INSTANCE.newHostnameVerifier(mHsConfig)); + okHttpClientBuilder.connectionSpecs(CertUtil.INSTANCE.newConnectionSpecs(mHsConfig)); } catch (Exception e) { - Log.e(LOG_TAG, "## RestClient() setSslSocketFactory failed" + e.getMessage(), e); + Timber.e("## RestClient() setSslSocketFactory failed" + e.getMessage(), e); } - mOkHttpClient = okHttpClientBuilder.build(); - final String endPoint = makeEndpoint(hsConfig, uriPrefix, endPointServer); - + final String endPoint = makeEndpoint(mHsConfig, uriPrefix, endPointServer); // Rest adapter for turning API interfaces into actual REST-calling objects Retrofit.Builder builder = new Retrofit.Builder() .baseUrl(endPoint) @@ -226,9 +222,12 @@ public class RestClient { break; case HOME_SERVER: default: - baseUrl = hsConfig.getHomeserverUri().toString(); + baseUrl = hsConfig.getHomeServerUri().toString(); } + if (baseUrl == null) { + throw new IllegalArgumentException("Base url shouldn't be null"); + } baseUrl = sanitizeBaseUrl(baseUrl); String dynamicPath = sanitizeDynamicPath(uriPrefix); return baseUrl + dynamicPath; @@ -270,7 +269,7 @@ public class RestClient { PackageInfo pkgInfo = pm.getPackageInfo(appContext.getApplicationContext().getPackageName(), 0); appVersion = pkgInfo.versionName; } catch (Exception e) { - Log.e(LOG_TAG, "## initUserAgent() : failed " + e.getMessage(), e); + Timber.e("## initUserAgent() : failed " + e.getMessage(), e); } } @@ -321,12 +320,12 @@ public class RestClient { .readTimeout((int) (READ_TIMEOUT_MS * factor), TimeUnit.MILLISECONDS) .writeTimeout((int) (WRITE_TIMEOUT_MS * factor), TimeUnit.MILLISECONDS); - Log.d(LOG_TAG, "## refreshConnectionTimeout() : update setConnectTimeout to " + (CONNECTION_TIMEOUT_MS * factor) + " ms"); - Log.d(LOG_TAG, "## refreshConnectionTimeout() : update setReadTimeout to " + (READ_TIMEOUT_MS * factor) + " ms"); - Log.d(LOG_TAG, "## refreshConnectionTimeout() : update setWriteTimeout to " + (WRITE_TIMEOUT_MS * factor) + " ms"); + Timber.d("## refreshConnectionTimeout() : update setConnectTimeout to " + (CONNECTION_TIMEOUT_MS * factor) + " ms"); + Timber.d("## refreshConnectionTimeout() : update setReadTimeout to " + (READ_TIMEOUT_MS * factor) + " ms"); + Timber.d("## refreshConnectionTimeout() : update setWriteTimeout to " + (WRITE_TIMEOUT_MS * factor) + " ms"); } else { builder.connectTimeout(1, TimeUnit.MILLISECONDS); - Log.d(LOG_TAG, "## refreshConnectionTimeout() : update the requests timeout to 1 ms"); + Timber.d("## refreshConnectionTimeout() : update the requests timeout to 1 ms"); } // FIXME It has no effect to the rest client @@ -373,25 +372,25 @@ public class RestClient { networkConnectivityReceiver.addEventListener(new IMXNetworkEventListener() { @Override public void onNetworkConnectionUpdate(boolean isConnected) { - Log.d(LOG_TAG, "## setUnsentEventsManager() : update the requests timeout to " + (isConnected ? CONNECTION_TIMEOUT_MS : 1) + " ms"); + Timber.d("## setUnsentEventsManager() : update the requests timeout to " + (isConnected ? CONNECTION_TIMEOUT_MS : 1) + " ms"); refreshConnectionTimeout(networkConnectivityReceiver); } }); } /** - * Get the user's credentials. Typically for saving them somewhere persistent. + * Get the user's getCredentials. Typically for saving them somewhere persistent. * - * @return the user credentials + * @return the user getCredentials */ public Credentials getCredentials() { return mCredentials; } /** - * Provide the user's credentials. To be called after login or registration. + * Provide the user's getCredentials. To be called after login or registration. * - * @param credentials the user credentials + * @param credentials the user getCredentials */ public void setCredentials(Credentials credentials) { mCredentials = credentials; diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/call/MXCall.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/call/MXCall.java index c1ad66c7..4b87a3d7 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/call/MXCall.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/call/MXCall.java @@ -26,13 +26,6 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; -import im.vector.matrix.android.internal.legacy.MXSession; -import im.vector.matrix.android.internal.legacy.data.Room; -import im.vector.matrix.android.internal.legacy.rest.callback.ApiCallback; -import im.vector.matrix.android.internal.legacy.rest.model.Event; -import im.vector.matrix.android.internal.legacy.rest.model.MatrixError; -import im.vector.matrix.android.internal.legacy.util.Log; - import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; @@ -40,6 +33,13 @@ import java.util.List; import java.util.Set; import java.util.Timer; +import im.vector.matrix.android.internal.legacy.MXSession; +import im.vector.matrix.android.internal.legacy.data.Room; +import im.vector.matrix.android.internal.legacy.rest.callback.ApiCallback; +import im.vector.matrix.android.internal.legacy.rest.model.Event; +import im.vector.matrix.android.internal.legacy.rest.model.MatrixError; +import im.vector.matrix.android.internal.legacy.util.Log; + /** * This class is the default implementation */ @@ -657,7 +657,7 @@ public class MXCall implements IMXCall { hangupContent.add("reason", new JsonPrimitive(reason)); } - Event event = new Event(Event.EVENT_TYPE_CALL_HANGUP, hangupContent, mSession.getCredentials().userId, mCallSignalingRoom.getRoomId()); + Event event = new Event(Event.EVENT_TYPE_CALL_HANGUP, hangupContent, mSession.getCredentials().getUserId(), mCallSignalingRoom.getRoomId()); // local notification to indicate the end of call mUIThreadHandler.post(new Runnable() { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/call/MXChromeCall.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/call/MXChromeCall.java index 7ef50613..b60ece1d 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/call/MXChromeCall.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/call/MXChromeCall.java @@ -631,7 +631,7 @@ public class MXChromeCall extends MXCall { } if (addIt) { - Event event = new Event(eventType, content, mSession.getCredentials().userId, mCallSignalingRoom.getRoomId()); + Event event = new Event(eventType, content, mSession.getCredentials().getUserId(), mCallSignalingRoom.getRoomId()); if (null != event) { // receive an hangup -> close the window asap diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/call/MXWebRtcCall.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/call/MXWebRtcCall.java index 0a60d0a7..902e8b95 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/call/MXWebRtcCall.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/call/MXWebRtcCall.java @@ -374,7 +374,7 @@ public class MXWebRtcCall extends MXCall { offerContent.addProperty("type", sessionDescription.type.canonicalForm()); inviteContent.add("offer", offerContent); - Event event = new Event(Event.EVENT_TYPE_CALL_INVITE, inviteContent, mSession.getCredentials().userId, mCallSignalingRoom.getRoomId()); + Event event = new Event(Event.EVENT_TYPE_CALL_INVITE, inviteContent, mSession.getCredentials().getUserId(), mCallSignalingRoom.getRoomId()); mPendingEvents.add(event); @@ -434,7 +434,7 @@ public class MXWebRtcCall extends MXCall { offerContent.addProperty("type", sessionDescription.type.canonicalForm()); answerContent.add("answer", offerContent); - Event event = new Event(Event.EVENT_TYPE_CALL_ANSWER, answerContent, mSession.getCredentials().userId, mCallSignalingRoom.getRoomId()); + Event event = new Event(Event.EVENT_TYPE_CALL_ANSWER, answerContent, mSession.getCredentials().getUserId(), mCallSignalingRoom.getRoomId()); mPendingEvents.add(event); sendNextEvent(); @@ -737,7 +737,7 @@ public class MXWebRtcCall extends MXCall { } if (addIt) { - Event event = new Event(Event.EVENT_TYPE_CALL_CANDIDATES, content, mSession.getCredentials().userId, + Event event = new Event(Event.EVENT_TYPE_CALL_CANDIDATES, content, mSession.getCredentials().getUserId(), mCallSignalingRoom.getRoomId()); mPendingEvents.add(event); diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/crypto/MXCrypto.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/crypto/MXCrypto.java index fb67654d..91be02ee 100755 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/crypto/MXCrypto.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/crypto/MXCrypto.java @@ -207,17 +207,17 @@ public class MXCrypto { mRoomEncryptors = new HashMap<>(); mRoomDecryptors = new HashMap<>(); - String deviceId = mSession.getCredentials().deviceId; + String deviceId = mSession.getCredentials().getDeviceId(); // deviceId should always be defined boolean refreshDevicesList = !TextUtils.isEmpty(deviceId); if (TextUtils.isEmpty(deviceId)) { // use the stored one - mSession.getCredentials().deviceId = deviceId = mCryptoStore.getDeviceId(); + deviceId = mCryptoStore.getDeviceId(); } if (TextUtils.isEmpty(deviceId)) { - mSession.getCredentials().deviceId = deviceId = UUID.randomUUID().toString(); + deviceId = UUID.randomUUID().toString(); Log.d(LOG_TAG, "Warning: No device id in MXCredentials. An id was created. Think of storing it"); mCryptoStore.storeDeviceId(deviceId); } @@ -230,11 +230,11 @@ public class MXCrypto { Map keys = new HashMap<>(); if (!TextUtils.isEmpty(mOlmDevice.getDeviceEd25519Key())) { - keys.put("ed25519:" + mSession.getCredentials().deviceId, mOlmDevice.getDeviceEd25519Key()); + keys.put("ed25519:" + mSession.getCredentials().getDeviceId(), mOlmDevice.getDeviceEd25519Key()); } if (!TextUtils.isEmpty(mOlmDevice.getDeviceCurve25519Key())) { - keys.put("curve25519:" + mSession.getCredentials().deviceId, mOlmDevice.getDeviceCurve25519Key()); + keys.put("curve25519:" + mSession.getCredentials().getDeviceId(), mOlmDevice.getDeviceCurve25519Key()); } mMyDevice.keys = keys; @@ -441,7 +441,7 @@ public class MXCrypto { if (!hasBeenReleased()) { Log.d(LOG_TAG, "###########################################################"); Log.d(LOG_TAG, "uploadDeviceKeys done for " + mSession.getMyUserId()); - Log.d(LOG_TAG, " - device id : " + mSession.getCredentials().deviceId); + Log.d(LOG_TAG, " - device id : " + mSession.getCredentials().getDeviceId()); Log.d(LOG_TAG, " - ed25519 : " + mOlmDevice.getDeviceEd25519Key()); Log.d(LOG_TAG, " - curve25519 : " + mOlmDevice.getDeviceCurve25519Key()); Log.d(LOG_TAG, " - oneTimeKeys: " + mLastPublishedOneTimeKeys); // They are @@ -600,17 +600,17 @@ public class MXCrypto { * @param fromToken the start sync token * @param isCatchingUp true if there is a catch-up in progress. */ - public void onSyncCompleted(final SyncResponse syncResponse, final String fromToken, final boolean isCatchingUp) { + public void onSyncCompleted(final im.vector.matrix.android.internal.events.sync.data.SyncResponse syncResponse, final String fromToken, final boolean isCatchingUp) { getEncryptingThreadHandler().post(new Runnable() { @Override public void run() { - if (null != syncResponse.deviceLists) { - getDeviceList().handleDeviceListsChanges(syncResponse.deviceLists.changed, syncResponse.deviceLists.left); + if (null != syncResponse.getDeviceLists()) { + getDeviceList().handleDeviceListsChanges(syncResponse.getDeviceLists().getChanged(), syncResponse.getDeviceLists().getLeft()); } - if (null != syncResponse.deviceOneTimeKeysCount) { - int currentCount = (null != syncResponse.deviceOneTimeKeysCount.signed_curve25519) ? - syncResponse.deviceOneTimeKeysCount.signed_curve25519 : 0; + if (null != syncResponse.getDeviceOneTimeKeysCount()) { + int currentCount = (null != syncResponse.getDeviceOneTimeKeysCount().getSignedCurve25519()) ? + syncResponse.getDeviceOneTimeKeysCount().getSignedCurve25519() : 0; updateOneTimeKeyCount(currentCount); } @@ -1470,7 +1470,7 @@ public class MXCrypto { Map payloadJson = new HashMap<>(payloadFields); payloadJson.put("sender", mSession.getMyUserId()); - payloadJson.put("sender_device", mSession.getCredentials().deviceId); + payloadJson.put("sender_device", mSession.getCredentials().getDeviceId()); // Include the Ed25519 key so that the recipient knows what // device this message came from. diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/crypto/algorithms/megolm/MXMegolmEncryption.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/crypto/algorithms/megolm/MXMegolmEncryption.java index eb4e13c7..bb5904dc 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/crypto/algorithms/megolm/MXMegolmEncryption.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/crypto/algorithms/megolm/MXMegolmEncryption.java @@ -22,6 +22,12 @@ import android.text.TextUtils; import com.google.gson.JsonElement; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import im.vector.matrix.android.internal.legacy.MXSession; import im.vector.matrix.android.internal.legacy.crypto.MXCrypto; import im.vector.matrix.android.internal.legacy.crypto.MXCryptoAlgorithms; @@ -39,12 +45,6 @@ import im.vector.matrix.android.internal.legacy.rest.model.MatrixError; import im.vector.matrix.android.internal.legacy.util.JsonUtils; import im.vector.matrix.android.internal.legacy.util.Log; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - public class MXMegolmEncryption implements IMXEncrypting { private static final String LOG_TAG = MXMegolmEncryption.class.getSimpleName(); @@ -76,7 +76,7 @@ public class MXMegolmEncryption implements IMXEncrypting { mCrypto = matrixSession.getCrypto(); mRoomId = roomId; - mDeviceId = matrixSession.getCredentials().deviceId; + mDeviceId = matrixSession.getCredentials().getDeviceId(); // Default rotation periods // TODO: Make it configurable via parameters diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/data/cryptostore/IMXCryptoStore.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/data/cryptostore/IMXCryptoStore.java index fb649853..4d6ece7b 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/data/cryptostore/IMXCryptoStore.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/data/cryptostore/IMXCryptoStore.java @@ -18,11 +18,11 @@ package im.vector.matrix.android.internal.legacy.data.cryptostore; import android.content.Context; +import im.vector.matrix.android.internal.auth.data.Credentials; import im.vector.matrix.android.internal.legacy.crypto.IncomingRoomKeyRequest; import im.vector.matrix.android.internal.legacy.crypto.OutgoingRoomKeyRequest; import im.vector.matrix.android.internal.legacy.crypto.data.MXDeviceInfo; import im.vector.matrix.android.internal.legacy.crypto.data.MXOlmInboundGroupSession2; -import im.vector.matrix.android.internal.legacy.rest.model.login.Credentials; import org.matrix.olm.OlmAccount; import org.matrix.olm.OlmSession; @@ -35,10 +35,10 @@ import java.util.Set; */ public interface IMXCryptoStore { /** - * Init a crypto store for the passed credentials. + * Init a crypto store for the passed getCredentials. * * @param context the application context - * @param credentials the credentials of the account. + * @param credentials the getCredentials of the account. */ void initWithCredentials(Context context, Credentials credentials); @@ -55,7 +55,7 @@ public interface IMXCryptoStore { boolean hasData(); /** - * Delete the crypto store for the passed credentials. + * Delete the crypto store for the passed getCredentials. */ void deleteStore(); diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/data/cryptostore/MXFileCryptoStore.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/data/cryptostore/MXFileCryptoStore.java index 7b66e5bf..08eef3d8 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/data/cryptostore/MXFileCryptoStore.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/data/cryptostore/MXFileCryptoStore.java @@ -22,16 +22,6 @@ import android.content.Context; import android.os.Looper; import android.text.TextUtils; -import im.vector.matrix.android.internal.legacy.crypto.IncomingRoomKeyRequest; -import im.vector.matrix.android.internal.legacy.crypto.OutgoingRoomKeyRequest; -import im.vector.matrix.android.internal.legacy.crypto.data.MXDeviceInfo; -import im.vector.matrix.android.internal.legacy.crypto.data.MXOlmInboundGroupSession; -import im.vector.matrix.android.internal.legacy.crypto.data.MXOlmInboundGroupSession2; -import im.vector.matrix.android.internal.legacy.crypto.data.MXUsersDevicesMap; -import im.vector.matrix.android.internal.legacy.rest.model.login.Credentials; -import im.vector.matrix.android.internal.legacy.util.CompatUtil; -import im.vector.matrix.android.internal.legacy.util.ContentUtils; -import im.vector.matrix.android.internal.legacy.util.Log; import org.matrix.olm.OlmAccount; import org.matrix.olm.OlmSession; @@ -51,6 +41,17 @@ import java.util.Set; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; +import im.vector.matrix.android.internal.auth.data.Credentials; +import im.vector.matrix.android.internal.legacy.crypto.IncomingRoomKeyRequest; +import im.vector.matrix.android.internal.legacy.crypto.OutgoingRoomKeyRequest; +import im.vector.matrix.android.internal.legacy.crypto.data.MXDeviceInfo; +import im.vector.matrix.android.internal.legacy.crypto.data.MXOlmInboundGroupSession; +import im.vector.matrix.android.internal.legacy.crypto.data.MXOlmInboundGroupSession2; +import im.vector.matrix.android.internal.legacy.crypto.data.MXUsersDevicesMap; +import im.vector.matrix.android.internal.legacy.util.CompatUtil; +import im.vector.matrix.android.internal.legacy.util.ContentUtils; +import im.vector.matrix.android.internal.legacy.util.Log; + /** * the crypto data store */ @@ -91,7 +92,7 @@ public class MXFileCryptoStore implements IMXCryptoStore { private static final String MXFILE_CRYPTO_STORE_INCOMING_ROOM_KEY_REQUESTS_FILE = "incomingRoomKeyRequests"; private static final String MXFILE_CRYPTO_STORE_INCOMING_ROOM_KEY_REQUESTS_FILE_TMP = "incomingRoomKeyRequests.tmp"; - // The credentials used for this store + // The getCredentials used for this store private Credentials mCredentials; // Meta data about the store @@ -182,7 +183,7 @@ public class MXFileCryptoStore implements IMXCryptoStore { public void initWithCredentials(Context context, Credentials credentials) { mCredentials = credentials; - mStoreFile = new File(new File(context.getApplicationContext().getFilesDir(), MXFILE_CRYPTO_STORE_FOLDER), mCredentials.userId); + mStoreFile = new File(new File(context.getApplicationContext().getFilesDir(), MXFILE_CRYPTO_STORE_FOLDER), mCredentials.getUserId()); mMetaDataFile = new File(mStoreFile, MXFILE_CRYPTO_STORE_METADATA_FILE); mMetaDataFileTmp = new File(mStoreFile, MXFILE_CRYPTO_STORE_METADATA_FILE_TMP); @@ -217,11 +218,8 @@ public class MXFileCryptoStore implements IMXCryptoStore { mIncomingRoomKeyRequestsFileTmp = new File(mStoreFile, MXFILE_CRYPTO_STORE_INCOMING_ROOM_KEY_REQUESTS_FILE_TMP); // Build default metadata - if ((null == mMetaData) - && (null != credentials.homeServer) - && (null != credentials.userId) - && (null != credentials.accessToken)) { - mMetaData = new MXFileCryptoStoreMetaData2(mCredentials.userId, mCredentials.deviceId, MXFILE_CRYPTO_VERSION); + if (mMetaData == null) { + mMetaData = new MXFileCryptoStoreMetaData2(mCredentials.getUserId(), mCredentials.getDeviceId(), MXFILE_CRYPTO_VERSION); } mUsersDevicesInfoMap = new MXUsersDevicesMap<>(); @@ -243,7 +241,7 @@ public class MXFileCryptoStore implements IMXCryptoStore { if (null != mMetaData) { result = TextUtils.isEmpty(mMetaData.mDeviceId) - || TextUtils.equals(mCredentials.deviceId, mMetaData.mDeviceId); + || TextUtils.equals(mCredentials.getDeviceId(), mMetaData.mDeviceId); } } @@ -284,11 +282,11 @@ public class MXFileCryptoStore implements IMXCryptoStore { Log.e(LOG_TAG, "## open() : New MXFileCryptoStore version detected"); resetData(); } - // Check credentials - // The device id may not have been provided in credentials. + // Check getCredentials + // The device id may not have been provided in getCredentials. // Check it only if provided, else trust the stored one. - else if (!TextUtils.equals(mMetaData.mUserId, mCredentials.userId) - || ((null != mCredentials.deviceId) && !TextUtils.equals(mCredentials.deviceId, mMetaData.mDeviceId))) { + else if (!TextUtils.equals(mMetaData.mUserId, mCredentials.getUserId()) + || ((null != mCredentials.getDeviceId()) && !TextUtils.equals(mCredentials.getDeviceId(), mMetaData.mDeviceId))) { Log.e(LOG_TAG, "## open() : Credentials do not match"); resetData(); } @@ -298,12 +296,9 @@ public class MXFileCryptoStore implements IMXCryptoStore { preloadCryptoData(); } - // Else, if credentials is valid, create and store it - if ((null == mMetaData) - && (null != mCredentials.homeServer) - && (null != mCredentials.userId) - && (null != mCredentials.accessToken)) { - mMetaData = new MXFileCryptoStoreMetaData2(mCredentials.userId, mCredentials.deviceId, MXFILE_CRYPTO_VERSION); + // Else, if getCredentials is valid, create and store it + if (mMetaData == null){ + mMetaData = new MXFileCryptoStoreMetaData2(mCredentials.getUserId(), mCredentials.getDeviceId(), MXFILE_CRYPTO_VERSION); mIsReady = true; // flush the metadata saveMetaData(); diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/data/store/MXFileStore.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/data/store/MXFileStore.java index e474c41f..db1edda0 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/data/store/MXFileStore.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/data/store/MXFileStore.java @@ -23,25 +23,6 @@ import android.os.HandlerThread; import android.support.annotation.Nullable; import android.text.TextUtils; -import im.vector.matrix.android.internal.legacy.HomeServerConnectionConfig; -import im.vector.matrix.android.internal.legacy.data.Room; -import im.vector.matrix.android.internal.legacy.data.RoomAccountData; -import im.vector.matrix.android.internal.legacy.data.RoomState; -import im.vector.matrix.android.internal.legacy.data.RoomSummary; -import im.vector.matrix.android.internal.legacy.data.timeline.EventTimeline; -import im.vector.matrix.android.internal.legacy.rest.callback.ApiCallback; -import im.vector.matrix.android.internal.legacy.rest.model.Event; -import im.vector.matrix.android.internal.legacy.rest.model.ReceiptData; -import im.vector.matrix.android.internal.legacy.rest.model.RoomMember; -import im.vector.matrix.android.internal.legacy.rest.model.TokensChunkEvents; -import im.vector.matrix.android.internal.legacy.rest.model.User; -import im.vector.matrix.android.internal.legacy.rest.model.group.Group; -import im.vector.matrix.android.internal.legacy.rest.model.pid.ThirdPartyIdentifier; -import im.vector.matrix.android.internal.legacy.util.CompatUtil; -import im.vector.matrix.android.internal.legacy.util.ContentUtils; -import im.vector.matrix.android.internal.legacy.util.Log; -import im.vector.matrix.android.internal.legacy.util.MXOsHandler; - import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -60,6 +41,25 @@ import java.util.Set; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; +import im.vector.matrix.android.internal.auth.data.Credentials; +import im.vector.matrix.android.internal.legacy.data.Room; +import im.vector.matrix.android.internal.legacy.data.RoomAccountData; +import im.vector.matrix.android.internal.legacy.data.RoomState; +import im.vector.matrix.android.internal.legacy.data.RoomSummary; +import im.vector.matrix.android.internal.legacy.data.timeline.EventTimeline; +import im.vector.matrix.android.internal.legacy.rest.callback.ApiCallback; +import im.vector.matrix.android.internal.legacy.rest.model.Event; +import im.vector.matrix.android.internal.legacy.rest.model.ReceiptData; +import im.vector.matrix.android.internal.legacy.rest.model.RoomMember; +import im.vector.matrix.android.internal.legacy.rest.model.TokensChunkEvents; +import im.vector.matrix.android.internal.legacy.rest.model.User; +import im.vector.matrix.android.internal.legacy.rest.model.group.Group; +import im.vector.matrix.android.internal.legacy.rest.model.pid.ThirdPartyIdentifier; +import im.vector.matrix.android.internal.legacy.util.CompatUtil; +import im.vector.matrix.android.internal.legacy.util.ContentUtils; +import im.vector.matrix.android.internal.legacy.util.Log; +import im.vector.matrix.android.internal.legacy.util.MXOsHandler; + /** * An in-file IMXStore. */ @@ -217,21 +217,21 @@ public class MXFileStore extends MXMemoryStore { /** * Constructor * - * @param hsConfig the expected credentials + * @param credentials the expected getCredentials * @param enableFileEncryption set to true to enable file encryption. * @param context the context. */ - public MXFileStore(HomeServerConnectionConfig hsConfig, boolean enableFileEncryption, Context context) { + public MXFileStore(Credentials credentials, boolean enableFileEncryption, Context context) { setContext(context); mEnableFileEncryption = enableFileEncryption; mIsReady = false; - mCredentials = hsConfig.getCredentials(); + mCredentials = credentials; - mHandlerThread = new HandlerThread("MXFileStoreBackgroundThread_" + mCredentials.userId, Thread.MIN_PRIORITY); + mHandlerThread = new HandlerThread("MXFileStoreBackgroundThread_" + mCredentials.getUserId(), Thread.MIN_PRIORITY); - createDirTree(mCredentials.userId); + createDirTree(mCredentials.getUserId()); // updated data mRoomsToCommitForMessages = new HashSet<>(); @@ -260,8 +260,8 @@ public class MXFileStore extends MXMemoryStore { mFileStoreHandler = new MXOsHandler(mHandlerThread.getLooper()); mMetadata = new MXFileStoreMetaData(); - mMetadata.mUserId = mCredentials.userId; - mMetadata.mAccessToken = mCredentials.accessToken; + mMetadata.mUserId = mCredentials.getUserId(); + mMetadata.mAccessToken = mCredentials.getAccessToken(); mMetadata.mVersion = MXFILE_VERSION; mMetaDataHasChanged = true; saveMetaData(); @@ -360,8 +360,8 @@ public class MXFileStore extends MXMemoryStore { String errorDescription = null; boolean succeed = (mMetadata.mVersion == MXFILE_VERSION) - && TextUtils.equals(mMetadata.mUserId, mCredentials.userId) - && TextUtils.equals(mMetadata.mAccessToken, mCredentials.accessToken); + && TextUtils.equals(mMetadata.mUserId, mCredentials.getUserId()) + && TextUtils.equals(mMetadata.mAccessToken, mCredentials.getAccessToken()); if (!succeed) { errorDescription = "Invalid store content"; @@ -437,7 +437,7 @@ public class MXFileStore extends MXMemoryStore { if (null == room) { succeed = false; Log.e(LOG_TAG, "loadSummaries : the room " + roomId + " does not exist"); - } else if (null == room.getMember(mCredentials.userId)) { + } else if (null == room.getMember(mCredentials.getUserId())) { //succeed = false; Log.e(LOG_TAG, "loadSummaries) : a summary exists for the roomId " + roomId + " but the user is not anymore a member"); @@ -482,8 +482,8 @@ public class MXFileStore extends MXMemoryStore { // mMetadata should only be null at file store loading if (null == mMetadata) { mMetadata = new MXFileStoreMetaData(); - mMetadata.mUserId = mCredentials.userId; - mMetadata.mAccessToken = mCredentials.accessToken; + mMetadata.mUserId = mCredentials.getUserId(); + mMetadata.mAccessToken = mCredentials.getAccessToken(); mMetaDataHasChanged = true; } else { mMetadata.mEventStreamToken = null; @@ -515,7 +515,7 @@ public class MXFileStore extends MXMemoryStore { // post processing Log.d(LOG_TAG, "## open() : post processing."); - dispatchPostProcess(mCredentials.userId); + dispatchPostProcess(mCredentials.getUserId()); mIsPostProcessingDone = true; synchronized (this) { @@ -525,7 +525,7 @@ public class MXFileStore extends MXMemoryStore { if (!succeed && !mIsNewStorage) { Log.e(LOG_TAG, "The store is corrupted."); - dispatchOnStoreCorrupted(mCredentials.userId, errorDescription); + dispatchOnStoreCorrupted(mCredentials.getUserId(), errorDescription); } else { // extract the room states mRoomReceiptsToLoad.addAll(listFiles(mStoreRoomsMessagesReceiptsFolderFile.list())); @@ -535,7 +535,7 @@ public class MXFileStore extends MXMemoryStore { } Log.d(LOG_TAG, "The store is opened."); - dispatchOnStoreReady(mCredentials.userId); + dispatchOnStoreReady(mCredentials.getUserId()); // load the following items with delay // theses items are not required to be ready @@ -567,12 +567,12 @@ public class MXFileStore extends MXMemoryStore { } else { if (!mIsPostProcessingDone) { Log.e(LOG_TAG, "## open() : is ready but the post processing was not yet done."); - dispatchPostProcess(mCredentials.userId); + dispatchPostProcess(mCredentials.getUserId()); mIsPostProcessingDone = true; } else { Log.e(LOG_TAG, "## open() when ready : the post processing is already done."); } - dispatchOnStoreReady(mCredentials.userId); + dispatchOnStoreReady(mCredentials.getUserId()); mPreloadTime = System.currentTimeMillis() - fLoadTimeT0; if (mMetricsListener != null) { mMetricsListener.onStorePreloaded(mPreloadTime); @@ -662,7 +662,7 @@ public class MXFileStore extends MXMemoryStore { try { ContentUtils.deleteDirectory(mStoreFolderFile); if (init) { - createDirTree(mCredentials.userId); + createDirTree(mCredentials.getUserId()); } } catch (Exception e) { Log.e(LOG_TAG, "deleteAllData failed " + e.getMessage(), e); @@ -790,7 +790,7 @@ public class MXFileStore extends MXMemoryStore { @Override public void storeUser(User user) { - if (!TextUtils.equals(mCredentials.userId, user.user_id)) { + if (!TextUtils.equals(mCredentials.getUserId(), user.user_id)) { mUserIdsToCommit.add(user.user_id); } super.storeUser(user); diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/data/store/MXMemoryStore.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/data/store/MXMemoryStore.java index 42aaf1b0..69a07ac8 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/data/store/MXMemoryStore.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/data/store/MXMemoryStore.java @@ -24,6 +24,7 @@ import android.os.Looper; import android.support.annotation.Nullable; import android.text.TextUtils; +import im.vector.matrix.android.internal.auth.data.Credentials; import im.vector.matrix.android.internal.legacy.MXDataHandler; import im.vector.matrix.android.internal.legacy.data.Room; import im.vector.matrix.android.internal.legacy.data.RoomAccountData; @@ -38,7 +39,6 @@ import im.vector.matrix.android.internal.legacy.rest.model.RoomMember; import im.vector.matrix.android.internal.legacy.rest.model.TokensChunkEvents; import im.vector.matrix.android.internal.legacy.rest.model.User; import im.vector.matrix.android.internal.legacy.rest.model.group.Group; -import im.vector.matrix.android.internal.legacy.rest.model.login.Credentials; import im.vector.matrix.android.internal.legacy.rest.model.pid.ThirdPartyIdentifier; import im.vector.matrix.android.internal.legacy.util.Log; @@ -149,7 +149,7 @@ public class MXMemoryStore implements IMXStore { /** * Default constructor * - * @param credentials the expected credentials + * @param credentials the expected getCredentials * @param context the context */ public MXMemoryStore(Credentials credentials, Context context) { @@ -245,7 +245,7 @@ public class MXMemoryStore implements IMXStore { */ @Override public void setCorrupted(String reason) { - dispatchOnStoreCorrupted(mCredentials.userId, reason); + dispatchOnStoreCorrupted(mCredentials.getUserId(), reason); } /** @@ -607,7 +607,7 @@ public class MXMemoryStore implements IMXStore { */ @Override public int eventsCountAfter(String roomId, String eventId) { - return eventsAfter(roomId, eventId, mCredentials.userId, null).size(); + return eventsAfter(roomId, eventId, mCredentials.getUserId(), null).size(); } @Override @@ -1155,7 +1155,7 @@ public class MXMemoryStore implements IMXStore { synchronized (mReceiptsByRoomIdLock) { if (mReceiptsByRoomId.containsKey(roomId)) { - String myUserID = mCredentials.userId; + String myUserID = mCredentials.getUserId(); Map receiptsByUserId = mReceiptsByRoomId.get(roomId); // copy the user id list to avoid having update while looping @@ -1237,7 +1237,7 @@ public class MXMemoryStore implements IMXStore { } // check if the read receipt is not for an already read message - if (TextUtils.equals(receipt.userId, mCredentials.userId)) { + if (TextUtils.equals(receipt.userId, mCredentials.getUserId())) { synchronized (mReceiptsByRoomIdLock) { LinkedHashMap eventsMap = mRoomEvents.get(roomId); @@ -1334,7 +1334,7 @@ public class MXMemoryStore implements IMXStore { for (int index = 0; index < events.size(); index++) { Event event = events.get(index); - if (TextUtils.equals(event.getSender(), mCredentials.userId) || TextUtils.equals(event.getType(), Event.EVENT_TYPE_STATE_ROOM_MEMBER)) { + if (TextUtils.equals(event.getSender(), mCredentials.getUserId()) || TextUtils.equals(event.getType(), Event.EVENT_TYPE_STATE_ROOM_MEMBER)) { events.remove(index); index--; } @@ -1402,10 +1402,10 @@ public class MXMemoryStore implements IMXStore { if (mReceiptsByRoomId.containsKey(roomId)) { Map receiptsByUserId = mReceiptsByRoomId.get(roomId); - if (receiptsByUserId.containsKey(mCredentials.userId)) { - ReceiptData data = receiptsByUserId.get(mCredentials.userId); + if (receiptsByUserId.containsKey(mCredentials.getUserId())) { + ReceiptData data = receiptsByUserId.get(mCredentials.getUserId()); - res = eventsAfter(roomId, data.eventId, mCredentials.userId, types); + res = eventsAfter(roomId, data.eventId, mCredentials.getUserId(), types); } } } @@ -1479,7 +1479,7 @@ public class MXMemoryStore implements IMXStore { List listeners = getListeners(); for (IMXStoreListener listener : listeners) { - listener.onStoreOOM(mCredentials.userId, e.getMessage()); + listener.onStoreOOM(mCredentials.getUserId(), e.getMessage()); } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/data/timeline/TimelineEventSaver.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/data/timeline/TimelineEventSaver.java index a7b9b507..35b6e1ac 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/data/timeline/TimelineEventSaver.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/data/timeline/TimelineEventSaver.java @@ -51,7 +51,7 @@ class TimelineEventSaver { public void storeEvent(@NonNull final Event event) { final MXDataHandler dataHandler = mRoom.getDataHandler(); - final String myUserId = dataHandler.getCredentials().userId; + final String myUserId = dataHandler.getCredentials().getUserId(); // create dummy read receipt for any incoming event // to avoid not synchronized read receipt and event diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/data/timeline/TimelineLiveEventHandler.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/data/timeline/TimelineLiveEventHandler.java index 9d75e94d..0b81de42 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/data/timeline/TimelineLiveEventHandler.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/data/timeline/TimelineLiveEventHandler.java @@ -19,6 +19,11 @@ package im.vector.matrix.android.internal.legacy.data.timeline; import android.support.annotation.NonNull; import android.text.TextUtils; +import java.util.ArrayList; +import java.util.List; + +import javax.annotation.Nonnull; + import im.vector.matrix.android.internal.legacy.MXDataHandler; import im.vector.matrix.android.internal.legacy.data.MyUser; import im.vector.matrix.android.internal.legacy.data.Room; @@ -32,11 +37,6 @@ import im.vector.matrix.android.internal.legacy.util.EventDisplay; import im.vector.matrix.android.internal.legacy.util.JsonUtils; import im.vector.matrix.android.internal.legacy.util.Log; -import java.util.ArrayList; -import java.util.List; - -import javax.annotation.Nonnull; - /** * This class is responsible for handling live event */ @@ -203,7 +203,7 @@ class TimelineLiveEventHandler { @NonNull Event event, final boolean checkRedactedStateEvent) { boolean shouldBeSaved = false; - String myUserId = dataHandler.getCredentials().userId; + String myUserId = dataHandler.getCredentials().getUserId(); if (Event.EVENT_TYPE_REDACTION.equals(event.getType())) { if (event.getRedactedEventId() != null) { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/db/MXMediaDownloadWorkerTask.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/db/MXMediaDownloadWorkerTask.java index 7ae2f8da..27ef7230 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/db/MXMediaDownloadWorkerTask.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/db/MXMediaDownloadWorkerTask.java @@ -32,23 +32,6 @@ import android.widget.ImageView; import com.google.gson.JsonElement; import com.google.gson.JsonParser; -import im.vector.matrix.android.internal.legacy.HomeServerConnectionConfig; -import im.vector.matrix.android.internal.legacy.RestClient; -import im.vector.matrix.android.internal.legacy.crypto.MXEncryptedAttachments; -import im.vector.matrix.android.internal.legacy.listeners.IMXMediaDownloadListener; -import im.vector.matrix.android.internal.legacy.network.NetworkConnectivityReceiver; -import im.vector.matrix.android.internal.legacy.rest.callback.ApiCallback; -import im.vector.matrix.android.internal.legacy.rest.callback.SimpleApiCallback; -import im.vector.matrix.android.internal.legacy.rest.client.MediaScanRestClient; -import im.vector.matrix.android.internal.legacy.rest.model.EncryptedMediaScanBody; -import im.vector.matrix.android.internal.legacy.rest.model.EncryptedMediaScanEncryptedBody; -import im.vector.matrix.android.internal.legacy.rest.model.MatrixError; -import im.vector.matrix.android.internal.legacy.rest.model.crypto.EncryptedBodyFileInfo; -import im.vector.matrix.android.internal.legacy.rest.model.crypto.EncryptedFileInfo; -import im.vector.matrix.android.internal.legacy.ssl.CertUtil; -import im.vector.matrix.android.internal.legacy.util.ImageUtils; -import im.vector.matrix.android.internal.legacy.util.JsonUtils; -import im.vector.matrix.android.internal.legacy.util.Log; import org.matrix.olm.OlmPkEncryption; import org.matrix.olm.OlmPkMessage; @@ -78,6 +61,24 @@ import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.X509TrustManager; +import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig; +import im.vector.matrix.android.internal.legacy.RestClient; +import im.vector.matrix.android.internal.legacy.crypto.MXEncryptedAttachments; +import im.vector.matrix.android.internal.legacy.listeners.IMXMediaDownloadListener; +import im.vector.matrix.android.internal.legacy.network.NetworkConnectivityReceiver; +import im.vector.matrix.android.internal.legacy.rest.callback.ApiCallback; +import im.vector.matrix.android.internal.legacy.rest.callback.SimpleApiCallback; +import im.vector.matrix.android.internal.legacy.rest.client.MediaScanRestClient; +import im.vector.matrix.android.internal.legacy.rest.model.EncryptedMediaScanBody; +import im.vector.matrix.android.internal.legacy.rest.model.EncryptedMediaScanEncryptedBody; +import im.vector.matrix.android.internal.legacy.rest.model.MatrixError; +import im.vector.matrix.android.internal.legacy.rest.model.crypto.EncryptedBodyFileInfo; +import im.vector.matrix.android.internal.legacy.rest.model.crypto.EncryptedFileInfo; +import im.vector.matrix.android.internal.legacy.util.ImageUtils; +import im.vector.matrix.android.internal.legacy.util.JsonUtils; +import im.vector.matrix.android.internal.legacy.util.Log; +import im.vector.matrix.android.internal.network.ssl.CertUtil; + /** * This class manages the media downloading in background. *

@@ -746,9 +747,9 @@ class MXMediaDownloadWorkerTask extends AsyncTask { // Add SSL Socket factory. HttpsURLConnection sslConn = (HttpsURLConnection) connection; try { - Pair pair = CertUtil.newPinnedSSLSocketFactory(mHsConfig); + Pair pair = CertUtil.INSTANCE.newPinnedSSLSocketFactory(mHsConfig); sslConn.setSSLSocketFactory(pair.first); - sslConn.setHostnameVerifier(CertUtil.newHostnameVerifier(mHsConfig)); + sslConn.setHostnameVerifier(CertUtil.INSTANCE.newHostnameVerifier(mHsConfig)); } catch (Exception e) { Log.e(LOG_TAG, "doInBackground SSL exception " + e.getMessage(), e); } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/db/MXMediaUploadWorkerTask.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/db/MXMediaUploadWorkerTask.java index 2ec1f01f..1adf7e91 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/db/MXMediaUploadWorkerTask.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/db/MXMediaUploadWorkerTask.java @@ -22,15 +22,6 @@ import android.util.Pair; import org.json.JSONException; import org.json.JSONObject; -import im.vector.matrix.android.internal.legacy.RestClient; -import im.vector.matrix.android.internal.legacy.listeners.IMXMediaUploadListener; -import im.vector.matrix.android.internal.legacy.rest.callback.ApiCallback; -import im.vector.matrix.android.internal.legacy.rest.model.ContentResponse; -import im.vector.matrix.android.internal.legacy.rest.model.MatrixError; -import im.vector.matrix.android.internal.legacy.ssl.CertUtil; -import im.vector.matrix.android.internal.legacy.util.ContentManager; -import im.vector.matrix.android.internal.legacy.util.JsonUtils; -import im.vector.matrix.android.internal.legacy.util.Log; import java.io.DataOutputStream; import java.io.EOFException; @@ -51,6 +42,16 @@ import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.X509TrustManager; +import im.vector.matrix.android.internal.legacy.RestClient; +import im.vector.matrix.android.internal.legacy.listeners.IMXMediaUploadListener; +import im.vector.matrix.android.internal.legacy.rest.callback.ApiCallback; +import im.vector.matrix.android.internal.legacy.rest.model.ContentResponse; +import im.vector.matrix.android.internal.legacy.rest.model.MatrixError; +import im.vector.matrix.android.internal.legacy.util.ContentManager; +import im.vector.matrix.android.internal.legacy.util.JsonUtils; +import im.vector.matrix.android.internal.legacy.util.Log; +import im.vector.matrix.android.internal.network.ssl.CertUtil; + /** * Private AsyncTask used to upload files. */ @@ -282,7 +283,7 @@ public class MXMediaUploadWorkerTask extends AsyncTask { String serverResponse = null; - String urlString = mContentManager.getHsConfig().getHomeserverUri().toString() + ContentManager.URI_PREFIX_CONTENT_API + "upload"; + String urlString = mContentManager.getHsConfig().getHomeServerUri().toString() + ContentManager.URI_PREFIX_CONTENT_API + "upload"; if (null != mFilename) { try { @@ -300,7 +301,7 @@ public class MXMediaUploadWorkerTask extends AsyncTask { if (RestClient.getUserAgent() != null) { conn.setRequestProperty("User-Agent", RestClient.getUserAgent()); } - conn.setRequestProperty("Authorization", "Bearer " + mContentManager.getHsConfig().getCredentials().accessToken); + conn.setRequestProperty("Authorization", "Bearer " + mContentManager.getCredentials().getAccessToken()); conn.setDoInput(true); conn.setDoOutput(true); conn.setUseCaches(false); @@ -310,9 +311,9 @@ public class MXMediaUploadWorkerTask extends AsyncTask { // Add SSL Socket factory. HttpsURLConnection sslConn = (HttpsURLConnection) conn; try { - Pair pair = CertUtil.newPinnedSSLSocketFactory(mContentManager.getHsConfig()); + Pair pair = CertUtil.INSTANCE.newPinnedSSLSocketFactory(mContentManager.getHsConfig()); sslConn.setSSLSocketFactory(pair.first); - sslConn.setHostnameVerifier(CertUtil.newHostnameVerifier(mContentManager.getHsConfig())); + sslConn.setHostnameVerifier(CertUtil.INSTANCE.newHostnameVerifier(mContentManager.getHsConfig())); } catch (Exception e) { Log.e(LOG_TAG, "sslConn " + e.getMessage(), e); } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/db/MXMediasCache.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/db/MXMediasCache.java index ab2ecced..ac42c643 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/db/MXMediasCache.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/db/MXMediasCache.java @@ -31,7 +31,18 @@ import android.text.TextUtils; import android.webkit.MimeTypeMap; import android.widget.ImageView; -import im.vector.matrix.android.internal.legacy.HomeServerConnectionConfig; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Set; +import java.util.concurrent.RejectedExecutionException; + +import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig; import im.vector.matrix.android.internal.legacy.crypto.MXEncryptedAttachments; import im.vector.matrix.android.internal.legacy.listeners.IMXMediaDownloadListener; import im.vector.matrix.android.internal.legacy.listeners.IMXMediaUploadListener; @@ -46,17 +57,6 @@ import im.vector.matrix.android.internal.legacy.util.ContentUtils; import im.vector.matrix.android.internal.legacy.util.Log; import im.vector.matrix.android.internal.legacy.util.MXOsHandler; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Set; -import java.util.concurrent.RejectedExecutionException; - public class MXMediasCache { private static final String LOG_TAG = MXMediasCache.class.getSimpleName(); diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/AccountDataRestClient.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/AccountDataRestClient.java index ea7cfce3..36c65254 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/AccountDataRestClient.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/AccountDataRestClient.java @@ -16,15 +16,15 @@ */ package im.vector.matrix.android.internal.legacy.rest.client; -import im.vector.matrix.android.internal.legacy.HomeServerConnectionConfig; +import java.util.HashMap; +import java.util.Map; + +import im.vector.matrix.android.internal.auth.data.SessionParams; import im.vector.matrix.android.internal.legacy.RestClient; import im.vector.matrix.android.internal.legacy.rest.api.AccountDataApi; import im.vector.matrix.android.internal.legacy.rest.callback.ApiCallback; import im.vector.matrix.android.internal.legacy.rest.callback.RestAdapterCallback; -import java.util.HashMap; -import java.util.Map; - public class AccountDataRestClient extends RestClient { /** * Account data types @@ -43,8 +43,8 @@ public class AccountDataRestClient extends RestClient { /** * {@inheritDoc} */ - public AccountDataRestClient(HomeServerConnectionConfig hsConfig) { - super(hsConfig, AccountDataApi.class, RestClient.URI_API_PREFIX_PATH_R0, false); + public AccountDataRestClient(SessionParams sessionParams) { + super(sessionParams, AccountDataApi.class, RestClient.URI_API_PREFIX_PATH_R0, false); } /** @@ -62,11 +62,11 @@ public class AccountDataRestClient extends RestClient { mApi.setAccountData(userId, type, params) .enqueue(new RestAdapterCallback(description, mUnsentEventsManager, callback, new RestAdapterCallback.RequestRetryCallBack() { - @Override - public void onRetry() { - setAccountData(userId, type, params, callback); - } - })); + @Override + public void onRetry() { + setAccountData(userId, type, params, callback); + } + })); } /** @@ -82,11 +82,11 @@ public class AccountDataRestClient extends RestClient { mApi.openIdToken(userId, new HashMap<>()) .enqueue(new RestAdapterCallback>(description, mUnsentEventsManager, callback, - new RestAdapterCallback.RequestRetryCallBack() { - @Override - public void onRetry() { - openIdToken(userId, callback); - } - })); + new RestAdapterCallback.RequestRetryCallBack() { + @Override + public void onRetry() { + openIdToken(userId, callback); + } + })); } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/CallRestClient.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/CallRestClient.java index a8336754..296515bb 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/CallRestClient.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/CallRestClient.java @@ -17,7 +17,7 @@ package im.vector.matrix.android.internal.legacy.rest.client; import com.google.gson.JsonObject; -import im.vector.matrix.android.internal.legacy.HomeServerConnectionConfig; +import im.vector.matrix.android.internal.auth.data.SessionParams; import im.vector.matrix.android.internal.legacy.RestClient; import im.vector.matrix.android.internal.legacy.rest.api.CallRulesApi; import im.vector.matrix.android.internal.legacy.rest.callback.ApiCallback; @@ -28,8 +28,8 @@ public class CallRestClient extends RestClient { /** * {@inheritDoc} */ - public CallRestClient(HomeServerConnectionConfig hsConfig) { - super(hsConfig, CallRulesApi.class, RestClient.URI_API_PREFIX_PATH_R0, false); + public CallRestClient(SessionParams sessionParams) { + super(sessionParams, CallRulesApi.class, RestClient.URI_API_PREFIX_PATH_R0, false); } public void getTurnServer(final ApiCallback callback) { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/CryptoRestClient.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/CryptoRestClient.java index 026ddfdb..18ab534d 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/CryptoRestClient.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/CryptoRestClient.java @@ -19,7 +19,12 @@ package im.vector.matrix.android.internal.legacy.rest.client; import android.text.TextUtils; -import im.vector.matrix.android.internal.legacy.HomeServerConnectionConfig; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import im.vector.matrix.android.internal.auth.data.SessionParams; import im.vector.matrix.android.internal.legacy.RestClient; import im.vector.matrix.android.internal.legacy.crypto.data.MXKey; import im.vector.matrix.android.internal.legacy.crypto.data.MXUsersDevicesMap; @@ -34,12 +39,6 @@ import im.vector.matrix.android.internal.legacy.rest.model.pid.DeleteDeviceParam import im.vector.matrix.android.internal.legacy.rest.model.sync.DevicesListResponse; import im.vector.matrix.android.internal.legacy.util.JsonUtils; import im.vector.matrix.android.internal.legacy.util.Log; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; - import retrofit2.Response; public class CryptoRestClient extends RestClient { @@ -49,8 +48,8 @@ public class CryptoRestClient extends RestClient { /** * {@inheritDoc} */ - public CryptoRestClient(HomeServerConnectionConfig hsConfig) { - super(hsConfig, CryptoApi.class, URI_API_PREFIX_PATH_UNSTABLE, false, false); + public CryptoRestClient(SessionParams sessionParams) { + super(sessionParams, CryptoApi.class, URI_API_PREFIX_PATH_UNSTABLE, false, false); } /** @@ -82,20 +81,20 @@ public class CryptoRestClient extends RestClient { mApi.uploadKeys(encodedDeviceId, params) .enqueue(new RestAdapterCallback(description, null, callback, new RestAdapterCallback.RequestRetryCallBack() { - @Override - public void onRetry() { - uploadKeys(deviceKeys, oneTimeKeys, deviceId, callback); - } - })); + @Override + public void onRetry() { + uploadKeys(deviceKeys, oneTimeKeys, deviceId, callback); + } + })); } else { mApi.uploadKeys(params) .enqueue(new RestAdapterCallback(description, null, callback, new RestAdapterCallback.RequestRetryCallBack() { - @Override - public void onRetry() { - uploadKeys(deviceKeys, oneTimeKeys, deviceId, callback); - } - })); + @Override + public void onRetry() { + uploadKeys(deviceKeys, oneTimeKeys, deviceId, callback); + } + })); } } @@ -127,11 +126,11 @@ public class CryptoRestClient extends RestClient { mApi.downloadKeysForUsers(parameters) .enqueue(new RestAdapterCallback(description, mUnsentEventsManager, callback, new RestAdapterCallback.RequestRetryCallBack() { - @Override - public void onRetry() { - downloadKeysForUsers(userIds, token, callback); - } - })); + @Override + public void onRetry() { + downloadKeysForUsers(userIds, token, callback); + } + })); } /** @@ -151,40 +150,40 @@ public class CryptoRestClient extends RestClient { mApi.claimOneTimeKeysForUsersDevices(params) .enqueue(new RestAdapterCallback(description, mUnsentEventsManager, callback, new RestAdapterCallback.RequestRetryCallBack() { - @Override - public void onRetry() { - claimOneTimeKeysForUsersDevices(usersDevicesKeyTypesMap, callback); - } - }) { - @Override - public void success(KeysClaimResponse keysClaimResponse, Response response) { - onEventSent(); + @Override + public void onRetry() { + claimOneTimeKeysForUsersDevices(usersDevicesKeyTypesMap, callback); + } + }) { + @Override + public void success(KeysClaimResponse keysClaimResponse, Response response) { + onEventSent(); - Map> map = new HashMap<>(); + Map> map = new HashMap<>(); - if (null != keysClaimResponse.oneTimeKeys) { - for (String userId : keysClaimResponse.oneTimeKeys.keySet()) { - Map>> mapByUserId = keysClaimResponse.oneTimeKeys.get(userId); + if (null != keysClaimResponse.oneTimeKeys) { + for (String userId : keysClaimResponse.oneTimeKeys.keySet()) { + Map>> mapByUserId = keysClaimResponse.oneTimeKeys.get(userId); - Map keysMap = new HashMap<>(); + Map keysMap = new HashMap<>(); - for (String deviceId : mapByUserId.keySet()) { - try { - keysMap.put(deviceId, new MXKey(mapByUserId.get(deviceId))); - } catch (Exception e) { - Log.e(LOG_TAG, "## claimOneTimeKeysForUsersDevices : fail to create a MXKey " + e.getMessage(), e); + for (String deviceId : mapByUserId.keySet()) { + try { + keysMap.put(deviceId, new MXKey(mapByUserId.get(deviceId))); + } catch (Exception e) { + Log.e(LOG_TAG, "## claimOneTimeKeysForUsersDevices : fail to create a MXKey " + e.getMessage(), e); + } + } + + if (keysMap.size() != 0) { + map.put(userId, keysMap); + } } } - if (keysMap.size() != 0) { - map.put(userId, keysMap); - } + callback.onSuccess(new MXUsersDevicesMap<>(map)); } - } - - callback.onSuccess(new MXUsersDevicesMap<>(map)); - } - }); + }); } /** @@ -217,11 +216,11 @@ public class CryptoRestClient extends RestClient { mApi.sendToDevice(eventType, transactionId, content) .enqueue(new RestAdapterCallback(description, null, callback, new RestAdapterCallback.RequestRetryCallBack() { - @Override - public void onRetry() { - sendToDevice(eventType, contentMap, callback); - } - })); + @Override + public void onRetry() { + sendToDevice(eventType, contentMap, callback); + } + })); } /** @@ -235,11 +234,11 @@ public class CryptoRestClient extends RestClient { mApi.getDevices() .enqueue(new RestAdapterCallback(description, mUnsentEventsManager, callback, new RestAdapterCallback.RequestRetryCallBack() { - @Override - public void onRetry() { - getDevices(callback); - } - })); + @Override + public void onRetry() { + getDevices(callback); + } + })); } /** @@ -255,11 +254,11 @@ public class CryptoRestClient extends RestClient { mApi.deleteDevice(deviceId, params) .enqueue(new RestAdapterCallback(description, mUnsentEventsManager, callback, new RestAdapterCallback.RequestRetryCallBack() { - @Override - public void onRetry() { - deleteDevice(deviceId, params, callback); - } - })); + @Override + public void onRetry() { + deleteDevice(deviceId, params, callback); + } + })); } /** @@ -278,11 +277,11 @@ public class CryptoRestClient extends RestClient { mApi.updateDeviceInfo(deviceId, params) .enqueue(new RestAdapterCallback(description, mUnsentEventsManager, callback, new RestAdapterCallback.RequestRetryCallBack() { - @Override - public void onRetry() { - setDeviceName(deviceId, deviceName, callback); - } - })); + @Override + public void onRetry() { + setDeviceName(deviceId, deviceName, callback); + } + })); } /** @@ -299,10 +298,10 @@ public class CryptoRestClient extends RestClient { mApi.getKeyChanges(from, to) .enqueue(new RestAdapterCallback(description, mUnsentEventsManager, callback, new RestAdapterCallback.RequestRetryCallBack() { - @Override - public void onRetry() { - getKeyChanges(from, to, callback); - } - })); + @Override + public void onRetry() { + getKeyChanges(from, to, callback); + } + })); } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/EventsRestClient.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/EventsRestClient.java index 987572da..161f3332 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/EventsRestClient.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/EventsRestClient.java @@ -19,7 +19,7 @@ package im.vector.matrix.android.internal.legacy.rest.client; import android.text.TextUtils; -import im.vector.matrix.android.internal.legacy.HomeServerConnectionConfig; +import im.vector.matrix.android.internal.auth.data.SessionParams; import im.vector.matrix.android.internal.legacy.RestClient; import im.vector.matrix.android.internal.legacy.rest.api.EventsApi; import im.vector.matrix.android.internal.legacy.rest.callback.ApiCallback; @@ -62,8 +62,8 @@ public class EventsRestClient extends RestClient { /** * {@inheritDoc} */ - public EventsRestClient(HomeServerConnectionConfig hsConfig) { - super(hsConfig, EventsApi.class, "", false); + public EventsRestClient(SessionParams sessionParams) { + super(sessionParams, EventsApi.class, "", false); } protected EventsRestClient(EventsApi api) { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/FilterRestClient.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/FilterRestClient.java index fb506562..7c45590f 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/FilterRestClient.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/FilterRestClient.java @@ -16,7 +16,7 @@ */ package im.vector.matrix.android.internal.legacy.rest.client; -import im.vector.matrix.android.internal.legacy.HomeServerConnectionConfig; +import im.vector.matrix.android.internal.auth.data.SessionParams; import im.vector.matrix.android.internal.legacy.RestClient; import im.vector.matrix.android.internal.legacy.rest.api.FilterApi; import im.vector.matrix.android.internal.legacy.rest.callback.ApiCallback; @@ -24,21 +24,21 @@ import im.vector.matrix.android.internal.legacy.rest.callback.RestAdapterCallbac import im.vector.matrix.android.internal.legacy.rest.model.filter.FilterBody; import im.vector.matrix.android.internal.legacy.rest.model.filter.FilterResponse; -public class FilterRestClient extends RestClient{ +public class FilterRestClient extends RestClient { /** * {@inheritDoc} */ - public FilterRestClient(HomeServerConnectionConfig hsConfig) { - super(hsConfig, FilterApi.class, RestClient.URI_API_PREFIX_PATH_R0, false); + public FilterRestClient(SessionParams sessionParams) { + super(sessionParams, FilterApi.class, RestClient.URI_API_PREFIX_PATH_R0, false); } /** * Uploads a FilterBody to homeserver * - * @param userId the user id + * @param userId the user id * @param filterBody FilterBody which should be send to server - * @param callback on success callback containing a String with populated filterId + * @param callback on success callback containing a String with populated filterId */ public void uploadFilter(final String userId, final FilterBody filterBody, final ApiCallback callback) { final String description = "uploadFilter userId : " + userId + " filter : " + filterBody; diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/GroupsRestClient.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/GroupsRestClient.java index 8471adb4..774741a7 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/GroupsRestClient.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/GroupsRestClient.java @@ -17,13 +17,18 @@ */ package im.vector.matrix.android.internal.legacy.rest.client; -import im.vector.matrix.android.internal.legacy.HomeServerConnectionConfig; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import im.vector.matrix.android.internal.auth.data.SessionParams; import im.vector.matrix.android.internal.legacy.RestClient; import im.vector.matrix.android.internal.legacy.rest.api.GroupsApi; import im.vector.matrix.android.internal.legacy.rest.callback.ApiCallback; import im.vector.matrix.android.internal.legacy.rest.callback.RestAdapterCallback; import im.vector.matrix.android.internal.legacy.rest.callback.SimpleApiCallback; -import im.vector.matrix.android.internal.legacy.rest.model.MatrixError; import im.vector.matrix.android.internal.legacy.rest.model.group.AcceptGroupInvitationParams; import im.vector.matrix.android.internal.legacy.rest.model.group.AddGroupParams; import im.vector.matrix.android.internal.legacy.rest.model.group.CreateGroupParams; @@ -39,13 +44,6 @@ import im.vector.matrix.android.internal.legacy.rest.model.group.GroupSummary; import im.vector.matrix.android.internal.legacy.rest.model.group.GroupUsers; import im.vector.matrix.android.internal.legacy.rest.model.group.LeaveGroupParams; import im.vector.matrix.android.internal.legacy.rest.model.group.UpdatePubliciseParams; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import retrofit2.Response; /** @@ -56,8 +54,8 @@ public class GroupsRestClient extends RestClient { /** * {@inheritDoc} */ - public GroupsRestClient(HomeServerConnectionConfig hsConfig) { - super(hsConfig, GroupsApi.class, RestClient.URI_API_PREFIX_PATH_R0, false); + public GroupsRestClient(SessionParams sessionParams) { + super(sessionParams, GroupsApi.class, RestClient.URI_API_PREFIX_PATH_R0, false); } protected GroupsRestClient(GroupsApi api) { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/LoginRestClient.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/LoginRestClient.java index 3671ed2d..ff603302 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/LoginRestClient.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/LoginRestClient.java @@ -23,23 +23,22 @@ import android.text.TextUtils; import com.google.gson.JsonObject; -import im.vector.matrix.android.internal.legacy.HomeServerConnectionConfig; +import java.util.List; +import java.util.UUID; + +import im.vector.matrix.android.internal.auth.data.Credentials; +import im.vector.matrix.android.internal.auth.data.SessionParams; import im.vector.matrix.android.internal.legacy.RestClient; import im.vector.matrix.android.internal.legacy.rest.api.LoginApi; import im.vector.matrix.android.internal.legacy.rest.callback.ApiCallback; import im.vector.matrix.android.internal.legacy.rest.callback.RestAdapterCallback; import im.vector.matrix.android.internal.legacy.rest.model.Versions; -import im.vector.matrix.android.internal.legacy.rest.model.login.Credentials; import im.vector.matrix.android.internal.legacy.rest.model.login.LoginFlow; import im.vector.matrix.android.internal.legacy.rest.model.login.LoginFlowResponse; import im.vector.matrix.android.internal.legacy.rest.model.login.LoginParams; import im.vector.matrix.android.internal.legacy.rest.model.login.PasswordLoginParams; import im.vector.matrix.android.internal.legacy.rest.model.login.RegistrationParams; import im.vector.matrix.android.internal.legacy.rest.model.login.TokenLoginParams; - -import java.util.List; -import java.util.UUID; - import retrofit2.Response; /** @@ -59,10 +58,10 @@ public class LoginRestClient extends RestClient { /** * Public constructor. * - * @param hsConfig the home server connection config + * @param sessionParams the session connection data */ - public LoginRestClient(HomeServerConnectionConfig hsConfig) { - super(hsConfig, LoginApi.class, "", false); + public LoginRestClient(SessionParams sessionParams) { + super(sessionParams, LoginApi.class, "", false); } /** diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/MediaScanRestClient.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/MediaScanRestClient.java index 34a20f10..a7f4c3df 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/MediaScanRestClient.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/MediaScanRestClient.java @@ -18,7 +18,11 @@ package im.vector.matrix.android.internal.legacy.rest.client; import android.support.annotation.Nullable; import android.text.TextUtils; -import im.vector.matrix.android.internal.legacy.HomeServerConnectionConfig; +import org.matrix.olm.OlmException; +import org.matrix.olm.OlmPkEncryption; +import org.matrix.olm.OlmPkMessage; + +import im.vector.matrix.android.internal.auth.data.SessionParams; import im.vector.matrix.android.internal.legacy.RestClient; import im.vector.matrix.android.internal.legacy.data.store.IMXStore; import im.vector.matrix.android.internal.legacy.rest.api.MediaScanApi; @@ -32,10 +36,6 @@ import im.vector.matrix.android.internal.legacy.rest.model.MediaScanPublicKeyRes import im.vector.matrix.android.internal.legacy.rest.model.MediaScanResult; import im.vector.matrix.android.internal.legacy.rest.model.crypto.EncryptedBodyFileInfo; import im.vector.matrix.android.internal.legacy.util.JsonUtils; -import org.matrix.olm.OlmException; -import org.matrix.olm.OlmPkEncryption; -import org.matrix.olm.OlmPkMessage; - import retrofit2.Call; /** @@ -49,8 +49,8 @@ public class MediaScanRestClient extends RestClient { /** * {@inheritDoc} */ - public MediaScanRestClient(HomeServerConnectionConfig hsConfig) { - super(hsConfig, MediaScanApi.class, RestClient.URI_API_PREFIX_PATH_MEDIA_PROXY_UNSTABLE, false, EndPointServer.ANTIVIRUS_SERVER); + public MediaScanRestClient(SessionParams sessionParams) { + super(sessionParams, MediaScanApi.class, RestClient.URI_API_PREFIX_PATH_MEDIA_PROXY_UNSTABLE, false, EndPointServer.ANTIVIRUS_SERVER); } /** diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/PresenceRestClient.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/PresenceRestClient.java index 73a90e84..0d282493 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/PresenceRestClient.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/PresenceRestClient.java @@ -16,7 +16,7 @@ */ package im.vector.matrix.android.internal.legacy.rest.client; -import im.vector.matrix.android.internal.legacy.HomeServerConnectionConfig; +import im.vector.matrix.android.internal.auth.data.SessionParams; import im.vector.matrix.android.internal.legacy.RestClient; import im.vector.matrix.android.internal.legacy.rest.api.PresenceApi; import im.vector.matrix.android.internal.legacy.rest.callback.ApiCallback; @@ -31,8 +31,8 @@ public class PresenceRestClient extends RestClient { /** * {@inheritDoc} */ - public PresenceRestClient(HomeServerConnectionConfig hsConfig) { - super(hsConfig, PresenceApi.class, RestClient.URI_API_PREFIX_PATH_R0, false); + public PresenceRestClient(SessionParams sessionParams) { + super(sessionParams, PresenceApi.class, RestClient.URI_API_PREFIX_PATH_R0, false); } /** diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/ProfileRestClient.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/ProfileRestClient.java index 11a45617..4ca0e413 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/ProfileRestClient.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/ProfileRestClient.java @@ -18,7 +18,10 @@ package im.vector.matrix.android.internal.legacy.rest.client; import android.text.TextUtils; -import im.vector.matrix.android.internal.legacy.HomeServerConnectionConfig; +import java.util.List; +import java.util.Map; + +import im.vector.matrix.android.internal.auth.data.SessionParams; import im.vector.matrix.android.internal.legacy.RestClient; import im.vector.matrix.android.internal.legacy.rest.api.ProfileApi; import im.vector.matrix.android.internal.legacy.rest.callback.ApiCallback; @@ -34,18 +37,11 @@ import im.vector.matrix.android.internal.legacy.rest.model.RequestPhoneNumberVal import im.vector.matrix.android.internal.legacy.rest.model.RequestPhoneNumberValidationResponse; import im.vector.matrix.android.internal.legacy.rest.model.ThreePidCreds; import im.vector.matrix.android.internal.legacy.rest.model.User; -import im.vector.matrix.android.internal.legacy.rest.model.login.Credentials; -import im.vector.matrix.android.internal.legacy.rest.model.login.TokenRefreshParams; -import im.vector.matrix.android.internal.legacy.rest.model.login.TokenRefreshResponse; import im.vector.matrix.android.internal.legacy.rest.model.pid.AccountThreePidsResponse; import im.vector.matrix.android.internal.legacy.rest.model.pid.AddThreePidsParams; import im.vector.matrix.android.internal.legacy.rest.model.pid.DeleteThreePidParams; import im.vector.matrix.android.internal.legacy.rest.model.pid.ThirdPartyIdentifier; import im.vector.matrix.android.internal.legacy.rest.model.pid.ThreePid; - -import java.util.List; -import java.util.Map; - import retrofit2.Response; /** @@ -57,8 +53,8 @@ public class ProfileRestClient extends RestClient { /** * {@inheritDoc} */ - public ProfileRestClient(HomeServerConnectionConfig hsConfig) { - super(hsConfig, ProfileApi.class, "", false); + public ProfileRestClient(SessionParams sessionParams) { + super(sessionParams, ProfileApi.class, "", false); } /** @@ -102,7 +98,7 @@ public class ProfileRestClient extends RestClient { // don't retry if the network comes back // let the user chooses what he want to do - mApi.displayname(mCredentials.userId, user) + mApi.displayname(mCredentials.getUserId(), user) .enqueue(new RestAdapterCallback(description, mUnsentEventsManager, callback, new RestAdapterCallback.RequestRetryCallBack() { @Override public void onRetry() { @@ -150,7 +146,7 @@ public class ProfileRestClient extends RestClient { User user = new User(); user.setAvatarUrl(newUrl); - mApi.avatarUrl(mCredentials.userId, user) + mApi.avatarUrl(mCredentials.getUserId(), user) .enqueue(new RestAdapterCallback(description, mUnsentEventsManager, callback, new RestAdapterCallback.RequestRetryCallBack() { @Override public void onRetry() { @@ -288,31 +284,6 @@ public class ProfileRestClient extends RestClient { })); } - /** - * Refresh access/refresh tokens, using the current refresh token. - * - * @param callback the callback success and failure callback - */ - public void refreshTokens(final ApiCallback callback) { - final String description = "refreshTokens"; - - TokenRefreshParams params = new TokenRefreshParams(); - params.refresh_token = mCredentials.refreshToken; - - mApi.tokenrefresh(params) - .enqueue(new RestAdapterCallback(description, mUnsentEventsManager, callback, null) { - @Override - public void success(TokenRefreshResponse tokenreponse, Response response) { - onEventSent(); - mCredentials.refreshToken = tokenreponse.refresh_token; - mCredentials.accessToken = tokenreponse.access_token; - if (null != callback) { - callback.onSuccess(mCredentials); - } - } - }); - } - /** * List all 3PIDs linked to the Matrix user account. * @@ -447,14 +418,14 @@ public class ProfileRestClient extends RestClient { AddThreePidsParams params = new AddThreePidsParams(); params.three_pid_creds = new ThreePidCreds(); - String identityServerHost = mHsConfig.getIdentityServerUri().toString(); - if (identityServerHost.startsWith("http://")) { - identityServerHost = identityServerHost.substring("http://".length()); - } else if (identityServerHost.startsWith("https://")) { - identityServerHost = identityServerHost.substring("https://".length()); + if (identityServerHost != null) { + if (identityServerHost.startsWith("http://")) { + identityServerHost = identityServerHost.substring("http://".length()); + } else if (identityServerHost.startsWith("https://")) { + identityServerHost = identityServerHost.substring("https://".length()); + } } - params.three_pid_creds.id_server = identityServerHost; params.three_pid_creds.sid = pid.sid; params.three_pid_creds.client_secret = pid.clientSecret; diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/PushRulesRestClient.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/PushRulesRestClient.java index 022a0932..1858ba0e 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/PushRulesRestClient.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/PushRulesRestClient.java @@ -16,7 +16,7 @@ */ package im.vector.matrix.android.internal.legacy.rest.client; -import im.vector.matrix.android.internal.legacy.HomeServerConnectionConfig; +import im.vector.matrix.android.internal.auth.data.SessionParams; import im.vector.matrix.android.internal.legacy.RestClient; import im.vector.matrix.android.internal.legacy.rest.api.PushRulesApi; import im.vector.matrix.android.internal.legacy.rest.callback.ApiCallback; @@ -29,8 +29,8 @@ public class PushRulesRestClient extends RestClient { /** * {@inheritDoc} */ - public PushRulesRestClient(HomeServerConnectionConfig hsConfig) { - super(hsConfig, PushRulesApi.class, RestClient.URI_API_PREFIX_PATH_R0, false); + public PushRulesRestClient(SessionParams sessionParams) { + super(sessionParams, PushRulesApi.class, RestClient.URI_API_PREFIX_PATH_R0, false); } /** diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/PushersRestClient.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/PushersRestClient.java index 2bddac1c..145af038 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/PushersRestClient.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/PushersRestClient.java @@ -17,7 +17,9 @@ package im.vector.matrix.android.internal.legacy.rest.client; -import im.vector.matrix.android.internal.legacy.HomeServerConnectionConfig; +import java.util.HashMap; + +import im.vector.matrix.android.internal.auth.data.SessionParams; import im.vector.matrix.android.internal.legacy.RestClient; import im.vector.matrix.android.internal.legacy.data.Pusher; import im.vector.matrix.android.internal.legacy.rest.api.PushersApi; @@ -25,8 +27,6 @@ import im.vector.matrix.android.internal.legacy.rest.callback.ApiCallback; import im.vector.matrix.android.internal.legacy.rest.callback.RestAdapterCallback; import im.vector.matrix.android.internal.legacy.rest.model.PushersResponse; -import java.util.HashMap; - /** * REST client for the Pushers API. */ @@ -36,8 +36,8 @@ public class PushersRestClient extends RestClient { private static final String PUSHER_KIND_HTTP = "http"; private static final String DATA_KEY_HTTP_URL = "url"; - public PushersRestClient(HomeServerConnectionConfig hsConfig) { - super(hsConfig, PushersApi.class, RestClient.URI_API_PREFIX_PATH_R0, true); + public PushersRestClient(SessionParams sessionParams) { + super(sessionParams, PushersApi.class, RestClient.URI_API_PREFIX_PATH_R0, true); } /** diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/RoomsRestClient.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/RoomsRestClient.java index 8f0caeb2..71259674 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/RoomsRestClient.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/RoomsRestClient.java @@ -24,7 +24,10 @@ import android.text.TextUtils; import com.google.gson.JsonElement; import com.google.gson.JsonObject; -import im.vector.matrix.android.internal.legacy.HomeServerConnectionConfig; +import java.util.HashMap; +import java.util.Map; + +import im.vector.matrix.android.internal.auth.data.SessionParams; import im.vector.matrix.android.internal.legacy.RestClient; import im.vector.matrix.android.internal.legacy.data.RoomState; import im.vector.matrix.android.internal.legacy.data.timeline.EventTimeline; @@ -52,14 +55,10 @@ import im.vector.matrix.android.internal.legacy.rest.model.filter.RoomEventFilte import im.vector.matrix.android.internal.legacy.rest.model.message.Message; import im.vector.matrix.android.internal.legacy.rest.model.sync.RoomResponse; -import java.util.HashMap; -import java.util.Map; - /** * Class used to make requests to the rooms API. */ public class RoomsRestClient extends RestClient { - private static final String LOG_TAG = RoomsRestClient.class.getSimpleName(); public static final int DEFAULT_MESSAGES_PAGINATION_LIMIT = 30; @@ -70,8 +69,8 @@ public class RoomsRestClient extends RestClient { /** * {@inheritDoc} */ - public RoomsRestClient(HomeServerConnectionConfig hsConfig) { - super(hsConfig, RoomsApi.class, RestClient.URI_API_PREFIX_PATH_R0, false); + public RoomsRestClient(SessionParams sessionParams) { + super(sessionParams, RoomsApi.class, RestClient.URI_API_PREFIX_PATH_R0, false); } /** @@ -857,7 +856,7 @@ public class RoomsRestClient extends RestClient { Map hashMap = new HashMap<>(); hashMap.put("order", order); - mApi.addTag(mCredentials.userId, roomId, tag, hashMap) + mApi.addTag(mCredentials.getUserId(), roomId, tag, hashMap) .enqueue(new RestAdapterCallback(description, mUnsentEventsManager, callback, new RestAdapterCallback.RequestRetryCallBack() { @Override public void onRetry() { @@ -876,7 +875,7 @@ public class RoomsRestClient extends RestClient { public void removeTag(final String roomId, final String tag, final ApiCallback callback) { final String description = "removeTag : roomId " + roomId + " - tag " + tag; - mApi.removeTag(mCredentials.userId, roomId, tag) + mApi.removeTag(mCredentials.getUserId(), roomId, tag) .enqueue(new RestAdapterCallback(description, mUnsentEventsManager, callback, new RestAdapterCallback.RequestRetryCallBack() { @Override public void onRetry() { @@ -898,7 +897,7 @@ public class RoomsRestClient extends RestClient { Map params = new HashMap<>(); params.put(AccountDataRestClient.ACCOUNT_DATA_KEY_URL_PREVIEW_DISABLE, !status); - mApi.updateAccountData(mCredentials.userId, roomId, Event.EVENT_TYPE_URL_PREVIEW, params) + mApi.updateAccountData(mCredentials.getUserId(), roomId, Event.EVENT_TYPE_URL_PREVIEW, params) .enqueue(new RestAdapterCallback(description, mUnsentEventsManager, callback, new RestAdapterCallback.RequestRetryCallBack() { @Override public void onRetry() { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/ThirdPidRestClient.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/ThirdPidRestClient.java index b3db9a53..eb3a66e7 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/ThirdPidRestClient.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/client/ThirdPidRestClient.java @@ -17,7 +17,14 @@ */ package im.vector.matrix.android.internal.legacy.rest.client; -import im.vector.matrix.android.internal.legacy.HomeServerConnectionConfig; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import im.vector.matrix.android.internal.auth.data.SessionParams; import im.vector.matrix.android.internal.legacy.RestClient; import im.vector.matrix.android.internal.legacy.rest.api.ThirdPidApi; import im.vector.matrix.android.internal.legacy.rest.callback.ApiCallback; @@ -27,14 +34,6 @@ import im.vector.matrix.android.internal.legacy.rest.model.BulkLookupResponse; import im.vector.matrix.android.internal.legacy.rest.model.HttpError; import im.vector.matrix.android.internal.legacy.rest.model.HttpException; import im.vector.matrix.android.internal.legacy.rest.model.pid.PidResponse; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; @@ -46,8 +45,8 @@ public class ThirdPidRestClient extends RestClient { /** * {@inheritDoc} */ - public ThirdPidRestClient(HomeServerConnectionConfig hsConfig) { - super(hsConfig, ThirdPidApi.class, URI_API_PREFIX_IDENTITY, false, true); + public ThirdPidRestClient(SessionParams sessionParams) { + super(sessionParams, ThirdPidApi.class, URI_API_PREFIX_IDENTITY, false, true); } /** diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/model/CreateRoomParams.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/model/CreateRoomParams.java index 70cb803b..82503ecb 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/model/CreateRoomParams.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/model/CreateRoomParams.java @@ -22,19 +22,20 @@ import android.text.TextUtils; import com.google.gson.annotations.SerializedName; -import im.vector.matrix.android.internal.legacy.HomeServerConnectionConfig; -import im.vector.matrix.android.internal.legacy.MXPatterns; -import im.vector.matrix.android.internal.legacy.data.RoomState; -import im.vector.matrix.android.internal.legacy.rest.model.pid.Invite3Pid; -import im.vector.matrix.android.internal.legacy.rest.model.pid.ThreePid; -import im.vector.matrix.android.internal.legacy.util.JsonUtils; - import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig; +import im.vector.matrix.android.internal.auth.data.Credentials; +import im.vector.matrix.android.internal.legacy.MXPatterns; +import im.vector.matrix.android.internal.legacy.data.RoomState; +import im.vector.matrix.android.internal.legacy.rest.model.pid.Invite3Pid; +import im.vector.matrix.android.internal.legacy.rest.model.pid.ThreePid; +import im.vector.matrix.android.internal.legacy.util.JsonUtils; + public class CreateRoomParams { public static final String PRESET_PRIVATE_CHAT = "private_chat"; @@ -225,7 +226,7 @@ public class CreateRoomParams { * * @param ids the participant ids to add. */ - public void addParticipantIds(HomeServerConnectionConfig hsConfig, List ids) { + public void addParticipantIds(HomeServerConnectionConfig homeServerConnectionConfig, Credentials credentials, List ids) { for (String id : ids) { if (android.util.Patterns.EMAIL_ADDRESS.matcher(id).matches()) { if (null == invite3pids) { @@ -233,14 +234,14 @@ public class CreateRoomParams { } Invite3Pid pid = new Invite3Pid(); - pid.id_server = hsConfig.getIdentityServerUri().getHost(); + pid.id_server = homeServerConnectionConfig.getIdentityServerUri().getHost(); pid.medium = ThreePid.MEDIUM_EMAIL; pid.address = id; invite3pids.add(pid); } else if (MXPatterns.isUserId(id)) { // do not invite oneself - if (!TextUtils.equals(hsConfig.getCredentials().userId, id)) { + if (!TextUtils.equals(credentials.getUserId(), id)) { if (null == invitedUserIds) { invitedUserIds = new ArrayList<>(); } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/model/ThreePidCreds.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/model/ThreePidCreds.java index e2b64742..8c4ecabb 100755 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/model/ThreePidCreds.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/model/ThreePidCreds.java @@ -16,7 +16,7 @@ package im.vector.matrix.android.internal.legacy.rest.model; /** - * 3 pid credentials + * 3 pid getCredentials */ public class ThreePidCreds { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/model/login/Credentials.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/model/login/Credentials.java index 77d7f2d6..fb2872fd 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/model/login/Credentials.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/model/login/Credentials.java @@ -21,7 +21,7 @@ import org.json.JSONException; import org.json.JSONObject; /** - * The user's credentials. + * The user's getCredentials. */ public class Credentials { public String userId; diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/model/pid/AddThreePidsParams.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/model/pid/AddThreePidsParams.java index 698f7b2d..1ab806a4 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/model/pid/AddThreePidsParams.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/rest/model/pid/AddThreePidsParams.java @@ -23,7 +23,7 @@ import im.vector.matrix.android.internal.legacy.rest.model.ThreePidCreds; */ public class AddThreePidsParams { - // the 3rd party id credentials + // the 3rd party id getCredentials public ThreePidCreds three_pid_creds; // true when the email has been binded. diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/ssl/CertUtil.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/ssl/CertUtil.java deleted file mode 100644 index 0e577f81..00000000 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/ssl/CertUtil.java +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright 2016 OpenMarket 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.matrix.android.internal.legacy.ssl; - -import android.util.Pair; - -import im.vector.matrix.android.internal.legacy.HomeServerConnectionConfig; -import im.vector.matrix.android.internal.legacy.util.Log; - -import java.security.KeyStore; -import java.security.MessageDigest; -import java.security.cert.Certificate; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.List; - -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLPeerUnverifiedException; -import javax.net.ssl.SSLSession; -import javax.net.ssl.SSLSocketFactory; -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; -import javax.net.ssl.X509TrustManager; - -import okhttp3.CipherSuite; -import okhttp3.ConnectionSpec; -import okhttp3.TlsVersion; - -/** - * Various utility classes for dealing with X509Certificates - */ -public class CertUtil { - private static final String LOG_TAG = CertUtil.class.getSimpleName(); - - /** - * Generates the SHA-256 fingerprint of the given certificate - * - * @param cert the certificate. - * @return the finger print - * @throws CertificateException the certificate exception - */ - public static byte[] generateSha256Fingerprint(X509Certificate cert) throws CertificateException { - return generateFingerprint(cert, "SHA-256"); - } - - /** - * Generates the SHA-1 fingerprint of the given certificate - * - * @param cert the certificated - * @return the SHA1 fingerprint - * @throws CertificateException the certificate exception - */ - public static byte[] generateSha1Fingerprint(X509Certificate cert) throws CertificateException { - return generateFingerprint(cert, "SHA-1"); - } - - /** - * Generate the fingerprint for a dedicated type. - * - * @param cert the certificate - * @param type the type - * @return the fingerprint - * @throws CertificateException certificate exception - */ - private static byte[] generateFingerprint(X509Certificate cert, String type) throws CertificateException { - final byte[] fingerprint; - final MessageDigest md; - try { - md = MessageDigest.getInstance(type); - } catch (Exception e) { - // This really *really* shouldn't throw, as java should always have a SHA-256 and SHA-1 impl. - throw new CertificateException(e); - } - - fingerprint = md.digest(cert.getEncoded()); - - return fingerprint; - } - - final private static char[] hexArray = "0123456789ABCDEF".toCharArray(); - - /** - * Convert the fingerprint to an hexa string. - * - * @param fingerprint the fingerprint - * @return the hexa string. - */ - public static String fingerprintToHexString(byte[] fingerprint) { - return fingerprintToHexString(fingerprint, ' '); - } - - public static String fingerprintToHexString(byte[] fingerprint, char sep) { - char[] hexChars = new char[fingerprint.length * 3]; - for (int j = 0; j < fingerprint.length; j++) { - int v = fingerprint[j] & 0xFF; - hexChars[j * 3] = hexArray[v >>> 4]; - hexChars[j * 3 + 1] = hexArray[v & 0x0F]; - hexChars[j * 3 + 2] = sep; - } - return new String(hexChars, 0, hexChars.length - 1); - } - - /** - * Recursively checks the exception to see if it was caused by an - * UnrecognizedCertificateException - * - * @param e the throwable. - * @return The UnrecognizedCertificateException if exists, else null. - */ - public static UnrecognizedCertificateException getCertificateException(Throwable e) { - int i = 0; // Just in case there is a getCause loop - while (e != null && i < 10) { - if (e instanceof UnrecognizedCertificateException) { - return (UnrecognizedCertificateException) e; - } - e = e.getCause(); - i++; - } - - return null; - } - - /** - * Create a SSLSocket factory for a HS config. - * - * @param hsConfig the HS config. - * @return SSLSocket factory - */ - public static Pair newPinnedSSLSocketFactory(HomeServerConnectionConfig hsConfig) { - try { - X509TrustManager defaultTrustManager = null; - - // If we haven't specified that we wanted to pin the certs, fallback to standard - // X509 checks if fingerprints don't match. - if (!hsConfig.shouldPin()) { - TrustManagerFactory tf = null; - - // get the PKIX instance - try { - tf = TrustManagerFactory.getInstance("PKIX"); - } catch (Exception e) { - Log.e(LOG_TAG, "## newPinnedSSLSocketFactory() : TrustManagerFactory.getInstance failed " + e.getMessage(), e); - } - - // it doesn't exist, use the default one. - if (null == tf) { - try { - tf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - } catch (Exception e) { - Log.e(LOG_TAG, "## addRule : onBingRuleUpdateFailure failed " + e.getMessage(), e); - } - } - - tf.init((KeyStore) null); - TrustManager[] trustManagers = tf.getTrustManagers(); - - for (int i = 0; i < trustManagers.length; i++) { - if (trustManagers[i] instanceof X509TrustManager) { - defaultTrustManager = (X509TrustManager) trustManagers[i]; - break; - } - } - } - - TrustManager[] trustPinned = new TrustManager[]{ - new PinnedTrustManager(hsConfig.getAllowedFingerprints(), defaultTrustManager) - }; - - SSLSocketFactory sslSocketFactory; - - if (hsConfig.forceUsageOfTlsVersions() && hsConfig.getAcceptedTlsVersions() != null) { - // Force usage of accepted Tls Versions for Android < 20 - sslSocketFactory = new TLSSocketFactory(trustPinned, hsConfig.getAcceptedTlsVersions()); - } else { - SSLContext sslContext = SSLContext.getInstance("TLS"); - sslContext.init(null, trustPinned, new java.security.SecureRandom()); - sslSocketFactory = sslContext.getSocketFactory(); - } - - return new Pair<>(sslSocketFactory, defaultTrustManager); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - /** - * Create a Host name verifier for a hs config. - * - * @param hsConfig the hs config. - * @return a new HostnameVerifier. - */ - public static HostnameVerifier newHostnameVerifier(HomeServerConnectionConfig hsConfig) { - final HostnameVerifier defaultVerifier = HttpsURLConnection.getDefaultHostnameVerifier(); - final List trusted_fingerprints = hsConfig.getAllowedFingerprints(); - - return new HostnameVerifier() { - @Override - public boolean verify(String hostname, SSLSession session) { - if (defaultVerifier.verify(hostname, session)) return true; - if (trusted_fingerprints == null || trusted_fingerprints.size() == 0) return false; - - // If remote cert matches an allowed fingerprint, just accept it. - try { - for (Certificate cert : session.getPeerCertificates()) { - for (Fingerprint allowedFingerprint : trusted_fingerprints) { - if (allowedFingerprint != null && cert instanceof X509Certificate && allowedFingerprint.matchesCert((X509Certificate) cert)) { - return true; - } - } - } - } catch (SSLPeerUnverifiedException e) { - return false; - } catch (CertificateException e) { - return false; - } - - return false; - } - }; - } - - /** - * Create a list of accepted TLS specifications for a hs config. - * - * @param hsConfig the hs config. - * @return a list of accepted TLS specifications. - */ - public static List newConnectionSpecs(HomeServerConnectionConfig hsConfig) { - final ConnectionSpec.Builder builder = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS); - - final List tlsVersions = hsConfig.getAcceptedTlsVersions(); - if (null != tlsVersions) { - builder.tlsVersions(tlsVersions.toArray(new TlsVersion[0])); - } - - final List tlsCipherSuites = hsConfig.getAcceptedTlsCipherSuites(); - if (null != tlsCipherSuites) { - builder.cipherSuites(tlsCipherSuites.toArray(new CipherSuite[0])); - } - - builder.supportsTlsExtensions(hsConfig.shouldAcceptTlsExtensions()); - - List list = new ArrayList<>(); - - list.add(builder.build()); - - if (hsConfig.isHttpConnectionAllowed()) { - list.add(ConnectionSpec.CLEARTEXT); - } - - return list; - } -} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/ssl/Fingerprint.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/ssl/Fingerprint.java deleted file mode 100644 index 1c5a7208..00000000 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/ssl/Fingerprint.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright 2016 OpenMarket 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.matrix.android.internal.legacy.ssl; - -import android.util.Base64; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.util.Arrays; - -/** - * Represents a X509 Certificate fingerprint. - */ -public class Fingerprint { - public enum HashType {SHA1, SHA256} - - private final byte[] mBytes; - private final HashType mHashType; - private String mDisplayableHexRepr; - - public Fingerprint(byte[] bytes, HashType hashType) { - mBytes = bytes; - mHashType = hashType; - mDisplayableHexRepr = null; - } - - public static Fingerprint newSha256Fingerprint(X509Certificate cert) throws CertificateException { - return new Fingerprint( - CertUtil.generateSha256Fingerprint(cert), - HashType.SHA256 - ); - } - - public static Fingerprint newSha1Fingerprint(X509Certificate cert) throws CertificateException { - return new Fingerprint( - CertUtil.generateSha1Fingerprint(cert), - HashType.SHA1 - ); - } - - public HashType getType() { - return mHashType; - } - - public byte[] getBytes() { - return mBytes; - } - - public String getBytesAsHexString() { - if (mDisplayableHexRepr == null) { - mDisplayableHexRepr = CertUtil.fingerprintToHexString(mBytes); - } - - return mDisplayableHexRepr; - } - - 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(fingerprintBytes, hashType); - } - - public boolean matchesCert(X509Certificate cert) throws CertificateException { - Fingerprint o = null; - switch (mHashType) { - case SHA256: - o = Fingerprint.newSha256Fingerprint(cert); - break; - case SHA1: - o = Fingerprint.newSha1Fingerprint(cert); - break; - } - - return equals(o); - } - - public String toString() { - return String.format("Fingerprint{type: '%s', fingeprint: '%s'}", mHashType.toString(), getBytesAsHexString()); - } - - @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/im/vector/matrix/android/internal/legacy/ssl/PinnedTrustManager.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/ssl/PinnedTrustManager.java deleted file mode 100644 index 15925c79..00000000 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/ssl/PinnedTrustManager.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2016 OpenMarket 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.matrix.android.internal.legacy.ssl; - -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.util.List; - -import javax.net.ssl.X509TrustManager; - -/** - * Implements a TrustManager that checks Certificates against an explicit list of known - * fingerprints. - */ -public class PinnedTrustManager implements X509TrustManager { - private final List mFingerprints; - private final X509TrustManager mDefaultTrustManager; - - /** - * @param fingerprints An array of SHA256 cert fingerprints - * @param defaultTrustManager Optional trust manager to fall back on if cert does not match - * any of the fingerprints. Can be null. - */ - public PinnedTrustManager(List fingerprints, X509TrustManager defaultTrustManager) { - mFingerprints = fingerprints; - mDefaultTrustManager = defaultTrustManager; - } - - @Override - public void checkClientTrusted(X509Certificate[] chain, String s) throws CertificateException { - try { - if (mDefaultTrustManager != null) { - mDefaultTrustManager.checkClientTrusted( - chain, s - ); - return; - } - } catch (CertificateException e) { - // If there is an exception we fall back to checking fingerprints - if (mFingerprints == null || mFingerprints.size() == 0) { - throw new UnrecognizedCertificateException(chain[0], Fingerprint.newSha256Fingerprint(chain[0]), e.getCause()); - } - } - checkTrusted("client", chain); - } - - @Override - public void checkServerTrusted(X509Certificate[] chain, String s) throws CertificateException { - try { - if (mDefaultTrustManager != null) { - mDefaultTrustManager.checkServerTrusted( - chain, s - ); - return; - } - } catch (CertificateException e) { - // If there is an exception we fall back to checking fingerprints - if (mFingerprints == null || mFingerprints.size() == 0) { - throw new UnrecognizedCertificateException(chain[0], Fingerprint.newSha256Fingerprint(chain[0]), e.getCause()); - } - } - checkTrusted("server", chain); - } - - private void checkTrusted(String type, X509Certificate[] chain) throws CertificateException { - X509Certificate cert = chain[0]; - - boolean found = false; - if (mFingerprints != null) { - for (Fingerprint allowedFingerprint : mFingerprints) { - if (allowedFingerprint != null && allowedFingerprint.matchesCert(cert)) { - found = true; - break; - } - } - } - - if (!found) { - throw new UnrecognizedCertificateException(cert, Fingerprint.newSha256Fingerprint(cert), null); - } - } - - @Override - public X509Certificate[] getAcceptedIssuers() { - return new X509Certificate[0]; - } -} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/ssl/TLSSocketFactory.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/ssl/TLSSocketFactory.java deleted file mode 100644 index 60e6ecc6..00000000 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/ssl/TLSSocketFactory.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 2018 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.matrix.android.internal.legacy.ssl; - -import im.vector.matrix.android.internal.legacy.util.Log; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.Socket; -import java.net.UnknownHostException; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSocket; -import javax.net.ssl.SSLSocketFactory; -import javax.net.ssl.TrustManager; - -import okhttp3.TlsVersion; - -/** - * Force the usage of Tls versions on every created socket - * Inspired from https://blog.dev-area.net/2015/08/13/android-4-1-enable-tls-1-1-and-tls-1-2/ - */ -/*package*/ class TLSSocketFactory extends SSLSocketFactory { - private static final String LOG_TAG = TLSSocketFactory.class.getSimpleName(); - - private SSLSocketFactory internalSSLSocketFactory; - - private String[] enabledProtocols; - - /** - * Constructor - * - * @param trustPinned - * @param acceptedTlsVersions - * @throws KeyManagementException - * @throws NoSuchAlgorithmException - */ - /*package*/ TLSSocketFactory(TrustManager[] trustPinned, List acceptedTlsVersions) throws KeyManagementException, NoSuchAlgorithmException { - SSLContext context = SSLContext.getInstance("TLS"); - context.init(null, trustPinned, new SecureRandom()); - internalSSLSocketFactory = context.getSocketFactory(); - - enabledProtocols = new String[acceptedTlsVersions.size()]; - int i = 0; - for (TlsVersion tlsVersion : acceptedTlsVersions) { - enabledProtocols[i] = tlsVersion.javaName(); - i++; - } - } - - @Override - public String[] getDefaultCipherSuites() { - return internalSSLSocketFactory.getDefaultCipherSuites(); - } - - @Override - public String[] getSupportedCipherSuites() { - return internalSSLSocketFactory.getSupportedCipherSuites(); - } - - @Override - public Socket createSocket() throws IOException { - return enableTLSOnSocket(internalSSLSocketFactory.createSocket()); - } - - @Override - public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException { - return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, host, port, autoClose)); - } - - @Override - public Socket createSocket(String host, int port) throws IOException, UnknownHostException { - return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port)); - } - - @Override - public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException { - return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort)); - } - - @Override - public Socket createSocket(InetAddress host, int port) throws IOException { - return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port)); - } - - @Override - public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException { - return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort)); - } - - private Socket enableTLSOnSocket(Socket socket) { - if (socket != null && (socket instanceof SSLSocket)) { - SSLSocket sslSocket = (SSLSocket) socket; - - List supportedProtocols = Arrays.asList(sslSocket.getSupportedProtocols()); - List filteredEnabledProtocols = new ArrayList<>(); - - for (String protocol : enabledProtocols) { - if (supportedProtocols.contains(protocol)) { - filteredEnabledProtocols.add(protocol); - } - } - - if (!filteredEnabledProtocols.isEmpty()) { - try { - sslSocket.setEnabledProtocols(filteredEnabledProtocols.toArray(new String[filteredEnabledProtocols.size()])); - } catch (Exception e) { - Log.e(LOG_TAG, "Exception: ", e); - } - } - } - return socket; - } -} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/ssl/UnrecognizedCertificateException.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/ssl/UnrecognizedCertificateException.java deleted file mode 100644 index e85b86e8..00000000 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/ssl/UnrecognizedCertificateException.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2016 OpenMarket 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.matrix.android.internal.legacy.ssl; - -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; - -/** - * Thrown when we are given a certificate that does match the certificate we were told to - * expect. - */ -public class UnrecognizedCertificateException extends CertificateException { - private final X509Certificate mCert; - private final Fingerprint mFingerprint; - - public UnrecognizedCertificateException(X509Certificate cert, Fingerprint fingerprint, Throwable cause) { - super("Unrecognized certificate with unknown fingerprint: " + cert.getSubjectDN(), cause); - mCert = cert; - mFingerprint = fingerprint; - } - - public X509Certificate getCertificate() { - return mCert; - } - - public Fingerprint getFingerprint() { - return mFingerprint; - } -} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/util/BingRulesManager.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/util/BingRulesManager.java index 8c9363cc..86ab5717 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/util/BingRulesManager.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/util/BingRulesManager.java @@ -146,7 +146,7 @@ public class BingRulesManager { public BingRulesManager(MXSession session, NetworkConnectivityReceiver networkConnectivityReceiver) { mSession = session; mApiClient = session.getBingRulesApiClient(); - mMyUserId = session.getCredentials().userId; + mMyUserId = session.getCredentials().getUserId(); mDataHandler = session.getDataHandler(); mNetworkListener = new IMXNetworkEventListener() { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/util/ContentManager.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/util/ContentManager.java index 740930ed..696c7df1 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/util/ContentManager.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/util/ContentManager.java @@ -19,7 +19,8 @@ package im.vector.matrix.android.internal.legacy.util; import android.support.annotation.Nullable; -import im.vector.matrix.android.internal.legacy.HomeServerConnectionConfig; +import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig; +import im.vector.matrix.android.internal.auth.data.Credentials; import im.vector.matrix.android.internal.legacy.RestClient; /** @@ -39,6 +40,7 @@ public class ContentManager { // HS config private final HomeServerConnectionConfig mHsConfig; + private final Credentials mCredentials; // the unsent events Manager private final UnsentEventsManager mUnsentEventsManager; @@ -53,8 +55,9 @@ public class ContentManager { * @param hsConfig the HomeserverConnectionConfig to use * @param unsentEventsManager the unsent events manager */ - public ContentManager(HomeServerConnectionConfig hsConfig, UnsentEventsManager unsentEventsManager) { + public ContentManager(HomeServerConnectionConfig hsConfig, Credentials credentials, UnsentEventsManager unsentEventsManager) { mHsConfig = hsConfig; + mCredentials = credentials; mUnsentEventsManager = unsentEventsManager; // The AV scanner is disabled by default configureAntiVirusScanner(false); @@ -73,7 +76,7 @@ public class ContentManager { if (isEnabled) { mDownloadUrlPrefix = mHsConfig.getAntiVirusServerUri().toString() + "/" + RestClient.URI_API_PREFIX_PATH_MEDIA_PROXY_UNSTABLE; } else { - mDownloadUrlPrefix = mHsConfig.getHomeserverUri().toString() + URI_PREFIX_CONTENT_API; + mDownloadUrlPrefix = mHsConfig.getHomeServerUri().toString() + URI_PREFIX_CONTENT_API; } } @@ -88,6 +91,13 @@ public class ContentManager { return mHsConfig; } + /** + * @return the getCredentials. + */ + public Credentials getCredentials() { + return mCredentials; + } + /** * @return the unsent events manager */ @@ -210,7 +220,7 @@ public class ContentManager { // Caution: identicon has no thumbnail path. if (mediaServerAndId.startsWith(MATRIX_CONTENT_IDENTICON_PREFIX)) { // identicon url still go to the media repo since they don’t need virus scanning - url = mHsConfig.getHomeserverUri().toString() + URI_PREFIX_CONTENT_API; + url = mHsConfig.getHomeServerUri().toString() + URI_PREFIX_CONTENT_API; } else { // Use the current download url prefix to take into account a potential antivirus scanner url = mDownloadUrlPrefix + "thumbnail/"; diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/util/EventUtils.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/util/EventUtils.java index 9e15611a..ea23cbc7 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/util/EventUtils.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/util/EventUtils.java @@ -97,7 +97,7 @@ public class EventUtils { Room room = session.getDataHandler().getRoom(event.roomId); return RoomDirectoryVisibility.DIRECTORY_VISIBILITY_PRIVATE.equals(room.getVisibility()) - && !TextUtils.equals(event.getSender(), session.getCredentials().userId); + && !TextUtils.equals(event.getSender(), session.getCredentials().getUserId()); } /** diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/util/JsonUtils.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/util/JsonUtils.java index 98af3049..63e47933 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/util/JsonUtils.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/util/JsonUtils.java @@ -26,6 +26,12 @@ import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import java.lang.reflect.Constructor; +import java.lang.reflect.Modifier; +import java.util.HashMap; +import java.util.Map; +import java.util.TreeSet; + import im.vector.matrix.android.internal.legacy.rest.json.BooleanDeserializer; import im.vector.matrix.android.internal.legacy.rest.json.ConditionDeserializer; import im.vector.matrix.android.internal.legacy.rest.json.MatrixFieldNamingStrategy; @@ -59,11 +65,6 @@ import im.vector.matrix.android.internal.legacy.rest.model.message.StickerMessag import im.vector.matrix.android.internal.legacy.rest.model.message.VideoMessage; import im.vector.matrix.android.internal.legacy.rest.model.pid.RoomThirdPartyInvite; -import java.lang.reflect.Constructor; -import java.lang.reflect.Modifier; -import java.util.Map; -import java.util.TreeSet; - /** * Static methods for converting json into objects. */ @@ -527,6 +528,16 @@ public class JsonUtils { return new JsonObject(); } + public static JsonObject toJson(Map data) { + try { + return (JsonObject) gson.toJsonTree(data); + } catch (Exception e) { + Log.e(LOG_TAG, "## toJson failed " + e.getMessage(), e); + } + + return new JsonObject(); + } + /** * Convert an Message instance into a Json object. * diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/util/UnsentEventsManager.java b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/util/UnsentEventsManager.java index 7a2229b2..d07e44c5 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/util/UnsentEventsManager.java +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/legacy/util/UnsentEventsManager.java @@ -20,15 +20,6 @@ package im.vector.matrix.android.internal.legacy.util; import android.content.Context; import android.text.TextUtils; -import im.vector.matrix.android.internal.legacy.MXDataHandler; -import im.vector.matrix.android.internal.legacy.listeners.IMXNetworkEventListener; -import im.vector.matrix.android.internal.legacy.network.NetworkConnectivityReceiver; -import im.vector.matrix.android.internal.legacy.rest.callback.ApiCallback; -import im.vector.matrix.android.internal.legacy.rest.callback.RestAdapterCallback; -import im.vector.matrix.android.internal.legacy.rest.model.MatrixError; -import im.vector.matrix.android.internal.legacy.ssl.CertUtil; -import im.vector.matrix.android.internal.legacy.ssl.UnrecognizedCertificateException; - import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; @@ -38,6 +29,14 @@ import java.util.Random; import java.util.Timer; import java.util.TimerTask; +import im.vector.matrix.android.internal.legacy.MXDataHandler; +import im.vector.matrix.android.internal.legacy.listeners.IMXNetworkEventListener; +import im.vector.matrix.android.internal.legacy.network.NetworkConnectivityReceiver; +import im.vector.matrix.android.internal.legacy.rest.callback.ApiCallback; +import im.vector.matrix.android.internal.legacy.rest.callback.RestAdapterCallback; +import im.vector.matrix.android.internal.legacy.rest.model.MatrixError; +import im.vector.matrix.android.internal.network.ssl.CertUtil; +import im.vector.matrix.android.internal.network.ssl.UnrecognizedCertificateException; import retrofit2.Response; /** @@ -405,8 +404,7 @@ public class UnsentEventsManager { } if (null != exception) { - UnrecognizedCertificateException unrecCertEx = CertUtil.getCertificateException(exception); - + UnrecognizedCertificateException unrecCertEx = CertUtil.INSTANCE.getCertificateException(exception); if (null != unrecCertEx) { Log.e(LOG_TAG, "## onEventSendingFailed() : SSL issue detected"); mDataHandler.onSSLCertificateError(unrecCertEx); diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/AccessTokenInterceptor.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/AccessTokenInterceptor.kt index ab30a02a..2274a4fc 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/AccessTokenInterceptor.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/AccessTokenInterceptor.kt @@ -1,18 +1,18 @@ package im.vector.matrix.android.internal.network -import im.vector.matrix.android.api.auth.CredentialsStore +import im.vector.matrix.android.api.auth.SessionParamsStore import okhttp3.Interceptor import okhttp3.Response -class AccessTokenInterceptor(private val credentialsStore: CredentialsStore) : Interceptor { +class AccessTokenInterceptor(private val sessionParamsStore: SessionParamsStore) : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { var request = chain.request() val newRequestBuilder = request.newBuilder() // Add the access token to all requests if it is set - val credentials = credentialsStore.get() - credentials?.let { - newRequestBuilder.addHeader("Authorization", "Bearer " + it.accessToken) + val sessionParams = sessionParamsStore.get() + sessionParams?.let { + newRequestBuilder.addHeader("Authorization", "Bearer " + it.credentials.accessToken) } request = newRequestBuilder.build() return chain.proceed(request) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/Request.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/Request.kt index 5db65d8b..a6692f38 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/Request.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/Request.kt @@ -1,9 +1,9 @@ package im.vector.matrix.android.internal.network +import arrow.core.Either import com.squareup.moshi.Moshi import im.vector.matrix.android.api.failure.Failure import im.vector.matrix.android.api.failure.MatrixError -import im.vector.matrix.android.internal.util.Either import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Deferred import kotlinx.coroutines.withContext @@ -21,7 +21,7 @@ class Request { suspend fun execute(): Either = withContext(dispatcher) { return@withContext try { - + val response = apiCall.await() if (response.isSuccessful) { val result = response.body() diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/ssl/CertUtil.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/ssl/CertUtil.kt new file mode 100644 index 00000000..33a157af --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/ssl/CertUtil.kt @@ -0,0 +1,247 @@ +/* + * Copyright 2016 OpenMarket 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.matrix.android.internal.network.ssl + +import android.util.Pair +import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig +import okhttp3.ConnectionSpec +import timber.log.Timber +import java.security.KeyStore +import java.security.MessageDigest +import java.security.cert.CertificateException +import java.security.cert.X509Certificate +import java.util.* +import javax.net.ssl.* +import kotlin.experimental.and + +/** + * Various utility classes for dealing with X509Certificates + */ +object CertUtil { + + private val hexArray = "0123456789ABCDEF".toCharArray() + + /** + * Generates the SHA-256 fingerprint of the given certificate + * + * @param cert the certificate. + * @return the finger print + * @throws CertificateException the certificate exception + */ + @Throws(CertificateException::class) + fun generateSha256Fingerprint(cert: X509Certificate): ByteArray { + return generateFingerprint(cert, "SHA-256") + } + + /** + * Generates the SHA-1 fingerprint of the given certificate + * + * @param cert the certificated + * @return the SHA1 fingerprint + * @throws CertificateException the certificate exception + */ + @Throws(CertificateException::class) + fun generateSha1Fingerprint(cert: X509Certificate): ByteArray { + return generateFingerprint(cert, "SHA-1") + } + + /** + * Generate the fingerprint for a dedicated type. + * + * @param cert the certificate + * @param type the type + * @return the fingerprint + * @throws CertificateException certificate exception + */ + @Throws(CertificateException::class) + private fun generateFingerprint(cert: X509Certificate, type: String): ByteArray { + val fingerprint: ByteArray + val md: MessageDigest + try { + md = MessageDigest.getInstance(type) + } catch (e: Exception) { + // This really *really* shouldn't throw, as java should always have a SHA-256 and SHA-1 impl. + throw CertificateException(e) + } + + fingerprint = md.digest(cert.encoded) + + return fingerprint + } + + /** + * Convert the fingerprint to an hexa string. + * + * @param fingerprint the fingerprint + * @return the hexa string. + */ + @JvmOverloads + fun fingerprintToHexString(fingerprint: ByteArray, sep: Char = ' '): String { + val hexChars = CharArray(fingerprint.size * 3) + for (j in fingerprint.indices) { + val v = (fingerprint[j] and 0xFF.toByte()).toInt() + hexChars[j * 3] = hexArray[v.ushr(4)] + hexChars[j * 3 + 1] = hexArray[v and 0x0F] + hexChars[j * 3 + 2] = sep + } + return String(hexChars, 0, hexChars.size - 1) + } + + /** + * Recursively checks the exception to see if it was caused by an + * UnrecognizedCertificateException + * + * @param e the throwable. + * @return The UnrecognizedCertificateException if exists, else null. + */ + fun getCertificateException(e: Throwable?): UnrecognizedCertificateException? { + var e = e + var i = 0 // Just in case there is a getCause loop + while (e != null && i < 10) { + if (e is UnrecognizedCertificateException) { + return e + } + e = e.cause + i++ + } + + return null + } + + /** + * Create a SSLSocket factory for a HS config. + * + * @param hsConfig the HS config. + * @return SSLSocket factory + */ + fun newPinnedSSLSocketFactory(hsConfig: HomeServerConnectionConfig): Pair { + try { + var defaultTrustManager: X509TrustManager? = null + + // If we haven't specified that we wanted to shouldPin the certs, fallback to standard + // X509 checks if fingerprints don't match. + if (!hsConfig.shouldPin) { + var tf: TrustManagerFactory? = null + + // get the PKIX instance + try { + tf = TrustManagerFactory.getInstance("PKIX") + } catch (e: Exception) { + Timber.e("## newPinnedSSLSocketFactory() : TrustManagerFactory.getInstance failed " + e.message, e) + } + + // it doesn't exist, use the default one. + if (null == tf) { + try { + tf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()) + } catch (e: Exception) { + Timber.e("## addRule : onBingRuleUpdateFailure failed " + e.message, e) + } + + } + + tf!!.init(null as KeyStore?) + val trustManagers = tf.trustManagers + + for (i in trustManagers.indices) { + if (trustManagers[i] is X509TrustManager) { + defaultTrustManager = trustManagers[i] as X509TrustManager + break + } + } + } + + val trustPinned = arrayOf(PinnedTrustManager(hsConfig.allowedFingerprints, defaultTrustManager)) + + val sslSocketFactory: SSLSocketFactory + + if (hsConfig.forceUsageTlsVersions && hsConfig.tlsVersions != null) { + // Force usage of accepted Tls Versions for Android < 20 + sslSocketFactory = TLSSocketFactory(trustPinned, hsConfig.tlsVersions) + } else { + val sslContext = SSLContext.getInstance("TLS") + sslContext.init(null, trustPinned, java.security.SecureRandom()) + sslSocketFactory = sslContext.socketFactory + } + + return Pair(sslSocketFactory, defaultTrustManager) + } catch (e: Exception) { + throw RuntimeException(e) + } + + } + + /** + * Create a Host name verifier for a hs config. + * + * @param hsConfig the hs config. + * @return a new HostnameVerifier. + */ + fun newHostnameVerifier(hsConfig: HomeServerConnectionConfig): HostnameVerifier { + val defaultVerifier = HttpsURLConnection.getDefaultHostnameVerifier() + val trustedFingerprints = hsConfig.allowedFingerprints + + return HostnameVerifier { hostname, session -> + if (defaultVerifier.verify(hostname, session)) return@HostnameVerifier true + if (trustedFingerprints == null || trustedFingerprints.size == 0) return@HostnameVerifier false + + // If remote cert matches an allowed fingerprint, just accept it. + try { + for (cert in session.peerCertificates) { + for (allowedFingerprint in trustedFingerprints) { + if (allowedFingerprint != null && cert is X509Certificate && allowedFingerprint.matchesCert(cert)) { + return@HostnameVerifier true + } + } + } + } catch (e: SSLPeerUnverifiedException) { + return@HostnameVerifier false + } catch (e: CertificateException) { + return@HostnameVerifier false + } + + false + } + } + + /** + * Create a list of accepted TLS specifications for a hs config. + * + * @param hsConfig the hs config. + * @return a list of accepted TLS specifications. + */ + fun newConnectionSpecs(hsConfig: HomeServerConnectionConfig): List { + val builder = ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS) + val tlsVersions = hsConfig.tlsVersions + if (null != tlsVersions) { + builder.tlsVersions(*tlsVersions.toTypedArray()) + } + + val tlsCipherSuites = hsConfig.tlsCipherSuites + if (null != tlsCipherSuites) { + builder.cipherSuites(*tlsCipherSuites.toTypedArray()) + } + + builder.supportsTlsExtensions(hsConfig.shouldAcceptTlsExtensions) + val list = ArrayList() + list.add(builder.build()) + if (hsConfig.allowHttpExtension) { + list.add(ConnectionSpec.CLEARTEXT) + } + return list + } +} \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/ssl/Fingerprint.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/ssl/Fingerprint.kt new file mode 100644 index 00000000..215e72d2 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/ssl/Fingerprint.kt @@ -0,0 +1,68 @@ +package im.vector.matrix.android.internal.network.ssl + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass +import java.security.cert.CertificateException +import java.security.cert.X509Certificate + +@JsonClass(generateAdapter = true) +data class Fingerprint( + val mBytes: ByteArray, + val mHashType: HashType +) { + + val displayableHexRepr: String by lazy { + CertUtil.fingerprintToHexString(mBytes) + } + + @Throws(CertificateException::class) + fun matchesCert(cert: X509Certificate): Boolean { + var o: Fingerprint? = when (mHashType) { + Fingerprint.HashType.SHA256 -> Fingerprint.newSha256Fingerprint(cert) + Fingerprint.HashType.SHA1 -> Fingerprint.newSha1Fingerprint(cert) + } + return equals(o) + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as Fingerprint + if (!mBytes.contentEquals(other.mBytes)) return false + if (mHashType != other.mHashType) return false + + return true + } + + override fun hashCode(): Int { + var result = mBytes.contentHashCode() + result = 31 * result + mHashType.hashCode() + return result + } + + companion object { + + @Throws(CertificateException::class) + fun newSha256Fingerprint(cert: X509Certificate): Fingerprint { + return Fingerprint( + CertUtil.generateSha256Fingerprint(cert), + HashType.SHA256 + ) + } + + @Throws(CertificateException::class) + fun newSha1Fingerprint(cert: X509Certificate): Fingerprint { + return Fingerprint( + CertUtil.generateSha1Fingerprint(cert), + HashType.SHA1 + ) + } + } + + enum class HashType { + @Json(name = "sha-1") SHA1, + @Json(name = "sha-256")SHA256 + } + +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/ssl/PinnedTrustManager.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/ssl/PinnedTrustManager.kt new file mode 100644 index 00000000..6e8a0c5e --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/ssl/PinnedTrustManager.kt @@ -0,0 +1,97 @@ +/* + * Copyright 2016 OpenMarket 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.matrix.android.internal.network.ssl + +import java.security.cert.CertificateException +import java.security.cert.X509Certificate + +import javax.net.ssl.X509TrustManager + +/** + * Implements a TrustManager that checks Certificates against an explicit list of known + * fingerprints. + */ + +/** + * @param fingerprints An array of SHA256 cert fingerprints + * @param defaultTrustManager Optional trust manager to fall back on if cert does not match + * any of the fingerprints. Can be null. + */ +class PinnedTrustManager(private val mFingerprints: List?, + private val mDefaultTrustManager: X509TrustManager?) : X509TrustManager { + + @Throws(CertificateException::class) + override fun checkClientTrusted(chain: Array, s: String) { + try { + if (mDefaultTrustManager != null) { + mDefaultTrustManager.checkClientTrusted( + chain, s + ) + return + } + } catch (e: CertificateException) { + // If there is an exception we fall back to checking fingerprints + if (mFingerprints == null || mFingerprints.isEmpty()) { + throw UnrecognizedCertificateException(chain[0], Fingerprint.newSha256Fingerprint(chain[0]), e.cause) + } + } + + checkTrusted("client", chain) + } + + @Throws(CertificateException::class) + override fun checkServerTrusted(chain: Array, s: String) { + try { + if (mDefaultTrustManager != null) { + mDefaultTrustManager.checkServerTrusted( + chain, s + ) + return + } + } catch (e: CertificateException) { + // If there is an exception we fall back to checking fingerprints + if (mFingerprints == null || mFingerprints.isEmpty()) { + throw UnrecognizedCertificateException(chain[0], Fingerprint.newSha256Fingerprint(chain[0]), e.cause) + } + } + + checkTrusted("server", chain) + } + + @Throws(CertificateException::class) + private fun checkTrusted(type: String, chain: Array) { + val cert = chain[0] + + var found = false + if (mFingerprints != null) { + for (allowedFingerprint in mFingerprints) { + if (allowedFingerprint.matchesCert(cert)) { + found = true + break + } + } + } + + if (!found) { + throw UnrecognizedCertificateException(cert, Fingerprint.newSha256Fingerprint(cert), null) + } + } + + override fun getAcceptedIssuers(): Array { + return emptyArray() + } +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/ssl/TLSSocketFactory.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/ssl/TLSSocketFactory.kt new file mode 100644 index 00000000..ce292dc2 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/ssl/TLSSocketFactory.kt @@ -0,0 +1,131 @@ +/* + * Copyright 2018 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.matrix.android.internal.network.ssl + +import im.vector.matrix.android.internal.legacy.util.Log +import okhttp3.TlsVersion +import java.io.IOException +import java.net.InetAddress +import java.net.Socket +import java.net.UnknownHostException +import java.security.KeyManagementException +import java.security.NoSuchAlgorithmException +import java.security.SecureRandom +import java.util.* +import javax.net.ssl.SSLContext +import javax.net.ssl.SSLSocket +import javax.net.ssl.SSLSocketFactory +import javax.net.ssl.TrustManager + +/** + * Force the usage of Tls versions on every created socket + * Inspired from https://blog.dev-area.net/2015/08/13/android-4-1-enable-tls-1-1-and-tls-1-2/ + */ + +internal class TLSSocketFactory + + +/** + * Constructor + * + * @param trustPinned + * @param acceptedTlsVersions + * @throws KeyManagementException + * @throws NoSuchAlgorithmException + */ +@Throws(KeyManagementException::class, NoSuchAlgorithmException::class) +constructor(trustPinned: Array, acceptedTlsVersions: List) : SSLSocketFactory() { + + private val internalSSLSocketFactory: SSLSocketFactory + private val enabledProtocols: Array + + init { + val context = SSLContext.getInstance("TLS") + context.init(null, trustPinned, SecureRandom()) + internalSSLSocketFactory = context.socketFactory + enabledProtocols = Array(acceptedTlsVersions.size) { + acceptedTlsVersions[it].javaName() + } + } + + override fun getDefaultCipherSuites(): Array { + return internalSSLSocketFactory.defaultCipherSuites + } + + override fun getSupportedCipherSuites(): Array { + return internalSSLSocketFactory.supportedCipherSuites + } + + @Throws(IOException::class) + override fun createSocket(): Socket? { + return enableTLSOnSocket(internalSSLSocketFactory.createSocket()) + } + + @Throws(IOException::class) + override fun createSocket(s: Socket, host: String, port: Int, autoClose: Boolean): Socket? { + return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, host, port, autoClose)) + } + + @Throws(IOException::class, UnknownHostException::class) + override fun createSocket(host: String, port: Int): Socket? { + return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port)) + } + + @Throws(IOException::class, UnknownHostException::class) + override fun createSocket(host: String, port: Int, localHost: InetAddress, localPort: Int): Socket? { + return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort)) + } + + @Throws(IOException::class) + override fun createSocket(host: InetAddress, port: Int): Socket? { + return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port)) + } + + @Throws(IOException::class) + override fun createSocket(address: InetAddress, port: Int, localAddress: InetAddress, localPort: Int): Socket? { + return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort)) + } + + private fun enableTLSOnSocket(socket: Socket?): Socket? { + if (socket != null && socket is SSLSocket) { + val sslSocket = socket as SSLSocket? + + val supportedProtocols = Arrays.asList(*sslSocket!!.supportedProtocols) + val filteredEnabledProtocols = ArrayList() + + for (protocol in enabledProtocols) { + if (supportedProtocols.contains(protocol)) { + filteredEnabledProtocols.add(protocol) + } + } + + if (!filteredEnabledProtocols.isEmpty()) { + try { + sslSocket.enabledProtocols = filteredEnabledProtocols.toTypedArray() + } catch (e: Exception) { + Log.e(LOG_TAG, "Exception: ", e) + } + + } + } + return socket + } + + companion object { + private val LOG_TAG = TLSSocketFactory::class.java.simpleName + } +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/ssl/UnrecognizedCertificateException.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/ssl/UnrecognizedCertificateException.kt new file mode 100644 index 00000000..bbc00aa8 --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/network/ssl/UnrecognizedCertificateException.kt @@ -0,0 +1,30 @@ +/* + * Copyright 2016 OpenMarket 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.matrix.android.internal.network.ssl + +import java.security.cert.CertificateException +import java.security.cert.X509Certificate + +/** + * Thrown when we are given a certificate that does match the certificate we were told to + * expect. + */ +data class UnrecognizedCertificateException( + val certificate: X509Certificate, + val fingerprint: Fingerprint, + override val cause: Throwable? +) : CertificateException("Unrecognized certificate with unknown fingerprint: " + certificate.subjectDN, cause) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt index a187b9ce..09fb9167 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/DefaultSession.kt @@ -1,7 +1,7 @@ package im.vector.matrix.android.internal.session -import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig import im.vector.matrix.android.api.session.Session +import im.vector.matrix.android.internal.auth.data.SessionParams import im.vector.matrix.android.internal.di.SessionModule import im.vector.matrix.android.internal.events.sync.SyncModule import im.vector.matrix.android.internal.events.sync.Synchronizer @@ -11,13 +11,13 @@ import org.koin.standalone.StandAloneContext import org.koin.standalone.getKoin import org.koin.standalone.inject -class DefaultSession(homeServerConnectionConfig: HomeServerConnectionConfig) : Session, KoinComponent { +class DefaultSession(sessionParams: SessionParams) : Session, KoinComponent { private val synchronizer by inject() private val scope: Scope init { - val sessionModule = SessionModule(homeServerConnectionConfig) + val sessionModule = SessionModule(sessionParams) val syncModule = SyncModule() StandAloneContext.loadKoinModules(listOf(sessionModule, syncModule)) scope = getKoin().createScope(SCOPE) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/Either.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/Either.kt deleted file mode 100644 index 56016e4b..00000000 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/util/Either.kt +++ /dev/null @@ -1,35 +0,0 @@ -package im.vector.matrix.android.internal.util - -sealed class Either { - /** * Represents the left side of [Either] class which by convention is a "Failure". */ - data class Left(val a: L) : Either() - - /** * Represents the right side of [Either] class which by convention is a "Success". */ - data class Right(val b: R) : Either() - - val isRight get() = this is Right - val isLeft get() = this is Left - - fun left(a: L) = Left(a) - fun right(b: R) = Right(b) - - fun either(fnL: (L) -> Any, fnR: (R) -> Any): Any = - when (this) { - is Left -> fnL(a) - is Right -> fnR(b) - } -} - -// Credits to Alex Hart -> https://proandroiddev.com/kotlins-nothing-type-946de7d464fb -// Composes 2 functions -fun ((A) -> B).c(f: (B) -> C): (A) -> C = { - f(this(it)) -} - -fun Either.flatMap(fn: (R) -> Either): Either = - when (this) { - is Either.Left -> Either.Left(a) - is Either.Right -> fn(b) - } - -fun Either.map(fn: (R) -> (T)): Either = this.flatMap(fn.c(::right)) \ No newline at end of file