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: add use case to decide if a user can create password protected invite links [WPB-1531] #1950

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 @@ -317,10 +317,20 @@ class ServerConfigMapperImpl(
)
}

sealed class CommonApiVersionType(open val version: Int) {
object New : CommonApiVersionType(NEW_API_VERSION_NUMBER)
object Unknown : CommonApiVersionType(UNKNOWN_API_VERSION_NUMBER)
data class Valid(override val version: Int) : CommonApiVersionType(version)
sealed interface CommonApiVersionType {
val version: Int

data object New : CommonApiVersionType {
override val version: Int
get() = NEW_API_VERSION_NUMBER
}

data object Unknown : CommonApiVersionType {
override val version: Int
get() = UNKNOWN_API_VERSION_NUMBER
}
Comment on lines +323 to +331
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice!


data class Valid(override val version: Int) : CommonApiVersionType

companion object {
const val NEW_API_VERSION_NUMBER = -1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1203,7 +1203,6 @@ class UserSessionScope internal constructor(
syncManager,
mlsConversationRepository,
clientIdProvider,
assetRepository,
messages.messageSender,
teamRepository,
userId,
Expand All @@ -1215,6 +1214,7 @@ class UserSessionScope internal constructor(
renamedConversationHandler,
qualifiedIdMapper,
team.isSelfATeamMember,
globalScope.serverConfigRepository,
this
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
package com.wire.kalium.logic.feature.conversation

import com.wire.kalium.logic.cache.SelfConversationIdProvider
import com.wire.kalium.logic.data.asset.AssetRepository
import com.wire.kalium.logic.configuration.server.ServerConfigRepository
import com.wire.kalium.logic.data.connection.ConnectionRepository
import com.wire.kalium.logic.data.conversation.ConversationGroupRepository
import com.wire.kalium.logic.data.conversation.ConversationRepository
Expand All @@ -38,6 +38,7 @@ import com.wire.kalium.logic.feature.connection.MarkConnectionRequestAsNotifiedU
import com.wire.kalium.logic.feature.connection.MarkConnectionRequestAsNotifiedUseCaseImpl
import com.wire.kalium.logic.feature.connection.ObserveConnectionListUseCase
import com.wire.kalium.logic.feature.connection.ObserveConnectionListUseCaseImpl
import com.wire.kalium.logic.feature.conversation.guestroomlink.CanCreatePasswordProtectedLinksUseCase
import com.wire.kalium.logic.feature.conversation.guestroomlink.GenerateGuestRoomLinkUseCase
import com.wire.kalium.logic.feature.conversation.guestroomlink.GenerateGuestRoomLinkUseCaseImpl
import com.wire.kalium.logic.feature.conversation.guestroomlink.ObserveGuestRoomLinkUseCase
Expand Down Expand Up @@ -68,7 +69,6 @@ class ConversationScope internal constructor(
private val syncManager: SyncManager,
private val mlsConversationRepository: MLSConversationRepository,
private val currentClientIdProvider: CurrentClientIdProvider,
private val assetRepository: AssetRepository,
private val messageSender: MessageSender,
private val teamRepository: TeamRepository,
private val selfUserId: UserId,
Expand All @@ -80,6 +80,7 @@ class ConversationScope internal constructor(
private val renamedConversationHandler: RenamedConversationEventHandler,
private val qualifiedIdMapper: QualifiedIdMapper,
private val isSelfATeamMember: IsSelfATeamMemberUseCase,
private val serverConfigRepository: ServerConfigRepository,
private val scope: CoroutineScope
) {

Expand Down Expand Up @@ -239,4 +240,10 @@ class ConversationScope internal constructor(
get() = RefreshConversationsWithoutMetadataUseCaseImpl(
conversationRepository = conversationRepository
)

val canCreatePasswordProtectedLinks: CanCreatePasswordProtectedLinksUseCase
get() = CanCreatePasswordProtectedLinksUseCase(
serverConfigRepository,
selfUserId
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* 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.feature.conversation.guestroomlink

import com.wire.kalium.logic.configuration.server.ServerConfigRepository
import com.wire.kalium.logic.data.user.UserId
import com.wire.kalium.logic.functional.fold

/**
* Use case to check if the current user can create password protected invite links.
* This is only possible if the server api version is greater or equal to 4.
*/
class CanCreatePasswordProtectedLinksUseCase internal constructor(
private val serverConfigRepository: ServerConfigRepository,
private val selfUserId: UserId
) {
suspend operator fun invoke(): Boolean =
serverConfigRepository.configForUser(selfUserId).fold(
{ false },
{
it.metaData.commonApiVersion.version >= MIN_API_TO_SUPPORT_PASSWORD_LINKS
}
)

private companion object {
const val MIN_API_TO_SUPPORT_PASSWORD_LINKS = 4
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* 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.feature.conversation.guestroomlink

import com.wire.kalium.logic.configuration.server.CommonApiVersionType
import com.wire.kalium.logic.data.user.UserId
import com.wire.kalium.logic.functional.Either
import com.wire.kalium.logic.util.arrangement.repository.ServerConfigRepositoryArrangement
import com.wire.kalium.logic.util.arrangement.repository.ServerConfigRepositoryArrangementImpl
import com.wire.kalium.logic.util.stubs.newServerConfig
import io.mockative.eq
import io.mockative.once
import io.mockative.verify
import kotlinx.coroutines.test.runTest
import kotlin.test.Test
import kotlin.test.assertFalse
import kotlin.test.assertTrue

class CanCreatePasswordProtectedLinksUseCaseTest {

@Test
fun givenApiIs4_whenInvokingUseCase_thenReturnTrue() = runTest {
val expected = newServerConfig(1).let {
it.copy(metaData = it.metaData.copy(commonApiVersion = CommonApiVersionType.Valid(4)))
}
val (arrangement, useCase) = Arrangement().arrange {
withServerConfigForUser(Either.Right(expected))
}

useCase().also {
assertTrue(it)
}

verify(arrangement.serverConfigRepository)
.suspendFunction(arrangement.serverConfigRepository::configForUser)
.with(eq(SELF_USER_ID))
.wasInvoked(exactly = once)
}

@Test
fun givenApiIsGraterThan4_whenInvokingUseCase_thenReturnTrue() = runTest {
val expected = newServerConfig(1).let {
it.copy(metaData = it.metaData.copy(commonApiVersion = CommonApiVersionType.Valid(5)))
}
val (arrangement, useCase) = Arrangement().arrange {
withServerConfigForUser(Either.Right(expected))
}

useCase().also {
assertTrue(it)
}

verify(arrangement.serverConfigRepository)
.suspendFunction(arrangement.serverConfigRepository::configForUser)
.with(eq(SELF_USER_ID))
.wasInvoked(exactly = once)
}

@Test
fun givenApiIsLessThan4_whenInvokingUseCase_thenReturnFalse() = runTest {
val expected = newServerConfig(1).let {
it.copy(metaData = it.metaData.copy(commonApiVersion = CommonApiVersionType.Valid(3)))
}
val (arrangement, useCase) = Arrangement().arrange {
withServerConfigForUser(Either.Right(expected))
}

useCase().also {
assertFalse(it)
}

verify(arrangement.serverConfigRepository)
.suspendFunction(arrangement.serverConfigRepository::configForUser)
.with(eq(SELF_USER_ID))
.wasInvoked(exactly = once)
}

private companion object {
val SELF_USER_ID = UserId("selfUser", "domain")
}
private class Arrangement : ServerConfigRepositoryArrangement by ServerConfigRepositoryArrangementImpl() {

private val useCase: CanCreatePasswordProtectedLinksUseCase = CanCreatePasswordProtectedLinksUseCase(
serverConfigRepository,
SELF_USER_ID
)

fun arrange(block: Arrangement.() -> Unit): Pair<Arrangement, CanCreatePasswordProtectedLinksUseCase> {
apply(block)
return this to useCase
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* 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.util.arrangement.repository

import com.wire.kalium.logic.StorageFailure
import com.wire.kalium.logic.configuration.server.ServerConfig
import com.wire.kalium.logic.configuration.server.ServerConfigRepository
import com.wire.kalium.logic.data.user.UserId
import com.wire.kalium.logic.functional.Either
import io.mockative.Mock
import io.mockative.any
import io.mockative.given
import io.mockative.matchers.Matcher
import io.mockative.mock

internal interface ServerConfigRepositoryArrangement {
@Mock
val serverConfigRepository: ServerConfigRepository

fun withServerConfigForUser(
result: Either<StorageFailure, ServerConfig>,
userId: Matcher<UserId> = any()
) {
given(serverConfigRepository)
.suspendFunction(serverConfigRepository::configForUser)
.whenInvokedWith(userId)
.then { result }
}
}

internal class ServerConfigRepositoryArrangementImpl : ServerConfigRepositoryArrangement {

@Mock
override val serverConfigRepository: ServerConfigRepository = mock(ServerConfigRepository::class)
}
Loading