diff --git a/modules/banquepopulaire/browser.py b/modules/banquepopulaire/browser.py index 98cc535908d560342daa79909b6233dc97966c9d..cafebafb2a82c22f10fe36c0359c3c612be15e6e 100644 --- a/modules/banquepopulaire/browser.py +++ b/modules/banquepopulaire/browser.py @@ -382,6 +382,11 @@ def do_new_login(self): self.authorize.go(params=params) self.page.send_form() + if self.need_relogin_before_redirect(): + # Banque populaire now checks if the association login/phase parameter + # are well associated. Let's do login again without phase parameter + return self.do_login() + self.page.check_errors(feature='login') validation_id = self.page.get_validation_id() @@ -466,11 +471,16 @@ def need_relogin_before_redirect(self): WARNING: doing so can serves as a backdoor to avoid 2FA, but we don't know for how long. Logger here to have a trace. If 2FA still happens, it is catched in 'self.page.check_errors(feature='login')' + + Moreover, for some users the phase paramater can't validate: + - In password request. Consequently we get the same state than login transaction request (Authentication) + - The login post leads to AUTHENTICATION_FAILED """ - redirect_data = self.page.get_redirect_data() status = self.page.get_status() - if redirect_data and status == 'AUTHENTICATION_LOCKED': - assert not self.retry_login_without_phase, 'the login failed with and without phase 1 param' # avoid infinite loop at login + if status in ('AUTHENTICATION', 'AUTHENTICATION_LOCKED', 'AUTHENTICATION_FAILED' ): + if self.retry_login_without_phase: + raise BrowserIncorrectPassword() + self.retry_login_without_phase = True self.session.cookies.clear() self.logger.warning("'AUTHENTICATION_LOCKED' status at first login, trying second login, whitout phase parameter") @@ -481,6 +491,7 @@ def do_redirect(self, headers): if not redirect_data and self.page.is_new_login(): # assert to avoid infinite loop assert not self.retry_login_without_phase, 'the login failed with and without phase 1 param' + self.retry_login_without_phase = True self.session.cookies.clear() return self.do_login() diff --git a/modules/banquepopulaire/pages.py b/modules/banquepopulaire/pages.py index e94021b62be34c7d1e0a637aa697283bbde45481..803b1ca38378d6ef344450fd37a7308fe58e9960 100644 --- a/modules/banquepopulaire/pages.py +++ b/modules/banquepopulaire/pages.py @@ -30,7 +30,7 @@ from weboob.browser.elements import method, DictElement, ItemElement from weboob.browser.filters.standard import ( CleanText, CleanDecimal, Regexp, Eval, - Date, Field, MapIn, + Date, Field, MapIn, Coalesce, ) from weboob.browser.filters.html import Attr, Link, AttributeNotFound from weboob.browser.filters.json import Dict @@ -376,6 +376,9 @@ def is_new_login(self): # We check here if we are doing a new login return bool(Dict('step/phase/state', default=NotAvailable)(self.doc)) + def get_status(self): + return Dict('response/status', default=NotAvailable)(self.doc) + class AuthenticationStepPage(AbstractPage): PARENT = 'caissedepargne' @@ -383,7 +386,10 @@ class AuthenticationStepPage(AbstractPage): BROWSER_ATTR = 'package.browser.CaisseEpargne' def get_status(self): - return Dict('response/status', default=NotAvailable)(self.doc) + return Coalesce( + Dict('response/status', default=NotAvailable), + Dict('phase/state', default=NotAvailable) + )(self.doc) class LoginPage(MyHTMLPage):