@@ -3,15 +3,12 @@ import KeychainAccess
33import WordPressAuthenticator
44import WordPressKit
55import Yosemite
6- import WordPressUI
76import class Networking. UserAgent
87import enum Experiments. ABTest
98import struct Networking. Settings
109import protocol Experiments. FeatureFlagService
1110import protocol Storage. StorageManagerType
12- import protocol Networking. ApplicationPasswordUseCase
1311import class Networking. DefaultApplicationPasswordUseCase
14- import enum Networking. ApplicationPasswordUseCaseError
1512
1613/// Encapsulates all of the interactions with the WordPress Authenticator
1714///
@@ -48,13 +45,8 @@ class AuthenticationManager: Authentication {
4845
4946 private let analytics : Analytics
5047
51- /// Keep strong reference of the use case to check for application password availability if necessary.
52- private var applicationPasswordUseCase : ApplicationPasswordUseCase ?
53-
54- /// Keep strong reference of the use case to check for role eligibility if necessary.
55- private lazy var roleEligibilityUseCase : RoleEligibilityUseCase = {
56- . init( stores: ServiceLocator . stores)
57- } ( )
48+ /// Keeps a reference to the checker
49+ private var postSiteCredentialLoginChecker : PostSiteCredentialLoginChecker ?
5850
5951 init ( storageManager: StorageManagerType = ServiceLocator . storageManager,
6052 featureFlagService: FeatureFlagService = ServiceLocator . featureFlagService,
@@ -391,8 +383,7 @@ extension AuthenticationManager: WordPressAuthenticatorDelegate {
391383 featureFlagService. isFeatureFlagEnabled ( . applicationPasswordAuthenticationForSiteCredentialLogin) {
392384 return didAuthenticateUser ( to: siteURL,
393385 with: siteCredentials,
394- in: navigationController,
395- source: source)
386+ in: navigationController)
396387 }
397388
398389 /// Jetpack is required. Present an error if we don't detect a valid installation for a self-hosted site.
@@ -736,7 +727,7 @@ private extension AuthenticationManager {
736727 /// The error screen to be displayed when the user tries to enter a site without WooCommerce.
737728 ///
738729 func noWooUI( for site: Site ,
739- with matcher: ULAccountMatcher ,
730+ with matcher: ULAccountMatcher = . init ( ) ,
740731 navigationController: UINavigationController ,
741732 onStorePickerDismiss: @escaping ( ) -> Void ) -> UIViewController {
742733 let viewModel = NoWooErrorViewModel (
@@ -800,139 +791,24 @@ private extension AuthenticationManager {
800791 return accountMismatchUI ( for: site. url, siteCredentials: nil , with: matcher, in: navigationController)
801792 }
802793
803- /// The error screen to be displayed when the user tries to log in with site credentials
804- /// with application password disabled.
805- ///
806- func applicationPasswordDisabledUI( for siteURL: String ) -> UIViewController {
807- let viewModel = ApplicationPasswordDisabledViewModel ( siteURL: siteURL)
808- return ULErrorViewController ( viewModel: viewModel)
809- }
810-
811794 /// Checks if the authenticated user is eligible to use the app and navigates to the home screen.
812795 ///
813796 func didAuthenticateUser( to siteURL: String ,
814797 with siteCredentials: WordPressOrgCredentials ,
815- in navigationController: UINavigationController ,
816- source: SignInSource ? ) {
817- // check if application password is enabled
818- guard let applicationPasswordUseCase = try ? DefaultApplicationPasswordUseCase (
798+ in navigationController: UINavigationController ) {
799+ guard let useCase = try ? DefaultApplicationPasswordUseCase (
819800 username: siteCredentials. username,
820801 password: siteCredentials. password,
821802 siteAddress: siteCredentials. siteURL
822803 ) else {
823804 return assertionFailure ( " ⛔️ Error creating application password use case " )
824805 }
825- self . applicationPasswordUseCase = applicationPasswordUseCase
826- checkApplicationPassword ( for: siteURL,
827- with: applicationPasswordUseCase,
828- in: navigationController) { [ weak self] in
829- guard let self else { return }
830- self . checkRoleEligibility ( in: navigationController) { [ weak self] in
831- guard let self else { return }
832- // TODO: check for Woo
833- // navigates to home screen immediately with a placeholder store ID
834- self . startStorePicker ( with: WooConstants . placeholderStoreID, in: navigationController)
835- }
806+ let checker = PostSiteCredentialLoginChecker ( applicationPasswordUseCase: useCase)
807+ checker. checkEligibility ( for: siteURL, from: navigationController) { [ weak self] in
808+ // navigates to home screen immediately with a placeholder store ID
809+ self ? . startStorePicker ( with: WooConstants . placeholderStoreID, in: navigationController)
836810 }
837- }
838-
839- func checkApplicationPassword( for siteURL: String ,
840- with useCase: ApplicationPasswordUseCase ,
841- in navigationController: UINavigationController , onSuccess: @escaping ( ) -> Void ) {
842- Task {
843- do {
844- let _ = try await useCase. generateNewPassword ( )
845- await MainActor . run {
846- onSuccess ( )
847- }
848- } catch ApplicationPasswordUseCaseError . applicationPasswordsDisabled {
849- // show application password disabled error
850- await MainActor . run {
851- let errorUI = applicationPasswordDisabledUI ( for: siteURL)
852- navigationController. show ( errorUI, sender: nil )
853- }
854- } catch {
855- // show generic error
856- await MainActor . run {
857- DDLogError ( " ⛔️ Error generating application password: \( error) " )
858- let alert = FancyAlertViewController . makeSiteCredentialLoginAlert (
859- message: Localization . applicationPasswordError,
860- retryAction: { [ weak self] in
861- self ? . checkApplicationPassword ( for: siteURL, with: useCase, in: navigationController, onSuccess: onSuccess)
862- } ,
863- restartLoginAction: {
864- ServiceLocator . stores. deauthenticate ( )
865- navigationController. popToRootViewController ( animated: true )
866- }
867- )
868- navigationController. present ( alert, animated: true )
869- }
870- }
871- }
872- }
873-
874- /// Checks role eligibility for the logged in user with the site address saved in the credentials.
875- /// Placeholder store ID is used because we are checking for users logging in with site credentials.
876- ///
877- func checkRoleEligibility( in navigationController: UINavigationController , onSuccess: @escaping ( ) -> Void ) {
878- roleEligibilityUseCase. checkEligibility ( for: WooConstants . placeholderStoreID) { [ weak self] result in
879- guard let self else { return }
880- switch result {
881- case . success:
882- onSuccess ( )
883- case . failure( let error) :
884- if case let RoleEligibilityError . insufficientRole( errorInfo) = error {
885- self . showRoleErrorScreen ( for: WooConstants . placeholderStoreID,
886- errorInfo: errorInfo,
887- in: navigationController,
888- onSuccess: onSuccess)
889- } else {
890- // show generic error
891- DDLogError ( " ⛔️ Error checking role eligibility: \( error) " )
892- let alert = FancyAlertViewController . makeSiteCredentialLoginAlert (
893- message: Localization . roleEligibilityCheckError,
894- retryAction: { [ weak self] in
895- self ? . checkRoleEligibility ( in: navigationController, onSuccess: onSuccess)
896- } ,
897- restartLoginAction: {
898- ServiceLocator . stores. deauthenticate ( )
899- navigationController. popToRootViewController ( animated: true )
900- }
901- )
902- navigationController. present ( alert, animated: true )
903- }
904- }
905- }
906- }
907-
908- /// Shows a Role Error page using the provided error information.
909- ///
910- func showRoleErrorScreen( for siteID: Int64 ,
911- errorInfo: StorageEligibilityErrorInfo ,
912- in navigationController: UINavigationController ,
913- onSuccess: @escaping ( ) -> Void ) {
914- let errorViewModel = RoleErrorViewModel ( siteID: siteID, title: errorInfo. name, subtitle: errorInfo. humanizedRoles, useCase: self . roleEligibilityUseCase)
915- let errorViewController = RoleErrorViewController ( viewModel: errorViewModel)
916-
917- errorViewModel. onSuccess = onSuccess
918- errorViewModel. onDeauthenticationRequest = {
919- ServiceLocator . stores. deauthenticate ( )
920- navigationController. popToRootViewController ( animated: true )
921- }
922- navigationController. show ( errorViewController, sender: self )
923- }
924- }
925-
926- private extension AuthenticationManager {
927- enum Localization {
928- static let applicationPasswordError = NSLocalizedString (
929- " Error fetching application password for your site. " ,
930- comment: " Error message displayed when application password cannot be fetched after authentication. "
931- )
932- static let roleEligibilityCheckError = NSLocalizedString (
933- " Error fetching user information. " ,
934- comment: " Error message displayed when user information cannot be fetched after authentication. "
935- )
811+ self . postSiteCredentialLoginChecker = checker
936812 }
937813}
938814
0 commit comments