Skip to content

Commit

Permalink
feat: Conversation MLS verification status updating (WPB-3872) (#2035)
Browse files Browse the repository at this point in the history
* feat: Conversation MLS verification status updating

* feat: Conversation MLS verification status updating: code-style

* feat: Conversation MLS verification status updating: code-style

* feat: Conversation MLS verification status updating: code-style

* feat: Conversation MLS verification status updating: make it simpler

* Code style fix

* feat: Conversation MLS verification status updating: fixed db migration

* Removed useles comment

* make ConversationVerificationStatusHandler to share flows instead of creating a new for each observer

* Update DB migration

* Review fixes

* Code style fixes

* Updated ConversationVerificationStatusHandlerTest

* Code style fix

* feat: Conversation MLS verification status updating: fixed tests

* Review fixes

* Moved MLS verification status handler to UserScope

* Removed useles class

* Small review changes

* Code style fix

* Fixed test

* feat: Conversation MLS verification status updating: review changes
  • Loading branch information
borichellow authored Sep 28, 2023
1 parent 718a7e1 commit 2497ff6
Show file tree
Hide file tree
Showing 38 changed files with 695 additions and 671 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,8 @@ internal class ConnectionDataSource(
messageTimer = null,
userMessageTimer = null,
archived = false,
archivedInstant = null
archivedInstant = null,
verificationStatus = ConversationEntity.VerificationStatus.NOT_VERIFIED
)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ data class Conversation(
val messageTimer: Duration?,
val userMessageTimer: Duration?,
val archived: Boolean,
val archivedDateTime: Instant?
val archivedDateTime: Instant?,
val verificationStatus: VerificationStatus
) {

companion object {
Expand Down Expand Up @@ -178,6 +179,8 @@ data class Conversation(
enum class ReceiptMode { DISABLED, ENABLED }
enum class TypingIndicatorMode { STARTED, STOPPED }

enum class VerificationStatus { VERIFIED, NOT_VERIFIED, DEGRADED }

@Suppress("MagicNumber")
enum class CipherSuite(val tag: Int) {
UNKNOWN(0),
Expand Down Expand Up @@ -300,7 +303,8 @@ sealed class ConversationDetails(open val conversation: Conversation) {
messageTimer = null,
userMessageTimer = null,
archived = false,
archivedDateTime = null
archivedDateTime = null,
verificationStatus = Conversation.VerificationStatus.NOT_VERIFIED
)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ interface ConversationMapper {

fun fromMigrationModel(conversation: Conversation): ConversationEntity
fun fromFailedGroupConversationToEntity(conversationId: NetworkQualifiedId): ConversationEntity
fun verificationStatusToEntity(verificationStatus: Conversation.VerificationStatus): ConversationEntity.VerificationStatus
fun verificationStatusFromEntity(verificationStatus: ConversationEntity.VerificationStatus): Conversation.VerificationStatus
}

@Suppress("TooManyFunctions", "LongParameterList")
Expand Down Expand Up @@ -119,7 +121,8 @@ internal class ConversationMapperImpl(
userMessageTimer = null, // user picked self deletion timer is only persisted locally
hasIncompleteMetadata = false,
archived = apiModel.members.self.otrArchived ?: false,
archivedInstant = apiModel.members.self.otrArchivedRef?.toInstant()
archivedInstant = apiModel.members.self.otrArchivedRef?.toInstant(),
verificationStatus = ConversationEntity.VerificationStatus.NOT_VERIFIED
)

override fun fromApiModelToDaoModel(apiModel: ConvProtocol): Protocol = when (apiModel) {
Expand Down Expand Up @@ -161,7 +164,8 @@ internal class ConversationMapperImpl(
messageTimer = messageTimer?.toDuration(DurationUnit.MILLISECONDS),
userMessageTimer = userMessageTimer?.toDuration(DurationUnit.MILLISECONDS),
archived = archived,
archivedDateTime = archivedDateTime
archivedDateTime = archivedDateTime,
verificationStatus = verificationStatusFromEntity(verificationStatus)
)
}

Expand All @@ -186,7 +190,8 @@ internal class ConversationMapperImpl(
messageTimer = messageTimer?.toDuration(DurationUnit.MILLISECONDS),
userMessageTimer = userMessageTimer?.toDuration(DurationUnit.MILLISECONDS),
archived = archived,
archivedDateTime = archivedInstant
archivedDateTime = archivedInstant,
verificationStatus = verificationStatusFromEntity(verificationStatus)
)
}

Expand Down Expand Up @@ -378,7 +383,8 @@ internal class ConversationMapperImpl(
messageTimer = messageTimer?.inWholeMilliseconds,
userMessageTimer = userMessageTimer?.inWholeMilliseconds,
archived = archived,
archivedInstant = archivedDateTime
archivedInstant = archivedDateTime,
verificationStatus = verificationStatusToEntity(verificationStatus)
)
}

Expand Down Expand Up @@ -406,7 +412,8 @@ internal class ConversationMapperImpl(
userMessageTimer = null,
hasIncompleteMetadata = true,
archived = false,
archivedInstant = null
archivedInstant = null,
verificationStatus = ConversationEntity.VerificationStatus.NOT_VERIFIED
)

private fun ConversationResponse.getProtocolInfo(mlsGroupState: GroupState?): ProtocolInfo {
Expand Down Expand Up @@ -443,6 +450,12 @@ internal class ConversationMapperImpl(
ConversationResponse.Type.WAIT_FOR_CONNECTION -> ConversationEntity.Type.CONNECTION_PENDING
}
}

override fun verificationStatusFromEntity(verificationStatus: ConversationEntity.VerificationStatus) =
Conversation.VerificationStatus.valueOf(verificationStatus.name)

override fun verificationStatusToEntity(verificationStatus: Conversation.VerificationStatus) =
ConversationEntity.VerificationStatus.valueOf(verificationStatus.name)
}

private fun ConversationEntity.Type.fromDaoModelToType(): Conversation.Type = when (this) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,13 @@ interface ConversationRepository {
suspend fun getOneOnOneConversationsWithFederatedMembers(
domain: String
): Either<CoreFailure, OneOnOneMembers>

suspend fun updateVerificationStatus(
verificationStatus: Conversation.VerificationStatus,
conversationID: ConversationId
): Either<CoreFailure, Unit>

suspend fun getConversationDetailsByMLSGroupId(mlsGroupId: GroupID): Either<CoreFailure, ConversationDetails>
}

@Suppress("LongParameterList", "TooManyFunctions")
Expand Down Expand Up @@ -838,6 +845,21 @@ internal class ConversationDataSource internal constructor(
.mapValues { it.value.toModel() }
}

override suspend fun updateVerificationStatus(
verificationStatus: Conversation.VerificationStatus,
conversationID: ConversationId
): Either<CoreFailure, Unit> =
wrapStorageRequest {
conversationDAO.updateVerificationStatus(
conversationMapper.verificationStatusToEntity(verificationStatus),
conversationID.toDao()
)
}

override suspend fun getConversationDetailsByMLSGroupId(mlsGroupId: GroupID): Either<CoreFailure, ConversationDetails> =
wrapStorageRequest { conversationDAO.getConversationByGroupID(mlsGroupId.value) }
.map { conversationMapper.fromDaoModelToDetails(it, null, mapOf()) }

private suspend fun persistIncompleteConversations(
conversationsFailed: List<NetworkQualifiedId>
): Either<CoreFailure, Unit> {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ interface MLSConversationRepository {
suspend fun setProposalTimer(timer: ProposalTimer, inMemory: Boolean = false)
suspend fun observeProposalTimers(): Flow<ProposalTimer>
suspend fun observeEpochChanges(): Flow<GroupID>
suspend fun getConversationVerificationStatus(groupID: GroupID): Either<CoreFailure, ConversationVerificationStatus>
suspend fun getConversationVerificationStatus(groupID: GroupID): Either<CoreFailure, Conversation.VerificationStatus>
}

private enum class CommitStrategy {
Expand Down Expand Up @@ -195,7 +195,7 @@ internal class MLSConversationDataSource(
kaliumLogger.i("Created conversation from welcome message (groupID = $groupID)")

wrapStorageRequest {
if (conversationDAO.getConversationByGroupID(groupID).first() != null) {
if (conversationDAO.observeConversationByGroupID(groupID).first() != null) {
// Welcome arrived after the conversation create event, updating existing conversation.
conversationDAO.updateConversationGroupState(
ConversationEntity.GroupState.ESTABLISHED,
Expand Down Expand Up @@ -486,12 +486,12 @@ internal class MLSConversationDataSource(
}
}

override suspend fun getConversationVerificationStatus(groupID: GroupID): Either<CoreFailure, ConversationVerificationStatus> =
override suspend fun getConversationVerificationStatus(groupID: GroupID): Either<CoreFailure, Conversation.VerificationStatus> =
mlsClientProvider.getMLSClient().flatMap { mlsClient ->
wrapMLSRequest { mlsClient.isGroupVerified(idMapper.toCryptoModel(groupID)) }
}.map {
if (it) ConversationVerificationStatus.VERIFIED
else ConversationVerificationStatus.NOT_VERIFIED
if (it) Conversation.VerificationStatus.VERIFIED
else Conversation.VerificationStatus.NOT_VERIFIED
}

private suspend fun retryOnCommitFailure(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,8 @@ fun WebConversationContent.toConversation(selfUserId: UserId): Conversation? {
messageTimer = messageTimer?.toDuration(DurationUnit.MILLISECONDS),
userMessageTimer = null,
archived = archivedState ?: false,
archivedDateTime = conversationArchivedTimestamp
archivedDateTime = conversationArchivedTimestamp,
verificationStatus = Conversation.VerificationStatus.NOT_VERIFIED
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,10 @@ import com.wire.kalium.logic.feature.connection.ConnectionScope
import com.wire.kalium.logic.feature.connection.SyncConnectionsUseCase
import com.wire.kalium.logic.feature.connection.SyncConnectionsUseCaseImpl
import com.wire.kalium.logic.feature.conversation.ConversationScope
import com.wire.kalium.logic.feature.conversation.ConversationVerificationStatusHandler
import com.wire.kalium.logic.feature.conversation.ConversationVerificationStatusHandlerImpl
import com.wire.kalium.logic.feature.conversation.ConversationsRecoveryManager
import com.wire.kalium.logic.feature.conversation.ConversationsRecoveryManagerImpl
import com.wire.kalium.logic.feature.conversation.GetConversationVerificationStatusUseCase
import com.wire.kalium.logic.feature.conversation.GetConversationVerificationStatusUseCaseImpl
import com.wire.kalium.logic.feature.conversation.ObserveOtherUserSecurityClassificationLabelUseCase
import com.wire.kalium.logic.feature.conversation.ObserveOtherUserSecurityClassificationLabelUseCaseImpl
import com.wire.kalium.logic.feature.conversation.JoinExistingMLSConversationUseCase
import com.wire.kalium.logic.feature.conversation.JoinExistingMLSConversationUseCaseImpl
import com.wire.kalium.logic.feature.conversation.JoinExistingMLSConversationsUseCase
Expand All @@ -170,8 +168,8 @@ import com.wire.kalium.logic.feature.conversation.LeaveSubconversationUseCase
import com.wire.kalium.logic.feature.conversation.LeaveSubconversationUseCaseImpl
import com.wire.kalium.logic.feature.conversation.MLSConversationsRecoveryManager
import com.wire.kalium.logic.feature.conversation.MLSConversationsRecoveryManagerImpl
import com.wire.kalium.logic.feature.conversation.ObserveOtherUserSecurityClassificationLabelUseCase
import com.wire.kalium.logic.feature.conversation.ObserveOtherUserSecurityClassificationLabelUseCaseImpl
import com.wire.kalium.logic.feature.conversation.MLSConversationsVerificationStatusesHandler
import com.wire.kalium.logic.feature.conversation.MLSConversationsVerificationStatusesHandlerImpl
import com.wire.kalium.logic.feature.conversation.ObserveSecurityClassificationLabelUseCase
import com.wire.kalium.logic.feature.conversation.ObserveSecurityClassificationLabelUseCaseImpl
import com.wire.kalium.logic.feature.conversation.RecoverMLSConversationsUseCase
Expand Down Expand Up @@ -1498,20 +1496,6 @@ class UserSessionScope internal constructor(
}
}

private val conversationVerificationStatusHandler: ConversationVerificationStatusHandler
get() = ConversationVerificationStatusHandlerImpl(
conversationRepository,
persistMessage,
userId
)

val getConversationVerificationStatus: GetConversationVerificationStatusUseCase
get() = GetConversationVerificationStatusUseCaseImpl(
conversationRepository,
mlsConversationRepository,
conversationVerificationStatusHandler
)

internal val getProxyCredentials: GetProxyCredentialsUseCase
get() = GetProxyCredentialsUseCaseImpl(sessionManager)

Expand All @@ -1521,6 +1505,10 @@ class UserSessionScope internal constructor(

override val coroutineContext: CoroutineContext = SupervisorJob()

private val mlsConversationsVerificationStatusesHandler: MLSConversationsVerificationStatusesHandler by lazy {
MLSConversationsVerificationStatusesHandlerImpl(conversationRepository, persistMessage, mlsConversationRepository, userId)
}

init {
launch {
apiMigrationManager.performMigrations()
Expand Down Expand Up @@ -1556,6 +1544,10 @@ class UserSessionScope internal constructor(
launch {
avsSyncStateReporter.execute()
}

launch {
mlsConversationsVerificationStatusesHandler.invoke()
}
}

fun onDestroy() {
Expand Down

This file was deleted.

Loading

0 comments on commit 2497ff6

Please sign in to comment.