Skip to content

Commit

Permalink
#40: Use the Rust AuthenticationService.
Browse files Browse the repository at this point in the history
* Update SDK package to 1.0.12-alpha.
* Use an app group for storage and stop stripping the http from the homeserver when configuring the service.
* Rename access token to restore token.
* Remove matrix.org server description inline with latest FTUE changes.
  • Loading branch information
pixlwave authored Jul 27, 2022
1 parent 03d6097 commit 1878a16
Show file tree
Hide file tree
Showing 29 changed files with 283 additions and 203 deletions.
40 changes: 27 additions & 13 deletions ElementX.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@
{
"identity" : "matrix-rust-components-swift",
"kind" : "remoteSourceControl",
"location" : "https://github.com/matrix-org/matrix-rust-components-swift.git",
"location" : "https://github.com/matrix-org/matrix-rust-components-swift",
"state" : {
"revision" : "7d5bdf05ff97e2229cb504982162fc02c37c58e5",
"version" : "1.0.11-alpha"
"revision" : "3dbb1533d1c27dcd311a8c9751de7c020ccf2d8c",
"version" : "1.0.12-alpha"
}
},
{
Expand Down
2 changes: 1 addition & 1 deletion ElementX/Sources/AppCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ class AppCoordinator: AuthenticationCoordinatorDelegate, Coordinator {
}

private func startAuthentication() {
let authenticationService = AuthenticationService(userSessionStore: userSessionStore)
let authenticationService = AuthenticationServiceProxy(userSessionStore: userSessionStore)
let coordinator = AuthenticationCoordinator(authenticationService: authenticationService,
navigationRouter: navigationRouter)
coordinator.delegate = self
Expand Down
2 changes: 1 addition & 1 deletion ElementX/Sources/BuildSettings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import Foundation
final class BuildSettings {
// MARK: - Servers

static let defaultHomeserverURLString = "https://matrix.org"
static let defaultHomeserverAddress = "matrix.org"

// MARK: - Bug report

Expand Down
1 change: 1 addition & 0 deletions ElementX/Sources/Generated/InfoPlist.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ internal enum ElementInfoPlist {
internal static let cfBundleVersion: String = _document["CFBundleVersion"]
internal static let uiLaunchStoryboardName: String = _document["UILaunchStoryboardName"]
internal static let uiSupportedInterfaceOrientations: [String] = _document["UISupportedInterfaceOrientations"]
internal static let appGroupIdentifier: String = _document["appGroupIdentifier"]
}
// swiftlint:enable identifier_name line_length type_body_length

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,21 @@ protocol AuthenticationCoordinatorDelegate: AnyObject {
}

class AuthenticationCoordinator: Coordinator, Presentable {
private let authenticationService: AuthenticationServiceProtocol
private let authenticationService: AuthenticationServiceProxyProtocol
private let navigationRouter: NavigationRouter
private var indicatorPresenter: UserIndicatorTypePresenterProtocol
private var activityIndicator: UserIndicator?

private(set) var clientProxy: ClientProxyProtocol?
var childCoordinators: [Coordinator] = []

weak var delegate: AuthenticationCoordinatorDelegate?

init(authenticationService: AuthenticationServiceProtocol,
init(authenticationService: AuthenticationServiceProxyProtocol,
navigationRouter: NavigationRouter) {
self.authenticationService = authenticationService
self.navigationRouter = navigationRouter

indicatorPresenter = UserIndicatorTypePresenter(presentingViewController: navigationRouter.toPresentable())
}

func start() {
Expand All @@ -47,7 +50,7 @@ class AuthenticationCoordinator: Coordinator, Presentable {
guard let self = self else { return }
switch action {
case .login:
self.showLoginScreen()
Task { await self.startAuthentication() }
}
}

Expand All @@ -59,19 +62,54 @@ class AuthenticationCoordinator: Coordinator, Presentable {
}
}

private func startAuthentication() async {
startLoading()

switch await authenticationService.configure(for: BuildSettings.defaultHomeserverAddress) {
case .success:
stopLoading()
showLoginScreen()
case .failure:
stopLoading()
showServerSelectionScreen()
}
}

private func showServerSelectionScreen() {
let parameters = ServerSelectionCoordinatorParameters(authenticationService: authenticationService,
hasModalPresentation: false)
let coordinator = ServerSelectionCoordinator(parameters: parameters)

coordinator.callback = { [weak self] action in
guard let self = self else { return }

switch action {
case .updated:
self.showLoginScreen()
case .dismiss:
MXLog.failure("[AuthenticationCoordinator] ServerSelectionScreen is requesting dismiss when part of a stack.")
}
}

coordinator.start()
add(childCoordinator: coordinator)

navigationRouter.push(coordinator) { [weak self] in
self?.remove(childCoordinator: coordinator)
}
}

private func showLoginScreen() {
let parameters = LoginCoordinatorParameters(authenticationService: authenticationService,
navigationRouter: navigationRouter)
let coordinator = LoginCoordinator(parameters: parameters)

coordinator.callback = { [weak self, weak coordinator] action in
guard let self = self, let coordinator = coordinator else { return }
coordinator.callback = { [weak self] action in
guard let self = self else { return }

switch action {
case .signedIn(let userSession):
self.delegate?.authenticationCoordinator(self, didLoginWithSession: userSession)
self.remove(childCoordinator: coordinator)
self.navigationRouter.dismissModule()
case .continueWithOIDC:
break
}
Expand All @@ -84,4 +122,14 @@ class AuthenticationCoordinator: Coordinator, Presentable {
self?.remove(childCoordinator: coordinator)
}
}

/// Show a blocking activity indicator.
private func startLoading() {
activityIndicator = indicatorPresenter.present(.loading(label: ElementL10n.loading, isInteractionBlocking: true))
}

/// Hide the currently displayed activity indicator.
private func stopLoading() {
activityIndicator = nil
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import SwiftUI

struct LoginCoordinatorParameters {
/// The service used to authenticate the user.
let authenticationService: AuthenticationServiceProtocol
let authenticationService: AuthenticationServiceProxyProtocol
/// The navigation router used to present the server selection screen.
let navigationRouter: NavigationRouterType
}
Expand All @@ -46,7 +46,7 @@ final class LoginCoordinator: Coordinator, Presentable {
}
}

private var authenticationService: AuthenticationServiceProtocol { parameters.authenticationService }
private var authenticationService: AuthenticationServiceProxyProtocol { parameters.authenticationService }
private var navigationRouter: NavigationRouterType { parameters.navigationRouter }
private var indicatorPresenter: UserIndicatorTypePresenterProtocol
private var activityIndicator: UserIndicator?
Expand Down Expand Up @@ -163,7 +163,7 @@ final class LoginCoordinator: Coordinator, Presentable {
startLoading(isInteractionBlocking: false)

Task {
switch await authenticationService.startLogin(for: homeserverDomain) {
switch await authenticationService.configure(for: homeserverDomain) {
case .success:
updateViewModel()
stopLoading()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,15 @@ import Foundation
struct LoginHomeserver: Equatable {
/// The homeserver string to be shown to the user.
let address: String
/// Whether or not the homeserver is matrix.org.
let isMatrixDotOrg: Bool
/// The types login supported by the homeserver.
let loginMode: LoginMode
}

extension LoginHomeserver {
/// Temporary initialiser for use until the FFI has homeserver discovery etc.
init(address: String) {
var loginMode: LoginMode

/// Creates a new homeserver value.
init(address: String, loginMode: LoginMode) {
let address = Self.sanitized(address).components(separatedBy: "://").last ?? address

self.address = address
isMatrixDotOrg = address == "matrix.org"
loginMode = .password
self.loginMode = loginMode
}

/// Sanitizes a user entered homeserver address with the following rules
Expand All @@ -59,30 +54,23 @@ extension LoginHomeserver {
extension LoginHomeserver {
/// A mock homeserver that is configured just like matrix.org.
static var mockMatrixDotOrg: LoginHomeserver {
LoginHomeserver(address: "matrix.org",
isMatrixDotOrg: true,
loginMode: .password)
LoginHomeserver(address: "matrix.org", loginMode: .password)
}

/// A mock homeserver that supports login and registration via a password but has no SSO providers.
static var mockBasicServer: LoginHomeserver {
LoginHomeserver(address: "example.com",
isMatrixDotOrg: false,
loginMode: .password)
LoginHomeserver(address: "example.com", loginMode: .password)
}

/// A mock homeserver that supports only supports authentication via a single SSO provider.
static var mockOIDC: LoginHomeserver {
LoginHomeserver(address: "company.com",
isMatrixDotOrg: false,
// swiftlint:disable:next force_unwrapping
loginMode: .oidc(URL(string: "https://auth.company.com")!))
// swiftlint:disable:next force_unwrapping
let issuerURL = URL(string: "https://auth.company.com")!
return LoginHomeserver(address: "company.com", loginMode: .oidc(issuerURL))
}

/// A mock homeserver that only with no supported login flows.
static var mockUnsupported: LoginHomeserver {
LoginHomeserver(address: "server.net",
isMatrixDotOrg: false,
loginMode: .unsupported)
LoginHomeserver(address: "server.net", loginMode: .unsupported)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,7 @@ struct LoginScreen: View {

/// The sever information section that includes a button to select a different server.
var serverInfo: some View {
LoginServerInfoSection(address: context.viewState.homeserver.address,
showMatrixDotOrgInfo: context.viewState.homeserver.isMatrixDotOrg) {
LoginServerInfoSection(address: context.viewState.homeserver.address) {
context.send(viewAction: .selectServer)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ struct LoginServerInfoSection: View {

/// The address shown for the server.
let address: String
/// Whether or not to show the matrix.org description.
let showMatrixDotOrgInfo: Bool
/// The action performed when tapping the edit button.
let editAction: () -> Void

Expand All @@ -37,18 +35,9 @@ struct LoginServerInfoSection: View {
.foregroundColor(.element.secondaryContent)

HStack {
VStack(alignment: .leading, spacing: 2) {
Text(address)
.font(.element.body)
.foregroundColor(.element.primaryContent)

if showMatrixDotOrgInfo {
Text(ElementL10n.authenticationServerInfoMatrixDescription)
.font(.element.caption1)
.foregroundColor(.element.tertiaryContent)
.accessibilityIdentifier("serverDescriptionText")
}
}
Text(address)
.font(.element.body)
.foregroundColor(.element.primaryContent)

Spacer()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import SwiftUI

struct ServerSelectionCoordinatorParameters {
/// The service used to authenticate the user.
let authenticationService: AuthenticationServiceProtocol
let authenticationService: AuthenticationServiceProxyProtocol
/// Whether the screen is presented modally or within a navigation stack.
let hasModalPresentation: Bool
}
Expand All @@ -37,7 +37,7 @@ final class ServerSelectionCoordinator: Coordinator, Presentable {
private let serverSelectionHostingController: UIViewController
private var serverSelectionViewModel: ServerSelectionViewModelProtocol

private var authenticationService: AuthenticationServiceProtocol { parameters.authenticationService }
private var authenticationService: AuthenticationServiceProxyProtocol { parameters.authenticationService }
private var indicatorPresenter: UserIndicatorTypePresenterProtocol
private var loadingIndicator: UserIndicator?

Expand Down Expand Up @@ -103,7 +103,7 @@ final class ServerSelectionCoordinator: Coordinator, Presentable {
startLoading()

Task {
switch await authenticationService.startLogin(for: homeserverAddress) {
switch await authenticationService.configure(for: homeserverAddress) {
case .success:
callback?(.updated)
stopLoading()
Expand All @@ -117,7 +117,7 @@ final class ServerSelectionCoordinator: Coordinator, Presentable {
/// Processes an error to either update the flow or display it to the user.
private func handleError(_ error: AuthenticationServiceError) {
switch error {
case .invalidServer:
case .invalidServer, .invalidHomeserverAddress:
serverSelectionViewModel.displayError(.footerMessage(ElementL10n.loginErrorHomeserverNotFound))
default:
serverSelectionViewModel.displayError(.footerMessage(ElementL10n.unknownError))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ struct PlaceholderAvatarImage: View {
.padding(4)
.foregroundColor(.white)
// Make the text resizable (i.e. Make it large and then allow it to scale down)
.font(.system(size: 200))
.font(.system(size: 200).weight(.semibold))
.minimumScaleFactor(0.001)
}
.aspectRatio(1, contentMode: .fill)
Expand Down
Loading

0 comments on commit 1878a16

Please sign in to comment.