From e435ce53a48732c6b1fdf64c82187f87e82ab4e7 Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Wed, 23 Aug 2023 19:41:33 +0200 Subject: [PATCH] 7648 completed --- Riot/Managers/Settings/RiotSettings.swift | 4 ++++ Riot/Modules/Application/LegacyAppDelegate.m | 2 ++ .../AuthenticationCoordinator.swift | 2 ++ .../Legacy/AuthenticationViewController.m | 4 ++-- .../SocialLoginButtonFactory.swift | 6 ++--- .../SocialLogin/SocialLoginListView.swift | 8 +++---- .../Modules/Settings/SettingsViewController.m | 4 ++-- .../Common/AuthenticationModels.swift | 5 ++++- .../MatrixSDK/AuthenticationService.swift | 22 +++++++++++++++---- .../Service/MatrixSDK/LoginModels.swift | 4 +--- changelog.d/7648.bugfix | 1 + 11 files changed, 43 insertions(+), 19 deletions(-) create mode 100644 changelog.d/7648.bugfix diff --git a/Riot/Managers/Settings/RiotSettings.swift b/Riot/Managers/Settings/RiotSettings.swift index 06746801ce..e74d974b76 100644 --- a/Riot/Managers/Settings/RiotSettings.swift +++ b/Riot/Managers/Settings/RiotSettings.swift @@ -33,6 +33,7 @@ final class RiotSettings: NSObject { static let enableUISIAutoReporting = "enableUISIAutoReporting" static let enableLiveLocationSharing = "enableLiveLocationSharing" static let showIPAddressesInSessionsManager = "showIPAddressesInSessionsManager" + static let isAuthenticatedWithOIDC = "isAuthenticatedWithOIDC" } static let shared = RiotSettings() @@ -74,6 +75,9 @@ final class RiotSettings: NSObject { @UserDefault(key: "identityserverurl", defaultValue: BuildSettings.serverConfigDefaultIdentityServerUrlString, storage: defaults) var identityServerUrlString + @UserDefault(key: UserDefaultsKeys.isAuthenticatedWithOIDC, defaultValue: false, storage: defaults) + var isAuthenticatedWithOIDC + // MARK: Notifications /// Indicate if `showDecryptedContentInNotifications` settings has been set once. diff --git a/Riot/Modules/Application/LegacyAppDelegate.m b/Riot/Modules/Application/LegacyAppDelegate.m index ab17eeac5c..a06137a0cf 100644 --- a/Riot/Modules/Application/LegacyAppDelegate.m +++ b/Riot/Modules/Application/LegacyAppDelegate.m @@ -2190,6 +2190,8 @@ - (void)logoutSendingRequestServer:(BOOL)sendLogoutServerRequest [TimelinePollProvider.shared reset]; + RiotSettings.shared.isAuthenticatedWithOIDC = NO; + #ifdef MX_CALL_STACK_ENDPOINT // Erase all created certificates and private keys by MXEndpointCallStack for (MXKAccount *account in MXKAccountManager.sharedManager.accounts) diff --git a/Riot/Modules/Authentication/AuthenticationCoordinator.swift b/Riot/Modules/Authentication/AuthenticationCoordinator.swift index 295a591f73..ff6f527d8f 100644 --- a/Riot/Modules/Authentication/AuthenticationCoordinator.swift +++ b/Riot/Modules/Authentication/AuthenticationCoordinator.swift @@ -681,6 +681,8 @@ extension AuthenticationCoordinator: SSOAuthenticationPresenterDelegate { return } + RiotSettings.shared.isAuthenticatedWithOIDC = identityProvider?.isOIDC ?? false + Task { await handleLoginToken(token, using: loginWizard) } } diff --git a/Riot/Modules/Authentication/Legacy/AuthenticationViewController.m b/Riot/Modules/Authentication/Legacy/AuthenticationViewController.m index c0605d8131..99d59f9bfd 100644 --- a/Riot/Modules/Authentication/Legacy/AuthenticationViewController.m +++ b/Riot/Modules/Authentication/Legacy/AuthenticationViewController.m @@ -1524,7 +1524,7 @@ - (BOOL)isSocialLoginViewShown - (CGFloat)socialLoginViewHeightFittingWidth:(CGFloat)width { - NSArray *identityProviders = self.currentLoginSSOFlow.identityProviders; + NSArray *identityProviders = self.currentLoginSSOFlow.ssoIdentityProviders; if (!identityProviders.count && self.socialLoginListView) { @@ -1546,7 +1546,7 @@ - (void)showSocialLoginViewWithLoginSSOFlow:(MXLoginSSOFlow*)loginSSOFlow andMod listView.delegate = self; } - [listView updateWith:loginSSOFlow.identityProviders mode:mode]; + [listView updateWith: loginSSOFlow.ssoIdentityProviders mode:mode]; [self refreshContentViewHeightConstraint]; } diff --git a/Riot/Modules/Authentication/Legacy/SocialLogin/SocialLoginButtonFactory.swift b/Riot/Modules/Authentication/Legacy/SocialLogin/SocialLoginButtonFactory.swift index 21a7c5d292..68a0d37477 100644 --- a/Riot/Modules/Authentication/Legacy/SocialLogin/SocialLoginButtonFactory.swift +++ b/Riot/Modules/Authentication/Legacy/SocialLogin/SocialLoginButtonFactory.swift @@ -28,7 +28,7 @@ class SocialLoginButtonFactory { // MARK - Public - func build(with identityProvider: MXLoginSSOIdentityProvider, mode: SocialLoginButtonMode) -> SocialLoginButton { + func build(with identityProvider: SSOIdentityProvider, mode: SocialLoginButtonMode) -> SocialLoginButton { let button = SocialLoginButton() let defaultStyle: SocialLoginButtonStyle @@ -37,7 +37,7 @@ class SocialLoginButtonFactory { let buildDefaultButtonStyles: () -> (SocialLoginButtonStyle, [String: SocialLoginButtonStyle]) = { let image: SourceImage? - if let imageStringURL = identityProvider.icon, let imageURL = URL(string: imageStringURL) { + if let imageStringURL = identityProvider.iconURL, let imageURL = URL(string: imageStringURL) { image = .remote(imageURL) } else { image = nil @@ -71,7 +71,7 @@ class SocialLoginButtonFactory { let title = self.buildButtonTitle(with: identityProvider.name, mode: mode) - let viewData = SocialLoginButtonViewData(identityProvider: identityProvider.ssoIdentityProvider, + let viewData = SocialLoginButtonViewData(identityProvider: identityProvider, title: title, defaultStyle: defaultStyle, themeStyles: styles) diff --git a/Riot/Modules/Authentication/Legacy/SocialLogin/SocialLoginListView.swift b/Riot/Modules/Authentication/Legacy/SocialLogin/SocialLoginListView.swift index dc80526b63..0a16356b00 100644 --- a/Riot/Modules/Authentication/Legacy/SocialLogin/SocialLoginListView.swift +++ b/Riot/Modules/Authentication/Legacy/SocialLogin/SocialLoginListView.swift @@ -61,7 +61,7 @@ final class SocialLoginListView: UIView, NibLoadable { // MARK: - Public - func update(with identityProviders: [MXLoginSSOIdentityProvider], mode: SocialLoginButtonMode) { + func update(with identityProviders: [SSOIdentityProvider], mode: SocialLoginButtonMode) { self.mode = mode let title: String @@ -89,7 +89,7 @@ final class SocialLoginListView: UIView, NibLoadable { self.buttons = buttons } - static func contentViewHeight(identityProviders: [MXLoginSSOIdentityProvider], + static func contentViewHeight(identityProviders: [SSOIdentityProvider], mode: SocialLoginButtonMode, fitting width: CGFloat) -> CGFloat { let sizingView = self.sizingView @@ -113,7 +113,7 @@ final class SocialLoginListView: UIView, NibLoadable { self.buttons = [] } - private func socialLoginButtons(for identityProviders: [MXLoginSSOIdentityProvider], mode: SocialLoginButtonMode) -> [SocialLoginButton] { + private func socialLoginButtons(for identityProviders: [SSOIdentityProvider], mode: SocialLoginButtonMode) -> [SocialLoginButton] { var buttons: [SocialLoginButton] = [] @@ -122,7 +122,7 @@ final class SocialLoginListView: UIView, NibLoadable { if let firstIdentityProviderBrand = firstIdentityProvider.brand, let secondIdentityProviderBrand = secondIdentityProvider.brand { return firstIdentityProviderBrand < secondIdentityProviderBrand } else { - return firstIdentityProvider.identifier < secondIdentityProvider.identifier + return firstIdentityProvider.id < secondIdentityProvider.id } } diff --git a/Riot/Modules/Settings/SettingsViewController.m b/Riot/Modules/Settings/SettingsViewController.m index be87bea3b8..3d4693d0a2 100644 --- a/Riot/Modules/Settings/SettingsViewController.m +++ b/Riot/Modules/Settings/SettingsViewController.m @@ -607,8 +607,8 @@ - (void)updateSections [tmpSections addObject:sectionLabs]; } } - - if (BuildSettings.settingsScreenAllowDeactivatingAccount) + + if (BuildSettings.settingsScreenAllowDeactivatingAccount && !RiotSettings.shared.isAuthenticatedWithOIDC) { Section *sectionDeactivate = [Section sectionWithTag:SECTION_TAG_DEACTIVATE_ACCOUNT]; [sectionDeactivate addRowWithTag:0]; diff --git a/RiotSwiftUI/Modules/Authentication/Common/AuthenticationModels.swift b/RiotSwiftUI/Modules/Authentication/Common/AuthenticationModels.swift index 34d7adb905..333543519e 100644 --- a/RiotSwiftUI/Modules/Authentication/Common/AuthenticationModels.swift +++ b/RiotSwiftUI/Modules/Authentication/Common/AuthenticationModels.swift @@ -112,11 +112,14 @@ class HomeserverAddress: NSObject { let brand: String? /// The icon field is an optional field that points to an icon representing the identity provider. If present then it must be an HTTPS URL to an image resource. let iconURL: String? + /// Dertermines if this provider uses OIDC + let isOIDC: Bool - init(id: String, name: String, brand: String?, iconURL: String?) { + init(id: String = "", name: String, brand: String?, iconURL: String?, isOIDC: Bool = false) { self.id = id self.name = name self.brand = brand self.iconURL = iconURL + self.isOIDC = isOIDC } } diff --git a/RiotSwiftUI/Modules/Authentication/Common/Service/MatrixSDK/AuthenticationService.swift b/RiotSwiftUI/Modules/Authentication/Common/Service/MatrixSDK/AuthenticationService.swift index 9be77dc001..4cf1affbb9 100644 --- a/RiotSwiftUI/Modules/Authentication/Common/Service/MatrixSDK/AuthenticationService.swift +++ b/RiotSwiftUI/Modules/Authentication/Common/Service/MatrixSDK/AuthenticationService.swift @@ -290,9 +290,16 @@ class AuthenticationService: NSObject { // Get the login flow let loginFlowResponse = try await client.getLoginSession() - let identityProviders = loginFlowResponse.flows?.compactMap { $0 as? MXLoginSSOFlow }.first?.identityProviders ?? [] + let loginFlow = loginFlowResponse.flows?.compactMap { $0 as? MXLoginSSOFlow }.first + var identityProviders = loginFlow?.ssoIdentityProviders ?? [] + if identityProviders.isEmpty { + // Provide a backup for homeservers that support SSO but don't offer any identity providers + // https://spec.matrix.org/latest/client-server-api/#client-login-via-sso + identityProviders = [SSOIdentityProvider(name: "SSO", brand: nil, iconURL: nil, isOIDC: loginFlow?.isOIDC ?? false)] + } + return LoginFlowResult(supportedLoginTypes: loginFlowResponse.flows?.compactMap { $0 } ?? [], - ssoIdentityProviders: identityProviders.sorted { $0.name < $1.name }.map(\.ssoIdentityProvider), + ssoIdentityProviders: identityProviders.sorted { $0.name < $1.name }, homeserverAddress: client.homeserver) } @@ -309,7 +316,14 @@ class AuthenticationService: NSObject { } extension MXLoginSSOIdentityProvider { - var ssoIdentityProvider: SSOIdentityProvider { - SSOIdentityProvider(id: identifier, name: name, brand: brand, iconURL: icon) + @objc func makeSSOIdentityProvider(isOIDC: Bool) -> SSOIdentityProvider { + SSOIdentityProvider(id: identifier, name: name, brand: brand, iconURL: icon, isOIDC: isOIDC) + } +} + +extension MXLoginSSOFlow { + @objc var ssoIdentityProviders: [SSOIdentityProvider] { + identityProviders.map { $0.makeSSOIdentityProvider(isOIDC: isOIDC)} } } + diff --git a/RiotSwiftUI/Modules/Authentication/Common/Service/MatrixSDK/LoginModels.swift b/RiotSwiftUI/Modules/Authentication/Common/Service/MatrixSDK/LoginModels.swift index 90c12f503c..964c0810b7 100644 --- a/RiotSwiftUI/Modules/Authentication/Common/Service/MatrixSDK/LoginModels.swift +++ b/RiotSwiftUI/Modules/Authentication/Common/Service/MatrixSDK/LoginModels.swift @@ -52,9 +52,7 @@ enum LoginMode { var ssoIdentityProviders: [SSOIdentityProvider]? { switch self { case .sso(let ssoIdentityProviders), .ssoAndPassword(let ssoIdentityProviders): - // Provide a backup for homeservers that support SSO but don't offer any identity providers - // https://spec.matrix.org/latest/client-server-api/#client-login-via-sso - return ssoIdentityProviders.count > 0 ? ssoIdentityProviders : [SSOIdentityProvider(id: "", name: "SSO", brand: nil, iconURL: nil)] + return ssoIdentityProviders default: return nil } diff --git a/changelog.d/7648.bugfix b/changelog.d/7648.bugfix new file mode 100644 index 0000000000..d5a4b13888 --- /dev/null +++ b/changelog.d/7648.bugfix @@ -0,0 +1 @@ +Deactivate account option is disabled when logging in with OIDC. \ No newline at end of file