Skip to content

Commit

Permalink
refactor: implement UpdateApiVersionsUseCaseImpl to be proxy safe
Browse files Browse the repository at this point in the history
  • Loading branch information
MohamadJaara committed Jan 26, 2024
1 parent 27f3e8e commit affdf27
Show file tree
Hide file tree
Showing 13 changed files with 444 additions and 194 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,20 @@ class GlobalKaliumScope internal constructor(

val session: SessionScope get() = SessionScope(sessionRepository)
val fetchServerConfigFromDeepLink: GetServerConfigUseCase get() = GetServerConfigUseCase(customServerConfigRepository)
val updateApiVersions: UpdateApiVersionsUseCase get() = UpdateApiVersionsUseCaseImpl()
val updateApiVersions: UpdateApiVersionsUseCase
get() = UpdateApiVersionsUseCaseImpl(
sessionRepository,
globalPreferences.authTokenStorage,
{ serverConfig, proxyCredentials ->
authenticationScopeProvider.provide(
serverConfig,
proxyCredentials,
networkStateObserver,
globalDatabase,
kaliumConfigs
).serverConfigRepository
},
)
val storeServerConfig: StoreServerConfigUseCase get() = StoreServerConfigUseCaseImpl(customServerConfigRepository)

val saveNotificationToken: SaveNotificationTokenUseCase
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

package com.wire.kalium.logic.configuration.server

import com.wire.kalium.logic.data.id.IdMapper
import com.wire.kalium.logic.data.id.toModel
import com.wire.kalium.logic.data.user.UserId
import com.wire.kalium.network.tools.ApiVersionDTO
Expand Down Expand Up @@ -163,8 +162,7 @@ interface ServerConfigMapper {
}

class ServerConfigMapperImpl(
private val apiVersionMapper: ApiVersionMapper,
private val idMapper: IdMapper
private val apiVersionMapper: ApiVersionMapper
) : ServerConfigMapper {
override fun toDTO(serverConfig: ServerConfig): ServerConfigDTO = with(serverConfig) {
ServerConfigDTO(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,28 +37,9 @@ import com.wire.kalium.persistence.daokaliumdb.ServerConfigurationDAO
import com.wire.kalium.util.KaliumDispatcher
import com.wire.kalium.util.KaliumDispatcherImpl
import io.ktor.http.Url
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.withContext

@Suppress("TooManyFunctions")
internal interface ServerConfigRepository {

/**
* @return list of all locally stored server configurations
*/
suspend fun configList(): Either<StorageFailure, List<ServerConfig>>

/**
* @return observable list of all locally stored server configurations
*/
suspend fun configFlow(): Either<StorageFailure, Flow<List<ServerConfig>>>

/**
* delete a locally stored server configuration
*/
suspend fun deleteById(id: String): Either<StorageFailure, Unit>
suspend fun delete(serverConfig: ServerConfig): Either<StorageFailure, Unit>
suspend fun getOrFetchMetadata(serverLinks: ServerConfig.Links): Either<CoreFailure, ServerConfig>
suspend fun storeConfig(links: ServerConfig.Links, metadata: ServerConfig.MetaData): Either<StorageFailure, ServerConfig>

Expand All @@ -72,20 +53,10 @@ internal interface ServerConfigRepository {
*/
suspend fun fetchApiVersionAndStore(links: ServerConfig.Links): Either<CoreFailure, ServerConfig>

/**
* retrieve a config from the local DB by ID
*/
fun configById(id: String): Either<StorageFailure, ServerConfig>

/**
* retrieve a config from the local DB by Links
*/
suspend fun configByLinks(links: ServerConfig.Links): Either<StorageFailure, ServerConfig>

/**
* update the api version of a locally stored config
*/
suspend fun updateConfigApiVersion(id: String): Either<CoreFailure, Unit>
suspend fun updateConfigApiVersion(serverConfig: ServerConfig): Either<CoreFailure, Unit>

/**
* Return the server links and metadata for the given userId
Expand All @@ -101,15 +72,6 @@ internal class ServerConfigDataSource(
private val dispatchers: KaliumDispatcher = KaliumDispatcherImpl
) : ServerConfigRepository {

override suspend fun configList(): Either<StorageFailure, List<ServerConfig>> =
wrapStorageRequest { dao.allConfig() }.map { it.map(serverConfigMapper::fromEntity) }

override suspend fun configFlow(): Either<StorageFailure, Flow<List<ServerConfig>>> =
wrapStorageRequest { dao.allConfigFlow().map { it.map(serverConfigMapper::fromEntity) } }

override suspend fun deleteById(id: String) = wrapStorageRequest { dao.deleteById(id) }

override suspend fun delete(serverConfig: ServerConfig) = deleteById(serverConfig.id)
override suspend fun getOrFetchMetadata(serverLinks: ServerConfig.Links): Either<CoreFailure, ServerConfig> =
wrapStorageRequest { dao.configByLinks(serverConfigMapper.toEntity(serverLinks)) }.fold({
fetchApiVersionAndStore(serverLinks)
Expand Down Expand Up @@ -164,16 +126,9 @@ internal class ServerConfigDataSource(
storeConfig(links, metaData)
}

override fun configById(id: String): Either<StorageFailure, ServerConfig> = wrapStorageRequest {
dao.configById(id)
}.map { serverConfigMapper.fromEntity(it) }

override suspend fun configByLinks(links: ServerConfig.Links): Either<StorageFailure, ServerConfig> =
wrapStorageRequest { dao.configByLinks(serverConfigMapper.toEntity(links)) }.map { serverConfigMapper.fromEntity(it) }

override suspend fun updateConfigApiVersion(id: String): Either<CoreFailure, Unit> = configById(id)
.flatMap { fetchMetadata(it.links) }
.flatMap { wrapStorageRequest { dao.updateApiVersion(id, it.commonApiVersion.version) } }
override suspend fun updateConfigApiVersion(serverConfig: ServerConfig): Either<CoreFailure, Unit> =
fetchMetadata(serverConfig.links)
.flatMap { wrapStorageRequest { dao.updateApiVersion(serverConfig.id, it.commonApiVersion.version) } }

override suspend fun configForUser(userId: UserId): Either<StorageFailure, ServerConfig> =
wrapStorageRequest { dao.configForUser(userId.toDao()) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
package com.wire.kalium.logic.data.session

import com.wire.kalium.logic.data.auth.login.ProxyCredentials
import com.wire.kalium.logic.data.id.IdMapper
import com.wire.kalium.logic.data.id.toApi
import com.wire.kalium.logic.data.id.toDao
import com.wire.kalium.logic.data.id.toModel
Expand Down Expand Up @@ -49,18 +48,18 @@ interface SessionMapper {
fun fromSsoIdEntity(ssoIdEntity: SsoIdEntity?): SsoId?
fun toLogoutReason(reason: LogoutReasonEntity): LogoutReason
fun fromEntityToProxyCredentialsDTO(proxyCredentialsEntity: ProxyCredentialsEntity): ProxyCredentialsDTO
fun formEntityToProxyModel(proxyCredentialsEntity: ProxyCredentialsEntity): ProxyCredentials
fun fromPersistentWebSocketStatusEntity(
persistentWebSocketStatusEntity: PersistentWebSocketStatusEntity
): PersistentWebSocketStatus

fun fromModelToProxyCredentialsEntity(proxyCredentialsModel: ProxyCredentials): ProxyCredentialsEntity
fun fromModelToProxyCredentialsDTO(proxyCredentialsModel: ProxyCredentials): ProxyCredentialsDTO
fun fromDTOToProxyCredentialsModel(proxyCredentialsDTO: ProxyCredentialsDTO?): ProxyCredentials?
}

@Suppress("TooManyFunctions")
internal class SessionMapperImpl(
private val idMapper: IdMapper
) : SessionMapper {
internal class SessionMapperImpl : SessionMapper {

override fun toSessionDTO(authSession: AccountTokens): SessionDTO = with(authSession) {
SessionDTO(
Expand Down Expand Up @@ -137,12 +136,19 @@ internal class SessionMapperImpl(
override fun fromEntityToProxyCredentialsDTO(proxyCredentialsEntity: ProxyCredentialsEntity): ProxyCredentialsDTO =
ProxyCredentialsDTO(proxyCredentialsEntity.username, proxyCredentialsEntity.password)

override fun formEntityToProxyModel(proxyCredentialsEntity: ProxyCredentialsEntity): ProxyCredentials =
ProxyCredentials(
username = proxyCredentialsEntity.username,
password = proxyCredentialsEntity.password
)

override fun fromPersistentWebSocketStatusEntity(
persistentWebSocketStatusEntity: PersistentWebSocketStatusEntity
): PersistentWebSocketStatus = PersistentWebSocketStatus(
persistentWebSocketStatusEntity.userIDEntity.toModel(),
persistentWebSocketStatusEntity.isPersistentWebSocketEnabled
)

override fun fromModelToProxyCredentialsEntity(proxyCredentialsModel: ProxyCredentials): ProxyCredentialsEntity =
ProxyCredentialsEntity(proxyCredentialsModel.username, proxyCredentialsModel.password)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ interface SessionRepository {
suspend fun persistentWebSocketStatus(userId: UserId): Either<StorageFailure, Boolean>
suspend fun cookieLabel(userId: UserId): Either<StorageFailure, String?>
suspend fun isAccountReadOnly(userId: UserId): Either<StorageFailure, Boolean>

suspend fun validSessionsWithServerConfig(): Either<StorageFailure, Map<UserId, ServerConfig>>
}

@Suppress("TooManyFunctions", "LongParameterList")
Expand Down Expand Up @@ -231,6 +231,14 @@ internal class SessionDataSource(
}
}

override suspend fun validSessionsWithServerConfig(): Either<StorageFailure, Map<UserId, ServerConfig>> = wrapStorageRequest {
accountsDAO.validAccountWithServerConfigId()
}.map {
it.map { (userId, serverConfig) ->
userId.toModel() to serverConfigMapper.fromEntity(serverConfig)
}.toMap()
}

internal fun ManagedByDTO.toDao() = when (this) {
ManagedByDTO.WIRE -> ManagedByEntity.WIRE
ManagedByDTO.SCIM -> ManagedByEntity.SCIM
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ import com.wire.kalium.logic.data.user.type.UserEntityTypeMapperImpl
internal object MapperProvider {
fun apiVersionMapper(): ApiVersionMapper = ApiVersionMapperImpl()
fun idMapper(): IdMapper = IdMapperImpl()
fun serverConfigMapper(): ServerConfigMapper = ServerConfigMapperImpl(apiVersionMapper(), idMapper())
fun sessionMapper(): SessionMapper = SessionMapperImpl(idMapper())
fun serverConfigMapper(): ServerConfigMapper = ServerConfigMapperImpl(apiVersionMapper())
fun sessionMapper(): SessionMapper = SessionMapperImpl()
fun availabilityStatusMapper(): AvailabilityStatusMapper = AvailabilityStatusMapperImpl()
fun connectionStateMapper(): ConnectionStateMapper = ConnectionStateMapperImpl()
fun userMapper(): UserMapper = UserMapperImpl(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,67 @@

package com.wire.kalium.logic.feature.server

import com.wire.kalium.logic.configuration.server.ServerConfig
import com.wire.kalium.logic.configuration.server.ServerConfigRepository
import com.wire.kalium.logic.data.auth.login.ProxyCredentials
import com.wire.kalium.logic.data.id.toDao
import com.wire.kalium.logic.data.session.SessionMapper
import com.wire.kalium.logic.data.session.SessionRepository
import com.wire.kalium.logic.data.user.UserId
import com.wire.kalium.logic.di.MapperProvider
import com.wire.kalium.logic.functional.getOrElse
import com.wire.kalium.logic.functional.map
import com.wire.kalium.logic.kaliumLogger
import com.wire.kalium.logic.wrapStorageNullableRequest
import com.wire.kalium.persistence.client.AuthTokenStorage
import io.ktor.util.collections.ConcurrentSet
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.joinAll
import kotlinx.coroutines.launch

/**
* Iterates over all locally stored server configs and update each api version
*/
interface UpdateApiVersionsUseCase {
suspend operator fun invoke()
}

class UpdateApiVersionsUseCaseImpl internal constructor() : UpdateApiVersionsUseCase {
class UpdateApiVersionsUseCaseImpl internal constructor(
private val sessionRepository: SessionRepository,
private val tokenStorage: AuthTokenStorage,
private val serverConfigRepoProvider: (serverConfig: ServerConfig, proxyCredentials: ProxyCredentials?) -> ServerConfigRepository,
private val sessionMapper: SessionMapper = MapperProvider.sessionMapper()
) : UpdateApiVersionsUseCase {
override suspend operator fun invoke() {
// TODO: reimplement this in a safe way
//
// configRepository.configList().onSuccess { configList ->
// configList.forEach {
// configRepository.updateConfigApiVersion(it.id)
// }
// }
coroutineScope {
val updatedServerId = ConcurrentSet<String>()
sessionRepository.validSessionsWithServerConfig().getOrElse {
return@coroutineScope
}.map { (userId, serverConfig) ->
launch {
if (updatedServerId.contains(serverConfig.id)) {
return@launch
}
updatedServerId.add(serverConfig.id)
updateApiForUser(userId, serverConfig)
}
}.joinAll()
}
}

private suspend fun updateApiForUser(userId: UserId, serverConfig: ServerConfig) {
val proxyCredentials: ProxyCredentials? = if (serverConfig.links.apiProxy?.needsAuthentication == true) {
wrapStorageNullableRequest {
tokenStorage.proxyCredentials(userId.toDao())
}.map {
it?.let { sessionMapper.formEntityToProxyModel(it) }
}.getOrElse {
kaliumLogger.d("No proxy credentials found for user ${userId.toLogString()}}")
return
}
} else {
null
}
serverConfigRepoProvider(serverConfig, proxyCredentials).updateConfigApiVersion(serverConfig)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import com.wire.kalium.logic.configuration.server.ServerConfig
import com.wire.kalium.logic.configuration.server.ServerConfigMapper
import com.wire.kalium.logic.configuration.server.ServerConfigMapperImpl
import com.wire.kalium.logic.configuration.server.toCommonApiVersionType
import com.wire.kalium.logic.di.MapperProvider
import com.wire.kalium.logic.util.stubs.newServerConfig
import com.wire.kalium.logic.util.stubs.newServerConfigDTO
import com.wire.kalium.logic.util.stubs.newServerConfigEntity
Expand All @@ -49,7 +48,7 @@ class ServerConfigMapperTest {

@BeforeTest
fun setup() {
serverConfigMapper = ServerConfigMapperImpl(versionMapper, MapperProvider.idMapper())
serverConfigMapper = ServerConfigMapperImpl(versionMapper)
given(versionMapper).invocation { toDTO(SERVER_CONFIG_TEST.metaData.commonApiVersion) }.then { ApiVersionDTO.Valid(1) }
}

Expand Down
Loading

0 comments on commit affdf27

Please sign in to comment.