Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/feat/e2ei/rotate-conversation-wi…
Browse files Browse the repository at this point in the history
…th-e2ei-certificate' into feat/e2ei/rotate-conversation-with-e2ei-certificate
  • Loading branch information
mchenani committed Oct 25, 2023
2 parents 3937c15 + b12a5a6 commit f33b52c
Show file tree
Hide file tree
Showing 26 changed files with 498 additions and 113 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,12 @@ internal class ConversationGroupRepositoryImpl(
)
}
}
}.flatMap {
wrapStorageRequest {
newGroupConversationSystemMessagesCreator.value.conversationStartedUnverifiedWarning(
conversationEntity.id.toModel()
)
}
}.flatMap {
wrapStorageRequest {
conversationDAO.getConversationByQualifiedID(conversationEntity.id)?.let {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ internal interface NewGroupConversationSystemMessagesCreator {
conversationId: ConversationId,
userIdList: Set<UserId>
): Either<CoreFailure, Unit>

suspend fun conversationStartedUnverifiedWarning(conversationId: ConversationId): Either<CoreFailure, Unit>
}

internal class NewGroupConversationSystemMessagesCreatorImpl(
Expand Down Expand Up @@ -196,4 +198,18 @@ internal class NewGroupConversationSystemMessagesCreatorImpl(
}

}

override suspend fun conversationStartedUnverifiedWarning(conversationId: ConversationId): Either<CoreFailure, Unit> =
persistMessage(
Message.System(
uuid4().toString(),
MessageContent.ConversationStartedUnverifiedWarning,
conversationId,
DateTimeUtil.currentIsoDateTimeString(),
selfUserId,
Message.Status.Sent,
Message.Visibility.VISIBLE,
expirationData = null
)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,10 @@ sealed interface Message {
is MessageContent.ConversationProtocolChanged -> mutableMapOf(
typeKey to "conversationProtocolChanged"
)

is MessageContent.ConversationStartedUnverifiedWarning -> mutableMapOf(
typeKey to "conversationStartedUnverifiedWarning"
)
}

val standardProperties = mapOf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ sealed class MessageContent {

data object HistoryLost : System()
data object ConversationCreated : System()
data object ConversationStartedUnverifiedWarning : System()
data object ConversationDegradedMLS : System()
data object ConversationVerifiedMLS : System()
data object ConversationDegradedProteus : System()
Expand Down Expand Up @@ -357,6 +358,7 @@ fun MessageContent?.getType() = when (this) {
is MessageContent.Unknown -> "Unknown"
MessageContent.ConversationVerifiedMLS -> "ConversationVerification.Verified.MLS"
MessageContent.ConversationVerifiedProteus -> "ConversationVerification.Verified.Proteus"
is MessageContent.ConversationStartedUnverifiedWarning -> "ConversationStartedUnverifiedWarning"
null -> "null"
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ class MessageMapperImpl(
MessageEntity.ContentType.CONVERSATION_VERIFIED_MLS -> null
MessageEntity.ContentType.CONVERSATION_VERIFIED_PREOTEUS -> null
MessageEntity.ContentType.CONVERSATION_PROTOCOL_CHANGED -> null
MessageEntity.ContentType.CONVERSATION_STARTED_UNVERIFIED_WARNING -> null
}
}

Expand Down Expand Up @@ -378,6 +379,7 @@ class MessageMapperImpl(
MessageEntity.FederationType.CONNECTION_REMOVED -> MessageContent.FederationStopped.ConnectionRemoved(domainList)
}
is MessageEntityContent.ConversationProtocolChanged -> MessageContent.ConversationProtocolChanged(protocol.toModel())
is MessageEntityContent.ConversationStartedUnverifiedWarning -> MessageContent.ConversationStartedUnverifiedWarning
}
}

Expand Down Expand Up @@ -592,4 +594,5 @@ fun MessageContent.System.toMessageEntityContent(): MessageEntityContent.System
MessageContent.ConversationVerifiedProteus -> MessageEntityContent.ConversationVerifiedProteus
is MessageContent.ConversationProtocolChanged -> MessageEntityContent.ConversationProtocolChanged(protocol.toDao())
MessageContent.HistoryLostProtocolChanged -> MessageEntityContent.HistoryLostProtocolChanged
is MessageContent.ConversationStartedUnverifiedWarning -> MessageEntityContent.ConversationStartedUnverifiedWarning
}
Original file line number Diff line number Diff line change
Expand Up @@ -109,5 +109,6 @@ internal class PersistMessageUseCaseImpl(
is MessageContent.FederationStopped.ConnectionRemoved -> false
is MessageContent.FederationStopped.Removed -> false
is MessageContent.ConversationProtocolChanged -> false
is MessageContent.ConversationStartedUnverifiedWarning -> false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1296,7 +1296,8 @@ class UserSessionScope internal constructor(
logout,
oneOnOneResolver,
userId,
clientIdProvider
clientIdProvider,
lazy { conversations.newGroupConversationSystemMessagesCreator }
)

private val userPropertiesEventReceiver: UserPropertiesEventReceiver
Expand Down Expand Up @@ -1647,7 +1648,8 @@ class UserSessionScope internal constructor(
connectionRepository,
conversationRepository,
userRepository,
oneOnOneResolver
oneOnOneResolver,
conversations.newGroupConversationSystemMessagesCreator
)

val observeSecurityClassificationLabel: ObserveSecurityClassificationLabelUseCase
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ package com.wire.kalium.logic.feature.connection
import com.wire.kalium.logic.CoreFailure
import com.wire.kalium.logic.data.connection.ConnectionRepository
import com.wire.kalium.logic.data.conversation.ConversationRepository
import com.wire.kalium.logic.data.conversation.NewGroupConversationSystemMessagesCreator
import com.wire.kalium.logic.data.user.ConnectionState
import com.wire.kalium.logic.data.user.UserId
import com.wire.kalium.logic.feature.conversation.mls.OneOnOneResolver
Expand All @@ -33,7 +34,7 @@ import com.wire.kalium.util.DateTimeUtil
/**
* Use Case that allows a user accept a connection request to connect with another User
*/
fun interface AcceptConnectionRequestUseCase {
interface AcceptConnectionRequestUseCase {
/**
* Use case [AcceptConnectionRequestUseCase] operation
*
Expand All @@ -46,7 +47,8 @@ fun interface AcceptConnectionRequestUseCase {
internal class AcceptConnectionRequestUseCaseImpl(
private val connectionRepository: ConnectionRepository,
private val conversationRepository: ConversationRepository,
private val oneOnOneResolver: OneOnOneResolver
private val oneOnOneResolver: OneOnOneResolver,
private val newGroupConversationSystemMessagesCreator: NewGroupConversationSystemMessagesCreator
) : AcceptConnectionRequestUseCase {

override suspend fun invoke(userId: UserId): AcceptConnectionRequestUseCaseResult {
Expand All @@ -62,6 +64,10 @@ internal class AcceptConnectionRequestUseCaseImpl(
oneOnOneResolver.resolveOneOnOneConversationWithUserId(
connection.qualifiedToId
).map { }
}.flatMap {
newGroupConversationSystemMessagesCreator.conversationStartedUnverifiedWarning(
connection.qualifiedConversationId
)
}
}
.fold({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,25 @@ package com.wire.kalium.logic.feature.connection

import com.wire.kalium.logic.data.connection.ConnectionRepository
import com.wire.kalium.logic.data.conversation.ConversationRepository
import com.wire.kalium.logic.data.conversation.NewGroupConversationSystemMessagesCreator
import com.wire.kalium.logic.data.user.UserRepository
import com.wire.kalium.logic.feature.conversation.mls.OneOnOneResolver

class ConnectionScope internal constructor(
private val connectionRepository: ConnectionRepository,
private val conversationRepository: ConversationRepository,
private val userRepository: UserRepository,
private val oneOnOneResolver: OneOnOneResolver
private val oneOnOneResolver: OneOnOneResolver,
private val newGroupConversationSystemMessagesCreator: NewGroupConversationSystemMessagesCreator
) {
val sendConnectionRequest: SendConnectionRequestUseCase get() = SendConnectionRequestUseCaseImpl(connectionRepository, userRepository)

val acceptConnectionRequest: AcceptConnectionRequestUseCase
get() = AcceptConnectionRequestUseCaseImpl(
connectionRepository,
conversationRepository,
oneOnOneResolver
oneOnOneResolver,
newGroupConversationSystemMessagesCreator
)

val cancelConnectionRequest: CancelConnectionRequestUseCase get() = CancelConnectionRequestUseCaseImpl(connectionRepository)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ package com.wire.kalium.logic.feature.conversation
import com.wire.kalium.logic.data.conversation.ConversationRepository
import com.wire.kalium.logic.data.conversation.MutedConversationStatus
import com.wire.kalium.logic.data.id.ConversationId
import com.wire.kalium.logic.functional.Either
import com.wire.kalium.logic.functional.flatMap
import com.wire.kalium.logic.functional.fold
import com.wire.kalium.logic.functional.onFailure
import com.wire.kalium.logic.functional.onSuccess
import com.wire.kalium.logic.kaliumLogger
import com.wire.kalium.util.DateTimeUtil

Expand All @@ -33,12 +35,14 @@ interface UpdateConversationArchivedStatusUseCase {
*
* @param conversationId the id of the conversation where status wants to be changed
* @param shouldArchiveConversation new archived status to be updated on the given conversation
* @param onlyLocally controls if archived status should only be updated locally
* @param archivedStatusTimestamp the timestamp when the archiving event occurred
* @return an [ConversationUpdateStatusResult] containing Success or Failure cases
*/
suspend operator fun invoke(
conversationId: ConversationId,
shouldArchiveConversation: Boolean,
onlyLocally: Boolean,
archivedStatusTimestamp: Long = DateTimeUtil.currentInstant().toEpochMilliseconds()
): ArchiveStatusUpdateResult
}
Expand All @@ -50,43 +54,92 @@ internal class UpdateConversationArchivedStatusUseCaseImpl(
override suspend operator fun invoke(
conversationId: ConversationId,
shouldArchiveConversation: Boolean,
onlyLocally: Boolean,
archivedStatusTimestamp: Long
): ArchiveStatusUpdateResult =
conversationRepository.updateArchivedStatusRemotely(conversationId, shouldArchiveConversation, archivedStatusTimestamp).onFailure {
kaliumLogger.e("Something went wrong when updating remotely convId (${conversationId.toLogString()}) archiving " +
"status to archived = ($shouldArchiveConversation)")
}.flatMap {
conversationRepository.updateArchivedStatusLocally(conversationId, shouldArchiveConversation, archivedStatusTimestamp)
}.fold({
kaliumLogger.e("Something went wrong when updating locally convId (${conversationId.toLogString()}) archiving " +
"status to archived = ($shouldArchiveConversation)")
ArchiveStatusUpdateResult.Failure
}, {
kaliumLogger.d("Successfully updated remotely and locally convId (${conversationId.toLogString()}) archiving " +
"status to archived = ($shouldArchiveConversation)")
if (!onlyLocally) {
archiveRemotely(conversationId, shouldArchiveConversation, archivedStatusTimestamp)
} else {
Either.Right(Unit)
}
.flatMap {
conversationRepository.updateArchivedStatusLocally(conversationId, shouldArchiveConversation, archivedStatusTimestamp)
}.fold({
kaliumLogger.e(
"Something went wrong when updating locally convId (${conversationId.toLogString()}) archiving " +
"status to archived = ($shouldArchiveConversation)"
)
ArchiveStatusUpdateResult.Failure
}, {
kaliumLogger.d(
"Successfully updated locally convId (${conversationId.toLogString()}) archiving " +
"status to archived = ($shouldArchiveConversation)"
)

// Now we should make sure the conversation gets muted if it's archived or un-muted if it's unarchived
val updatedMutedStatus = if (shouldArchiveConversation) {
MutedConversationStatus.AllMuted
} else {
MutedConversationStatus.AllAllowed
}
conversationRepository.updateMutedStatusRemotely(conversationId, updatedMutedStatus, archivedStatusTimestamp)
.flatMap {
conversationRepository.updateMutedStatusLocally(conversationId, updatedMutedStatus, archivedStatusTimestamp)
}.fold({
kaliumLogger.e(
"Something went wrong when updating the muting status of the convId: " +
"(${conversationId.toLogString()}) to (${updatedMutedStatus.status}"
)
}, {
kaliumLogger.d(
"Successfully updated remotely and locally the muting status of the convId: " +
"(${conversationId.toLogString()}) to (${updatedMutedStatus.status}")
})
// Even if the muting status update fails, we should still return success as the archived status update was successful
ArchiveStatusUpdateResult.Success
})
// Now we should make sure the conversation gets muted if it's archived or un-muted if it's unarchived
val updatedMutedStatus = if (shouldArchiveConversation) {
MutedConversationStatus.AllMuted
} else {
MutedConversationStatus.AllAllowed
}

if (!onlyLocally) {
updateMutedStatusRemotely(conversationId, updatedMutedStatus, archivedStatusTimestamp)
} else {
Either.Right(Unit)
}
.flatMap {
conversationRepository.updateMutedStatusLocally(conversationId, updatedMutedStatus, archivedStatusTimestamp)
}.fold({
kaliumLogger.e(
"Something went wrong when updating locally the muting status of the convId: " +
"(${conversationId.toLogString()}) to (${updatedMutedStatus.status}"
)
}, {
kaliumLogger.d(
"Successfully updated locally the muting status of the convId: " +
"(${conversationId.toLogString()}) to (${updatedMutedStatus.status}"
)
})
// Even if the muting status update fails, we should still return success as the archived status update was successful
ArchiveStatusUpdateResult.Success
})

private suspend fun archiveRemotely(
conversationId: ConversationId,
shouldArchiveConversation: Boolean,
archivedStatusTimestamp: Long
) = conversationRepository.updateArchivedStatusRemotely(conversationId, shouldArchiveConversation, archivedStatusTimestamp)
.onFailure {
kaliumLogger.e(
"Something went wrong when updating remotely convId (${conversationId.toLogString()}) archiving " +
"status to archived = ($shouldArchiveConversation)"
)
}
.onSuccess {
kaliumLogger.d(
"Successfully updated remotely convId (${conversationId.toLogString()}) archiving " +
"status to archived = ($shouldArchiveConversation)"
)
}

private suspend fun updateMutedStatusRemotely(
conversationId: ConversationId,
updatedMutedStatus: MutedConversationStatus,
archivedStatusTimestamp: Long
) = conversationRepository.updateMutedStatusRemotely(conversationId, updatedMutedStatus, archivedStatusTimestamp)
.onFailure {
kaliumLogger.e(
"Something went wrong when updating remotely the muting status of the convId: " +
"(${conversationId.toLogString()}) to (${updatedMutedStatus.status}"
)
}
.onSuccess {
kaliumLogger.d(
"Successfully updated remotely the muting status of the convId: " +
"(${conversationId.toLogString()}) to (${updatedMutedStatus.status}"
)
}
}

sealed class ArchiveStatusUpdateResult {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,23 +64,23 @@ class SessionManagerImpl internal constructor(
private val serverConfigMapper: ServerConfigMapper = MapperProvider.serverConfigMapper()
) : SessionManager {

private var session: SessionDTO? = null
private var serverConfig: ServerConfigDTO? = null

override suspend fun session(): SessionDTO? = withContext(coroutineContext) {
session ?: run {
wrapStorageRequest { tokenStorage.getToken(userId.toDao()) }
.map { sessionMapper.fromEntityToSessionDTO(it) }
.onSuccess { session = it }
.onFailure {
kaliumLogger.e(
override suspend fun session(): SessionDTO = withContext(coroutineContext) {
wrapStorageRequest { tokenStorage.getToken(userId.toDao()) }
.map { sessionMapper.fromEntityToSessionDTO(it) }
.fold(
{
error(
"""SESSION MANAGER:
|"error": "missing user session",
|"cause": "$it" """.trimMargin()
)
}, { session ->
kaliumLogger.i("_TOKEN_ FOUND SESSION = $session")
session
}
session
}
)
}

override fun serverConfig(): ServerConfigDTO = serverConfig ?: run {
Expand Down Expand Up @@ -118,9 +118,7 @@ class SessionManagerImpl internal constructor(
throw FailureToRefreshTokenException(message)
}, {
it
}).also {
session = it
}
})
}
}

Expand Down
Loading

0 comments on commit f33b52c

Please sign in to comment.