diff --git a/src/icloudpd/authentication.py b/src/icloudpd/authentication.py index da5a37864..fdcfc8994 100644 --- a/src/icloudpd/authentication.py +++ b/src/icloudpd/authentication.py @@ -14,13 +14,6 @@ from icloudpd.status import Status, StatusExchange -class TwoStepAuthRequiredError(Exception): - """ - Raised when 2SA is required. base.py catches this exception - and sends an email notification. - """ - - def authenticator( logger: logging.Logger, domain: str, @@ -33,13 +26,13 @@ def authenticator( ], mfa_provider: MFAProvider, status_exchange: StatusExchange, -) -> Callable[[str, Optional[str], bool, Optional[str]], PyiCloudService]: +) -> Callable[[str, Optional[str], Optional[Callable[[], None]], Optional[str]], PyiCloudService]: """Wraping authentication with domain context""" def authenticate_( username: str, cookie_directory: Optional[str] = None, - raise_error_on_2sa: bool = False, + mfa_error_callable: Optional[Callable[[], None]] = None, client_id: Optional[str] = None, ) -> PyiCloudService: """Authenticate with iCloud username and password""" @@ -74,8 +67,8 @@ def authenticate_( _writer(username, _valid_password) if icloud.requires_2fa: - if raise_error_on_2sa: - raise TwoStepAuthRequiredError("Two-factor authentication is required") + if mfa_error_callable: + mfa_error_callable() logger.info("Two-factor authentication is required (2fa)") if mfa_provider == MFAProvider.WEBUI: request_2fa_web(icloud, logger, status_exchange) @@ -83,8 +76,8 @@ def authenticate_( request_2fa(icloud, logger) elif icloud.requires_2sa: - if raise_error_on_2sa: - raise TwoStepAuthRequiredError("Two-step authentication is required") + if mfa_error_callable: + mfa_error_callable() logger.info("Two-step authentication is required (2sa)") request_2sa(icloud, logger) diff --git a/src/icloudpd/base.py b/src/icloudpd/base.py index 47cb41579..f43ce6ab4 100644 --- a/src/icloudpd/base.py +++ b/src/icloudpd/base.py @@ -55,7 +55,7 @@ from tzlocal import get_localzone from icloudpd import constants, download, exif_datetime -from icloudpd.authentication import TwoStepAuthRequiredError, authenticator +from icloudpd.authentication import authenticator from icloudpd.autodelete import autodelete_photos from icloudpd.config import Config from icloudpd.counter import Counter @@ -1174,29 +1174,7 @@ def core( ) -> int: """Download all iCloud photos to a local directory""" - raise_error_on_2sa = ( - smtp_username is not None - or notification_email is not None - or notification_script is not None - ) - try: - icloud = authenticator( - logger, - domain, - filename_cleaner, - lp_filename_generator, - raw_policy, - file_match_policy, - password_providers, - mfa_provider, - status_exchange, - )( - username, - cookie_directory, - raise_error_on_2sa, - os.environ.get("CLIENT_ID"), - ) - except TwoStepAuthRequiredError: + def _notify_mfa_error(): if notification_script is not None: subprocess.call([notification_script]) if smtp_username is not None or notification_email is not None: @@ -1210,7 +1188,23 @@ def core( notification_email, notification_email_from, ) - return 1 + + icloud = authenticator( + logger, + domain, + filename_cleaner, + lp_filename_generator, + raw_policy, + file_match_policy, + password_providers, + mfa_provider, + status_exchange, + )( + username, + cookie_directory, + _notify_mfa_error, + os.environ.get("CLIENT_ID"), + ) if auth_only: logger.info("Authentication completed successfully")