ports the key sharing strategy to the config

This commit is contained in:
Adam Brown 2022-06-30 14:28:48 +01:00
parent e795e9da52
commit f14aabcd22
7 changed files with 121 additions and 10 deletions

View File

@ -42,6 +42,11 @@ object Config {
*/ */
const val VOICE_MESSAGE_LIMIT_MS = 120_000L const val VOICE_MESSAGE_LIMIT_MS = 120_000L
/**
* The strategy for sharing device keys
*/
val KEY_SHARING_STRATEGY = KeySharingStrategy.WhenTyping
/** /**
* The onboarding flow * The onboarding flow
*/ */
@ -111,3 +116,21 @@ enum class OnboardingVariant {
LOGIN_2, LOGIN_2,
FTUE_AUTH FTUE_AUTH
} }
enum class KeySharingStrategy {
/**
* Keys will be sent for the first time when the first message is sent.
* This is handled by the Matrix SDK so there's no need to do it in Vector.
*/
WhenSendingEvent,
/**
* Keys will be sent for the first time when the timeline displayed.
*/
WhenEnteringRoom,
/**
* Keys will be sent for the first time when a typing started.
*/
WhenTyping
}

View File

@ -156,8 +156,6 @@ android {
buildConfigField "String", "GIT_BRANCH_NAME", "\"${gitBranchName()}\"" buildConfigField "String", "GIT_BRANCH_NAME", "\"${gitBranchName()}\""
buildConfigField "String", "BUILD_NUMBER", "\"${buildNumber}\"" buildConfigField "String", "BUILD_NUMBER", "\"${buildNumber}\""
buildConfigField "im.vector.app.features.crypto.keysrequest.OutboundSessionKeySharingStrategy", "outboundSessionKeySharingStrategy", "im.vector.app.features.crypto.keysrequest.OutboundSessionKeySharingStrategy.WhenTyping"
// If set, MSC3086 asserted identity messages sent on VoIP calls will cause the call to appear in the room corresponding to the asserted identity. // If set, MSC3086 asserted identity messages sent on VoIP calls will cause the call to appear in the room corresponding to the asserted identity.
// This *must* only be set in trusted environments. // This *must* only be set in trusted environments.
buildConfigField "Boolean", "handleCallAssertedIdentityEvents", "false" buildConfigField "Boolean", "handleCallAssertedIdentityEvents", "false"

View File

@ -0,0 +1,66 @@
/*
* Copyright (c) 2022 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.app.core.di
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import im.vector.app.BuildConfig
import im.vector.app.config.Analytics
import im.vector.app.config.Config
import im.vector.app.config.KeySharingStrategy
import im.vector.app.features.analytics.AnalyticsConfig
import im.vector.app.features.crypto.keysrequest.OutboundSessionKeySharingStrategy
import im.vector.app.features.home.room.detail.composer.voice.VoiceMessageConfig
import im.vector.app.features.raw.wellknown.CryptoConfig
@InstallIn(SingletonComponent::class)
@Module
object ConfigurationModule {
@Provides
fun providesAnalyticsConfig(): AnalyticsConfig {
val config: Analytics = when (BuildConfig.DEBUG) {
true -> Config.DEBUG_ANALYTICS_CONFIG
false -> Config.RELEASE_ANALYTICS_CONFIG
}
return when (config) {
Analytics.Disabled -> AnalyticsConfig(isEnabled = false, "", "", "")
is Analytics.PostHog -> AnalyticsConfig(
isEnabled = true,
postHogHost = config.postHogHost,
postHogApiKey = config.postHogApiKey,
policyLink = config.policyLink
)
}
}
@Provides
fun providesVoiceMessageConfig() = VoiceMessageConfig(
lengthLimitMs = Config.VOICE_MESSAGE_LIMIT_MS
)
@Provides
fun providesCryptoConfig() = CryptoConfig(
fallbackKeySharingStrategy = when (Config.KEY_SHARING_STRATEGY) {
KeySharingStrategy.WhenSendingEvent -> OutboundSessionKeySharingStrategy.WhenSendingEvent
KeySharingStrategy.WhenEnteringRoom -> OutboundSessionKeySharingStrategy.WhenSendingEvent
KeySharingStrategy.WhenTyping -> OutboundSessionKeySharingStrategy.WhenSendingEvent
}
)
}

View File

@ -207,6 +207,9 @@ object VectorStaticModule {
return GlobalScope return GlobalScope
} }
@Provides
fun providesPhoneNumberUtil(): PhoneNumberUtil = PhoneNumberUtil.getInstance()
@Provides @Provides
fun providesAnalyticsConfig(): AnalyticsConfig { fun providesAnalyticsConfig(): AnalyticsConfig {
val config: Analytics = when (BuildConfig.BUILD_TYPE) { val config: Analytics = when (BuildConfig.BUILD_TYPE) {
@ -226,9 +229,6 @@ object VectorStaticModule {
} }
} }
@Provides
fun providesPhoneNumberUtil(): PhoneNumberUtil = PhoneNumberUtil.getInstance()
@Provides @Provides
fun providesVoiceMessageConfig() = VoiceMessageConfig( fun providesVoiceMessageConfig() = VoiceMessageConfig(
lengthLimitMs = Config.VOICE_MESSAGE_LIMIT_MS lengthLimitMs = Config.VOICE_MESSAGE_LIMIT_MS

View File

@ -56,6 +56,7 @@ import im.vector.app.features.location.LocationSharingServiceConnection
import im.vector.app.features.location.live.StopLiveLocationShareUseCase import im.vector.app.features.location.live.StopLiveLocationShareUseCase
import im.vector.app.features.notifications.NotificationDrawerManager import im.vector.app.features.notifications.NotificationDrawerManager
import im.vector.app.features.powerlevel.PowerLevelsFlowFactory import im.vector.app.features.powerlevel.PowerLevelsFlowFactory
import im.vector.app.features.raw.wellknown.CryptoConfig
import im.vector.app.features.raw.wellknown.getOutboundSessionKeySharingStrategyOrDefault import im.vector.app.features.raw.wellknown.getOutboundSessionKeySharingStrategyOrDefault
import im.vector.app.features.raw.wellknown.withElementWellKnown import im.vector.app.features.raw.wellknown.withElementWellKnown
import im.vector.app.features.session.coroutineScope import im.vector.app.features.session.coroutineScope
@ -137,6 +138,7 @@ class TimelineViewModel @AssistedInject constructor(
private val locationSharingServiceConnection: LocationSharingServiceConnection, private val locationSharingServiceConnection: LocationSharingServiceConnection,
private val stopLiveLocationShareUseCase: StopLiveLocationShareUseCase, private val stopLiveLocationShareUseCase: StopLiveLocationShareUseCase,
private val redactLiveLocationShareEventUseCase: RedactLiveLocationShareEventUseCase, private val redactLiveLocationShareEventUseCase: RedactLiveLocationShareEventUseCase,
private val cryptoConfig: CryptoConfig,
timelineFactory: TimelineFactory, timelineFactory: TimelineFactory,
spaceStateHandler: SpaceStateHandler, spaceStateHandler: SpaceStateHandler,
) : VectorViewModel<RoomDetailViewState, RoomDetailAction, RoomDetailViewEvents>(initialState), ) : VectorViewModel<RoomDetailViewState, RoomDetailAction, RoomDetailViewEvents>(initialState),
@ -205,7 +207,7 @@ class TimelineViewModel @AssistedInject constructor(
// Ensure to share the outbound session keys with all members // Ensure to share the outbound session keys with all members
if (room.roomCryptoService().isEncrypted()) { if (room.roomCryptoService().isEncrypted()) {
rawService.withElementWellKnown(viewModelScope, session.sessionParams) { rawService.withElementWellKnown(viewModelScope, session.sessionParams) {
val strategy = it.getOutboundSessionKeySharingStrategyOrDefault() val strategy = it.getOutboundSessionKeySharingStrategyOrDefault(cryptoConfig.fallbackKeySharingStrategy)
if (strategy == OutboundSessionKeySharingStrategy.WhenEnteringRoom) { if (strategy == OutboundSessionKeySharingStrategy.WhenEnteringRoom) {
prepareForEncryption() prepareForEncryption()
} }
@ -688,7 +690,7 @@ class TimelineViewModel @AssistedInject constructor(
// Ensure outbound session keys // Ensure outbound session keys
if (room.roomCryptoService().isEncrypted()) { if (room.roomCryptoService().isEncrypted()) {
rawService.withElementWellKnown(viewModelScope, session.sessionParams) { rawService.withElementWellKnown(viewModelScope, session.sessionParams) {
val strategy = it.getOutboundSessionKeySharingStrategyOrDefault() val strategy = it.getOutboundSessionKeySharingStrategyOrDefault(cryptoConfig.fallbackKeySharingStrategy)
if (strategy == OutboundSessionKeySharingStrategy.WhenTyping && action.focused) { if (strategy == OutboundSessionKeySharingStrategy.WhenTyping && action.focused) {
// Should we add some rate limit here, or do it only once per model lifecycle? // Should we add some rate limit here, or do it only once per model lifecycle?
prepareForEncryption() prepareForEncryption()

View File

@ -0,0 +1,23 @@
/*
* Copyright (c) 2022 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.app.features.raw.wellknown
import im.vector.app.features.crypto.keysrequest.OutboundSessionKeySharingStrategy
data class CryptoConfig(
val fallbackKeySharingStrategy: OutboundSessionKeySharingStrategy
)

View File

@ -16,7 +16,6 @@
package im.vector.app.features.raw.wellknown package im.vector.app.features.raw.wellknown
import im.vector.app.BuildConfig
import im.vector.app.features.crypto.keysrequest.OutboundSessionKeySharingStrategy import im.vector.app.features.crypto.keysrequest.OutboundSessionKeySharingStrategy
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@ -35,12 +34,12 @@ suspend fun RawService.getElementWellknown(sessionParams: SessionParams): Elemen
fun ElementWellKnown.isE2EByDefault() = elementE2E?.e2eDefault ?: riotE2E?.e2eDefault ?: true fun ElementWellKnown.isE2EByDefault() = elementE2E?.e2eDefault ?: riotE2E?.e2eDefault ?: true
fun ElementWellKnown?.getOutboundSessionKeySharingStrategyOrDefault(): OutboundSessionKeySharingStrategy { fun ElementWellKnown?.getOutboundSessionKeySharingStrategyOrDefault(fallback: OutboundSessionKeySharingStrategy): OutboundSessionKeySharingStrategy {
return when (this?.elementE2E?.outboundsKeyPreSharingMode) { return when (this?.elementE2E?.outboundsKeyPreSharingMode) {
"on_room_opening" -> OutboundSessionKeySharingStrategy.WhenEnteringRoom "on_room_opening" -> OutboundSessionKeySharingStrategy.WhenEnteringRoom
"on_typing" -> OutboundSessionKeySharingStrategy.WhenTyping "on_typing" -> OutboundSessionKeySharingStrategy.WhenTyping
"disabled" -> OutboundSessionKeySharingStrategy.WhenSendingEvent "disabled" -> OutboundSessionKeySharingStrategy.WhenSendingEvent
else -> BuildConfig.outboundSessionKeySharingStrategy else -> fallback
} }
} }