diff --git a/modules/banquepopulaire/browser.py b/modules/banquepopulaire/browser.py index 1f500b25..bbeee3ea 100644 --- a/modules/banquepopulaire/browser.py +++ b/modules/banquepopulaire/browser.py @@ -23,7 +23,7 @@ import urllib from weboob.deprecated.browser import Browser, BrowserIncorrectPassword, BrokenPageError from .pages import LoginPage, IndexPage, AccountsPage, CardsPage, TransactionsPage, \ - UnavailablePage, RedirectPage, HomePage + UnavailablePage, RedirectPage, HomePage, Login2Page __all__ = ['BanquePopulaire'] @@ -49,6 +49,7 @@ class BanquePopulaire(Browser): 'https://[^/]+/portailinternet/Pages/.*.aspx\?vary=(?P.*)': HomePage, 'https://[^/]+/portailinternet/Pages/default.aspx': HomePage, 'https://[^/]+/portailinternet/Transactionnel/Pages/CyberIntegrationPage.aspx': HomePage, + 'https://[^/]+/WebSSO_BP/_(?P\d+)/index.html\?transactionID=(?P.*)': Login2Page, } def __init__(self, website, *args, **kwargs): @@ -60,6 +61,9 @@ class BanquePopulaire(Browser): def is_logged(self): return not self.is_on_page(LoginPage) + def home(self): + self.login() + def login(self): """ Attempt to log in. @@ -68,11 +72,8 @@ class BanquePopulaire(Browser): assert isinstance(self.username, basestring) assert isinstance(self.password, basestring) - if self.is_logged(): - return - if not self.is_on_page(LoginPage): - self.home() + self.location('%s://%s' % (self.PROTOCOL, self.DOMAIN), no_login=True) self.page.login(self.username, self.password) diff --git a/modules/banquepopulaire/pages.py b/modules/banquepopulaire/pages.py index ab778586..2e1c6ad9 100644 --- a/modules/banquepopulaire/pages.py +++ b/modules/banquepopulaire/pages.py @@ -22,11 +22,14 @@ import datetime from urlparse import urlsplit, parse_qsl from decimal import Decimal import re +import urllib from mechanize import Cookie, FormNotFoundError -from weboob.deprecated.browser import Page as _BasePage, BrowserUnavailable, BrokenPageError +from weboob.exceptions import BrowserUnavailable, BrowserIncorrectPassword +from weboob.deprecated.browser import Page as _BasePage, BrokenPageError from weboob.capabilities.bank import Account from weboob.tools.capabilities.bank.transactions import FrenchTransaction +from weboob.tools.json import json class WikipediaARC4(object): @@ -171,6 +174,37 @@ class LoginPage(BasePage): self.browser.submit(nologin=True) +class Login2Page(LoginPage): + @property + def request_url(self): + transactionID = self.group_dict['transactionID'] + return 'https://www.icgauth.banquepopulaire.fr/dacswebssoissuer/api/v1u0/transaction/%s' % transactionID + + def on_loaded(self): + r = self.browser.openurl(self.request_url) + doc = json.load(r) + self.form_id = doc['step']['validationUnits'][0]['PASSWORD_LOOKUP'][0]['id'] + + def login(self, login, password): + payload = {'validate': {'PASSWORD_LOOKUP': [{'id': self.form_id, + 'login': login.encode(self.browser.ENCODING), + 'password': password.encode(self.browser.ENCODING), + 'type': 'PASSWORD_LOOKUP' + }] + } + } + req = self.browser.request_class(self.request_url + '/step') + req.add_header('Content-Type', 'application/json') + r = self.browser.openurl(req, json.dumps(payload)) + + doc = json.load(r) + if ('phase' in doc and doc['phase']['previousResult'] == 'FAILED_AUTHENTICATION') or \ + doc['response']['status'] != 'AUTHENTICATION_SUCCESS': + raise BrowserIncorrectPassword() + + self.browser.location(doc['response']['saml2_post']['action'], urllib.urlencode({'SAMLResponse': doc['response']['saml2_post']['samlResponse']})) + + class IndexPage(BasePage): def get_token(self): url = self.document.getroot().xpath('//frame[@name="portalHeader"]')[0].attrib['src']