Exemplo n.º 1
0
    def on_load(self):
        msg = CleanText('//div[@class="confirmation"]//span[span]')(self.doc)

        self.logger.warning('Password expired.')
        if not self.browser.rotating_password:
            raise BrowserPasswordExpired(msg)

        if not self.looks_legit(self.browser.password):
            # we may not be able to restore the password, so reject it
            self.logger.warning('Unable to restore it, it is not legit.')
            raise BrowserPasswordExpired(msg)

        new_passwords = []
        for i in range(self.NOT_REUSABLE_PASSWORDS_COUNT):
            new_pass = ''.join(
                [str((int(l) + i + 1) % 10) for l in self.browser.password])
            if not self.looks_legit(new_pass):
                self.logger.warning('One of rotating password is not legit')
                raise BrowserPasswordExpired(msg)
            new_passwords.append(new_pass)

        current_password = self.browser.password
        for new_pass in new_passwords:
            self.logger.warning('Renewing with temp password')
            if not self.browser.change_pass(current_password, new_pass):
                self.logger.warning('New temp password is rejected, giving up')
                raise BrowserPasswordExpired(msg)
            current_password = new_pass

        if not self.browser.change_pass(current_password,
                                        self.browser.password):
            self.logger.error('Could not restore old password!')

        self.logger.warning('Old password restored.')
Exemplo n.º 2
0
    def on_load(self):
        if not self.looks_legit(self.browser.password):
            # we may not be able to restore the password, so reject it
            raise BrowserPasswordExpired()

        new_pass = ''.join(
            [str((int(l) + 1) % 10) for l in self.browser.password])
        self.logger.warning(
            'Password expired. Renewing it. Temporary password is %s',
            new_pass)
        if not self.change_pass(self.browser.password, new_pass):
            self.logger.warning('New temp password is rejected, giving up')
            raise BrowserPasswordExpired()

        if not self.change_pass(new_pass, self.browser.password):
            self.logger.error('Could not restore old password!')
Exemplo n.º 3
0
    def iter_accounts(self):
        if self.type == '1':
            self.ti_card_go()
        elif self.type == '2':
            self.accounts.go()

        if self.error.is_here():
            raise BrowserPasswordExpired()

        if self.type == '1':
            for account in self.page.iter_accounts(rib=None):
                self.page.expand(account=account)
                account.coming = self.page.get_balance()
                yield account
        if self.type == '2':
            for rib in self.page.get_rib_list():
                self.accounts.stay_or_go()
                self.page.expand(rib=rib)

                accounts = list(self.page.iter_accounts(rib=rib))
                ids = {}
                prev_rib = None
                for account in accounts:
                    if account.id in ids:
                        self.logger.warning('duplicate account %r', account.id)
                        account.id += '_%s' % ''.join(account.label.split())

                    if prev_rib != account._rib:
                        self.coming.go()
                        self.page.expand(rib=account._rib)
                    account.coming = self.page.get_balance(account)
                    prev_rib = account._rib

                    ids[account.id] = account
                    yield account
Exemplo n.º 4
0
 def on_load(self):
     # Handle <p class="h1">Modifier mon code personnel&nbsp;</p>
     # Handle <h1><span class="h1">Modifier&nbsp;votre code personnel</span></h1>
     msg = CleanText(
         '//*[@class="h1" and contains(text(), "code personnel")]')(
             self.doc)
     if msg:
         raise BrowserPasswordExpired(msg)
Exemplo n.º 5
0
    def do_login(self):
        self.login.go().login(self.username, self.password)
        if self.accounts.is_here():
            expired_error = self.page.get_password_expired()
            if expired_error:
                raise BrowserPasswordExpired(expired_error)

        # Force redirection to entry page if the redirect page does not contain an url
        if self.redirect.is_here():
            self.entrypage.go()

        if self.entrypage.is_here() or self.login.is_here():
            error = self.page.get_error()
            if error:
                if 'code confidentiel à la première connexion' in error:
                    raise BrowserPasswordExpired(error)
                raise BrowserIncorrectPassword(error)

        if not self.logged:
            raise BrowserIncorrectPassword()
Exemplo n.º 6
0
 def do_login(self):
     self.login.go()
     self.page.login(self.username, self.password)
     if self.login.is_here():
         if 'acceptation' in self.url:
             raise ActionNeeded("Veuillez accepter les conditions générales d'utilisation sur le site.")
         else:
             raise BrowserIncorrectPassword("L'identifiant ou le mot de passe est incorrect.")
     elif self.migration.is_here():
         # Usually landing here when customers have to renew their credentials
         message = self.page.get_error()
         raise BrowserPasswordExpired(message)
Exemplo n.º 7
0
 def iter_accounts(self):
     if not self.accounts:
         self.acc_home.go()
         if self.error.is_here():
             raise BrowserPasswordExpired()
         self.page.expand()
         for acc in self.page.iter_accounts():
             if acc.id in [a.id for a in self.accounts]:
                 # TODO apply that id to all accounts
                 acc.id = "%s_%s" % (acc.id, ''.join(acc.label.split()))
             self.accounts.append(acc)
     for acc in self.accounts:
         yield acc
