From deb2cd6d86d89e5133318055e510a31de68f06fd Mon Sep 17 00:00:00 2001 From: Florian Duguet Date: Wed, 28 Aug 2019 13:23:46 +0200 Subject: [PATCH] [materielnet] handle captcha Closes: 9588@zendesk 10032@zendesk --- modules/materielnet/browser.py | 19 ++++++++++++++----- modules/materielnet/module.py | 14 ++++++++------ modules/materielnet/pages.py | 9 ++++++++- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/modules/materielnet/browser.py b/modules/materielnet/browser.py index e86cf501b1..890d446f2c 100644 --- a/modules/materielnet/browser.py +++ b/modules/materielnet/browser.py @@ -17,9 +17,11 @@ # You should have received a copy of the GNU Lesser General Public License # along with this weboob module. If not, see . +from __future__ import unicode_literals + from weboob.browser import LoginBrowser, URL, need_login -from weboob.exceptions import BrowserIncorrectPassword +from weboob.exceptions import BrowserIncorrectPassword, NocaptchaQuestion from .pages import LoginPage, CaptchaPage, ProfilePage, DocumentsPage, DocumentsDetailsPage @@ -34,7 +36,7 @@ class MaterielnetBrowser(LoginBrowser): BASEURL = 'https://secure.materiel.net' login = MyURL(r'/(?P.*)Login/Login', LoginPage) - captcha = URL('/pm/client/captcha.html', CaptchaPage) + captcha = URL(r'/pm/client/captcha.html', CaptchaPage) profile = MyURL(r'/(?P.*)Account/InformationsSection', r'/pro/Account/InformationsSection', ProfilePage) documents = MyURL(r'/(?P.*)Orders/PartialCompletedOrdersHeader', @@ -42,8 +44,9 @@ class MaterielnetBrowser(LoginBrowser): document_details = MyURL(r'/(?P.*)Orders/PartialCompletedOrderContent', r'/pro/Orders/PartialCompletedOrderContent', DocumentsDetailsPage) - def __init__(self, *args, **kwargs): + def __init__(self, config, *args, **kwargs): super(MaterielnetBrowser, self).__init__(*args, **kwargs) + self.config = config self.is_pro = None self.lang = '' @@ -53,11 +56,17 @@ def par_or_pro_location(self, url, *args, **kwargs): elif self.lang: url = '/' + self.lang[:-1] + url - return super(MaterielnetBrowser, self).location(url, *args, **kwargs) + return self.location(url, *args, **kwargs) def do_login(self): self.login.go() - self.page.login(self.username, self.password) + sitekey = self.page.get_recaptcha_sitekey() + # captcha is not always present + if sitekey: + if not self.config['captcha_response'].get(): + raise NocaptchaQuestion(website_key=sitekey, website_url=self.login.build(lang=self.lang)) + + self.page.login(self.username, self.password, self.config['captcha_response'].get()) if self.captcha.is_here(): BrowserIncorrectPassword() diff --git a/modules/materielnet/module.py b/modules/materielnet/module.py index 3a54d69592..2f3b743de7 100644 --- a/modules/materielnet/module.py +++ b/modules/materielnet/module.py @@ -17,11 +17,12 @@ # You should have received a copy of the GNU Lesser General Public License # along with this weboob module. If not, see . +from __future__ import unicode_literals from weboob.capabilities.bill import DocumentTypes, CapDocument, Subscription, Document, SubscriptionNotFound, DocumentNotFound from weboob.capabilities.base import find_object, NotAvailable from weboob.tools.backend import Module, BackendConfig -from weboob.tools.value import ValueBackendPassword +from weboob.tools.value import ValueBackendPassword, Value from .browser import MaterielnetBrowser @@ -31,20 +32,21 @@ class MaterielnetModule(Module, CapDocument): NAME = 'materielnet' - DESCRIPTION = u'Materiel.net' - MAINTAINER = u'Edouard Lambert' + DESCRIPTION = 'Materiel.net' + MAINTAINER = 'Edouard Lambert' EMAIL = 'elambert@budget-insight.com' LICENSE = 'LGPLv3+' VERSION = '1.6' - CONFIG = BackendConfig(ValueBackendPassword('login', label='Email', regexp=r'.+@.+'), - ValueBackendPassword('password', label='Mot de passe')) + CONFIG = BackendConfig(ValueBackendPassword('login', label='Email'), + ValueBackendPassword('password', label='Mot de passe'), + Value('captcha_response', label='RĂ©ponse captcha', default='', required=False)) BROWSER = MaterielnetBrowser accepted_document_types = (DocumentTypes.BILL,) def create_default_browser(self): - return self.create_browser(self.config['login'].get(), self.config['password'].get()) + return self.create_browser(self.config, self.config['login'].get(), self.config['password'].get()) def iter_subscription(self): return self.browser.get_subscription_list() diff --git a/modules/materielnet/pages.py b/modules/materielnet/pages.py index 2fd24b7194..a9b048bd36 100644 --- a/modules/materielnet/pages.py +++ b/modules/materielnet/pages.py @@ -31,7 +31,10 @@ class LoginPage(PartialHTMLPage): - def login(self, login, password): + def get_recaptcha_sitekey(self): + return Attr('//div[@class="g-recaptcha"]', 'data-sitekey', default=NotAvailable)(self.doc) + + def login(self, login, password, captcha_response=None): maxlength = Attr('//input[@id="Email"]', 'data-val-maxlength-max')(self.doc) regex = Attr('//input[@id="Email"]', 'data-val-regex-pattern')(self.doc) # their regex is: ^([\w\-+\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,15}|[0-9]{1,3})(\]?)$ @@ -47,6 +50,10 @@ def login(self, login, password): form = self.get_form(xpath='//form[contains(@action, "/Login/Login")]') form['Email'] = login form['Password'] = password + + if captcha_response: + form['g-recaptcha-response'] = captcha_response + form.submit() def get_error(self): -- GitLab