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: stop handling team member add/removed events #2273

Merged
merged 5 commits into from
Nov 30, 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 @@ -24,8 +24,8 @@ import com.wire.kalium.logger.obfuscateDomain
import com.wire.kalium.logger.obfuscateId
import com.wire.kalium.logic.data.client.Client
import com.wire.kalium.logic.data.conversation.ClientId
import com.wire.kalium.logic.data.conversation.Conversation.Protocol
import com.wire.kalium.logic.data.conversation.Conversation.Member
import com.wire.kalium.logic.data.conversation.Conversation.Protocol
import com.wire.kalium.logic.data.conversation.Conversation.ReceiptMode
import com.wire.kalium.logic.data.conversation.Conversation.TypingIndicatorMode
import com.wire.kalium.logic.data.conversation.MutedConversationStatus
Expand Down Expand Up @@ -446,38 +446,6 @@ sealed class Event(open val id: String, open val transient: Boolean, open val li
)
}

data class MemberJoin(
override val id: String,
override val teamId: String,
override val transient: Boolean,
override val live: Boolean,
val memberId: String,
) : Team(id, teamId, transient, live) {
override fun toLogMap(): Map<String, Any?> = mapOf(
typeKey to "Team.MemberJoin",
idKey to id.obfuscateId(),
teamIdKey to teamId.obfuscateId(),
memberIdKey to memberId.obfuscateId(),
)
}

data class MemberLeave(
override val id: String,
override val transient: Boolean,
override val live: Boolean,
override val teamId: String,
val memberId: String,
val timestampIso: String,
) : Team(id, teamId, transient, live) {
override fun toLogMap(): Map<String, Any?> = mapOf(
typeKey to "Team.MemberLeave",
idKey to id.obfuscateId(),
teamIdKey to teamId.obfuscateId(),
timestampIsoKey to timestampIso,
memberIdKey to memberId.obfuscateId(),
)
}

