Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: handle legal hold events (WPB-5442) #2236

Merged
merged 7 commits into from
Nov 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ import com.wire.kalium.logic.StorageFailure
import com.wire.kalium.logic.data.featureConfig.MLSMigrationModel
import com.wire.kalium.logic.data.featureConfig.toEntity
import com.wire.kalium.logic.data.featureConfig.toModel
import com.wire.kalium.logic.data.user.SupportedProtocol
import com.wire.kalium.logic.data.user.toDao
import com.wire.kalium.logic.data.user.toModel
import com.wire.kalium.logic.data.message.SelfDeletionMapper.toSelfDeletionTimerEntity
import com.wire.kalium.logic.data.message.SelfDeletionMapper.toTeamSelfDeleteTimer
import com.wire.kalium.logic.data.message.TeamSettingsSelfDeletionStatus
import com.wire.kalium.logic.data.user.SupportedProtocol
import com.wire.kalium.logic.data.user.toDao
import com.wire.kalium.logic.data.user.toModel
import com.wire.kalium.logic.featureFlags.BuildFileRestrictionState
import com.wire.kalium.logic.featureFlags.KaliumConfigs
import com.wire.kalium.logic.functional.Either
Expand Down Expand Up @@ -107,6 +107,12 @@ interface UserConfigRepository {
fun setE2EINotificationTime(instant: Instant): Either<StorageFailure, Unit>
suspend fun getMigrationConfiguration(): Either<StorageFailure, MLSMigrationModel>
suspend fun setMigrationConfiguration(configuration: MLSMigrationModel): Either<StorageFailure, Unit>
suspend fun setLegalHoldRequest(
clientId: String,
lastPreKeyId: Int,
lastPreKey: String
): Either<StorageFailure, Unit>
suspend fun deleteLegalHoldRequest(): Either<StorageFailure, Unit>
}

