sgpe: Can login

This commit is contained in:
Laurent Bachelier 2013-07-19 19:03:13 +02:00 committed by Romain Bignon
commit 23c0954353
4 changed files with 169 additions and 4 deletions

View file

@ -23,9 +23,10 @@ from __future__ import with_statement
from weboob.capabilities.bank import ICapBank, AccountNotFound from weboob.capabilities.bank import ICapBank, AccountNotFound
from weboob.tools.backend import BaseBackend, BackendConfig from weboob.tools.backend import BaseBackend, BackendConfig
from weboob.tools.value import ValueBackendPassword from weboob.tools.value import Value, ValueBackendPassword
from .browser import SocieteGenerale from .browser import SocieteGenerale
from .sgpe.browser import SGEnterpriseBrowser, SGProfessionalBrowser
__all__ = ['SocieteGeneraleBackend'] __all__ = ['SocieteGeneraleBackend']
@ -38,11 +39,15 @@ class SocieteGeneraleBackend(BaseBackend, ICapBank):
VERSION = '0.g' VERSION = '0.g'
LICENSE = 'AGPLv3+' LICENSE = 'AGPLv3+'
DESCRIPTION = u'Société Générale French bank website' DESCRIPTION = u'Société Générale French bank website'
CONFIG = BackendConfig(ValueBackendPassword('login', label='Account ID', masked=False), CONFIG = BackendConfig(
ValueBackendPassword('password', label='Password')) ValueBackendPassword('login', label='Account ID', masked=False),
BROWSER = SocieteGenerale ValueBackendPassword('password', label='Password'),
Value('website', label='Website to use', default='par',
choices={'par': 'Particuliers', 'pro': 'Professionnels', 'ent': 'Entreprises'}))
def create_default_browser(self): def create_default_browser(self):
b = {'par': SocieteGenerale, 'pro': SGProfessionalBrowser, 'ent': SGEnterpriseBrowser}
self.BROWSER = b[self.config['website'].get()]
return self.create_browser(self.config['login'].get(), return self.create_browser(self.config['login'].get(),
self.config['password'].get()) self.config['password'].get())

View file

View file

@ -0,0 +1,72 @@
# -*- coding: utf-8 -*-
# Copyright(C) 2013 Laurent Bachelier
#
# This file is part of weboob.
#
# weboob is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# weboob is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
from weboob.tools.browser import BaseBrowser, BrowserIncorrectPassword
from weboob.tools.ordereddict import OrderedDict
from .pages import LoginPage, AccountsPage
__all__ = ['SGProfessionalBrowser', 'SGEnterpriseBrowser']
class SGPEBrowser(BaseBrowser):
PROTOCOL = 'https'
ENCODING = None
def __init__(self, *args, **kwargs):
self.PAGES = OrderedDict((
('%s://%s/Pgn/.+PageID=Compte&.+' % (self.PROTOCOL, self.DOMAIN), AccountsPage),
('%s://%s/' % (self.PROTOCOL, self.DOMAIN), LoginPage),
))
BaseBrowser.__init__(self, *args, **kwargs)
def is_logged(self):
if not self.page or self.is_on_page(LoginPage):
return False
error = self.page.get_error()
if error is None:
return True
return False
def login(self):
assert isinstance(self.username, basestring)
assert isinstance(self.password, basestring)
assert self.password.isdigit()
if not self.is_on_page(LoginPage):
self.location('https://' + self.DOMAIN + '/', no_login=True)
self.page.login(self.username, self.password)
if self.is_on_page(LoginPage):
raise BrowserIncorrectPassword()
class SGProfessionalBrowser(SGPEBrowser):
DOMAIN = 'professionnels.secure.societegenerale.fr'
LOGIN_FORM = 'auth_reco'
class SGEnterpriseBrowser(SGPEBrowser):
DOMAIN = 'entreprises.secure.societegenerale.fr'
LOGIN_FORM = 'auth'

View file

@ -0,0 +1,88 @@
# -*- coding: utf-8 -*-
# Copyright(C) 2013 Laurent Bachelier
#
# This file is part of weboob.
#
# weboob is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# weboob is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with weboob. If not, see <http://www.gnu.org/licenses/>.
from logging import error
import re
from weboob.tools.json import json
from weboob.tools.mech import ClientForm
from weboob.tools.browser import BasePage
from ..captcha import Captcha, TileError
__all__ = ['LoginPage', 'AccountsPage']
class SGPEPage(BasePage):
def get_error(self):
try:
return self.document.xpath('//div[@class="ngo_mire_reco_message"]')[0] \
.text.strip()
return self.document.xpath('//*[@id="nge_zone_centre"]//[@class="nge_cadre_message_utilisateur"')[0] \
.text_content.strip()
except IndexError:
return None
class LoginPage(SGPEPage):
def login(self, login, password):
DOMAIN = self.browser.DOMAIN
url_login = 'https://' + DOMAIN + '/'
base_url = 'https://' + DOMAIN
url = base_url + '//sec/vk/gen_crypto?estSession=0'
headers = {'Referer': url_login}
request = self.browser.request_class(url, None, headers)
infos_data = self.browser.readurl(request)
infos_data = re.match('^_vkCallback\((.*)\);$', infos_data).group(1)
infos = json.loads(infos_data.replace("'", '"'))
url = base_url + '//sec/vk/gen_ui?modeClavier=0&cryptogramme=' + infos["crypto"]
self.browser.readurl(url)
img = Captcha(self.browser.openurl(url), infos)
try:
img.build_tiles()
except TileError, err:
error("Error: %s" % err)
if err.tile:
err.tile.display()
self.browser.select_form(self.browser.LOGIN_FORM)
self.browser.controls.append(ClientForm.TextControl('text', 'codsec', {'value': ''}))
self.browser.controls.append(ClientForm.TextControl('text', 'cryptocvcs', {'value': ''}))
self.browser.controls.append(ClientForm.TextControl('text', 'vk_op', {'value': 'auth'}))
self.browser.set_all_readonly(False)
#self.browser['codcli'] = login
self.browser['user_id'] = login
self.browser['codsec'] = img.get_codes(password[:6])
self.browser['cryptocvcs'] = infos["crypto"]
self.browser.form.action = base_url + '/authent.html'
self.browser.submit(nologin=True)
class AccountsPage(SGPEPage):
pass