Allow the app to be configured to bypass the server selection screen. (#4131)
* Make account provider configuration more flexible. - Change defaultHomeserverAddress to an array of providers (needs UI). - Add allowOtherAccountProviders to prevent the user from manually entering a provider. * Refactor QR code scan failures into a common type. * Validate scanned QR codes against the allowed account providers. * Hide the login flow on the QR code screen when restricted.
This commit is contained in:
@@ -18,6 +18,16 @@ class AuthenticationStartScreenViewModelTests: XCTestCase {
|
||||
var viewModel: AuthenticationStartScreenViewModel!
|
||||
var context: AuthenticationStartScreenViewModel.Context { viewModel.context }
|
||||
|
||||
override func setUp() {
|
||||
AppSettings.resetAllSettings()
|
||||
let appSettings = AppSettings()
|
||||
ServiceLocator.shared.register(appSettings: appSettings)
|
||||
}
|
||||
|
||||
override func tearDown() {
|
||||
AppSettings.resetAllSettings()
|
||||
}
|
||||
|
||||
func testInitialState() async throws {
|
||||
// Given a view model that has no provisioning parameters.
|
||||
setupViewModel()
|
||||
@@ -80,6 +90,44 @@ class AuthenticationStartScreenViewModelTests: XCTestCase {
|
||||
XCTAssertEqual(authenticationService.homeserver.value.loginMode, .password)
|
||||
}
|
||||
|
||||
func testSingleProviderOIDCState() async throws {
|
||||
// Given a view model that for an app that only allows the use of a single provider that supports OIDC.
|
||||
setAllowedAccountProviders(["company.com"])
|
||||
setupViewModel()
|
||||
XCTAssertEqual(authenticationService.homeserver.value.loginMode, .unknown)
|
||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintCallsCount, 0)
|
||||
|
||||
// When tapping the login button the authentication service should be used and the screen
|
||||
// should request to continue the flow without any server selection needed.
|
||||
let deferred = deferFulfillment(viewModel.actions) { $0.isLoginDirectlyWithOIDC }
|
||||
context.send(viewAction: .login)
|
||||
try await deferred.fulfill()
|
||||
|
||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintCallsCount, 1)
|
||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintReceivedArguments?.prompt, .consent)
|
||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintReceivedArguments?.loginHint, nil)
|
||||
XCTAssertEqual(authenticationService.homeserver.value.loginMode, .oidc(supportsCreatePrompt: false))
|
||||
}
|
||||
|
||||
func testSingleProviderPasswordState() async throws {
|
||||
// Given a view model that for an app that only allows the use of a single provider that does not support OIDC.
|
||||
setAllowedAccountProviders(["company.com"])
|
||||
setupViewModel(supportsOIDC: false)
|
||||
XCTAssertEqual(authenticationService.homeserver.value.loginMode, .unknown)
|
||||
XCTAssertEqual(client.urlForOidcOidcConfigurationPromptLoginHintCallsCount, 0)
|
||||
|
||||
// When tapping the login button the authentication service should be used and the screen
|
||||
// should request to continue the flow without any server selection needed.
|
||||
let deferred = deferFulfillment(viewModel.actions) { $0.isLoginDirectlyWithPassword }
|
||||
context.send(viewAction: .login)
|
||||
try await deferred.fulfill()
|
||||
|
||||
// Then a call to configure service should be made.
|
||||
XCTAssertEqual(clientBuilderFactory.makeBuilderSessionDirectoriesPassphraseClientSessionDelegateAppSettingsAppHooksCallsCount, 1)
|
||||
XCTAssertEqual(authenticationService.homeserver.value.loginMode, .password)
|
||||
}
|
||||
|
||||
// MARK: - Helpers
|
||||
|
||||
private func setupViewModel(provisioningParameters: AccountProvisioningParameters? = nil, supportsOIDC: Bool = true) {
|
||||
@@ -106,6 +154,28 @@ class AuthenticationStartScreenViewModelTests: XCTestCase {
|
||||
// Add a fake window in order for the OIDC flow to continue
|
||||
viewModel.context.send(viewAction: .updateWindow(UIWindow()))
|
||||
}
|
||||
|
||||
private func setAllowedAccountProviders(_ providers: [String]) {
|
||||
let appSettings: AppSettings! = ServiceLocator.shared.settings
|
||||
appSettings.override(accountProviders: providers,
|
||||
allowOtherAccountProviders: false,
|
||||
pushGatewayBaseURL: appSettings.pushGatewayBaseURL,
|
||||
oidcRedirectURL: appSettings.oidcRedirectURL,
|
||||
websiteURL: appSettings.websiteURL,
|
||||
logoURL: appSettings.logoURL,
|
||||
copyrightURL: appSettings.copyrightURL,
|
||||
acceptableUseURL: appSettings.acceptableUseURL,
|
||||
privacyURL: appSettings.privacyURL,
|
||||
encryptionURL: appSettings.encryptionURL,
|
||||
deviceVerificationURL: appSettings.deviceVerificationURL,
|
||||
chatBackupDetailsURL: appSettings.chatBackupDetailsURL,
|
||||
identityPinningViolationDetailsURL: appSettings.identityPinningViolationDetailsURL,
|
||||
elementWebHosts: appSettings.elementWebHosts,
|
||||
accountProvisioningHost: appSettings.accountProvisioningHost,
|
||||
bugReportApplicationID: appSettings.bugReportApplicationID,
|
||||
analyticsTermsURL: appSettings.analyticsTermsURL,
|
||||
mapTilerConfiguration: appSettings.mapTilerConfiguration)
|
||||
}
|
||||
}
|
||||
|
||||
extension AuthenticationStartScreenViewModelAction {
|
||||
|
||||
Reference in New Issue
Block a user