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

fix: asset restriction [WPB-9947] (#2831) (#2856) (#2862) (#3157) #3170

Merged
merged 5 commits into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
3 changes: 2 additions & 1 deletion app/src/main/kotlin/com/wire/android/ui/WireActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ import com.wire.android.ui.home.E2EICertificateRevokedDialog
import com.wire.android.ui.home.E2EIRequiredDialog
import com.wire.android.ui.home.E2EIResultDialog
import com.wire.android.ui.home.E2EISnoozeDialog
import com.wire.android.ui.home.FeatureFlagState
import com.wire.android.ui.home.appLock.LockCodeTimeManager
import com.wire.android.ui.home.sync.FeatureFlagNotificationViewModel
import com.wire.android.ui.legalhold.dialog.deactivated.LegalHoldDeactivatedDialog
Expand Down Expand Up @@ -377,7 +378,7 @@ class WireActivity : AppCompatActivity() {
}
if (showFileSharingDialog) {
FileRestrictionDialog(
isFileSharingEnabled = isFileSharingEnabledState,
isFileSharingEnabled = (isFileSharingState !is FeatureFlagState.FileSharingState.DisabledByTeam),
hideDialogStatus = featureFlagNotificationViewModel::dismissFileSharingDialog
)
}
Expand Down
22 changes: 18 additions & 4 deletions app/src/main/kotlin/com/wire/android/ui/home/FeatureFlagState.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@
package com.wire.android.ui.home

import com.wire.android.ui.home.messagecomposer.SelfDeletionDuration
import com.wire.kalium.logic.configuration.FileSharingStatus
import kotlin.time.Duration

data class FeatureFlagState(
val showFileSharingDialog: Boolean = false,
val isFileSharingEnabledState: Boolean = true,
val fileSharingRestrictedState: SharingRestrictedState? = null,
val isFileSharingState: FileSharingState = FileSharingState.NoUser,
val shouldShowGuestRoomLinkDialog: Boolean = false,
val shouldShowE2eiCertificateRevokedDialog: Boolean = false,
val shouldShowTeamAppLockDialog: Boolean = false,
Expand All @@ -40,8 +40,12 @@ data class FeatureFlagState(
val showCallEndedBecauseOfConversationDegraded: Boolean = false,
val startGettingE2EICertificate: Boolean = false
) {
enum class SharingRestrictedState {
NONE, NO_USER, RESTRICTED_IN_TEAM

sealed interface FileSharingState {
data object NoUser : FileSharingState
data object AllowAll : FileSharingState
data class AllowSome(val allowedList: List<String>) : FileSharingState
data object DisabledByTeam : FileSharingState
}

data class E2EISnooze(val timeLeft: Duration)
Expand All @@ -64,3 +68,13 @@ data class FeatureFlagState(
data class Success(val certificate: String) : E2EIResult()
}
}

fun FileSharingStatus.Value.toFeatureFlagState(): FeatureFlagState.FileSharingState {
return when (this) {
FileSharingStatus.Value.Disabled -> FeatureFlagState.FileSharingState.DisabledByTeam
FileSharingStatus.Value.EnabledAll -> FeatureFlagState.FileSharingState.AllowAll
is FileSharingStatus.Value.EnabledSome -> FeatureFlagState.FileSharingState.AllowSome(
allowedType
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@ import com.wire.android.model.SnackBarMessage
import com.wire.android.util.ui.UIText

sealed class ConversationSnackbarMessages(override val uiText: UIText) : SnackBarMessage {
object ErrorPickingAttachment : ConversationSnackbarMessages(UIText.StringResource(R.string.error_conversation_generic))
object ErrorSendingAsset : ConversationSnackbarMessages(UIText.StringResource(R.string.error_conversation_sending_asset))
object ErrorSendingImage : ConversationSnackbarMessages(UIText.StringResource(R.string.error_conversation_sending_image))
object ErrorDownloadingAsset : ConversationSnackbarMessages(UIText.StringResource(R.string.error_conversation_downloading_asset))
object ErrorOpeningAssetFile : ConversationSnackbarMessages(UIText.StringResource(R.string.error_conversation_opening_asset_file))
object ErrorDeletingMessage : ConversationSnackbarMessages(UIText.StringResource(R.string.error_conversation_deleting_message))
data object ErrorPickingAttachment : ConversationSnackbarMessages(UIText.StringResource(R.string.error_conversation_generic))
data object ErrorSendingAsset : ConversationSnackbarMessages(UIText.StringResource(R.string.error_conversation_sending_asset))
data object ErrorSendingImage : ConversationSnackbarMessages(UIText.StringResource(R.string.error_conversation_sending_image))
data object ErrorDownloadingAsset : ConversationSnackbarMessages(UIText.StringResource(R.string.error_conversation_downloading_asset))
data object ErrorOpeningAssetFile : ConversationSnackbarMessages(UIText.StringResource(R.string.error_conversation_opening_asset_file))
data object ErrorDeletingMessage : ConversationSnackbarMessages(UIText.StringResource(R.string.error_conversation_deleting_message))
data object ErrorAssetRestriction : ConversationSnackbarMessages(UIText.StringResource(R.string.restricted_asset_error_toast_message))
data class ErrorMaxAssetSize(val maxLimitInMB: Int) :
ConversationSnackbarMessages(UIText.StringResource(R.string.error_conversation_max_asset_size_limit, maxLimitInMB))

Expand All @@ -42,6 +43,6 @@ sealed class MediaGallerySnackbarMessages(override val uiText: UIText) : SnackBa
class OnImageDownloaded(val assetName: String? = null) :
MediaGallerySnackbarMessages(UIText.StringResource(R.string.media_gallery_on_image_downloaded, assetName ?: ""))

object OnImageDownloadError : MediaGallerySnackbarMessages(UIText.StringResource(R.string.media_gallery_on_image_download_error))
object DeletingMessageError : MediaGallerySnackbarMessages(UIText.StringResource(R.string.error_conversation_deleting_message))
data object OnImageDownloadError : MediaGallerySnackbarMessages(UIText.StringResource(R.string.media_gallery_on_image_download_error))
data object DeletingMessageError : MediaGallerySnackbarMessages(UIText.StringResource(R.string.error_conversation_deleting_message))
}
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ class MessageComposerViewModel @Inject constructor(
}
}
}

else -> flowOf(InteractionAvailability.DISABLED)
}
}
Expand Down Expand Up @@ -167,13 +168,12 @@ class MessageComposerViewModel @Inject constructor(
}

private fun setFileSharingStatus() {
// TODO: handle restriction when sending assets
viewModelScope.launch {
messageComposerViewState.value = when (isFileSharingEnabled().state) {
FileSharingStatus.Value.Disabled,
is FileSharingStatus.Value.EnabledSome ->
FileSharingStatus.Value.Disabled ->
messageComposerViewState.value.copy(isFileSharingEnabled = false)

is FileSharingStatus.Value.EnabledSome,
FileSharingStatus.Value.EnabledAll ->
messageComposerViewState.value.copy(isFileSharingEnabled = true)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -338,18 +338,29 @@ class SendMessageViewModel @Inject constructor(
}
}

private fun Either<CoreFailure, Unit>.handleLegalHoldFailureAfterSendingMessage(conversationId: ConversationId) =
private fun Either<CoreFailure, Unit>.handleLegalHoldFailureAfterSendingMessage(
conversationId: ConversationId
): Either<CoreFailure, Unit> =
onFailure { it.handleLegalHoldFailureAfterSendingMessage(conversationId) }

private fun ScheduleNewAssetMessageResult.handleLegalHoldFailureAfterSendingMessage(conversationId: ConversationId) = let {
if (it is ScheduleNewAssetMessageResult.Failure) {
it.coreFailure.handleLegalHoldFailureAfterSendingMessage(conversationId)
}
when (this) {
is ScheduleNewAssetMessageResult.Failure -> Either.Left(coreFailure)
is ScheduleNewAssetMessageResult.Success -> Either.Right(Unit)
private fun ScheduleNewAssetMessageResult.handleLegalHoldFailureAfterSendingMessage(
conversationId: ConversationId
): Either<CoreFailure?, Unit> =
let {
when (this) {
is ScheduleNewAssetMessageResult.Success -> Either.Right(Unit)
ScheduleNewAssetMessageResult.Failure.DisabledByTeam,
ScheduleNewAssetMessageResult.Failure.RestrictedFileType -> {
onSnackbarMessage(ConversationSnackbarMessages.ErrorAssetRestriction)
Either.Left(null)
}

is ScheduleNewAssetMessageResult.Failure.Generic -> {
this.coreFailure.handleLegalHoldFailureAfterSendingMessage(conversationId)
Either.Left(coreFailure)
}
}
}
}

fun retrySendingMessages(messageIdList: List<String>, conversationId: ConversationId) {
messageIdList.forEach {
Expand Down Expand Up @@ -402,7 +413,6 @@ class SendMessageViewModel @Inject constructor(
}
sureAboutMessagingDialogState = SureAboutMessagingDialogState.Hidden
}

private companion object {
const val MAX_LIMIT_MESSAGE_SEND = 20
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,11 @@ class IsFileSharingEnabledViewModelImpl @Inject constructor(
getIsFileSharingEnabled()
}

// TODO: handle restriction when sending assets
private fun getIsFileSharingEnabled() = viewModelScope.launch {
state = when (isFileSharingEnabledUseCase().state) {
FileSharingStatus.Value.Disabled,
is FileSharingStatus.Value.EnabledSome -> false
FileSharingStatus.Value.EnabledAll -> true
FileSharingStatus.Value.Disabled -> false
FileSharingStatus.Value.EnabledAll,
is FileSharingStatus.Value.EnabledSome -> true
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ import com.wire.android.feature.DisableAppLockUseCase
import com.wire.android.ui.home.FeatureFlagState
import com.wire.android.ui.home.conversations.selfdeletion.SelfDeletionMapper.toSelfDeletionDuration
import com.wire.android.ui.home.messagecomposer.SelfDeletionDuration
import com.wire.android.ui.home.toFeatureFlagState
import com.wire.kalium.logic.CoreFailure
import com.wire.kalium.logic.CoreLogic
import com.wire.kalium.logic.configuration.FileSharingStatus
import com.wire.kalium.logic.data.message.TeamSelfDeleteTimer
import com.wire.kalium.logic.data.sync.SyncState
import com.wire.kalium.logic.data.user.UserId
Expand Down Expand Up @@ -87,14 +87,14 @@ class FeatureFlagNotificationViewModel @Inject constructor(
currentUserId = null
appLogger.i("$TAG: Failure while getting current session")
featureFlagState = FeatureFlagState( // no session, clear feature flag state to default and set NO_USER
fileSharingRestrictedState = FeatureFlagState.SharingRestrictedState.NO_USER
isFileSharingState = FeatureFlagState.FileSharingState.NoUser
)
}

currentSessionResult is CurrentSessionResult.Success && !currentSessionResult.accountInfo.isValid() -> {
appLogger.i("$TAG: Invalid current session")
featureFlagState = FeatureFlagState( // invalid session, clear feature flag state to default and set NO_USER
fileSharingRestrictedState = FeatureFlagState.SharingRestrictedState.NO_USER
isFileSharingState = FeatureFlagState.FileSharingState.NoUser
)
}

Expand Down Expand Up @@ -132,22 +132,11 @@ class FeatureFlagNotificationViewModel @Inject constructor(

private suspend fun setFileSharingState(userId: UserId) {
coreLogic.getSessionScope(userId).observeFileSharingStatus().collect { fileSharingStatus ->
fileSharingStatus.state.let {
// TODO: handle restriction when sending assets
val (fileSharingRestrictedState, state) = if (it is FileSharingStatus.Value.EnabledAll) {
FeatureFlagState.SharingRestrictedState.NONE to true
} else {
FeatureFlagState.SharingRestrictedState.RESTRICTED_IN_TEAM to false
}

featureFlagState = featureFlagState.copy(
fileSharingRestrictedState = fileSharingRestrictedState,
isFileSharingEnabledState = state
)
}
fileSharingStatus.isStatusChanged?.let {
featureFlagState = featureFlagState.copy(showFileSharingDialog = it)
}
val state: FeatureFlagState.FileSharingState = fileSharingStatus.state.toFeatureFlagState()
featureFlagState = featureFlagState.copy(
isFileSharingState = state,
showFileSharingDialog = fileSharingStatus.isStatusChanged ?: false
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ import com.wire.android.util.ui.PreviewMultipleThemes
@Destination
@Composable
fun AboutThisAppScreen(
viewModel: AboutThisAppViewModel = hiltViewModel(),
navigator: Navigator
navigator: Navigator,
viewModel: AboutThisAppViewModel = hiltViewModel()
) {
val context = LocalContext.current
AboutThisAppContent(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import com.wire.android.mapper.toUIPreview
import com.wire.android.model.ImageAsset
import com.wire.android.model.SnackBarMessage
import com.wire.android.model.UserAvatarData
import com.wire.android.ui.home.conversations.ConversationSnackbarMessages
import com.wire.android.ui.common.textfield.textAsFlow
import com.wire.android.ui.home.conversations.search.DEFAULT_SEARCH_QUERY_DEBOUNCE
import com.wire.android.ui.home.conversations.usecase.HandleUriAssetUseCase
Expand All @@ -54,6 +55,7 @@ import com.wire.kalium.logic.data.conversation.ConversationDetails
import com.wire.kalium.logic.data.id.ConversationId
import com.wire.kalium.logic.data.message.SelfDeletionTimer
import com.wire.kalium.logic.data.message.SelfDeletionTimer.Companion.SELF_DELETION_LOG_TAG
import com.wire.kalium.logic.feature.asset.ScheduleNewAssetMessageResult
import com.wire.kalium.logic.feature.conversation.ObserveConversationListDetailsUseCase
import com.wire.kalium.logic.feature.selfDeletingMessages.ObserveSelfDeletionTimerSettingsForConversationUseCase
import com.wire.kalium.logic.feature.selfDeletingMessages.PersistNewSelfDeletionTimerUseCase
Expand Down Expand Up @@ -301,6 +303,27 @@ class ImportMediaAuthenticatedViewModel @Inject constructor(
}
}

private fun handleError(result: ScheduleNewAssetMessageResult, conversationId: ConversationId) {
when (result) {
is ScheduleNewAssetMessageResult.Success -> appLogger.d(
"Successfully imported asset message to conversationId=${conversationId.toLogString()}"
)

is ScheduleNewAssetMessageResult.Failure.Generic ->
appLogger.e(
"Failed to import asset message to conversationId=${conversationId.toLogString()}"
)

ScheduleNewAssetMessageResult.Failure.RestrictedFileType,
ScheduleNewAssetMessageResult.Failure.DisabledByTeam -> {
onSnackbarMessage(ConversationSnackbarMessages.ErrorAssetRestriction)
appLogger.e(
"Failed to import asset message to conversationId=${conversationId.toLogString()}"
)
}
}
}

fun onNewConversationPicked(conversationId: ConversationId) = viewModelScope.launch {
importMediaState = importMediaState.copy(
selfDeletingTimer = observeSelfDeletionSettingsForConversation(
Expand Down Expand Up @@ -342,7 +365,7 @@ class ImportMediaAuthenticatedViewModel @Inject constructor(
}
}

fun onSnackbarMessage(type: SnackBarMessage) = viewModelScope.launch {
private fun onSnackbarMessage(type: SnackBarMessage) = viewModelScope.launch {
_infoMessage.emit(type)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,8 @@ fun ImportMediaScreen(
navigator: Navigator,
featureFlagNotificationViewModel: FeatureFlagNotificationViewModel = hiltViewModel(),
) {
when (val fileSharingRestrictedState =
featureFlagNotificationViewModel.featureFlagState.fileSharingRestrictedState) {
FeatureFlagState.SharingRestrictedState.NO_USER -> {
when (val fileSharingRestrictedState = featureFlagNotificationViewModel.featureFlagState.isFileSharingState) {
FeatureFlagState.FileSharingState.NoUser -> {
ImportMediaLoggedOutContent(
fileSharingRestrictedState = fileSharingRestrictedState,
navigateBack = navigator.finish,
Expand All @@ -122,17 +121,14 @@ fun ImportMediaScreen(
)
}

FeatureFlagState.SharingRestrictedState.RESTRICTED_IN_TEAM,
FeatureFlagState.SharingRestrictedState.NONE -> {
FeatureFlagState.FileSharingState.DisabledByTeam,
FeatureFlagState.FileSharingState.AllowAll,
is FeatureFlagState.FileSharingState.AllowSome -> {
ImportMediaAuthenticatedContent(
navigator = navigator,
isRestrictedInTeam = fileSharingRestrictedState == FeatureFlagState.SharingRestrictedState.RESTRICTED_IN_TEAM,
isRestrictedInTeam = fileSharingRestrictedState == FeatureFlagState.FileSharingState.DisabledByTeam,
)
}

null -> {
// state is not calculated yet, need to wait to avoid crash while requesting currentUser where it's absent
}
}

BackHandler { navigator.finish() }
Expand Down Expand Up @@ -221,7 +217,7 @@ fun ImportMediaRestrictedContent(
content = { internalPadding ->
FileSharingRestrictedContent(
internalPadding,
FeatureFlagState.SharingRestrictedState.RESTRICTED_IN_TEAM,
FeatureFlagState.FileSharingState.DisabledByTeam,
navigateBack
)
}
Expand Down Expand Up @@ -294,7 +290,7 @@ fun ImportMediaRegularContent(

@Composable
fun ImportMediaLoggedOutContent(
fileSharingRestrictedState: FeatureFlagState.SharingRestrictedState,
fileSharingRestrictedState: FeatureFlagState.FileSharingState,
navigateBack: () -> Unit,
openWireAction: () -> Unit,
modifier: Modifier = Modifier
Expand Down Expand Up @@ -322,7 +318,7 @@ fun ImportMediaLoggedOutContent(
@Composable
fun FileSharingRestrictedContent(
internalPadding: PaddingValues,
sharingRestrictedState: FeatureFlagState.SharingRestrictedState,
sharingRestrictedState: FeatureFlagState.FileSharingState,
openWireAction: () -> Unit,
modifier: Modifier = Modifier
) {
Expand All @@ -338,7 +334,7 @@ fun FileSharingRestrictedContent(
.padding(horizontal = dimensions().spacing48x)
) {
val textRes =
if (sharingRestrictedState == FeatureFlagState.SharingRestrictedState.NO_USER) {
if (sharingRestrictedState == FeatureFlagState.FileSharingState.NoUser) {
R.string.file_sharing_restricted_description_no_users
} else {
R.string.file_sharing_restricted_description_by_team
Expand All @@ -352,7 +348,7 @@ fun FileSharingRestrictedContent(

Spacer(modifier = Modifier.height(dimensions().spacing16x))

if (sharingRestrictedState == FeatureFlagState.SharingRestrictedState.NO_USER) {
if (sharingRestrictedState == FeatureFlagState.FileSharingState.NoUser) {
WirePrimaryButton(
onClick = openWireAction,
text = stringResource(R.string.file_sharing_restricted_button_text_no_users),
Expand Down Expand Up @@ -541,7 +537,7 @@ private fun SnackBarMessage(
fun PreviewImportMediaScreenLoggedOut() {
WireTheme {
ImportMediaLoggedOutContent(
fileSharingRestrictedState = FeatureFlagState.SharingRestrictedState.NO_USER,
fileSharingRestrictedState = FeatureFlagState.FileSharingState.NoUser,
navigateBack = {},
openWireAction = {},
)
Expand Down
Loading
Loading