diff --git a/modules/lcl/browser.py b/modules/lcl/browser.py index f2fce55c7c7ac18515f8c722fd78e50c061d31b1..cb6b98739c2064d64f83dd0b4ec422bbcc93d3d2 100644 --- a/modules/lcl/browser.py +++ b/modules/lcl/browser.py @@ -31,6 +31,7 @@ from weboob.exceptions import ( BrowserIncorrectPassword, BrowserUnavailable, BrowserQuestion, AppValidation, AppValidationCancelled, AppValidationExpired, + BrowserPasswordExpired, ) from weboob.browser import URL, need_login, TwoFactorBrowser from weboob.browser.exceptions import ServerError, ClientError @@ -52,6 +53,7 @@ Form2Page, DocumentsPage, ClientPage, SendTokenPage, CaliePage, ProfilePage, DepositPage, AVHistoryPage, AVInvestmentsPage, CardsPage, AVListPage, CalieContractsPage, RedirectPage, MarketOrdersPage, AVNotAuthorized, AVReroute, TwoFAPage, AuthentStatusPage, FinalizeTwoFAPage, + PasswordExpiredPage, ) @@ -69,7 +71,9 @@ class LCLBrowser(TwoFactorBrowser): r'/outil/UAUT\?from=.*', r'/outil/UWER/Accueil/majicER', r'/outil/UWER/Enregistrement/forwardAcc', - LoginPage) + LoginPage + ) + password_expired_page = URL(r'/outil/UWMC/NoConnect/incitationChangementMdp', PasswordExpiredPage) redirect_page = URL(r'/outil/UAUT/Accueil/preRoutageLogin', RedirectPage) contracts_page = URL( r'/outil/UAUT/Contrat/choixContrat.*', @@ -261,6 +265,9 @@ def init_login(self): if self.login.is_here(): self.page.check_error() + if self.password_expired_page.is_here(): + raise BrowserPasswordExpired(self.page.get_message()) + if (not self.contracts and not self.parsed_contracts and (self.contracts_choice.is_here() or self.contracts_page.is_here())): # On the preRoutageLogin page we gather the list of available contracts for this account diff --git a/modules/lcl/pages.py b/modules/lcl/pages.py index ef0f4dd7435aa64291a5f437adee5bf70190d19f..05bb66a83e31616c4e6256b80af072d8dd85255f 100644 --- a/modules/lcl/pages.py +++ b/modules/lcl/pages.py @@ -233,6 +233,11 @@ def select_contract(self, id_contract=None): form.submit() +class PasswordExpiredPage(LoggedPage, HTMLPage): + def get_message(self): + return CleanText('//form[@id="changementCodeForm"]//span[contains(., "nouveau code d’accès")]')(self.doc) + + class ContractsChoicePage(ContractsPage): def on_load(self): self.check_error()