mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-03 16:10:00 +00:00
Enforce HS disabling E2EE in DM creation too (Element Pro) (#7292)
This part was missing from the implementation of this Element Pro feature, which incorrectly only applied to rooms.
This commit is contained in:
committed by
GitHub
parent
00dcf48f28
commit
674354b1a6
@@ -43,6 +43,7 @@ dependencies {
|
|||||||
implementation(libs.coil.compose)
|
implementation(libs.coil.compose)
|
||||||
implementation(projects.libraries.featureflag.api)
|
implementation(projects.libraries.featureflag.api)
|
||||||
implementation(projects.features.createroom.api)
|
implementation(projects.features.createroom.api)
|
||||||
|
implementation(projects.features.enterprise.api)
|
||||||
api(projects.features.startchat.api)
|
api(projects.features.startchat.api)
|
||||||
|
|
||||||
testCommonDependencies(libs, true)
|
testCommonDependencies(libs, true)
|
||||||
@@ -55,4 +56,5 @@ dependencies {
|
|||||||
testImplementation(projects.features.createroom.test)
|
testImplementation(projects.features.createroom.test)
|
||||||
testImplementation(projects.features.startchat.test)
|
testImplementation(projects.features.startchat.test)
|
||||||
testImplementation(projects.libraries.featureflag.test)
|
testImplementation(projects.libraries.featureflag.test)
|
||||||
|
testImplementation(projects.features.enterprise.test)
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-1
@@ -11,6 +11,7 @@ package io.element.android.features.startchat.impl
|
|||||||
import androidx.compose.runtime.MutableState
|
import androidx.compose.runtime.MutableState
|
||||||
import dev.zacsweers.metro.ContributesBinding
|
import dev.zacsweers.metro.ContributesBinding
|
||||||
import im.vector.app.features.analytics.plan.CreatedRoom
|
import im.vector.app.features.analytics.plan.CreatedRoom
|
||||||
|
import io.element.android.features.enterprise.api.SessionEnterpriseService
|
||||||
import io.element.android.features.startchat.api.ConfirmingStartDmWithMatrixUser
|
import io.element.android.features.startchat.api.ConfirmingStartDmWithMatrixUser
|
||||||
import io.element.android.features.startchat.api.StartDMAction
|
import io.element.android.features.startchat.api.StartDMAction
|
||||||
import io.element.android.libraries.architecture.AsyncAction
|
import io.element.android.libraries.architecture.AsyncAction
|
||||||
@@ -26,6 +27,7 @@ import io.element.android.services.analytics.api.AnalyticsService
|
|||||||
class DefaultStartDMAction(
|
class DefaultStartDMAction(
|
||||||
private val matrixClient: MatrixClient,
|
private val matrixClient: MatrixClient,
|
||||||
private val analyticsService: AnalyticsService,
|
private val analyticsService: AnalyticsService,
|
||||||
|
private val sessionEnterpriseService: SessionEnterpriseService,
|
||||||
) : StartDMAction {
|
) : StartDMAction {
|
||||||
override suspend fun execute(
|
override suspend fun execute(
|
||||||
matrixUser: MatrixUser,
|
matrixUser: MatrixUser,
|
||||||
@@ -33,7 +35,11 @@ class DefaultStartDMAction(
|
|||||||
actionState: MutableState<AsyncAction<RoomId>>,
|
actionState: MutableState<AsyncAction<RoomId>>,
|
||||||
) {
|
) {
|
||||||
actionState.value = AsyncAction.Loading
|
actionState.value = AsyncAction.Loading
|
||||||
when (val result = matrixClient.startDM(matrixUser.userId, createIfDmDoesNotExist)) {
|
when (val result = matrixClient.startDM(
|
||||||
|
userId = matrixUser.userId,
|
||||||
|
createIfDmDoesNotExist = createIfDmDoesNotExist,
|
||||||
|
isEncryped = !sessionEnterpriseService.isEncryptionDisabledByHomeserver(),
|
||||||
|
)) {
|
||||||
is StartDMResult.Success -> {
|
is StartDMResult.Success -> {
|
||||||
if (result.isNew) {
|
if (result.isNew) {
|
||||||
analyticsService.capture(CreatedRoom(isDM = true))
|
analyticsService.capture(CreatedRoom(isDM = true))
|
||||||
|
|||||||
+31
@@ -11,6 +11,8 @@ package io.element.android.features.startchat.impl
|
|||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import im.vector.app.features.analytics.plan.CreatedRoom
|
import im.vector.app.features.analytics.plan.CreatedRoom
|
||||||
|
import io.element.android.features.enterprise.api.SessionEnterpriseService
|
||||||
|
import io.element.android.features.enterprise.test.FakeSessionEnterpriseService
|
||||||
import io.element.android.features.startchat.api.ConfirmingStartDmWithMatrixUser
|
import io.element.android.features.startchat.api.ConfirmingStartDmWithMatrixUser
|
||||||
import io.element.android.libraries.architecture.AsyncAction
|
import io.element.android.libraries.architecture.AsyncAction
|
||||||
import io.element.android.libraries.matrix.api.MatrixClient
|
import io.element.android.libraries.matrix.api.MatrixClient
|
||||||
@@ -25,6 +27,7 @@ import io.element.android.libraries.matrix.ui.components.aMatrixUser
|
|||||||
import io.element.android.services.analytics.api.AnalyticsService
|
import io.element.android.services.analytics.api.AnalyticsService
|
||||||
import io.element.android.services.analytics.test.FakeAnalyticsService
|
import io.element.android.services.analytics.test.FakeAnalyticsService
|
||||||
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
||||||
|
import io.element.android.tests.testutils.lambda.value
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
@@ -122,13 +125,41 @@ class DefaultStartDMActionTest {
|
|||||||
assertThat(state.value).isEqualTo(ConfirmingStartDmWithMatrixUser(aMatrixUser(), isUserIdentityUnknown = true))
|
assertThat(state.value).isEqualTo(ConfirmingStartDmWithMatrixUser(aMatrixUser(), isUserIdentityUnknown = true))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `when SessionEnterpriseService disables encryption the DM is created without encryption`() = runTest {
|
||||||
|
val createDmLambda = lambdaRecorder<UserId, Boolean, Result<RoomId>> { _, _ -> Result.success(A_ROOM_ID) }
|
||||||
|
val matrixClient = FakeMatrixClient().apply {
|
||||||
|
givenFindDmResult(Result.success(null))
|
||||||
|
createDmResult = createDmLambda
|
||||||
|
}
|
||||||
|
|
||||||
|
val action = createStartDMAction(
|
||||||
|
matrixClient = matrixClient,
|
||||||
|
sessionEnterpriseService = FakeSessionEnterpriseService(isEncryptionDisabledResult = { true })
|
||||||
|
)
|
||||||
|
val state = mutableStateOf<AsyncAction<RoomId>>(AsyncAction.Uninitialized)
|
||||||
|
|
||||||
|
val matrixUser = aMatrixUser()
|
||||||
|
action.execute(matrixUser = matrixUser, createIfDmDoesNotExist = true, actionState = state)
|
||||||
|
|
||||||
|
createDmLambda.assertions().isCalledOnce().with(
|
||||||
|
value(matrixUser.userId),
|
||||||
|
// isEncrypted should be false because encryption is disabled
|
||||||
|
value(false),
|
||||||
|
)
|
||||||
|
|
||||||
|
assertThat(state.value).isEqualTo(AsyncAction.Success(A_ROOM_ID))
|
||||||
|
}
|
||||||
|
|
||||||
private fun createStartDMAction(
|
private fun createStartDMAction(
|
||||||
matrixClient: MatrixClient = FakeMatrixClient(),
|
matrixClient: MatrixClient = FakeMatrixClient(),
|
||||||
analyticsService: AnalyticsService = FakeAnalyticsService(),
|
analyticsService: AnalyticsService = FakeAnalyticsService(),
|
||||||
|
sessionEnterpriseService: SessionEnterpriseService = FakeSessionEnterpriseService(isEncryptionDisabledResult = { false }),
|
||||||
): DefaultStartDMAction {
|
): DefaultStartDMAction {
|
||||||
return DefaultStartDMAction(
|
return DefaultStartDMAction(
|
||||||
matrixClient = matrixClient,
|
matrixClient = matrixClient,
|
||||||
analyticsService = analyticsService,
|
analyticsService = analyticsService,
|
||||||
|
sessionEnterpriseService = sessionEnterpriseService,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -84,7 +84,7 @@ interface MatrixClient {
|
|||||||
suspend fun ignoreUser(userId: UserId): Result<Unit>
|
suspend fun ignoreUser(userId: UserId): Result<Unit>
|
||||||
suspend fun unignoreUser(userId: UserId): Result<Unit>
|
suspend fun unignoreUser(userId: UserId): Result<Unit>
|
||||||
suspend fun createRoom(createRoomParams: CreateRoomParameters): Result<RoomId>
|
suspend fun createRoom(createRoomParams: CreateRoomParameters): Result<RoomId>
|
||||||
suspend fun createDM(userId: UserId): Result<RoomId>
|
suspend fun createDM(userId: UserId, isEncrypted: Boolean): Result<RoomId>
|
||||||
suspend fun getProfile(userId: UserId): Result<MatrixUser>
|
suspend fun getProfile(userId: UserId): Result<MatrixUser>
|
||||||
suspend fun searchUsers(searchTerm: String, limit: Long): Result<MatrixSearchUserResults>
|
suspend fun searchUsers(searchTerm: String, limit: Long): Result<MatrixSearchUserResults>
|
||||||
suspend fun setDisplayName(displayName: String): Result<Unit>
|
suspend fun setDisplayName(displayName: String): Result<Unit>
|
||||||
|
|||||||
+2
-1
@@ -18,6 +18,7 @@ import io.element.android.libraries.matrix.api.core.UserId
|
|||||||
suspend fun MatrixClient.startDM(
|
suspend fun MatrixClient.startDM(
|
||||||
userId: UserId,
|
userId: UserId,
|
||||||
createIfDmDoesNotExist: Boolean,
|
createIfDmDoesNotExist: Boolean,
|
||||||
|
isEncryped: Boolean,
|
||||||
): StartDMResult {
|
): StartDMResult {
|
||||||
return findDM(userId)
|
return findDM(userId)
|
||||||
.fold(
|
.fold(
|
||||||
@@ -25,7 +26,7 @@ suspend fun MatrixClient.startDM(
|
|||||||
if (existingDM != null) {
|
if (existingDM != null) {
|
||||||
StartDMResult.Success(existingDM, isNew = false)
|
StartDMResult.Success(existingDM, isNew = false)
|
||||||
} else if (createIfDmDoesNotExist) {
|
} else if (createIfDmDoesNotExist) {
|
||||||
createDM(userId).fold(
|
createDM(userId, isEncryped).fold(
|
||||||
{ StartDMResult.Success(it, isNew = true) },
|
{ StartDMResult.Success(it, isNew = true) },
|
||||||
{ StartDMResult.Failure(it) }
|
{ StartDMResult.Failure(it) }
|
||||||
)
|
)
|
||||||
|
|||||||
+2
-2
@@ -430,10 +430,10 @@ class RustMatrixClient(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun createDM(userId: UserId): Result<RoomId> {
|
override suspend fun createDM(userId: UserId, isEncrypted: Boolean): Result<RoomId> {
|
||||||
val createRoomParams = CreateRoomParameters(
|
val createRoomParams = CreateRoomParameters(
|
||||||
name = null,
|
name = null,
|
||||||
isEncrypted = true,
|
isEncrypted = isEncrypted,
|
||||||
isDirect = true,
|
isDirect = true,
|
||||||
visibility = RoomVisibility.Private,
|
visibility = RoomVisibility.Private,
|
||||||
preset = RoomPreset.TRUSTED_PRIVATE_CHAT,
|
preset = RoomPreset.TRUSTED_PRIVATE_CHAT,
|
||||||
|
|||||||
+1
-1
@@ -132,7 +132,7 @@ class RustMatrixClientTest {
|
|||||||
client = FakeFfiClient(createRoomResult = createRoomLambda)
|
client = FakeFfiClient(createRoomResult = createRoomLambda)
|
||||||
)
|
)
|
||||||
|
|
||||||
client.createDM(A_USER_ID)
|
client.createDM(userId = A_USER_ID, isEncrypted = true)
|
||||||
|
|
||||||
createRoomLambda.assertions().isCalledOnce()
|
createRoomLambda.assertions().isCalledOnce()
|
||||||
assertThat(createParameters?.historyVisibilityOverride).isEqualTo(RoomHistoryVisibility.Invited)
|
assertThat(createParameters?.historyVisibilityOverride).isEqualTo(RoomHistoryVisibility.Invited)
|
||||||
|
|||||||
+4
-4
@@ -145,7 +145,7 @@ class FakeMatrixClient(
|
|||||||
override val userProfile: StateFlow<MatrixUser> = _userProfile
|
override val userProfile: StateFlow<MatrixUser> = _userProfile
|
||||||
|
|
||||||
var createRoomResult: (CreateRoomParameters) -> Result<RoomId> = { Result.success(A_ROOM_ID) }
|
var createRoomResult: (CreateRoomParameters) -> Result<RoomId> = { Result.success(A_ROOM_ID) }
|
||||||
private var createDmResult: Result<RoomId> = Result.success(A_ROOM_ID)
|
var createDmResult: (UserId, Boolean) -> Result<RoomId> = { _, _ -> Result.success(A_ROOM_ID) }
|
||||||
private var findDmResult: Result<RoomId?> = Result.success(A_ROOM_ID)
|
private var findDmResult: Result<RoomId?> = Result.success(A_ROOM_ID)
|
||||||
private val getRoomResults = mutableMapOf<RoomId, BaseRoom>()
|
private val getRoomResults = mutableMapOf<RoomId, BaseRoom>()
|
||||||
private val searchUserResults = mutableMapOf<String, Result<MatrixSearchUserResults>>()
|
private val searchUserResults = mutableMapOf<String, Result<MatrixSearchUserResults>>()
|
||||||
@@ -196,8 +196,8 @@ class FakeMatrixClient(
|
|||||||
return createRoomResult(createRoomParams)
|
return createRoomResult(createRoomParams)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun createDM(userId: UserId): Result<RoomId> = simulateLongTask {
|
override suspend fun createDM(userId: UserId, isEncrypted: Boolean): Result<RoomId> = simulateLongTask {
|
||||||
return createDmResult
|
return createDmResult(userId, isEncrypted)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getProfile(userId: UserId): Result<MatrixUser> {
|
override suspend fun getProfile(userId: UserId): Result<MatrixUser> {
|
||||||
@@ -301,7 +301,7 @@ class FakeMatrixClient(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun givenCreateDmResult(result: Result<RoomId>) {
|
fun givenCreateDmResult(result: Result<RoomId>) {
|
||||||
createDmResult = result
|
createDmResult = { _, _ -> result }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun givenFindDmResult(result: Result<RoomId?>) {
|
fun givenFindDmResult(result: Result<RoomId?>) {
|
||||||
|
|||||||
Reference in New Issue
Block a user