Use a Client in AuthenticationService now that the Rust one has been removed. (#2954)

* Replace Rust's Authentication service by building a Client.

* Drop the Proxy from AuthenticationServiceProxy[Protocol].

* Make sure to call abortOIDCLogin.

* Centralise common ClientBuilder code.

* Update the SDK.
This commit is contained in:
Doug
2024-06-24 15:05:00 +01:00
committed by GitHub
parent fc0573a41d
commit 3465ea4cc1
23 changed files with 489 additions and 564 deletions
@@ -449,12 +449,12 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
private func startAuthentication() {
let encryptionKeyProvider = EncryptionKeyProvider()
let authenticationService = AuthenticationServiceProxy(userSessionStore: userSessionStore,
encryptionKeyProvider: encryptionKeyProvider,
appSettings: appSettings)
let qrCodeLoginService = QRCodeLoginService(oidcConfiguration: appSettings.oidcConfiguration.rustValue,
encryptionKeyProvider: encryptionKeyProvider,
userSessionStore: userSessionStore)
let authenticationService = AuthenticationService(userSessionStore: userSessionStore,
encryptionKeyProvider: encryptionKeyProvider,
appSettings: appSettings)
let qrCodeLoginService = QRCodeLoginService(encryptionKeyProvider: encryptionKeyProvider,
userSessionStore: userSessionStore,
appSettings: appSettings)
authenticationFlowCoordinator = AuthenticationFlowCoordinator(authenticationService: authenticationService,
qrCodeLoginService: qrCodeLoginService,
@@ -480,9 +480,9 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg
userDisplayName: userSession.clientProxy.userDisplayNamePublisher.value ?? "",
deviceID: userSession.clientProxy.deviceID)
let authenticationService = AuthenticationServiceProxy(userSessionStore: userSessionStore,
encryptionKeyProvider: EncryptionKeyProvider(),
appSettings: appSettings)
let authenticationService = AuthenticationService(userSessionStore: userSessionStore,
encryptionKeyProvider: EncryptionKeyProvider(),
appSettings: appSettings)
_ = await authenticationService.configure(for: userSession.clientProxy.homeserver)
let parameters = SoftLogoutScreenCoordinatorParameters(authenticationService: authenticationService,
@@ -23,7 +23,7 @@ protocol AuthenticationFlowCoordinatorDelegate: AnyObject {
}
class AuthenticationFlowCoordinator: FlowCoordinatorProtocol {
private let authenticationService: AuthenticationServiceProxyProtocol
private let authenticationService: AuthenticationServiceProtocol
private let bugReportService: BugReportServiceProtocol
private let navigationRootCoordinator: NavigationRootCoordinator
private let navigationStackCoordinator: NavigationStackCoordinator
@@ -42,7 +42,7 @@ class AuthenticationFlowCoordinator: FlowCoordinatorProtocol {
weak var delegate: AuthenticationFlowCoordinatorDelegate?
init(authenticationService: AuthenticationServiceProxyProtocol,
init(authenticationService: AuthenticationServiceProtocol,
qrCodeLoginService: QRCodeLoginServiceProtocol,
bugReportService: BugReportServiceProtocol,
navigationRootCoordinator: NavigationRootCoordinator,
@@ -80,347 +80,6 @@ open class AbortSendHandleSDKMock: MatrixRustSDK.AbortSendHandle {
}
}
}
open class AuthenticationServiceSDKMock: MatrixRustSDK.AuthenticationService {
init() {
super.init(noPointer: .init())
}
public required init(unsafeFromRawPointer pointer: UnsafeMutableRawPointer) {
fatalError("init(unsafeFromRawPointer:) has not been implemented")
}
fileprivate var pointer: UnsafeMutableRawPointer!
//MARK: - configureHomeserver
open var configureHomeserverServerNameOrHomeserverUrlThrowableError: Error?
var configureHomeserverServerNameOrHomeserverUrlUnderlyingCallsCount = 0
open var configureHomeserverServerNameOrHomeserverUrlCallsCount: Int {
get {
if Thread.isMainThread {
return configureHomeserverServerNameOrHomeserverUrlUnderlyingCallsCount
} else {
var returnValue: Int? = nil
DispatchQueue.main.sync {
returnValue = configureHomeserverServerNameOrHomeserverUrlUnderlyingCallsCount
}
return returnValue!
}
}
set {
if Thread.isMainThread {
configureHomeserverServerNameOrHomeserverUrlUnderlyingCallsCount = newValue
} else {
DispatchQueue.main.sync {
configureHomeserverServerNameOrHomeserverUrlUnderlyingCallsCount = newValue
}
}
}
}
open var configureHomeserverServerNameOrHomeserverUrlCalled: Bool {
return configureHomeserverServerNameOrHomeserverUrlCallsCount > 0
}
open var configureHomeserverServerNameOrHomeserverUrlReceivedServerNameOrHomeserverUrl: String?
open var configureHomeserverServerNameOrHomeserverUrlReceivedInvocations: [String] = []
open var configureHomeserverServerNameOrHomeserverUrlClosure: ((String) async throws -> Void)?
open override func configureHomeserver(serverNameOrHomeserverUrl: String) async throws {
if let error = configureHomeserverServerNameOrHomeserverUrlThrowableError {
throw error
}
configureHomeserverServerNameOrHomeserverUrlCallsCount += 1
configureHomeserverServerNameOrHomeserverUrlReceivedServerNameOrHomeserverUrl = serverNameOrHomeserverUrl
DispatchQueue.main.async {
self.configureHomeserverServerNameOrHomeserverUrlReceivedInvocations.append(serverNameOrHomeserverUrl)
}
try await configureHomeserverServerNameOrHomeserverUrlClosure?(serverNameOrHomeserverUrl)
}
//MARK: - homeserverDetails
var homeserverDetailsUnderlyingCallsCount = 0
open var homeserverDetailsCallsCount: Int {
get {
if Thread.isMainThread {
return homeserverDetailsUnderlyingCallsCount
} else {
var returnValue: Int? = nil
DispatchQueue.main.sync {
returnValue = homeserverDetailsUnderlyingCallsCount
}
return returnValue!
}
}
set {
if Thread.isMainThread {
homeserverDetailsUnderlyingCallsCount = newValue
} else {
DispatchQueue.main.sync {
homeserverDetailsUnderlyingCallsCount = newValue
}
}
}
}
open var homeserverDetailsCalled: Bool {
return homeserverDetailsCallsCount > 0
}
var homeserverDetailsUnderlyingReturnValue: HomeserverLoginDetails?
open var homeserverDetailsReturnValue: HomeserverLoginDetails? {
get {
if Thread.isMainThread {
return homeserverDetailsUnderlyingReturnValue
} else {
var returnValue: HomeserverLoginDetails?? = nil
DispatchQueue.main.sync {
returnValue = homeserverDetailsUnderlyingReturnValue
}
return returnValue!
}
}
set {
if Thread.isMainThread {
homeserverDetailsUnderlyingReturnValue = newValue
} else {
DispatchQueue.main.sync {
homeserverDetailsUnderlyingReturnValue = newValue
}
}
}
}
open var homeserverDetailsClosure: (() -> HomeserverLoginDetails?)?
open override func homeserverDetails() -> HomeserverLoginDetails? {
homeserverDetailsCallsCount += 1
if let homeserverDetailsClosure = homeserverDetailsClosure {
return homeserverDetailsClosure()
} else {
return homeserverDetailsReturnValue
}
}
//MARK: - login
open var loginUsernamePasswordInitialDeviceNameDeviceIdThrowableError: Error?
var loginUsernamePasswordInitialDeviceNameDeviceIdUnderlyingCallsCount = 0
open var loginUsernamePasswordInitialDeviceNameDeviceIdCallsCount: Int {
get {
if Thread.isMainThread {
return loginUsernamePasswordInitialDeviceNameDeviceIdUnderlyingCallsCount
} else {
var returnValue: Int? = nil
DispatchQueue.main.sync {
returnValue = loginUsernamePasswordInitialDeviceNameDeviceIdUnderlyingCallsCount
}
return returnValue!
}
}
set {
if Thread.isMainThread {
loginUsernamePasswordInitialDeviceNameDeviceIdUnderlyingCallsCount = newValue
} else {
DispatchQueue.main.sync {
loginUsernamePasswordInitialDeviceNameDeviceIdUnderlyingCallsCount = newValue
}
}
}
}
open var loginUsernamePasswordInitialDeviceNameDeviceIdCalled: Bool {
return loginUsernamePasswordInitialDeviceNameDeviceIdCallsCount > 0
}
open var loginUsernamePasswordInitialDeviceNameDeviceIdReceivedArguments: (username: String, password: String, initialDeviceName: String?, deviceId: String?)?
open var loginUsernamePasswordInitialDeviceNameDeviceIdReceivedInvocations: [(username: String, password: String, initialDeviceName: String?, deviceId: String?)] = []
var loginUsernamePasswordInitialDeviceNameDeviceIdUnderlyingReturnValue: Client!
open var loginUsernamePasswordInitialDeviceNameDeviceIdReturnValue: Client! {
get {
if Thread.isMainThread {
return loginUsernamePasswordInitialDeviceNameDeviceIdUnderlyingReturnValue
} else {
var returnValue: Client? = nil
DispatchQueue.main.sync {
returnValue = loginUsernamePasswordInitialDeviceNameDeviceIdUnderlyingReturnValue
}
return returnValue!
}
}
set {
if Thread.isMainThread {
loginUsernamePasswordInitialDeviceNameDeviceIdUnderlyingReturnValue = newValue
} else {
DispatchQueue.main.sync {
loginUsernamePasswordInitialDeviceNameDeviceIdUnderlyingReturnValue = newValue
}
}
}
}
open var loginUsernamePasswordInitialDeviceNameDeviceIdClosure: ((String, String, String?, String?) async throws -> Client)?
open override func login(username: String, password: String, initialDeviceName: String?, deviceId: String?) async throws -> Client {
if let error = loginUsernamePasswordInitialDeviceNameDeviceIdThrowableError {
throw error
}
loginUsernamePasswordInitialDeviceNameDeviceIdCallsCount += 1
loginUsernamePasswordInitialDeviceNameDeviceIdReceivedArguments = (username: username, password: password, initialDeviceName: initialDeviceName, deviceId: deviceId)
DispatchQueue.main.async {
self.loginUsernamePasswordInitialDeviceNameDeviceIdReceivedInvocations.append((username: username, password: password, initialDeviceName: initialDeviceName, deviceId: deviceId))
}
if let loginUsernamePasswordInitialDeviceNameDeviceIdClosure = loginUsernamePasswordInitialDeviceNameDeviceIdClosure {
return try await loginUsernamePasswordInitialDeviceNameDeviceIdClosure(username, password, initialDeviceName, deviceId)
} else {
return loginUsernamePasswordInitialDeviceNameDeviceIdReturnValue
}
}
//MARK: - loginWithOidcCallback
open var loginWithOidcCallbackAuthenticationDataCallbackUrlThrowableError: Error?
var loginWithOidcCallbackAuthenticationDataCallbackUrlUnderlyingCallsCount = 0
open var loginWithOidcCallbackAuthenticationDataCallbackUrlCallsCount: Int {
get {
if Thread.isMainThread {
return loginWithOidcCallbackAuthenticationDataCallbackUrlUnderlyingCallsCount
} else {
var returnValue: Int? = nil
DispatchQueue.main.sync {
returnValue = loginWithOidcCallbackAuthenticationDataCallbackUrlUnderlyingCallsCount
}
return returnValue!
}
}
set {
if Thread.isMainThread {
loginWithOidcCallbackAuthenticationDataCallbackUrlUnderlyingCallsCount = newValue
} else {
DispatchQueue.main.sync {
loginWithOidcCallbackAuthenticationDataCallbackUrlUnderlyingCallsCount = newValue
}
}
}
}
open var loginWithOidcCallbackAuthenticationDataCallbackUrlCalled: Bool {
return loginWithOidcCallbackAuthenticationDataCallbackUrlCallsCount > 0
}
open var loginWithOidcCallbackAuthenticationDataCallbackUrlReceivedArguments: (authenticationData: OidcAuthenticationData, callbackUrl: String)?
open var loginWithOidcCallbackAuthenticationDataCallbackUrlReceivedInvocations: [(authenticationData: OidcAuthenticationData, callbackUrl: String)] = []
var loginWithOidcCallbackAuthenticationDataCallbackUrlUnderlyingReturnValue: Client!
open var loginWithOidcCallbackAuthenticationDataCallbackUrlReturnValue: Client! {
get {
if Thread.isMainThread {
return loginWithOidcCallbackAuthenticationDataCallbackUrlUnderlyingReturnValue
} else {
var returnValue: Client? = nil
DispatchQueue.main.sync {
returnValue = loginWithOidcCallbackAuthenticationDataCallbackUrlUnderlyingReturnValue
}
return returnValue!
}
}
set {
if Thread.isMainThread {
loginWithOidcCallbackAuthenticationDataCallbackUrlUnderlyingReturnValue = newValue
} else {
DispatchQueue.main.sync {
loginWithOidcCallbackAuthenticationDataCallbackUrlUnderlyingReturnValue = newValue
}
}
}
}
open var loginWithOidcCallbackAuthenticationDataCallbackUrlClosure: ((OidcAuthenticationData, String) async throws -> Client)?
open override func loginWithOidcCallback(authenticationData: OidcAuthenticationData, callbackUrl: String) async throws -> Client {
if let error = loginWithOidcCallbackAuthenticationDataCallbackUrlThrowableError {
throw error
}
loginWithOidcCallbackAuthenticationDataCallbackUrlCallsCount += 1
loginWithOidcCallbackAuthenticationDataCallbackUrlReceivedArguments = (authenticationData: authenticationData, callbackUrl: callbackUrl)
DispatchQueue.main.async {
self.loginWithOidcCallbackAuthenticationDataCallbackUrlReceivedInvocations.append((authenticationData: authenticationData, callbackUrl: callbackUrl))
}
if let loginWithOidcCallbackAuthenticationDataCallbackUrlClosure = loginWithOidcCallbackAuthenticationDataCallbackUrlClosure {
return try await loginWithOidcCallbackAuthenticationDataCallbackUrlClosure(authenticationData, callbackUrl)
} else {
return loginWithOidcCallbackAuthenticationDataCallbackUrlReturnValue
}
}
//MARK: - urlForOidcLogin
open var urlForOidcLoginThrowableError: Error?
var urlForOidcLoginUnderlyingCallsCount = 0
open var urlForOidcLoginCallsCount: Int {
get {
if Thread.isMainThread {
return urlForOidcLoginUnderlyingCallsCount
} else {
var returnValue: Int? = nil
DispatchQueue.main.sync {
returnValue = urlForOidcLoginUnderlyingCallsCount
}
return returnValue!
}
}
set {
if Thread.isMainThread {
urlForOidcLoginUnderlyingCallsCount = newValue
} else {
DispatchQueue.main.sync {
urlForOidcLoginUnderlyingCallsCount = newValue
}
}
}
}
open var urlForOidcLoginCalled: Bool {
return urlForOidcLoginCallsCount > 0
}
var urlForOidcLoginUnderlyingReturnValue: OidcAuthenticationData!
open var urlForOidcLoginReturnValue: OidcAuthenticationData! {
get {
if Thread.isMainThread {
return urlForOidcLoginUnderlyingReturnValue
} else {
var returnValue: OidcAuthenticationData? = nil
DispatchQueue.main.sync {
returnValue = urlForOidcLoginUnderlyingReturnValue
}
return returnValue!
}
}
set {
if Thread.isMainThread {
urlForOidcLoginUnderlyingReturnValue = newValue
} else {
DispatchQueue.main.sync {
urlForOidcLoginUnderlyingReturnValue = newValue
}
}
}
}
open var urlForOidcLoginClosure: (() async throws -> OidcAuthenticationData)?
open override func urlForOidcLogin() async throws -> OidcAuthenticationData {
if let error = urlForOidcLoginThrowableError {
throw error
}
urlForOidcLoginCallsCount += 1
if let urlForOidcLoginClosure = urlForOidcLoginClosure {
return try await urlForOidcLoginClosure()
} else {
return urlForOidcLoginReturnValue
}
}
}
open class ClientSDKMock: MatrixRustSDK.Client {
init() {
super.init(noPointer: .init())
@@ -432,6 +91,48 @@ open class ClientSDKMock: MatrixRustSDK.Client {
fileprivate var pointer: UnsafeMutableRawPointer!
//MARK: - abortOidcLogin
var abortOidcLoginAuthorizationDataUnderlyingCallsCount = 0
open var abortOidcLoginAuthorizationDataCallsCount: Int {
get {
if Thread.isMainThread {
return abortOidcLoginAuthorizationDataUnderlyingCallsCount
} else {
var returnValue: Int? = nil
DispatchQueue.main.sync {
returnValue = abortOidcLoginAuthorizationDataUnderlyingCallsCount
}
return returnValue!
}
}
set {
if Thread.isMainThread {
abortOidcLoginAuthorizationDataUnderlyingCallsCount = newValue
} else {
DispatchQueue.main.sync {
abortOidcLoginAuthorizationDataUnderlyingCallsCount = newValue
}
}
}
}
open var abortOidcLoginAuthorizationDataCalled: Bool {
return abortOidcLoginAuthorizationDataCallsCount > 0
}
open var abortOidcLoginAuthorizationDataReceivedAuthorizationData: OidcAuthorizationData?
open var abortOidcLoginAuthorizationDataReceivedInvocations: [OidcAuthorizationData] = []
open var abortOidcLoginAuthorizationDataClosure: ((OidcAuthorizationData) async -> Void)?
open override func abortOidcLogin(authorizationData: OidcAuthorizationData) async {
abortOidcLoginAuthorizationDataCallsCount += 1
abortOidcLoginAuthorizationDataReceivedAuthorizationData = authorizationData
DispatchQueue.main.async {
self.abortOidcLoginAuthorizationDataReceivedInvocations.append(authorizationData)
}
await abortOidcLoginAuthorizationDataClosure?(authorizationData)
}
//MARK: - accountData
open var accountDataEventTypeThrowableError: Error?
@@ -1879,6 +1580,71 @@ open class ClientSDKMock: MatrixRustSDK.Client {
}
}
//MARK: - homeserverLoginDetails
var homeserverLoginDetailsUnderlyingCallsCount = 0
open var homeserverLoginDetailsCallsCount: Int {
get {
if Thread.isMainThread {
return homeserverLoginDetailsUnderlyingCallsCount
} else {
var returnValue: Int? = nil
DispatchQueue.main.sync {
returnValue = homeserverLoginDetailsUnderlyingCallsCount
}
return returnValue!
}
}
set {
if Thread.isMainThread {
homeserverLoginDetailsUnderlyingCallsCount = newValue
} else {
DispatchQueue.main.sync {
homeserverLoginDetailsUnderlyingCallsCount = newValue
}
}
}
}
open var homeserverLoginDetailsCalled: Bool {
return homeserverLoginDetailsCallsCount > 0
}
var homeserverLoginDetailsUnderlyingReturnValue: HomeserverLoginDetails!
open var homeserverLoginDetailsReturnValue: HomeserverLoginDetails! {
get {
if Thread.isMainThread {
return homeserverLoginDetailsUnderlyingReturnValue
} else {
var returnValue: HomeserverLoginDetails? = nil
DispatchQueue.main.sync {
returnValue = homeserverLoginDetailsUnderlyingReturnValue
}
return returnValue!
}
}
set {
if Thread.isMainThread {
homeserverLoginDetailsUnderlyingReturnValue = newValue
} else {
DispatchQueue.main.sync {
homeserverLoginDetailsUnderlyingReturnValue = newValue
}
}
}
}
open var homeserverLoginDetailsClosure: (() async -> HomeserverLoginDetails)?
open override func homeserverLoginDetails() async -> HomeserverLoginDetails {
homeserverLoginDetailsCallsCount += 1
if let homeserverLoginDetailsClosure = homeserverLoginDetailsClosure {
return await homeserverLoginDetailsClosure()
} else {
return homeserverLoginDetailsReturnValue
}
}
//MARK: - ignoreUser
open var ignoreUserUserIdThrowableError: Error?
@@ -2190,6 +1956,52 @@ open class ClientSDKMock: MatrixRustSDK.Client {
try await loginUsernamePasswordInitialDeviceNameDeviceIdClosure?(username, password, initialDeviceName, deviceId)
}
//MARK: - loginWithOidcCallback
open var loginWithOidcCallbackAuthorizationDataCallbackUrlThrowableError: Error?
var loginWithOidcCallbackAuthorizationDataCallbackUrlUnderlyingCallsCount = 0
open var loginWithOidcCallbackAuthorizationDataCallbackUrlCallsCount: Int {
get {
if Thread.isMainThread {
return loginWithOidcCallbackAuthorizationDataCallbackUrlUnderlyingCallsCount
} else {
var returnValue: Int? = nil
DispatchQueue.main.sync {
returnValue = loginWithOidcCallbackAuthorizationDataCallbackUrlUnderlyingCallsCount
}
return returnValue!
}
}
set {
if Thread.isMainThread {
loginWithOidcCallbackAuthorizationDataCallbackUrlUnderlyingCallsCount = newValue
} else {
DispatchQueue.main.sync {
loginWithOidcCallbackAuthorizationDataCallbackUrlUnderlyingCallsCount = newValue
}
}
}
}
open var loginWithOidcCallbackAuthorizationDataCallbackUrlCalled: Bool {
return loginWithOidcCallbackAuthorizationDataCallbackUrlCallsCount > 0
}
open var loginWithOidcCallbackAuthorizationDataCallbackUrlReceivedArguments: (authorizationData: OidcAuthorizationData, callbackUrl: String)?
open var loginWithOidcCallbackAuthorizationDataCallbackUrlReceivedInvocations: [(authorizationData: OidcAuthorizationData, callbackUrl: String)] = []
open var loginWithOidcCallbackAuthorizationDataCallbackUrlClosure: ((OidcAuthorizationData, String) async throws -> Void)?
open override func loginWithOidcCallback(authorizationData: OidcAuthorizationData, callbackUrl: String) async throws {
if let error = loginWithOidcCallbackAuthorizationDataCallbackUrlThrowableError {
throw error
}
loginWithOidcCallbackAuthorizationDataCallbackUrlCallsCount += 1
loginWithOidcCallbackAuthorizationDataCallbackUrlReceivedArguments = (authorizationData: authorizationData, callbackUrl: callbackUrl)
DispatchQueue.main.async {
self.loginWithOidcCallbackAuthorizationDataCallbackUrlReceivedInvocations.append((authorizationData: authorizationData, callbackUrl: callbackUrl))
}
try await loginWithOidcCallbackAuthorizationDataCallbackUrlClosure?(authorizationData, callbackUrl)
}
//MARK: - logout
open var logoutThrowableError: Error?
@@ -3398,6 +3210,81 @@ open class ClientSDKMock: MatrixRustSDK.Client {
}
}
//MARK: - urlForOidcLogin
open var urlForOidcLoginOidcConfigurationThrowableError: Error?
var urlForOidcLoginOidcConfigurationUnderlyingCallsCount = 0
open var urlForOidcLoginOidcConfigurationCallsCount: Int {
get {
if Thread.isMainThread {
return urlForOidcLoginOidcConfigurationUnderlyingCallsCount
} else {
var returnValue: Int? = nil
DispatchQueue.main.sync {
returnValue = urlForOidcLoginOidcConfigurationUnderlyingCallsCount
}
return returnValue!
}
}
set {
if Thread.isMainThread {
urlForOidcLoginOidcConfigurationUnderlyingCallsCount = newValue
} else {
DispatchQueue.main.sync {
urlForOidcLoginOidcConfigurationUnderlyingCallsCount = newValue
}
}
}
}
open var urlForOidcLoginOidcConfigurationCalled: Bool {
return urlForOidcLoginOidcConfigurationCallsCount > 0
}
open var urlForOidcLoginOidcConfigurationReceivedOidcConfiguration: OidcConfiguration?
open var urlForOidcLoginOidcConfigurationReceivedInvocations: [OidcConfiguration] = []
var urlForOidcLoginOidcConfigurationUnderlyingReturnValue: OidcAuthorizationData!
open var urlForOidcLoginOidcConfigurationReturnValue: OidcAuthorizationData! {
get {
if Thread.isMainThread {
return urlForOidcLoginOidcConfigurationUnderlyingReturnValue
} else {
var returnValue: OidcAuthorizationData? = nil
DispatchQueue.main.sync {
returnValue = urlForOidcLoginOidcConfigurationUnderlyingReturnValue
}
return returnValue!
}
}
set {
if Thread.isMainThread {
urlForOidcLoginOidcConfigurationUnderlyingReturnValue = newValue
} else {
DispatchQueue.main.sync {
urlForOidcLoginOidcConfigurationUnderlyingReturnValue = newValue
}
}
}
}
open var urlForOidcLoginOidcConfigurationClosure: ((OidcConfiguration) async throws -> OidcAuthorizationData)?
open override func urlForOidcLogin(oidcConfiguration: OidcConfiguration) async throws -> OidcAuthorizationData {
if let error = urlForOidcLoginOidcConfigurationThrowableError {
throw error
}
urlForOidcLoginOidcConfigurationCallsCount += 1
urlForOidcLoginOidcConfigurationReceivedOidcConfiguration = oidcConfiguration
DispatchQueue.main.async {
self.urlForOidcLoginOidcConfigurationReceivedInvocations.append(oidcConfiguration)
}
if let urlForOidcLoginOidcConfigurationClosure = urlForOidcLoginOidcConfigurationClosure {
return try await urlForOidcLoginOidcConfigurationClosure(oidcConfiguration)
} else {
return urlForOidcLoginOidcConfigurationReturnValue
}
}
//MARK: - userId
open var userIdThrowableError: Error?
@@ -4320,6 +4207,71 @@ open class ClientBuilderSDKMock: MatrixRustSDK.ClientBuilder {
}
}
//MARK: - requiresSlidingSync
var requiresSlidingSyncUnderlyingCallsCount = 0
open var requiresSlidingSyncCallsCount: Int {
get {
if Thread.isMainThread {
return requiresSlidingSyncUnderlyingCallsCount
} else {
var returnValue: Int? = nil
DispatchQueue.main.sync {
returnValue = requiresSlidingSyncUnderlyingCallsCount
}
return returnValue!
}
}
set {
if Thread.isMainThread {
requiresSlidingSyncUnderlyingCallsCount = newValue
} else {
DispatchQueue.main.sync {
requiresSlidingSyncUnderlyingCallsCount = newValue
}
}
}
}
open var requiresSlidingSyncCalled: Bool {
return requiresSlidingSyncCallsCount > 0
}
var requiresSlidingSyncUnderlyingReturnValue: ClientBuilder!
open var requiresSlidingSyncReturnValue: ClientBuilder! {
get {
if Thread.isMainThread {
return requiresSlidingSyncUnderlyingReturnValue
} else {
var returnValue: ClientBuilder? = nil
DispatchQueue.main.sync {
returnValue = requiresSlidingSyncUnderlyingReturnValue
}
return returnValue!
}
}
set {
if Thread.isMainThread {
requiresSlidingSyncUnderlyingReturnValue = newValue
} else {
DispatchQueue.main.sync {
requiresSlidingSyncUnderlyingReturnValue = newValue
}
}
}
}
open var requiresSlidingSyncClosure: (() -> ClientBuilder)?
open override func requiresSlidingSync() -> ClientBuilder {
requiresSlidingSyncCallsCount += 1
if let requiresSlidingSyncClosure = requiresSlidingSyncClosure {
return requiresSlidingSyncClosure()
} else {
return requiresSlidingSyncReturnValue
}
}
//MARK: - serverName
var serverNameServerNameUnderlyingCallsCount = 0
@@ -9294,82 +9246,6 @@ open class NotificationSettingsSDKMock: MatrixRustSDK.NotificationSettings {
try await unmuteRoomRoomIdIsEncryptedIsOneToOneClosure?(roomId, isEncrypted, isOneToOne)
}
}
open class OidcAuthenticationDataSDKMock: MatrixRustSDK.OidcAuthenticationData {
init() {
super.init(noPointer: .init())
}
public required init(unsafeFromRawPointer pointer: UnsafeMutableRawPointer) {
fatalError("init(unsafeFromRawPointer:) has not been implemented")
}
fileprivate var pointer: UnsafeMutableRawPointer!
//MARK: - loginUrl
var loginUrlUnderlyingCallsCount = 0
open var loginUrlCallsCount: Int {
get {
if Thread.isMainThread {
return loginUrlUnderlyingCallsCount
} else {
var returnValue: Int? = nil
DispatchQueue.main.sync {
returnValue = loginUrlUnderlyingCallsCount
}
return returnValue!
}
}
set {
if Thread.isMainThread {
loginUrlUnderlyingCallsCount = newValue
} else {
DispatchQueue.main.sync {
loginUrlUnderlyingCallsCount = newValue
}
}
}
}
open var loginUrlCalled: Bool {
return loginUrlCallsCount > 0
}
var loginUrlUnderlyingReturnValue: String!
open var loginUrlReturnValue: String! {
get {
if Thread.isMainThread {
return loginUrlUnderlyingReturnValue
} else {
var returnValue: String? = nil
DispatchQueue.main.sync {
returnValue = loginUrlUnderlyingReturnValue
}
return returnValue!
}
}
set {
if Thread.isMainThread {
loginUrlUnderlyingReturnValue = newValue
} else {
DispatchQueue.main.sync {
loginUrlUnderlyingReturnValue = newValue
}
}
}
}
open var loginUrlClosure: (() -> String)?
open override func loginUrl() -> String {
loginUrlCallsCount += 1
if let loginUrlClosure = loginUrlClosure {
return loginUrlClosure()
} else {
return loginUrlReturnValue
}
}
}
open class QrCodeDataSDKMock: MatrixRustSDK.QrCodeData {
init() {
super.init(noPointer: .init())
@@ -0,0 +1,42 @@
//
// Copyright 2024 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.
//
import Foundation
import MatrixRustSDK
extension ClientBuilder {
/// A helper method that applies the common builder modifiers needed for the app.
static func baseBuilder(setupEncryption: Bool = true, httpProxy: String? = nil, slidingSyncProxy: URL? = nil, sessionDelegate: ClientSessionDelegate) -> ClientBuilder {
var builder = ClientBuilder()
.slidingSyncProxy(slidingSyncProxy: slidingSyncProxy?.absoluteString)
.enableCrossProcessRefreshLock(processId: InfoPlistReader.main.bundleIdentifier, sessionDelegate: sessionDelegate)
.userAgent(userAgent: UserAgentBuilder.makeASCIIUserAgent())
.serverVersions(versions: ["v1.0", "v1.1", "v1.2", "v1.3", "v1.4", "v1.5"]) // FIXME: Quick and dirty fix for stopping version requests on startup https://github.com/matrix-org/matrix-rust-sdk/pull/1376
if setupEncryption {
builder = builder
.autoEnableCrossSigning(autoEnableCrossSigning: true)
.backupDownloadStrategy(backupDownloadStrategy: .afterDecryptionFailure)
.autoEnableBackups(autoEnableBackups: true)
}
if let httpProxy {
builder = builder.proxy(url: httpProxy)
}
return builder
}
}
@@ -19,7 +19,7 @@ import SwiftUI
struct LoginScreenCoordinatorParameters {
/// The service used to authenticate the user.
let authenticationService: AuthenticationServiceProxyProtocol
let authenticationService: AuthenticationServiceProtocol
let analytics: AnalyticsService
let userIndicatorController: UserIndicatorControllerProtocol
@@ -38,7 +38,7 @@ final class LoginScreenCoordinator: CoordinatorProtocol {
private let parameters: LoginScreenCoordinatorParameters
private var viewModel: LoginScreenViewModelProtocol
private var authenticationService: AuthenticationServiceProxyProtocol { parameters.authenticationService }
private var authenticationService: AuthenticationServiceProtocol { parameters.authenticationService }
private let actionsSubject: PassthroughSubject<LoginScreenCoordinatorAction, Never> = .init()
private var cancellables = Set<AnyCancellable>()
@@ -19,21 +19,21 @@ import AuthenticationServices
/// Presents a web authentication session for an OIDC request.
@MainActor
class OIDCAuthenticationPresenter: NSObject {
private let authenticationService: AuthenticationServiceProxyProtocol
private let authenticationService: AuthenticationServiceProtocol
private let oidcRedirectURL: URL
private let presentationAnchor: UIWindow
/// The data required to complete a request.
struct Request {
let session: ASWebAuthenticationSession
let oidcData: OIDCAuthenticationDataProxy
let oidcData: OIDCAuthorizationDataProxy
let continuation: CheckedContinuation<Result<UserSessionProtocol, AuthenticationServiceError>, Never>
}
/// The current request in progress. This is a single use value and will be moved on access.
@Consumable private var request: Request?
init(authenticationService: AuthenticationServiceProxyProtocol, oidcRedirectURL: URL, presentationAnchor: UIWindow) {
init(authenticationService: AuthenticationServiceProtocol, oidcRedirectURL: URL, presentationAnchor: UIWindow) {
self.authenticationService = authenticationService
self.oidcRedirectURL = oidcRedirectURL
self.presentationAnchor = presentationAnchor
@@ -41,7 +41,7 @@ class OIDCAuthenticationPresenter: NSObject {
}
/// Presents a web authentication session for the supplied data.
func authenticate(using oidcData: OIDCAuthenticationDataProxy) async -> Result<UserSessionProtocol, AuthenticationServiceError> {
func authenticate(using oidcData: OIDCAuthorizationDataProxy) async -> Result<UserSessionProtocol, AuthenticationServiceError> {
await withCheckedContinuation { continuation in
let session = ASWebAuthenticationSession(url: oidcData.url,
callbackURLScheme: oidcRedirectURL.scheme) { [weak self] url, error in
@@ -107,7 +107,10 @@ class OIDCAuthenticationPresenter: NSObject {
return
}
request.continuation.resume(returning: .failure(error))
Task {
await authenticationService.abortOIDCLogin(data: request.oidcData)
request.continuation.resume(returning: .failure(error))
}
}
}
@@ -18,7 +18,7 @@ import Combine
import SwiftUI
struct ServerConfirmationScreenCoordinatorParameters {
let authenticationService: AuthenticationServiceProxyProtocol
let authenticationService: AuthenticationServiceProtocol
let authenticationFlow: AuthenticationFlow
}
@@ -26,7 +26,7 @@ class ServerConfirmationScreenViewModel: ServerConfirmationScreenViewModelType,
actionsSubject.eraseToAnyPublisher()
}
init(authenticationService: AuthenticationServiceProxyProtocol, authenticationFlow: AuthenticationFlow) {
init(authenticationService: AuthenticationServiceProtocol, authenticationFlow: AuthenticationFlow) {
super.init(initialViewState: ServerConfirmationScreenViewState(homeserverAddress: authenticationService.homeserver.value.address,
authenticationFlow: authenticationFlow))
@@ -19,7 +19,7 @@ import SwiftUI
struct ServerSelectionScreenCoordinatorParameters {
/// The service used to authenticate the user.
let authenticationService: AuthenticationServiceProxyProtocol
let authenticationService: AuthenticationServiceProtocol
let userIndicatorController: UserIndicatorControllerProtocol
/// Whether the screen is presented modally or within a navigation stack.
let isModallyPresented: Bool
@@ -34,7 +34,7 @@ final class ServerSelectionScreenCoordinator: CoordinatorProtocol {
private let parameters: ServerSelectionScreenCoordinatorParameters
private let userIndicatorController: UserIndicatorControllerProtocol
private var viewModel: ServerSelectionScreenViewModelProtocol
private var authenticationService: AuthenticationServiceProxyProtocol { parameters.authenticationService }
private var authenticationService: AuthenticationServiceProtocol { parameters.authenticationService }
private let actionsSubject: PassthroughSubject<ServerSelectionScreenCoordinatorAction, Never> = .init()
private var cancellables = Set<AnyCancellable>()
@@ -18,7 +18,7 @@ import Combine
import SwiftUI
struct SoftLogoutScreenCoordinatorParameters {
let authenticationService: AuthenticationServiceProxyProtocol
let authenticationService: AuthenticationServiceProtocol
let credentials: SoftLogoutScreenCredentials
let keyBackupNeeded: Bool
let userIndicatorController: UserIndicatorControllerProtocol
@@ -47,7 +47,7 @@ final class SoftLogoutScreenCoordinator: CoordinatorProtocol {
private let actionsSubject: PassthroughSubject<SoftLogoutScreenCoordinatorResult, Never> = .init()
private var cancellables = Set<AnyCancellable>()
private var authenticationService: AuthenticationServiceProxyProtocol { parameters.authenticationService }
private var authenticationService: AuthenticationServiceProtocol { parameters.authenticationService }
private var oidcPresenter: OIDCAuthenticationPresenter?
var actions: AnyPublisher<SoftLogoutScreenCoordinatorResult, Never> {
@@ -21,7 +21,7 @@ struct WaitlistScreenCoordinatorParameters {
/// The credentials for the login.
let credentials: WaitlistScreenCredentials
/// The service used to authenticate the user.
let authenticationService: AuthenticationServiceProxyProtocol
let authenticationService: AuthenticationServiceProtocol
/// The service locator for the screen.
var userIndicatorController: UserIndicatorControllerProtocol = ServiceLocator.shared.userIndicatorController
}
@@ -18,12 +18,14 @@ import Combine
import Foundation
import MatrixRustSDK
class AuthenticationServiceProxy: AuthenticationServiceProxyProtocol {
private let authenticationService: AuthenticationService
private let userSessionStore: UserSessionStoreProtocol
class AuthenticationService: AuthenticationServiceProtocol {
private var client: Client?
private let sessionDirectory: URL
private let passphrase: String
private let userSessionStore: UserSessionStoreProtocol
private let appSettings: AppSettings
private let homeserverSubject: CurrentValueSubject<LoginHomeserver, Never>
var homeserver: CurrentValuePublisher<LoginHomeserver, Never> { homeserverSubject.asCurrentValuePublisher() }
@@ -31,19 +33,10 @@ class AuthenticationServiceProxy: AuthenticationServiceProxyProtocol {
sessionDirectory = .sessionsBaseDirectory.appending(component: UUID().uuidString)
passphrase = encryptionKeyProvider.generateKey().base64EncodedString()
self.userSessionStore = userSessionStore
self.appSettings = appSettings
homeserverSubject = .init(LoginHomeserver(address: appSettings.defaultHomeserverAddress,
loginMode: .unknown))
authenticationService = AuthenticationService(sessionPath: sessionDirectory.path(percentEncoded: false),
passphrase: passphrase,
userAgent: UserAgentBuilder.makeASCIIUserAgent(),
additionalRootCertificates: [],
proxy: appSettings.websiteURL.globalProxy,
oidcConfiguration: appSettings.oidcConfiguration.rustValue,
customSlidingSyncProxy: appSettings.slidingSyncProxyURL?.absoluteString,
sessionDelegate: userSessionStore.clientSessionDelegate,
crossProcessRefreshLockId: InfoPlistReader.main.bundleIdentifier)
}
// MARK: - Public
@@ -52,24 +45,24 @@ class AuthenticationServiceProxy: AuthenticationServiceProxyProtocol {
do {
var homeserver = LoginHomeserver(address: homeserverAddress, loginMode: .unknown)
try await authenticationService.configureHomeserver(serverNameOrHomeserverUrl: homeserverAddress)
let client = try await makeClientBuilder().serverNameOrHomeserverUrl(serverNameOrUrl: homeserverAddress).build()
let loginDetails = await client.homeserverLoginDetails()
if let details = authenticationService.homeserverDetails() {
if details.supportsOidcLogin() {
homeserver.loginMode = .oidc
} else if details.supportsPasswordLogin() {
homeserver.loginMode = .password
} else {
homeserver.loginMode = .unsupported
}
if loginDetails.supportsOidcLogin() {
homeserver.loginMode = .oidc
} else if loginDetails.supportsPasswordLogin() {
homeserver.loginMode = .password
} else {
homeserver.loginMode = .unsupported
}
self.client = client
homeserverSubject.send(homeserver)
return .success(())
} catch AuthenticationError.WellKnownDeserializationError(let error) {
} catch ClientBuildError.WellKnownDeserializationError(let error) {
MXLog.error("The user entered a server with an invalid well-known file: \(error)")
return .failure(.invalidWellKnown(error))
} catch AuthenticationError.SlidingSyncNotAvailable {
} catch ClientBuildError.SlidingSyncNotAvailable {
MXLog.info("User entered a homeserver that isn't configured for sliding sync.")
return .failure(.slidingSyncNotAvailable)
} catch {
@@ -78,21 +71,29 @@ class AuthenticationServiceProxy: AuthenticationServiceProxyProtocol {
}
}
func urlForOIDCLogin() async -> Result<OIDCAuthenticationDataProxy, AuthenticationServiceError> {
func urlForOIDCLogin() async -> Result<OIDCAuthorizationDataProxy, AuthenticationServiceError> {
guard let client else { return .failure(.oidcError(.urlFailure)) }
do {
let oidcData = try await authenticationService.urlForOidcLogin()
return .success(OIDCAuthenticationDataProxy(underlyingData: oidcData))
let oidcData = try await client.urlForOidcLogin(oidcConfiguration: appSettings.oidcConfiguration.rustValue)
return .success(OIDCAuthorizationDataProxy(underlyingData: oidcData))
} catch {
MXLog.error("Failed to get URL for OIDC login: \(error)")
return .failure(.oidcError(.urlFailure))
}
}
func loginWithOIDCCallback(_ callbackURL: URL, data: OIDCAuthenticationDataProxy) async -> Result<UserSessionProtocol, AuthenticationServiceError> {
func abortOIDCLogin(data: OIDCAuthorizationDataProxy) async {
guard let client else { return }
MXLog.info("Aborting OIDC login.")
await client.abortOidcLogin(authorizationData: data.underlyingData)
}
func loginWithOIDCCallback(_ callbackURL: URL, data: OIDCAuthorizationDataProxy) async -> Result<UserSessionProtocol, AuthenticationServiceError> {
guard let client else { return .failure(.failedLoggingIn) }
do {
let client = try await authenticationService.loginWithOidcCallback(authenticationData: data.underlyingData, callbackUrl: callbackURL.absoluteString)
try await client.loginWithOidcCallback(authorizationData: data.underlyingData, callbackUrl: callbackURL.absoluteString)
return await userSession(for: client)
} catch AuthenticationError.OidcCancelled {
} catch OidcError.Cancelled {
return .failure(.oidcError(.userCancellation))
} catch {
MXLog.error("Login with OIDC failed: \(error)")
@@ -101,14 +102,11 @@ class AuthenticationServiceProxy: AuthenticationServiceProxyProtocol {
}
func login(username: String, password: String, initialDeviceName: String?, deviceID: String?) async -> Result<UserSessionProtocol, AuthenticationServiceError> {
guard let client else { return .failure(.failedLoggingIn) }
do {
let client = try await authenticationService.login(username: username,
password: password,
initialDeviceName: initialDeviceName,
deviceId: deviceID)
try await client.login(username: username, password: password, initialDeviceName: initialDeviceName, deviceId: deviceID)
let refreshToken = try? client.session().refreshToken
if refreshToken != nil {
MXLog.warning("Refresh token found for a non oidc session, can't restore session, logging out")
_ = try? await client.logout()
@@ -118,7 +116,8 @@ class AuthenticationServiceProxy: AuthenticationServiceProxyProtocol {
return await userSession(for: client)
} catch {
MXLog.error("Failed logging in with error: \(error)")
guard let error = error as? AuthenticationError else { return .failure(.failedLoggingIn) }
// FIXME: How about we make a proper type in the FFI? 😅
guard let error = error as? ClientError else { return .failure(.failedLoggingIn) }
if error.isElementWaitlist {
return .failure(.isOnWaitlist)
@@ -137,6 +136,16 @@ class AuthenticationServiceProxy: AuthenticationServiceProxyProtocol {
// MARK: - Private
private func makeClientBuilder() -> ClientBuilder {
ClientBuilder
.baseBuilder(httpProxy: appSettings.websiteURL.globalProxy,
slidingSyncProxy: appSettings.slidingSyncProxyURL,
sessionDelegate: userSessionStore.clientSessionDelegate)
.sessionPath(path: sessionDirectory.path(percentEncoded: false))
.passphrase(passphrase: passphrase)
.requiresSlidingSync()
}
private func userSession(for client: Client) async -> Result<UserSessionProtocol, AuthenticationServiceError> {
switch await userSessionStore.userSession(for: client, sessionDirectory: sessionDirectory, passphrase: passphrase) {
case .success(let clientProxy):
@@ -39,16 +39,18 @@ enum AuthenticationServiceError: Error {
case sessionTokenRefreshNotSupported
}
protocol AuthenticationServiceProxyProtocol {
protocol AuthenticationServiceProtocol {
/// The currently configured homeserver.
var homeserver: CurrentValuePublisher<LoginHomeserver, Never> { get }
/// Sets up the service for login on the specified homeserver address.
func configure(for homeserverAddress: String) async -> Result<Void, AuthenticationServiceError>
/// Performs login using OIDC for the current homeserver.
func urlForOIDCLogin() async -> Result<OIDCAuthenticationDataProxy, AuthenticationServiceError>
/// Add docs.
func loginWithOIDCCallback(_ callbackURL: URL, data: OIDCAuthenticationDataProxy) async -> Result<UserSessionProtocol, AuthenticationServiceError>
func urlForOIDCLogin() async -> Result<OIDCAuthorizationDataProxy, AuthenticationServiceError>
/// Asks the SDK to abort an ongoing OIDC login if we didn't get a callback to complete the request with.
func abortOIDCLogin(data: OIDCAuthorizationDataProxy) async
/// Completes an OIDC login that was started using ``urlForOIDCLogin``.
func loginWithOIDCCallback(_ callbackURL: URL, data: OIDCAuthorizationDataProxy) async -> Result<UserSessionProtocol, AuthenticationServiceError>
/// Performs a password login using the current homeserver.
func login(username: String, password: String, initialDeviceName: String?, deviceID: String?) async -> Result<UserSessionProtocol, AuthenticationServiceError>
}
@@ -66,8 +68,8 @@ enum OIDCError: Error {
case unknown
}
struct OIDCAuthenticationDataProxy: Equatable {
let underlyingData: OidcAuthenticationData
struct OIDCAuthorizationDataProxy: Equatable {
let underlyingData: OidcAuthorizationData
var url: URL {
guard let url = URL(string: underlyingData.loginUrl()) else {
@@ -77,8 +79,8 @@ struct OIDCAuthenticationDataProxy: Equatable {
}
}
extension OidcAuthenticationData: Equatable {
public static func == (lhs: MatrixRustSDK.OidcAuthenticationData, rhs: MatrixRustSDK.OidcAuthenticationData) -> Bool {
extension OidcAuthorizationData: Equatable {
public static func == (lhs: MatrixRustSDK.OidcAuthorizationData, rhs: MatrixRustSDK.OidcAuthorizationData) -> Bool {
lhs.loginUrl() == rhs.loginUrl()
}
}
@@ -18,7 +18,7 @@ import Combine
import Foundation
import MatrixRustSDK
class MockAuthenticationServiceProxy: AuthenticationServiceProxyProtocol {
class MockAuthenticationServiceProxy: AuthenticationServiceProtocol {
let validCredentials = (username: "alice", password: "12345678")
private let homeserverSubject: CurrentValueSubject<LoginHomeserver, Never>
@@ -48,11 +48,13 @@ class MockAuthenticationServiceProxy: AuthenticationServiceProxyProtocol {
}
}
func urlForOIDCLogin() async -> Result<OIDCAuthenticationDataProxy, AuthenticationServiceError> {
func urlForOIDCLogin() async -> Result<OIDCAuthorizationDataProxy, AuthenticationServiceError> {
.failure(.oidcError(.notSupported))
}
func loginWithOIDCCallback(_ callbackURL: URL, data: OIDCAuthenticationDataProxy) async -> Result<UserSessionProtocol, AuthenticationServiceError> {
func abortOIDCLogin(data: OIDCAuthorizationDataProxy) async { }
func loginWithOIDCCallback(_ callbackURL: URL, data: OIDCAuthorizationDataProxy) async -> Result<UserSessionProtocol, AuthenticationServiceError> {
.failure(.oidcError(.notSupported))
}
@@ -34,18 +34,6 @@ extension ClientError {
return first
}
}
extension AuthenticationError {
var code: MatrixErrorCode {
guard case let .Generic(message) = self else { return .unknown }
guard let first = MatrixErrorCode.allCases.first(where: { message.contains($0.rawValue) }) else {
return .unknown
}
return first
}
/// Whether or not the error is related to the sliding sync proxy being full.
///
@@ -20,21 +20,21 @@ import Foundation
import MatrixRustSDK
final class QRCodeLoginService: QRCodeLoginServiceProtocol {
private let oidcConfiguration: OidcConfiguration
private let sessionDirectory: URL
private let passphrase: String
private let userSessionStore: UserSessionStoreProtocol
private let appSettings: AppSettings
private let qrLoginProgressSubject = PassthroughSubject<QrLoginProgress, Never>()
var qrLoginProgressPublisher: AnyPublisher<QrLoginProgress, Never> {
qrLoginProgressSubject.eraseToAnyPublisher()
}
init(oidcConfiguration: OidcConfiguration,
encryptionKeyProvider: EncryptionKeyProviderProtocol,
userSessionStore: UserSessionStoreProtocol) {
self.oidcConfiguration = oidcConfiguration
init(encryptionKeyProvider: EncryptionKeyProviderProtocol,
userSessionStore: UserSessionStoreProtocol,
appSettings: AppSettings) {
self.userSessionStore = userSessionStore
self.appSettings = appSettings
sessionDirectory = .sessionsBaseDirectory.appending(component: UUID().uuidString)
passphrase = encryptionKeyProvider.generateKey().base64EncodedString()
}
@@ -53,14 +53,14 @@ final class QRCodeLoginService: QRCodeLoginServiceProtocol {
}
do {
let client = try await ClientBuilder()
let client = try await ClientBuilder
.baseBuilder(httpProxy: appSettings.websiteURL.globalProxy,
slidingSyncProxy: appSettings.slidingSyncProxyURL,
sessionDelegate: userSessionStore.clientSessionDelegate)
.sessionPath(path: sessionDirectory.path(percentEncoded: false))
.passphrase(passphrase: passphrase)
.userAgent(userAgent: UserAgentBuilder.makeASCIIUserAgent())
.enableCrossProcessRefreshLock(processId: InfoPlistReader.main.bundleIdentifier,
sessionDelegate: userSessionStore.clientSessionDelegate)
.serverVersions(versions: ["v1.0", "v1.1", "v1.2", "v1.3", "v1.4", "v1.5"]) // FIXME: Quick and dirty fix for stopping version requests on startup https://github.com/matrix-org/matrix-rust-sdk/pull/1376
.buildWithQrCode(qrCodeData: qrData, oidcConfiguration: oidcConfiguration, progressListener: listener)
.requiresSlidingSync()
.buildWithQrCode(qrCodeData: qrData, oidcConfiguration: appSettings.oidcConfiguration.rustValue, progressListener: listener)
return await login(client: client)
} catch let error as HumanQrLoginError {
MXLog.error("QRCode login error: \(error)")
@@ -118,24 +118,16 @@ class UserSessionStore: UserSessionStoreProtocol {
let homeserverURL = credentials.restorationToken.session.homeserverUrl
var builder = ClientBuilder()
let builder = ClientBuilder
.baseBuilder(httpProxy: URL(string: homeserverURL)?.globalProxy,
sessionDelegate: keychainController)
.sessionPath(path: credentials.restorationToken.sessionDirectory.path(percentEncoded: false))
.username(username: credentials.userID)
.homeserverUrl(url: homeserverURL)
.passphrase(passphrase: credentials.restorationToken.passphrase)
.userAgent(userAgent: UserAgentBuilder.makeASCIIUserAgent())
.enableCrossProcessRefreshLock(processId: InfoPlistReader.main.bundleIdentifier,
sessionDelegate: keychainController)
.serverVersions(versions: ["v1.0", "v1.1", "v1.2", "v1.3", "v1.4", "v1.5"]) // FIXME: Quick and dirty fix for stopping version requests on startup https://github.com/matrix-org/matrix-rust-sdk/pull/1376
if let homeserverURL = URL(string: homeserverURL),
let proxy = homeserverURL.globalProxy {
builder = builder.proxy(url: proxy)
}
let completeBuilder = builder
do {
let client = try await completeBuilder.build()
let client = try await builder.build()
try await client.restoreSession(session: credentials.restorationToken.session)