From 74cf825fda4d94b00ab4a832cbe653ac6c357976 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Sobucki?= Date: Mon, 17 May 2021 12:00:11 +0200 Subject: [PATCH] [hsbc] Handle more login errors Handle more login error messages, updated XPath for errors in LoginPage's `on_load()` method. Additionaly, added login errors check in `end_login()` to avoid FormNotFound exception due to a blocked account access. --- modules/hsbc/browser.py | 25 ++++++++++++++++++------- modules/hsbc/pages/account_pages.py | 21 +++++++++++---------- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/modules/hsbc/browser.py b/modules/hsbc/browser.py index ea5b9c7b36..980ff0586a 100644 --- a/modules/hsbc/browser.py +++ b/modules/hsbc/browser.py @@ -32,7 +32,10 @@ from woob.tools.capabilities.bank.transactions import sorted_transactions, keep_only_card_transactions from woob.tools.compat import parse_qsl, urlparse from woob.tools.value import Value -from woob.exceptions import ActionNeeded, BrowserIncorrectPassword, BrowserUnavailable, BrowserQuestion +from woob.exceptions import ( + BrowserIncorrectPassword, BrowserPasswordExpired, BrowserUnavailable, + BrowserUserBanned, BrowserQuestion, +) from woob.browser import URL, need_login, TwoFactorBrowser from woob.browser.exceptions import HTTPNotFound from woob.capabilities.base import find_object @@ -170,6 +173,18 @@ def handle_otp(self): self.page.login_with_secure_key(self.secret, otp) self.end_login() + def check_login_error(self): + error_msg = self.page.get_error() + + if error_msg: + if 'Please click Reset Credentials' in error_msg or 'Please reset your HSBC Secure Key' in error_msg: + raise BrowserPasswordExpired(error_msg) + + elif 'Please retry in 30 minutes' in error_msg: + raise BrowserUserBanned(error_msg) + + raise AssertionError('Unhandled error at login: %s' % error_msg) + def init_login(self): self.session.cookies.clear() @@ -192,12 +207,7 @@ def init_login(self): if no_secure_key_link: self.location(no_secure_key_link) else: - error = self.page.get_error() - if error and 'Please click Reset Credentials' in error: - raise ActionNeeded(error) - elif error: - raise AssertionError('Unhandled error at login: %s' % error) - + self.check_login_error() self.check_interactive() raise BrowserQuestion( Value( @@ -211,6 +221,7 @@ def init_login(self): def end_login(self): for _ in range(3): if self.login.is_here(): + self.check_login_error() self.page.useless_form() # This wonderful website has 2 baseurl with only one difference: the 's' at the end of 'client' diff --git a/modules/hsbc/pages/account_pages.py b/modules/hsbc/pages/account_pages.py index 1b482a21d5..4f6fdd8ff1 100644 --- a/modules/hsbc/pages/account_pages.py +++ b/modules/hsbc/pages/account_pages.py @@ -559,17 +559,18 @@ def logged(self): return False def on_load(self): - for message in self.doc.xpath('//div[has-class("csPanelErrors")]'): + for message in self.doc.xpath('//div[@class="mainBloc"]/*[@class="error"]'): # Sometimes

, sometimes

+ error_msg = CleanText('.')(message) - if any( - msg in error_msg - for msg in [ - 'Please enter valid credentials for memorable answer and password.', - 'Please enter a valid Username.', - 'mot de passe invalide', - 'Log on error', # wrong otp - ] - ): + + error_at_login_regex = re.compile( + 'Please enter valid credentials for memorable answer and password.' + + '|Please enter a valid Username.' + + '|mot de passe invalide' + + '|Log on error' # wrong otp + ) + + if error_at_login_regex.search(error_msg): raise BrowserIncorrectPassword(error_msg) else: raise BrowserUnavailable(error_msg) -- GitLab