diff --git a/modules/boursorama/browser.py b/modules/boursorama/browser.py
index 787f8481..2b25128f 100644
--- a/modules/boursorama/browser.py
+++ b/modules/boursorama/browser.py
@@ -44,7 +44,7 @@ class Boursorama(Browser):
'b290ef629c88f0508e9cc6305421c173bd4291175e3ddedbee05ee666b34c20e']
ENCODING = None # refer to the HTML encoding
PAGES = {
- '.*/connexion/securisation/index.phtml': AuthenticationPage,
+ '.*/connexion/securisation.*': AuthenticationPage,
'.*connexion.phtml.*': LoginPage,
'.*/comptes/synthese.phtml': AccountsList,
'.*/comptes/banque/detail/mouvements.phtml.*': AccountHistory,
@@ -55,10 +55,14 @@ class Boursorama(Browser):
'.*/opcvm.phtml.*': InvestmentDetail
}
- def __init__(self, device="weboob", enable_twofactors=False,
- *args, **kwargs):
- self.device = device
- self.enable_twofactors = enable_twofactors
+ __states__ = []
+
+ def __init__(self, config=None, *args, **kwargs):
+ self.config = config
+ self.auth_token = None
+ kwargs['get_home'] = False
+ kwargs['username'] = self.config['login'].get()
+ kwargs['password'] = self.config['password'].get()
Browser.__init__(self, *args, **kwargs)
def home(self):
@@ -72,32 +76,36 @@ class Boursorama(Browser):
def handle_authentication(self):
if self.is_on_page(AuthenticationPage):
- if self.enable_twofactors:
- self.page.authenticate(self.device)
+ if self.config['enable_twofactors'].get():
+ if not self.config['pin_code'].get() or not self.auth_token:
+ self.page.send_sms()
+ else:
+ self.page.authenticate()
else:
raise BrowserIncorrectAuthenticationCode(
"""Boursorama - activate the two factor authentication in boursorama config."""
""" You will receive SMS code but are limited in request per day (around 15)"""
)
-
def login(self):
- assert isinstance(self.device, basestring)
- assert isinstance(self.enable_twofactors, bool)
+ assert isinstance(self.config['device'].get(), basestring)
+ assert isinstance(self.config['enable_twofactors'].get(), bool)
assert self.password.isdigit()
- if not self.is_on_page(LoginPage):
- self.location('https://' + self.DOMAIN + '/connexion.phtml', no_login=True)
+ if self.is_on_page(AuthenticationPage):
+ self.handle_authentication()
+ else:
+ if not self.is_on_page(LoginPage):
+ self.location('https://' + self.DOMAIN + '/connexion.phtml', no_login=True)
- self.page.login(self.username, self.password)
+ self.page.login(self.username, self.password)
- if self.is_on_page(LoginPage):
- raise BrowserIncorrectPassword()
+ if self.is_on_page(LoginPage):
+ raise BrowserIncorrectPassword()
- #after login, we might be redirected to the two factor
- #authentication page
- #print "handle authentication"
- self.handle_authentication()
+ #after login, we might be redirected to the two factor
+ #authentication page
+ self.handle_authentication()
self.location('/comptes/synthese.phtml', no_login=True)
@@ -107,6 +115,8 @@ class Boursorama(Browser):
raise BrowserIncorrectAuthenticationCode()
def get_accounts_list(self):
+ if self.is_on_page(AuthenticationPage):
+ self.login()
if not self.is_on_page(AccountsList):
self.location('/comptes/synthese.phtml')
diff --git a/modules/boursorama/module.py b/modules/boursorama/module.py
index 3c5b6678..f3364cf5 100644
--- a/modules/boursorama/module.py
+++ b/modules/boursorama/module.py
@@ -41,15 +41,12 @@ class BoursoramaModule(Module, CapBank):
ValueBackendPassword('password', label='Mot de passe'),
ValueBool('enable_twofactors', label='Send validation sms', default=False),
Value('device', label='Device name', regexp='\w*', default=''),
+ Value('pin_code', label='Sms code', required=False),
)
BROWSER = Boursorama
def create_default_browser(self):
- return self.create_browser(
- self.config["device"].get()
- , self.config["enable_twofactors"].get()
- , self.config['login'].get()
- , self.config['password'].get())
+ return self.create_browser(self.config)
def iter_accounts(self):
for account in self.browser.get_accounts_list():
diff --git a/modules/boursorama/pages/two_authentication.py b/modules/boursorama/pages/two_authentication.py
index 3549a5d0..69a1b5ee 100644
--- a/modules/boursorama/pages/two_authentication.py
+++ b/modules/boursorama/pages/two_authentication.py
@@ -17,23 +17,55 @@
# You should have received a copy of the GNU Affero General Public License
# along with weboob. If not, see .
-from weboob.deprecated.browser import Page, BrowserIncorrectPassword
-import urllib2
import re
+import urllib2
+from weboob.exceptions import BrowserToBeContinued
+from weboob.deprecated.browser import Page, BrowserIncorrectPassword
class BrowserAuthenticationCodeMaxLimit(BrowserIncorrectPassword):
pass
class AuthenticationPage(Page):
- MAX_LIMIT = "vous avez atteint le nombre maximum "\
+ MAX_LIMIT = r"vous avez atteint le nombre maximum "\
"d'utilisation de l'authentification forte."
+ SECURE_PAGE = "https://www.boursorama.com/comptes/connexion/securisation/index.phtml"
+ REFERER = SECURE_PAGE
+
+ headers = {"User-Agent": "Mozilla/5.0 (Windows; U; Windows "
+ "NT 5.1; en-US; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8"
+ " GTB7.1 (.NET CLR 3.5.30729)",
+ "Referer": REFERER,
+ }
+
+ headers_ajax = {"User-Agent": "Mozilla/5.0 (Windows; U; Windows "
+ "NT 5.1; en-US; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8"
+ " GTB7.1 (.NET CLR 3.5.30729)",
+ "Accept": "application/json",
+ "X-Requested-With": "XMLHttpRequest",
+ "X-Request": "JSON",
+ "X-Brs-Xhr-Request": "true",
+ "X-Brs-Xhr-Schema": "DATA+OUT",
+ "Referer": REFERER,
+ }
def on_loaded(self):
pass
- def authenticate(self, device):
+ def authenticate(self):
+ url = "https://" + self.browser.DOMAIN + "/ajax/banque/otp.phtml"
+ data = "authentificationforteToken=%s&authentificationforteStep=otp&alertType=10100&org=%s&otp=%s&validate=" % (self.browser.auth_token, self.REFERER, self.browser.config['pin_code'].get())
+ req = urllib2.Request(url, data, self.headers_ajax)
+ response = self.browser.open(req)
+
+ url = "%s?" % (self.SECURE_PAGE)
+ data = "org=/&device=%s" % (self.browser.config['device'].get())
+ req = urllib2.Request(url, data, headers=self.headers)
+ response = self.browser.open(req)
+ self.browser.auth_token = None
+
+ def send_sms(self):
"""This function simulates the registration of a device on
boursorama two factor authentification web page.
I
@@ -41,73 +73,26 @@ class AuthenticationPage(Page):
@exception BrowserAuthenticationCodeMaxLimit when daily limit is consumed
@exception BrowserIncorrectAuthenticationCode when code is not correct
"""
- DOMAIN = self.browser.DOMAIN
- SECURE_PAGE = "https://www.boursorama.com/comptes/connexion/securisation/index.phtml"
- REFERER = SECURE_PAGE
-
- #print "Need to authenticate for device", device
- #print "Domain information", DOMAIN
-
- url = "https://%s/ajax/banque/otp.phtml?org=%s&alertType=10100" % (DOMAIN, REFERER)
- #print url
- headers = {"User-Agent": "Mozilla/5.0 (Windows; U; Windows "
- "NT 5.1; en-US; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8"
- " GTB7.1 (.NET CLR 3.5.30729)",
- "Referer": REFERER,
- }
-
- headers_ajax = {"User-Agent": "Mozilla/5.0 (Windows; U; Windows "
- "NT 5.1; en-US; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8"
- " GTB7.1 (.NET CLR 3.5.30729)",
- "Accept": "application/json",
- "X-Requested-With": "XMLHttpRequest",
- "X-Request": "JSON",
- "X-Brs-Xhr-Request": "true",
- "X-Brs-Xhr-Schema": "DATA+OUT",
- "Referer": REFERER,
- }
-
- req = urllib2.Request(url, headers=headers_ajax)
+ url = "https://%s/ajax/banque/otp.phtml?org=%s&alertType=10100" % (self.browser.DOMAIN, self.REFERER)
+ req = urllib2.Request(url, headers=self.headers_ajax)
response = self.browser.open(req)
#extrat authentication token from response (in form)
info = response.read()
- regex = re.compile(r"vous avez atteint le nombre maximum d'utilisation de l'authentification forte.")
+ regex = re.compile(self.MAX_LIMIT)
r = regex.search(info)
if r:
self.logger.info("Boursorama - Vous avez atteint le nombre maximum d'utilisation de l'authentification forte")
raise BrowserAuthenticationCodeMaxLimit()
- #print "Response from initial request,", len(info), response.info()
regex = re.compile(r"name=\\\"authentificationforteToken\\\" "
r"value=\\\"(?P\w*?)\\\"")
r = regex.search(info)
- token = r.group('value')
- #print "Extracted token", token
+ self.browser.auth_token = r.group('value')
#step2
- url = "https://" + DOMAIN + "/ajax/banque/otp.phtml"
- data = "authentificationforteToken=%s&authentificationforteStep=start&alertType=10100&org=%s&validate=" % (token, REFERER)
- req = urllib2.Request(url, data, headers_ajax)
+ url = "https://" + self.browser.DOMAIN + "/ajax/banque/otp.phtml"
+ data = "authentificationforteToken=%s&authentificationforteStep=start&alertType=10100&org=%s&validate=" % (self.browser.auth_token, self.REFERER)
+ req = urllib2.Request(url, data, self.headers_ajax)
response = self.browser.open(req)
- #info = response.read()
- #print "after asking to send token authentification" \
- # ,len(info), response.info()
-
-
- pin = raw_input('Enter the "Boursorama Banque" access code:')
- #print "Pin access code: ''%s''" % (pin)
- url = "https://" + DOMAIN + "/ajax/banque/otp.phtml"
- data = "authentificationforteToken=%s&authentificationforteStep=otp&alertType=10100&org=%s&otp=%s&validate=" % (token, REFERER, pin)
- req = urllib2.Request(url, data, headers_ajax)
- response = self.browser.open(req)
- #info = response.read()
- #print "after pin authentification", len(info), response.info()
-
- url = "%s?" % (SECURE_PAGE)
- data = "org=/&device=%s" % (device)
- req = urllib2.Request(url, data, headers=headers)
- response = self.browser.open(req)
-
- #result = response.read()
- #print response, "\n", response.info()
+ raise BrowserToBeContinued('pin_code')