Exemplo n.º 8
0
    def do_login(self):
        self.login_cas.go()
        try:
            self.page.login(self.username, self.password)
        except ClientError as e:
            if e.response.status_code == 401:
                raise BrowserIncorrectPassword()
            raise

        if not self.page.is_logged():
            raise BrowserIncorrectPassword(self.page.get_error_message())

        self.dashboard.go()
        if self.password_expired.is_here():
            raise BrowserPasswordExpired(self.page.get_error_message())
Exemplo n.º 9
0
    def do_login(self):
        assert isinstance(self.username, basestring)
        assert isinstance(self.password, basestring)

        try:
            self.loginpage.stay_or_go().login(self.username, self.password)
        except ClientError as error:
            if error.response.status_code == 401:
                raise BrowserIncorrectPassword()
            if error.response.status_code == 403:
                # occur when user try several times with a bad password, orange block his account for a short time
                raise BrowserIncorrectPassword(error.response.json())
            raise

        if self.password_page.is_here():
            error_message = self.page.get_change_password_message()
            if error_message:
                raise BrowserPasswordExpired(error_message)
Exemplo n.º 10
0
 def on_load(self):
     if self.doc['commun']['statut'].lower() == 'nok':
         reason = self.doc['commun']['raison']
         if reason == 'SYD-COMPTES-UNAUTHORIZED-ACCESS':
             raise NoAccountsException(
                 "Vous n'avez pas l'autorisation de consulter : {}".format(
                     reason))
         elif reason == 'niv_auth_insuff':
             raise BrowserIncorrectPassword(
                 'Vos identifiants sont incorrects')
         elif reason == 'chgt_mdp_oblig':
             raise BrowserPasswordExpired(
                 'Veuillez renouveler votre mot de passe')
         elif reason == 'oob_insc_oblig':
             raise AuthMethodNotImplemented(
                 "L'authentification par Secure Access n'est pas prise en charge"
             )
         raise BrowserUnavailable(reason)
Exemplo n.º 11
0
 def on_load(self):
     if self.doc['commun']['statut'].lower() == 'nok':
         reason = self.doc['commun']['raison']
         if reason == 'SYD-COMPTES-UNAUTHORIZED-ACCESS':
             raise NoAccountsException(
                 "Vous n'avez pas l'autorisation de consulter : {}".format(
                     reason))
         elif reason == 'niv_auth_insuff':
             return
         elif reason in ('chgt_mdp_oblig', 'chgt_mdp_init'):
             raise BrowserPasswordExpired(
                 'Veuillez vous rendre sur le site de la banque pour renouveler votre mot de passe'
             )
         elif reason == 'oob_insc_oblig':
             raise AuthMethodNotImplemented(
                 "L'authentification par Secure Access n'est pas prise en charge"
             )
         else:
             # the BrowserUnavailable was raised for every unknown error, and was masking the real error.
             # So users and developers didn't know what kind of error it was.
             assert False, 'Error %s is not handled yet.' % reason
Exemplo n.º 12
0
 def on_load(self):
     if self.doc.xpath('//h1[contains(text(), "Erreur")]'):
         raise BrowserUnavailable(CleanText('//h1[contains(text(), "Erreur")]//span')(self.doc))
     msg = CleanText('//div[@class="x-attentionErreur"]/b')(self.doc)
     if 'vous devez modifier votre code confidentiel' in msg:
         raise BrowserPasswordExpired(msg)