@Suppress("TooManyFunctions")
Expand Down Expand Up @@ -383,4 +389,16 @@ class UserConfigDataSource(
wrapStorageRequest {
userConfigDAO.setMigrationConfiguration(configuration.toEntity())
}

override suspend fun setLegalHoldRequest(
clientId: String,
lastPreKeyId: Int,
lastPreKey: String
): Either<StorageFailure, Unit> = wrapStorageRequest {
userConfigDAO.persistLegalHoldRequest(clientId, lastPreKeyId, lastPreKey)
}

override suspend fun deleteLegalHoldRequest(): Either<StorageFailure, Unit> = wrapStorageRequest {
userConfigDAO.clearLegalHoldRequest()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import com.wire.kalium.logic.data.event.Event
import com.wire.kalium.logic.data.id.toApi
import com.wire.kalium.logic.data.id.toDao
import com.wire.kalium.logic.data.user.UserId
import com.wire.kalium.logic.data.user.UserMapper
import com.wire.kalium.logic.di.MapperProvider
import com.wire.kalium.logic.functional.Either
import com.wire.kalium.logic.functional.flatMap
Expand Down Expand Up @@ -92,8 +91,7 @@ class ClientDataSource(
private val newClientDAO: NewClientDAO,
private val selfUserID: UserId,
private val clientApi: ClientApi,
private val clientMapper: ClientMapper = MapperProvider.clientMapper(),
private val userMapper: UserMapper = MapperProvider.userMapper(),
private val clientMapper: ClientMapper = MapperProvider.clientMapper()
) : ClientRepository {
override suspend fun registerClient(param: RegisterClientParam): Either<NetworkFailure, Client> {
return clientRemoteRepository.registerClient(param)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import com.wire.kalium.logic.data.featureConfig.MLSModel
import com.wire.kalium.logic.data.featureConfig.SelfDeletingMessagesModel
import com.wire.kalium.logic.data.id.ConversationId
import com.wire.kalium.logic.data.id.SubconversationId
import com.wire.kalium.logic.data.legalhold.LastPreKey
import com.wire.kalium.logic.data.user.Connection
import com.wire.kalium.logic.data.user.SupportedProtocol
import com.wire.kalium.logic.data.user.UserId
Expand Down Expand Up @@ -722,6 +723,51 @@ sealed class Event(open val id: String, open val transient: Boolean, open val li
"isMLSCapable" to client.isMLSCapable
)
}

data class LegalHoldRequest(
override val transient: Boolean,
override val live: Boolean,
override val id: String,
val clientId: ClientId,
val lastPreKey: LastPreKey,
val userId: UserId
) : User(id, transient, live) {
override fun toLogMap(): Map<String, Any?> = mapOf(
typeKey to "User.LegalHold-request",
idKey to id.obfuscateId(),
"transient" to "$transient",
"clientId" to clientId.value.obfuscateId(),
"userId" to userId.toLogString(),
)
}

data class LegalHoldEnabled(
override val transient: Boolean,
override val live: Boolean,
override val id: String,
val userId: UserId
) : User(id, transient, live) {
override fun toLogMap(): Map<String, Any?> = mapOf(
typeKey to "User.LegalHold-enabled",
idKey to id.obfuscateId(),
"transient" to "$transient",
"userId" to userId.toLogString()
)
}

data class LegalHoldDisabled(
override val transient: Boolean,
override val live: Boolean,
override val id: String,
val userId: UserId
) : User(id, transient, live) {
override fun toLogMap(): Map<String, Any?> = mapOf(
typeKey to "User.LegalHold-disabled",
idKey to id.obfuscateId(),
"transient" to "$transient",
"userId" to userId.toLogString()
)
}
}

sealed class UserProperty(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,11 @@ import com.wire.kalium.logic.data.conversation.toModel
import com.wire.kalium.logic.data.event.Event.UserProperty.ReadReceiptModeSet
import com.wire.kalium.logic.data.event.Event.UserProperty.TypingIndicatorModeSet
import com.wire.kalium.logic.data.featureConfig.FeatureConfigMapper
import com.wire.kalium.logic.data.id.QualifiedIdMapper
import com.wire.kalium.logic.data.id.QualifiedIdMapperImpl
import com.wire.kalium.logic.data.id.SubconversationId
import com.wire.kalium.logic.data.id.toModel
import com.wire.kalium.logic.data.legalhold.LastPreKey
import com.wire.kalium.logic.data.user.UserId
import com.wire.kalium.logic.data.user.toModel
import com.wire.kalium.logic.di.MapperProvider
Expand All @@ -51,15 +54,16 @@ import kotlinx.serialization.InternalSerializationApi
import kotlinx.serialization.SerializationException
import kotlinx.serialization.serializer

@Suppress("TooManyFunctions", "LongParameterList")
@Suppress("TooManyFunctions", "LongParameterList", "LargeClass")
class EventMapper(
private val memberMapper: MemberMapper,
private val connectionMapper: ConnectionMapper,
private val featureConfigMapper: FeatureConfigMapper,
private val roleMapper: ConversationRoleMapper,
private val selfUserId: UserId,
private val receiptModeMapper: ReceiptModeMapper = MapperProvider.receiptModeMapper(),
private val clientMapper: ClientMapper = MapperProvider.clientMapper()
private val clientMapper: ClientMapper = MapperProvider.clientMapper(),
private val qualifiedIdMapper: QualifiedIdMapper = QualifiedIdMapperImpl(selfUserId)
) {
fun fromDTO(eventResponse: EventResponse, live: Boolean = false): List<Event> {
// TODO(edge-case): Multiple payloads in the same event have the same ID, is this an issue when marking lastProcessedEventId?
Expand All @@ -82,8 +86,11 @@ class EventMapper(
is EventContentDTO.User.NewConnectionDTO -> connectionUpdate(id, eventContentDTO, transient, live)
is EventContentDTO.User.ClientRemoveDTO -> clientRemove(id, eventContentDTO, transient, live)
is EventContentDTO.User.UserDeleteDTO -> userDelete(id, eventContentDTO, transient, live)
is EventContentDTO.FeatureConfig.FeatureConfigUpdatedDTO -> featureConfig(id, eventContentDTO, transient, live)
is EventContentDTO.User.NewClientDTO -> newClient(id, eventContentDTO, transient, live)
is EventContentDTO.User.NewLegalHoldRequestDTO -> legalHoldRequest(id, transient, live, eventContentDTO)
is EventContentDTO.User.LegalHoldEnabledDTO -> legalHoldEnabled(id, transient, live, eventContentDTO)
is EventContentDTO.User.LegalHoldDisabledDTO -> legalHoldDisabled(id, transient, live, eventContentDTO)
is EventContentDTO.FeatureConfig.FeatureConfigUpdatedDTO -> featureConfig(id, eventContentDTO, transient, live)
is EventContentDTO.Unknown -> unknown(id, transient, live, eventContentDTO)
is EventContentDTO.Conversation.AccessUpdate -> unknown(id, transient, live, eventContentDTO)
is EventContentDTO.Conversation.DeletedConversationDTO -> conversationDeleted(id, eventContentDTO, transient, live)
Expand Down Expand Up @@ -355,6 +362,50 @@ class EventMapper(
connectionMapper.fromApiToModel(eventConnectionDTO.connection)
)

private fun legalHoldRequest(
id: String,
transient: Boolean,
live: Boolean,
eventContentDTO: EventContentDTO.User.NewLegalHoldRequestDTO
): Event.User.LegalHoldRequest {
return Event.User.LegalHoldRequest(
transient = transient,
live = live,
id = id,
clientId = ClientId(eventContentDTO.id),
lastPreKey = LastPreKey(eventContentDTO.lastPreKey.id, eventContentDTO.lastPreKey.key),
userId = qualifiedIdMapper.fromStringToQualifiedID(eventContentDTO.id)
)
}

private fun legalHoldEnabled(
id: String,
transient: Boolean,
live: Boolean,
eventContentDTO: EventContentDTO.User.LegalHoldEnabledDTO
): Event.User.LegalHoldEnabled {
return Event.User.LegalHoldEnabled(
transient,
live,
id,
qualifiedIdMapper.fromStringToQualifiedID(eventContentDTO.id)
)
}

private fun legalHoldDisabled(
id: String,
transient: Boolean,
live: Boolean,
eventContentDTO: EventContentDTO.User.LegalHoldDisabledDTO
): Event.User.LegalHoldDisabled {
return Event.User.LegalHoldDisabled(
transient,
live,
id,
qualifiedIdMapper.fromStringToQualifiedID(eventContentDTO.id)
)
}

private fun userDelete(
id: String,
eventUserDelete: EventContentDTO.User.UserDeleteDTO,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Wire
* Copyright (C) 2023 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
package com.wire.kalium.logic.data.legalhold

data class LastPreKey(
val id: Int,
val key: String,
)
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ import com.wire.kalium.logic.data.conversation.ConversationDataSource
import com.wire.kalium.logic.data.conversation.ConversationGroupRepository
import com.wire.kalium.logic.data.conversation.ConversationGroupRepositoryImpl
import com.wire.kalium.logic.data.conversation.ConversationRepository
import com.wire.kalium.logic.data.conversation.JoinExistingMLSConversationUseCase
import com.wire.kalium.logic.data.conversation.JoinExistingMLSConversationUseCaseImpl
import com.wire.kalium.logic.data.conversation.JoinExistingMLSConversationsUseCase
import com.wire.kalium.logic.data.conversation.JoinExistingMLSConversationsUseCaseImpl
import com.wire.kalium.logic.data.conversation.JoinSubconversationUseCase
import com.wire.kalium.logic.data.conversation.JoinSubconversationUseCaseImpl
import com.wire.kalium.logic.data.conversation.LeaveSubconversationUseCase
import com.wire.kalium.logic.data.conversation.LeaveSubconversationUseCaseImpl
import com.wire.kalium.logic.data.conversation.MLSConversationDataSource
import com.wire.kalium.logic.data.conversation.MLSConversationRepository
import com.wire.kalium.logic.data.conversation.NewConversationMembersRepository
Expand Down Expand Up @@ -156,25 +164,21 @@ import com.wire.kalium.logic.feature.call.usecase.ConversationClientsInCallUpdat
import com.wire.kalium.logic.feature.call.usecase.UpdateConversationClientsForCurrentCallUseCase
import com.wire.kalium.logic.feature.call.usecase.UpdateConversationClientsForCurrentCallUseCaseImpl
import com.wire.kalium.logic.feature.client.ClientScope
import com.wire.kalium.logic.feature.client.FetchSelfClientsFromRemoteUseCase
import com.wire.kalium.logic.feature.client.FetchSelfClientsFromRemoteUseCaseImpl
import com.wire.kalium.logic.feature.client.IsAllowedToRegisterMLSClientUseCase
import com.wire.kalium.logic.feature.client.IsAllowedToRegisterMLSClientUseCaseImpl
import com.wire.kalium.logic.feature.client.MLSClientManager
import com.wire.kalium.logic.feature.client.MLSClientManagerImpl
import com.wire.kalium.logic.feature.client.PersistOtherUserClientsUseCase
import com.wire.kalium.logic.feature.client.PersistOtherUserClientsUseCaseImpl
import com.wire.kalium.logic.feature.client.RegisterMLSClientUseCaseImpl
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.ConversationsRecoveryManager
import com.wire.kalium.logic.feature.conversation.ConversationsRecoveryManagerImpl
import com.wire.kalium.logic.data.conversation.JoinExistingMLSConversationUseCase
import com.wire.kalium.logic.data.conversation.JoinExistingMLSConversationUseCaseImpl
import com.wire.kalium.logic.data.conversation.JoinExistingMLSConversationsUseCase
import com.wire.kalium.logic.data.conversation.JoinExistingMLSConversationsUseCaseImpl
import com.wire.kalium.logic.data.conversation.JoinSubconversationUseCase
import com.wire.kalium.logic.data.conversation.JoinSubconversationUseCaseImpl
import com.wire.kalium.logic.data.conversation.LeaveSubconversationUseCase
import com.wire.kalium.logic.data.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.MLSConversationsVerificationStatusesHandler
Expand Down Expand Up @@ -208,9 +212,9 @@ import com.wire.kalium.logic.feature.featureConfig.handler.E2EIConfigHandler
import com.wire.kalium.logic.feature.featureConfig.handler.FileSharingConfigHandler
import com.wire.kalium.logic.feature.featureConfig.handler.GuestRoomConfigHandler
import com.wire.kalium.logic.feature.featureConfig.handler.MLSConfigHandler
import com.wire.kalium.logic.feature.featureConfig.handler.MLSMigrationConfigHandler
import com.wire.kalium.logic.feature.featureConfig.handler.SecondFactorPasswordChallengeConfigHandler
import com.wire.kalium.logic.feature.featureConfig.handler.SelfDeletingMessagesConfigHandler
import com.wire.kalium.logic.feature.featureConfig.handler.MLSMigrationConfigHandler
import com.wire.kalium.logic.feature.keypackage.KeyPackageManager
import com.wire.kalium.logic.feature.keypackage.KeyPackageManagerImpl
import com.wire.kalium.logic.feature.message.AddSystemMessageToAllConversationsUseCase
Expand Down Expand Up @@ -372,6 +376,8 @@ import com.wire.kalium.logic.sync.receiver.handler.MessageTextEditHandlerImpl
import com.wire.kalium.logic.sync.receiver.handler.ReceiptMessageHandlerImpl
import com.wire.kalium.logic.sync.receiver.handler.TypingIndicatorHandler
import com.wire.kalium.logic.sync.receiver.handler.TypingIndicatorHandlerImpl
import com.wire.kalium.logic.sync.receiver.handler.legalhold.LegalHoldHandlerImpl
import com.wire.kalium.logic.sync.receiver.handler.legalhold.LegalHoldRequestHandlerImpl
import com.wire.kalium.logic.sync.slow.RestartSlowSyncProcessForRecoveryUseCase
import com.wire.kalium.logic.sync.slow.RestartSlowSyncProcessForRecoveryUseCaseImpl
import com.wire.kalium.logic.sync.slow.SlowSlowSyncCriteriaProviderImpl
Expand Down Expand Up @@ -1307,6 +1313,31 @@ class UserSessionScope internal constructor(
protocolUpdateEventHandler
)
}
override val coroutineContext: CoroutineContext = SupervisorJob()

private val legalHoldRequestHandler = LegalHoldRequestHandlerImpl(
selfUserId = userId,
userConfigRepository = userConfigRepository
)

private val fetchSelfClientsFromRemote: FetchSelfClientsFromRemoteUseCase
get() = FetchSelfClientsFromRemoteUseCaseImpl(
clientRepository = clientRepository,
provideClientId = clientIdProvider
)
private val persistOtherUserClients: PersistOtherUserClientsUseCase
get() = PersistOtherUserClientsUseCaseImpl(
clientRemoteRepository = clientRemoteRepository,
clientRepository = clientRepository
)

private val legalHoldHandler = LegalHoldHandlerImpl(
selfUserId = userId,
persistOtherUserClients = persistOtherUserClients,
fetchSelfClientsFromRemote = fetchSelfClientsFromRemote,
userConfigRepository = userConfigRepository,
coroutineContext = coroutineContext
)

private val userEventReceiver: UserEventReceiver
get() = UserEventReceiverImpl(
Expand All @@ -1318,7 +1349,9 @@ class UserSessionScope internal constructor(
oneOnOneResolver,
userId,
clientIdProvider,
lazy { conversations.newGroupConversationSystemMessagesCreator }
lazy { conversations.newGroupConversationSystemMessagesCreator },
legalHoldRequestHandler,
legalHoldHandler
)

private val userPropertiesEventReceiver: UserPropertiesEventReceiver
Expand Down Expand Up @@ -1457,9 +1490,7 @@ class UserSessionScope internal constructor(
authenticationScope.secondFactorVerificationRepository,
slowSyncRepository,
cachedClientIdClearer,
updateSupportedProtocolsAndResolveOneOnOnes,
conversationRepository,
persistMessage
updateSupportedProtocolsAndResolveOneOnOnes
)
val conversations: ConversationScope by lazy {
ConversationScope(
Expand Down Expand Up @@ -1712,8 +1743,6 @@ class UserSessionScope internal constructor(
clientRepository, notificationTokenRepository, pushTokenRepository
)

override val coroutineContext: CoroutineContext = SupervisorJob()

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