data class MemberUpdate(
override val id: String,
override val teamId: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,6 @@ class EventMapper(
is EventContentDTO.Conversation.AccessUpdate -> unknown(id, transient, live, eventContentDTO)
is EventContentDTO.Conversation.DeletedConversationDTO -> conversationDeleted(id, eventContentDTO, transient, live)
is EventContentDTO.Conversation.ConversationRenameDTO -> conversationRenamed(id, eventContentDTO, transient, live)
is EventContentDTO.Team.MemberJoin -> teamMemberJoined(id, eventContentDTO, transient, live)
is EventContentDTO.Team.MemberLeave -> teamMemberLeft(id, eventContentDTO, transient, live)
is EventContentDTO.Team.MemberUpdate -> teamMemberUpdate(id, eventContentDTO, transient, live)
is EventContentDTO.Team.Update -> teamUpdate(id, eventContentDTO, transient, live)
is EventContentDTO.User.UpdateDTO -> userUpdate(id, eventContentDTO, transient, live)
Expand Down Expand Up @@ -655,33 +653,6 @@ class EventMapper(
timestampIso = event.time,
)

private fun teamMemberJoined(
id: String,
event: EventContentDTO.Team.MemberJoin,
transient: Boolean,
live: Boolean
) = Event.Team.MemberJoin(
id = id,
teamId = event.teamId,
transient = transient,
live = live,
memberId = event.teamMember.nonQualifiedUserId
)

private fun teamMemberLeft(
id: String,
event: EventContentDTO.Team.MemberLeave,
transient: Boolean,
live: Boolean
) = Event.Team.MemberLeave(
id = id,
teamId = event.teamId,
memberId = event.teamMember.nonQualifiedUserId,
transient = transient,
live = live,
timestampIso = event.time
)

private fun teamMemberUpdate(
id: String,
event: EventContentDTO.Team.MemberUpdate,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import com.wire.kalium.logic.data.id.ConversationId
import com.wire.kalium.logic.data.id.TeamId
import com.wire.kalium.logic.data.service.ServiceMapper
import com.wire.kalium.logic.data.user.UserId
import com.wire.kalium.logic.data.user.UserMapper
import com.wire.kalium.logic.data.user.type.UserEntityTypeMapper
import com.wire.kalium.logic.di.MapperProvider
import com.wire.kalium.logic.functional.Either
Expand All @@ -39,10 +38,7 @@ import com.wire.kalium.logic.wrapApiRequest
import com.wire.kalium.logic.wrapStorageRequest
import com.wire.kalium.network.api.base.authenticated.TeamsApi
import com.wire.kalium.network.api.base.authenticated.notification.EventContentDTO
import com.wire.kalium.network.api.base.authenticated.userDetails.UserDetailsApi
import com.wire.kalium.network.api.base.model.LegalHoldStatusDTO
import com.wire.kalium.network.api.base.model.QualifiedID
import com.wire.kalium.persistence.dao.ConnectionEntity
import com.wire.kalium.persistence.dao.QualifiedIDEntity
import com.wire.kalium.persistence.dao.ServiceDAO
import com.wire.kalium.persistence.dao.TeamDAO
Expand All @@ -57,8 +53,6 @@ interface TeamRepository {
suspend fun getTeam(teamId: TeamId): Flow<Team?>
suspend fun deleteConversation(conversationId: ConversationId, teamId: TeamId): Either<CoreFailure, Unit>
suspend fun updateMemberRole(teamId: String, userId: String, permissionCode: Int?): Either<CoreFailure, Unit>
suspend fun fetchTeamMember(teamId: String, userId: String): Either<CoreFailure, Unit>
suspend fun removeTeamMember(teamId: String, userId: String): Either<CoreFailure, Unit>
suspend fun updateTeam(team: Team): Either<CoreFailure, Unit>
suspend fun syncServices(teamId: TeamId): Either<CoreFailure, Unit>
suspend fun approveLegalHoldRequest(teamId: TeamId, password: String?): Either<CoreFailure, Unit>
Expand All @@ -71,12 +65,10 @@ internal class TeamDataSource(
private val userConfigDAO: UserConfigDAO,
private val teamDAO: TeamDAO,
private val teamsApi: TeamsApi,
private val userDetailsApi: UserDetailsApi,
private val selfUserId: UserId,
private val serviceDAO: ServiceDAO,
private val legalHoldHandler: LegalHoldHandler,
private val legalHoldRequestHandler: LegalHoldRequestHandler,
private val userMapper: UserMapper = MapperProvider.userMapper(),
private val teamMapper: TeamMapper = MapperProvider.teamMapper(),
private val serviceMapper: ServiceMapper = MapperProvider.serviceMapper(),
private val userTypeEntityTypeMapper: UserEntityTypeMapper = MapperProvider.userTypeEntityMapper(),
Expand Down Expand Up @@ -118,34 +110,6 @@ internal class TeamDataSource(
}
}

override suspend fun fetchTeamMember(teamId: String, userId: String): Either<CoreFailure, Unit> {
return wrapApiRequest {
teamsApi.getTeamMember(
teamId = teamId,
userId = userId,
)
}.flatMap { member ->
wrapApiRequest { userDetailsApi.getUserInfo(userId = QualifiedID(userId, selfUserId.domain)) }
.flatMap { userProfileDTO ->
wrapStorageRequest {
val userEntity = userMapper.fromUserProfileDtoToUserEntity(
userProfile = userProfileDTO,
connectionState = ConnectionEntity.State.ACCEPTED,
userTypeEntity = userTypeEntityTypeMapper.teamRoleCodeToUserType(member.permissions?.own)
)
userDAO.upsertUser(userEntity)
userDAO.upsertConnectionStatuses(mapOf(userEntity.id to userEntity.connectionStatus))
}
}
}
}

override suspend fun removeTeamMember(teamId: String, userId: String): Either<CoreFailure, Unit> {
return wrapStorageRequest {
userDAO.markUserAsDeleted(QualifiedIDEntity(userId, selfUserId.domain))
}
}

override suspend fun updateTeam(team: Team): Either<CoreFailure, Unit> {
return wrapStorageRequest {
teamDAO.updateTeam(teamMapper.fromModelToEntity(team))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,10 +221,10 @@ import com.wire.kalium.logic.feature.legalhold.ApproveLegalHoldRequestUseCase
import com.wire.kalium.logic.feature.legalhold.ApproveLegalHoldRequestUseCaseImpl
import com.wire.kalium.logic.feature.legalhold.FetchLegalHoldForSelfUserFromRemoteUseCase
import com.wire.kalium.logic.feature.legalhold.FetchLegalHoldForSelfUserFromRemoteUseCaseImpl
import com.wire.kalium.logic.feature.legalhold.ObserveLegalHoldRequestUseCase
import com.wire.kalium.logic.feature.legalhold.ObserveLegalHoldRequestUseCaseImpl
import com.wire.kalium.logic.feature.legalhold.ObserveLegalHoldForSelfUserUseCase
import com.wire.kalium.logic.feature.legalhold.ObserveLegalHoldForSelfUserUseCaseImpl
import com.wire.kalium.logic.feature.legalhold.ObserveLegalHoldRequestUseCase
import com.wire.kalium.logic.feature.legalhold.ObserveLegalHoldRequestUseCaseImpl
import com.wire.kalium.logic.feature.legalhold.ObserveLegalHoldStateForUserUseCase
import com.wire.kalium.logic.feature.legalhold.ObserveLegalHoldStateForUserUseCaseImpl
import com.wire.kalium.logic.feature.message.AddSystemMessageToAllConversationsUseCase
Expand Down Expand Up @@ -716,7 +716,6 @@ class UserSessionScope internal constructor(
userStorage.database.userConfigDAO,
userStorage.database.teamDAO,
authenticatedNetworkContainer.teamsApi,
authenticatedNetworkContainer.userDetailsApi,
userId,
userStorage.database.serviceDAO,
legalHoldHandler,
Expand Down Expand Up @@ -1402,7 +1401,7 @@ class UserSessionScope internal constructor(
)

private val teamEventReceiver: TeamEventReceiver
get() = TeamEventReceiverImpl(teamRepository, conversationRepository, userRepository, persistMessage, userId)
get() = TeamEventReceiverImpl(teamRepository)

private val guestRoomConfigHandler
get() = GuestRoomConfigHandler(userConfigRepository, kaliumConfigs)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,140 +18,36 @@

package com.wire.kalium.logic.sync.receiver

import com.benasher44.uuid.uuid4
import com.wire.kalium.logic.CoreFailure
import com.wire.kalium.logic.data.conversation.ConversationRepository
import com.wire.kalium.logic.data.event.Event
import com.wire.kalium.logic.data.event.EventLoggingStatus
import com.wire.kalium.logic.data.event.logEventProcessing
import com.wire.kalium.logic.data.message.Message
import com.wire.kalium.logic.data.message.MessageContent
import com.wire.kalium.logic.data.message.PersistMessageUseCase
import com.wire.kalium.logic.data.team.Team
import com.wire.kalium.logic.data.team.TeamRepository
import com.wire.kalium.logic.data.user.UserId
import com.wire.kalium.logic.data.user.UserRepository
import com.wire.kalium.logic.functional.Either
import com.wire.kalium.logic.functional.onFailure
import com.wire.kalium.logic.functional.onSuccess
import com.wire.kalium.logic.kaliumLogger
import kotlinx.coroutines.flow.first

internal interface TeamEventReceiver : EventReceiver<Event.Team>

internal class TeamEventReceiverImpl(
private val teamRepository: TeamRepository,
private val conversationRepository: ConversationRepository,
private val userRepository: UserRepository,
private val persistMessage: PersistMessageUseCase,
private val selfUserId: UserId,
private val teamRepository: TeamRepository

) : TeamEventReceiver {

override suspend fun onEvent(event: Event.Team): Either<CoreFailure, Unit> {
when (event) {
is Event.Team.MemberJoin -> handleMemberJoin(event)
is Event.Team.MemberLeave -> handleMemberLeave(event)
is Event.Team.MemberUpdate -> handleMemberUpdate(event)
is Event.Team.Update -> handleUpdate(event)
}
// TODO: Make sure errors are accounted for by each handler.
// onEvent now requires Either, so we can propagate errors,
// but not all handlers are using it yet.
// but not all handlers are using it yet.®
// Returning Either.Right is the equivalent of how it was originally working.
return Either.Right(Unit)
}

private suspend fun handleMemberJoin(event: Event.Team.MemberJoin) =
teamRepository.fetchTeamMember(
teamId = event.teamId,
userId = event.memberId,
)
.onSuccess {
kaliumLogger
.logEventProcessing(
EventLoggingStatus.SUCCESS,
event
)
}
.onFailure {
kaliumLogger
.logEventProcessing(
EventLoggingStatus.FAILURE,
event,
Pair("errorInfo", "$it")
)
}

@Suppress("LongMethod")
private suspend fun handleMemberLeave(event: Event.Team.MemberLeave) {
val userId = UserId(event.memberId, selfUserId.domain)
teamRepository.removeTeamMember(
teamId = event.teamId,
userId = event.memberId,
)
.onSuccess {
val knownUser = userRepository.getKnownUser(userId).first()
if (knownUser?.name != null) {
conversationRepository.getConversationsByUserId(userId)
.onSuccess {
it.forEach { conversation ->
val message = Message.System(
id = uuid4().toString(), // We generate a random uuid for this new system message
content = MessageContent.TeamMemberRemoved(knownUser.name),
conversationId = conversation.id,
date = event.timestampIso,
senderUserId = userId,
status = Message.Status.Sent,
visibility = Message.Visibility.VISIBLE,
expirationData = null
)
persistMessage(message)
}

conversationRepository.deleteUserFromConversations(userId)
.onSuccess {
kaliumLogger
.logEventProcessing(
EventLoggingStatus.SUCCESS,
event
)
}
.onFailure { deleteFailure ->
kaliumLogger
.logEventProcessing(
EventLoggingStatus.FAILURE,
event,
Pair("errorInfo", "$deleteFailure")
)
}

}.onFailure {
kaliumLogger
.logEventProcessing(
EventLoggingStatus.FAILURE,
event,
Pair("errorInfo", "$it")
)
}
} else {
kaliumLogger
.logEventProcessing(
EventLoggingStatus.SKIPPED,
event,
Pair("info", "User or User name is null")
)
}
}
.onFailure {
kaliumLogger
.logEventProcessing(
EventLoggingStatus.FAILURE,
event,
Pair("errorInfo", "$it")
)
}
}

private suspend fun handleMemberUpdate(event: Event.Team.MemberUpdate) =
teamRepository.updateMemberRole(
teamId = event.teamId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,8 @@ internal class UserEventReceiverImpl internal constructor(
logout(LogoutReason.DELETED_ACCOUNT)
Either.Right(Unit)
} else {
// TODO: those 2 steps must be done in one transaction
// userRepo.markAsDeleted(event.userId) will mark user as deleted and remove from the group conversations
userRepository.removeUser(event.userId)
.onSuccess {
conversationRepository.deleteUserFromConversations(event.userId)
Expand Down
Loading
Loading