Merge pull request #1969 from vector-im/feature/dm_creation

DM creation: handled denied federation error
This commit is contained in:
Benoit Marty 2020-08-20 17:15:44 +02:00 committed by GitHub
commit 3bce0be96e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 64 additions and 27 deletions

View File

@ -4,7 +4,16 @@
<JetCodeStyleSettings>
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
<value>
<package name="kotlinx.android.synthetic" withSubpackages="true" static="false" />
<package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" />
</value>
</option>
<option name="PACKAGES_IMPORT_LAYOUT">
<value>
<package name="" alias="false" withSubpackages="true" />
<package name="java" alias="false" withSubpackages="true" />
<package name="javax" alias="false" withSubpackages="true" />
<package name="kotlin" alias="false" withSubpackages="true" />
<package name="" alias="true" withSubpackages="true" />
</value>
</option>
<option name="ALIGN_IN_COLUMNS_CASE_BRANCH" value="true" />

View File

@ -9,6 +9,7 @@ Improvements 🙌:
- Give user the possibility to prevent accidental call (#1869)
- Display device information (name, id and key) in Cryptography setting screen (#1784)
- Ensure users do not accidentally ignore other users (#1890)
- Better handling DM creation when invitees cannot be inviting due to denied federation
- Support new config.json format and config.domain.json files (#1682)
- Increase Font size on Calling screen (#1643)
- Make the user's Avatar live in the general settings

View File

@ -18,8 +18,9 @@
package org.matrix.android.sdk.api.session.room.failure
import org.matrix.android.sdk.api.failure.Failure
import org.matrix.android.sdk.api.failure.MatrixError
sealed class CreateRoomFailure : Failure.FeatureFailure() {
object CreatedWithTimeout: CreateRoomFailure()
object CreatedWithTimeout : CreateRoomFailure()
data class CreatedWithFederationFailure(val matrixError: MatrixError) : CreateRoomFailure()
}

View File

@ -18,6 +18,11 @@
package org.matrix.android.sdk.internal.session.room.create
import com.zhuinden.monarchy.Monarchy
import io.realm.RealmConfiguration
import kotlinx.coroutines.TimeoutCancellationException
import org.greenrobot.eventbus.EventBus
import org.matrix.android.sdk.api.failure.Failure
import org.matrix.android.sdk.api.failure.MatrixError
import org.matrix.android.sdk.api.session.room.failure.CreateRoomFailure
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomPreset
@ -34,9 +39,6 @@ import org.matrix.android.sdk.internal.session.user.accountdata.DirectChatsHelpe
import org.matrix.android.sdk.internal.session.user.accountdata.UpdateUserAccountDataTask
import org.matrix.android.sdk.internal.task.Task
import org.matrix.android.sdk.internal.util.awaitTransaction
import io.realm.RealmConfiguration
import kotlinx.coroutines.TimeoutCancellationException
import org.greenrobot.eventbus.EventBus
import java.util.concurrent.TimeUnit
import javax.inject.Inject
@ -55,10 +57,26 @@ internal class DefaultCreateRoomTask @Inject constructor(
) : CreateRoomTask {
override suspend fun execute(params: CreateRoomParams): String {
val otherUserId = if (params.isDirect()) {
params.getFirstInvitedUserId()
?: throw IllegalStateException("You can't create a direct room without an invitedUser")
} else null
val createRoomBody = createRoomBodyBuilder.build(params)
val createRoomResponse = executeRequest<CreateRoomResponse>(eventBus) {
apiCall = roomAPI.createRoom(createRoomBody)
val createRoomResponse = try {
executeRequest<CreateRoomResponse>(eventBus) {
apiCall = roomAPI.createRoom(createRoomBody)
}
} catch (throwable: Throwable) {
if (throwable is Failure.ServerError
&& throwable.httpCode == 403
&& throwable.error.code == MatrixError.M_FORBIDDEN
&& throwable.error.message.startsWith("Federation denied with")) {
throw CreateRoomFailure.CreatedWithFederationFailure(throwable.error)
} else {
throw throwable
}
}
val roomId = createRoomResponse.roomId
// Wait for room to come back from the sync (but it can maybe be in the DB if the sync response is received before)
@ -70,17 +88,14 @@ internal class DefaultCreateRoomTask @Inject constructor(
} catch (exception: TimeoutCancellationException) {
throw CreateRoomFailure.CreatedWithTimeout
}
if (params.isDirect()) {
handleDirectChatCreation(params, roomId)
if (otherUserId != null) {
handleDirectChatCreation(roomId, otherUserId)
}
setReadMarkers(roomId)
return roomId
}
private suspend fun handleDirectChatCreation(params: CreateRoomParams, roomId: String) {
val otherUserId = params.getFirstInvitedUserId()
?: throw IllegalStateException("You can't create a direct room without an invitedUser")
private suspend fun handleDirectChatCreation(roomId: String, otherUserId: String) {
monarchy.awaitTransaction { realm ->
RoomSummaryEntity.where(realm, roomId).findFirst()?.apply {
this.directUserId = otherUserId

View File

@ -48,9 +48,9 @@ import im.vector.app.features.userdirectory.UserDirectoryFragment
import im.vector.app.features.userdirectory.UserDirectorySharedAction
import im.vector.app.features.userdirectory.UserDirectorySharedActionViewModel
import im.vector.app.features.userdirectory.UserDirectoryViewModel
import kotlinx.android.synthetic.main.activity.*
import org.matrix.android.sdk.api.failure.Failure
import org.matrix.android.sdk.api.session.room.failure.CreateRoomFailure
import kotlinx.android.synthetic.main.activity.*
import java.net.HttpURLConnection
import javax.inject.Inject
@ -138,19 +138,29 @@ class CreateDirectRoomActivity : SimpleFragmentActivity() {
private fun renderCreationFailure(error: Throwable) {
hideWaitingView()
if (error is CreateRoomFailure.CreatedWithTimeout) {
finish()
} else {
val message = if (error is Failure.ServerError && error.httpCode == HttpURLConnection.HTTP_INTERNAL_ERROR /*500*/) {
// This error happen if the invited userId does not exist.
getString(R.string.create_room_dm_failure)
} else {
errorFormatter.toHumanReadable(error)
when (error) {
is CreateRoomFailure.CreatedWithTimeout -> {
finish()
}
is CreateRoomFailure.CreatedWithFederationFailure -> {
AlertDialog.Builder(this)
.setMessage(getString(R.string.create_room_federation_error, error.matrixError.message))
.setCancelable(false)
.setPositiveButton(R.string.ok) { _, _ -> finish() }
.show()
}
else -> {
val message = if (error is Failure.ServerError && error.httpCode == HttpURLConnection.HTTP_INTERNAL_ERROR /*500*/) {
// This error happen if the invited userId does not exist.
getString(R.string.create_room_dm_failure)
} else {
errorFormatter.toHumanReadable(error)
}
AlertDialog.Builder(this)
.setMessage(message)
.setPositiveButton(R.string.ok, null)
.show()
}
AlertDialog.Builder(this)
.setMessage(message)
.setPositiveButton(R.string.ok, null)
.show()
}
}

View File

@ -1640,6 +1640,7 @@
<string name="create_room_public_description">"Anyone will be able to join this room"</string>
<string name="create_room_directory_title">"Room Directory"</string>
<string name="create_room_directory_description">"Publish this room in the room directory"</string>
<string name="create_room_federation_error">"The room has been created, but some invitations have not been sent for the following reason:\n\n%s"</string>
<string name="keys_backup_unable_to_get_trust_info">"An error occurred getting trust info"</string>
<string name="keys_backup_unable_to_get_keys_backup_data">"An error occurred getting keys backup data"</string>