Merge pull request #8193 from vector-im/feature/bma/certList

Be able to let the user trust several Fingerprints during login flow.
This commit is contained in:
ganfra 2023-03-08 11:53:43 +01:00 committed by GitHub
commit fc796154ea
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 21 additions and 24 deletions

View file

@ -23,7 +23,7 @@ import javax.inject.Inject
class HomeServerConnectionConfigFactory @Inject constructor() {
fun create(url: String?, fingerprint: Fingerprint? = null): HomeServerConnectionConfig? {
fun create(url: String?, fingerprints: List<Fingerprint>? = null): HomeServerConnectionConfig? {
if (url == null) {
return null
}
@ -31,13 +31,7 @@ class HomeServerConnectionConfigFactory @Inject constructor() {
return try {
HomeServerConnectionConfig.Builder()
.withHomeServerUri(url)
.run {
if (fingerprint == null) {
this
} else {
withAllowedFingerPrints(listOf(fingerprint))
}
}
.withAllowedFingerPrints(fingerprints)
.build()
} catch (t: Throwable) {
Timber.e(t)

View file

@ -160,6 +160,8 @@ class OnboardingViewModel @AssistedInject constructor(
private var emailVerificationPollingJob: Job? by cancelCurrentOnSet()
private var currentJob: Job? by cancelCurrentOnSet()
private val trustedFingerprints = mutableListOf<Fingerprint>()
override fun handle(action: OnboardingAction) {
when (action) {
is OnboardingAction.SplashAction -> handleSplashAction(action)
@ -293,13 +295,14 @@ class OnboardingViewModel @AssistedInject constructor(
private fun handleUserAcceptCertificate(action: OnboardingAction.UserAcceptCertificate) {
// It happens when we get the login flow, or during direct authentication.
// So alter the homeserver config and retrieve again the login flow
trustedFingerprints.add(action.fingerprint)
when (action.retryAction) {
is OnboardingAction.HomeServerChange -> handleHomeserverChange(action.retryAction, fingerprint = action.fingerprint)
is OnboardingAction.HomeServerChange -> handleHomeserverChange(action.retryAction, fingerprints = trustedFingerprints)
is AuthenticateAction.LoginDirect ->
handleDirectLogin(
action.retryAction,
// Will be replaced by the task
homeServerConnectionConfigFactory.create("https://dummy.org", action.fingerprint)
homeServerConnectionConfigFactory.create("https://dummy.org", trustedFingerprints)
)
else -> Unit
}
@ -696,10 +699,10 @@ class OnboardingViewModel @AssistedInject constructor(
private fun handleHomeserverChange(
action: OnboardingAction.HomeServerChange,
serverTypeOverride: ServerType? = null,
fingerprint: Fingerprint? = null,
fingerprints: List<Fingerprint>? = null,
postAction: suspend () -> Unit = {},
) {
val homeServerConnectionConfig = homeServerConnectionConfigFactory.create(action.homeServerUrl, fingerprint)
val homeServerConnectionConfig = homeServerConnectionConfigFactory.create(action.homeServerUrl, fingerprints)
if (homeServerConnectionConfig == null) {
// This is invalid
_viewEvents.post(OnboardingViewEvents.Failure(Throwable("Unable to create a HomeServerConnectionConfig")))

View file

@ -621,7 +621,7 @@ class OnboardingViewModelTest {
@Test
fun `when editing homeserver errors with certificate error, then emits error`() = runTest {
fakeHomeServerConnectionConfigFactory.givenConfigFor(A_HOMESERVER_URL, fingerprint = null, A_HOMESERVER_CONFIG)
fakeHomeServerConnectionConfigFactory.givenConfigFor(A_HOMESERVER_URL, fingerprints = null, A_HOMESERVER_CONFIG)
fakeStartAuthenticationFlowUseCase.givenErrors(A_HOMESERVER_CONFIG, AN_UNRECOGNISED_CERTIFICATE_ERROR)
val editAction = OnboardingAction.HomeServerChange.EditHomeServer(A_HOMESERVER_URL)
val test = viewModel.test()
@ -640,7 +640,7 @@ class OnboardingViewModelTest {
@Test
fun `when selecting homeserver errors with certificate error, then emits error`() = runTest {
fakeHomeServerConnectionConfigFactory.givenConfigFor(A_HOMESERVER_URL, fingerprint = null, A_HOMESERVER_CONFIG)
fakeHomeServerConnectionConfigFactory.givenConfigFor(A_HOMESERVER_URL, fingerprints = null, A_HOMESERVER_CONFIG)
fakeStartAuthenticationFlowUseCase.givenErrors(A_HOMESERVER_CONFIG, AN_UNRECOGNISED_CERTIFICATE_ERROR)
val selectAction = OnboardingAction.HomeServerChange.SelectHomeServer(A_HOMESERVER_URL)
val test = viewModel.test()
@ -842,7 +842,7 @@ class OnboardingViewModelTest {
A_HOMESERVER_URL,
SELECTED_HOMESERVER_STATE,
config = A_HOMESERVER_CONFIG.copy(allowedFingerprints = listOf(A_FINGERPRINT)),
fingerprint = A_FINGERPRINT,
fingerprints = listOf(A_FINGERPRINT),
)
viewModel.handle(OnboardingAction.UserAcceptCertificate(A_FINGERPRINT, OnboardingAction.HomeServerChange.SelectHomeServer(A_HOMESERVER_URL)))
@ -866,7 +866,7 @@ class OnboardingViewModelTest {
A_HOMESERVER_URL,
SELECTED_HOMESERVER_STATE,
config = A_HOMESERVER_CONFIG.copy(allowedFingerprints = listOf(A_FINGERPRINT)),
fingerprint = A_FINGERPRINT,
fingerprints = listOf(A_FINGERPRINT),
)
val test = viewModel.test()
@ -886,7 +886,7 @@ class OnboardingViewModelTest {
@Test
fun `given DirectLogin retry action, when accepting user certificate, then logs in directly`() = runTest {
fakeHomeServerConnectionConfigFactory.givenConfigFor("https://dummy.org", A_FINGERPRINT, A_HOMESERVER_CONFIG)
fakeHomeServerConnectionConfigFactory.givenConfigFor("https://dummy.org", listOf(A_FINGERPRINT), A_HOMESERVER_CONFIG)
fakeDirectLoginUseCase.givenSuccessResult(A_DIRECT_LOGIN, config = A_HOMESERVER_CONFIG, result = fakeSession)
givenInitialisesSession(fakeSession)
val test = viewModel.test()
@ -1175,16 +1175,16 @@ class OnboardingViewModelTest {
homeserverUrl: String,
resultingState: SelectedHomeserverState,
config: HomeServerConnectionConfig = A_HOMESERVER_CONFIG,
fingerprint: Fingerprint? = null,
fingerprints: List<Fingerprint>? = null,
) {
fakeHomeServerConnectionConfigFactory.givenConfigFor(homeserverUrl, fingerprint, config)
fakeHomeServerConnectionConfigFactory.givenConfigFor(homeserverUrl, fingerprints, config)
fakeStartAuthenticationFlowUseCase.givenResult(config, StartAuthenticationResult(isHomeserverOutdated = false, resultingState))
givenRegistrationResultFor(RegisterAction.StartRegistration, RegistrationActionHandler.Result.StartRegistration)
fakeHomeServerHistoryService.expectUrlToBeAdded(config.homeServerUri.toString())
}
private fun givenUpdatingHomeserverErrors(homeserverUrl: String, resultingState: SelectedHomeserverState, error: Throwable) {
fakeHomeServerConnectionConfigFactory.givenConfigFor(homeserverUrl, fingerprint = null, A_HOMESERVER_CONFIG)
fakeHomeServerConnectionConfigFactory.givenConfigFor(homeserverUrl, fingerprints = null, A_HOMESERVER_CONFIG)
fakeStartAuthenticationFlowUseCase.givenResult(A_HOMESERVER_CONFIG, StartAuthenticationResult(isHomeserverOutdated = false, resultingState))
givenRegistrationResultFor(RegisterAction.StartRegistration, RegistrationActionHandler.Result.Error(error))
fakeHomeServerHistoryService.expectUrlToBeAdded(A_HOMESERVER_CONFIG.homeServerUri.toString())
@ -1209,13 +1209,13 @@ class OnboardingViewModelTest {
private fun givenHomeserverSelectionFailsWithNetworkError() {
fakeContext.givenHasConnection()
fakeHomeServerConnectionConfigFactory.givenConfigFor(A_HOMESERVER_URL, fingerprint = null, A_HOMESERVER_CONFIG)
fakeHomeServerConnectionConfigFactory.givenConfigFor(A_HOMESERVER_URL, fingerprints = null, A_HOMESERVER_CONFIG)
fakeStartAuthenticationFlowUseCase.givenHomeserverUnavailable(A_HOMESERVER_CONFIG)
}
private fun givenHomeserverSelectionFailsWith(cause: Throwable) {
fakeContext.givenHasConnection()
fakeHomeServerConnectionConfigFactory.givenConfigFor(A_HOMESERVER_URL, fingerprint = null, A_HOMESERVER_CONFIG)
fakeHomeServerConnectionConfigFactory.givenConfigFor(A_HOMESERVER_URL, fingerprints = null, A_HOMESERVER_CONFIG)
fakeStartAuthenticationFlowUseCase.givenErrors(A_HOMESERVER_CONFIG, cause)
}
}

View file

@ -25,7 +25,7 @@ import org.matrix.android.sdk.api.network.ssl.Fingerprint
class FakeHomeServerConnectionConfigFactory {
val instance: HomeServerConnectionConfigFactory = mockk()
fun givenConfigFor(url: String, fingerprint: Fingerprint? = null, config: HomeServerConnectionConfig) {
every { instance.create(url, fingerprint) } returns config
fun givenConfigFor(url: String, fingerprints: List<Fingerprint>? = null, config: HomeServerConnectionConfig) {
every { instance.create(url, fingerprints) } returns config
}
}