Exemplo n.º 13
0
    def do_login(self):
        """
        Attempt to log in.
        Note: this method does nothing if we are already logged in.
        """
        # Among the parameters used during the login step, there is
        # a connection type (called typeAccount) that can take the
        # following values:
        # WE: espace particulier
        # WP: espace pro
        # WM: personnes protégées
        # EU: Cenet
        #
        # A connection can have one connection type as well as many of
        # them. There is an issue when there is many connection types:
        # the connection type to use can't be guessed in advance, we
        # have to test all of them until the login step is successful
        # (sometimes all connection type can be used for the login, sometimes
        # only one will work).
        #
        # For simplicity's sake, we try each connection type from first to
        # last (they are returned in a list by the first request)
        #
        # Examples of connection types combination that have been seen so far:
        # [WE]
        # [WP]
        # [WE, WP]
        # [WE, WP, WM]
        # [WP, WM]
        # [EU]
        # [EU, WE]  (EU tends to come first when present)

        if not self.username or not self.password:
            raise BrowserIncorrectPassword()

        # Retrieve the list of types: can contain a single type or more
        # - when there is a single type: all the information are available
        # - when there are several types: an additional request is needed
        try:
            connection = self.login.go(login=self.username)
        # The website crash sometime when the module is not on caissedepargne (on linebourse, for exemple).
        # The module think is not connected anymore, so we go to the home logged page. If there are no error
        # that mean we are already logged and now, on the good website

        except ValueError:
            self.home.go()
            if self.home.is_here():
                return
            # If that not the case, that's an other error that we have to correct
            raise

        data = connection.get_response()

        if data is None:
            raise BrowserIncorrectPassword()

        accounts_types = data.get('account', [])
        if not self.nuser and 'WE' not in accounts_types:
            raise BrowserIncorrectPassword(
                "Utilisez Caisse d'Épargne Professionnels et renseignez votre nuser pour connecter vos comptes sur l'epace Professionels ou Entreprises."
            )

        if len(accounts_types) > 1:
            # Additional request when there is more than one connection type
            # to "choose" from the list of connection types
            self.multi_type = True

            if self.inexttype < len(accounts_types):
                if accounts_types[self.inexttype] == 'EU' and not self.nuser:
                    # when EU is present and not alone, it tends to come first
                    # if nuser is unset though, user probably doesn't want 'EU'
                    self.inexttype += 1

                self.typeAccount = accounts_types[self.inexttype]
            else:
                assert False, 'should have logged in with at least one connection type'
            self.inexttype += 1

            data = self.account_login.go(
                login=self.username,
                accountType=self.typeAccount).get_response()

        assert data is not None

        if data.get(
                'authMode', ''
        ) == 'redirect':  # the connection type EU could also be used as a criteria
            raise SiteSwitch('cenet')

        typeAccount = data['account'][0]

        if self.multi_type:
            assert typeAccount == self.typeAccount

        id_token_clavier = data['keyboard']['Id']
        vk = CaissedepargneKeyboard(data['keyboard']['ImageClavier'],
                                    data['keyboard']['Num']['string'])
        newCodeConf = vk.get_string_code(self.password)

        playload = {
            'idTokenClavier': id_token_clavier,
            'newCodeConf': newCodeConf,
            'auth_mode': 'ajax',
            'nuusager': self.nuser.encode('utf-8'),
            'codconf': '',  # must be present though empty
            'typeAccount': typeAccount,
            'step': 'authentification',
            'ctx': 'typsrv={}'.format(typeAccount),
            'clavierSecurise': '1',
            'nuabbd': self.username
        }

        try:
            res = self.location(data['url'], params=playload)
        except ValueError:
            raise BrowserUnavailable()
        if not res.page:
            raise BrowserUnavailable()

        response = res.page.get_response()

        assert response is not None

        if response['error'] == 'Veuillez changer votre mot de passe':
            raise BrowserPasswordExpired(response['error'])

        if not response['action']:
            # the only possible way to log in w/o nuser is on WE. if we're here no need to go further.
            if not self.nuser and self.typeAccount == 'WE':
                raise BrowserIncorrectPassword(response['error'])

            # we tested all, next iteration will throw the assertion
            if self.inexttype == len(
                    accounts_types
            ) and 'Temporairement votre abonnement est bloqué' in response[
                    'error']:
                raise ActionNeeded(response['error'])

            if self.multi_type:
                # try to log in with the next connection type's value
                self.do_login()
                return
            raise BrowserIncorrectPassword(response['error'])

        self.BASEURL = urljoin(data['url'], '/')

        try:
            self.home.go()
        except BrowserHTTPNotFound:
            raise BrowserIncorrectPassword()
Exemplo n.º 14
0
 def on_load(self):
     raise BrowserPasswordExpired(
         u'Vous avez atteint le seuil de 100 connexions avec le même code secret. Par mesure de sécurité, veuillez le changer.'
     )
Exemplo n.º 15
0
 def on_load(self):
     raise BrowserPasswordExpired('New pass needed')
Exemplo n.º 16
0
 def on_load(self):
     raise BrowserPasswordExpired(
         CleanText('//p[@class="message"]')(self.doc))
Exemplo n.º 17
0
 def on_load(self):
     msg = CleanText('//div[@id="errors"]')(self.doc)
     if msg == 'Your password has expired: you must change it.':
         raise BrowserPasswordExpired(msg)
Exemplo n.º 18
0
 def on_load(self):
     message = CleanText('//h3')(self.doc) or CleanText('//h1')(self.doc)
     raise BrowserPasswordExpired(message)
Exemplo n.º 19
0
 def on_load(self):
     raise BrowserPasswordExpired()
Exemplo n.º 20
0
 def on_load(self):
     error_msg = CleanText('//fieldset//font[1]/text()',
                           default='')(self.doc)
     if 'Le code personnel que vous allez choisir' in error_msg:
         raise BrowserPasswordExpired()
     assert False, 'Unhandled error on PasswordExpiredPage: %s' % error_msg
Exemplo n.º 21
0
 def on_load(self):
     raise BrowserPasswordExpired("Renouvellement de mot de passe requis.")