def double_auth(self, recipient): try: form = self.get_form(id='formCache') except FormNotFound: raise AddRecipientError('form not found') self.browser.context = form['context'] self.browser.dup = form['dup'] self.browser.logged = 1 getsigninfo_data = {} getsigninfo_data['b64_jeton_transaction'] = form['context'] getsigninfo_data['action_level'] = self.get_action_level() r = self.browser.open( 'https://particuliers.secure.societegenerale.fr/sec/getsigninfo.json', data=getsigninfo_data) assert r.page.doc['commun']['statut'] == 'ok' recipient = self.get_recipient_object(recipient, get_info=True) self.browser.page = None if r.page.doc['donnees']['sign_proc'] == 'csa': send_data = {} send_data['csa_op'] = 'sign' send_data['context'] = form['context'] r = self.browser.open( 'https://particuliers.secure.societegenerale.fr/sec/csa/send.json', data=send_data) assert r.page.doc['commun']['statut'] == 'ok' raise AddRecipientStep( recipient, Value( 'code', label= u'Cette opération doit être validée par un Code Sécurité.') ) elif r.page.doc['donnees']['sign_proc'] == 'OOB': oob_data = {} oob_data['b64_jeton_transaction'] = form['context'] r = self.browser.open( 'https://particuliers.secure.societegenerale.fr/sec/oob_sendoob.json', data=oob_data) assert r.page.doc['commun']['statut'] == 'ok' self.browser.id_transaction = r.page.doc['donnees'][ 'id-transaction'] raise AddRecipientStep( recipient, ValueBool( 'pass', label= u'Valider cette opération sur votre applicaton société générale' )) else: raise AddRecipientError('sign process unknown')
def new_recipient(self, recipient, **params): if 'code' in params: # for sms authentication return self.send_code(recipient, **params) # prepare commun data for all authentication method data = {} data['adresseBeneficiaire'] = '' data['iban'] = recipient.iban data['libelleBeneficiaire'] = recipient.label data['notification'] = True data['typeBeneficiaire'] = '' # provisional if self.digital_key: if 'digital_key' in params: return self.new_recipient_digital_key(recipient, data) # need to be on recipient page send sms or mobile notification # needed to get the phone number, enabling the possibility to send sms. # all users with validated phone number can receive sms code self.recipients.go(data=JSON({'type': 'TOUS'})) # check type of recipient activation type_activation = 'sms' # provisional if self.digital_key: if self.page.has_digital_key(): # force users with digital key activated to use digital key authentication type_activation = 'digital_key' if type_activation == 'sms': # post recipient data sending sms with same request data['typeEnvoi'] = 'SMS' recipient = self.add_recip.go(data=json.dumps(data), headers={ 'Content-Type': 'application/json' }).get_recipient(recipient) raise AddRecipientStep( recipient, Value('code', label='Saisissez le code reçu par SMS.')) elif type_activation == 'digital_key': # recipient validated with digital key are immediatly available recipient.enabled_date = datetime.today() raise AddRecipientStep( recipient, ValueBool( 'digital_key', label= 'Validez pour recevoir une demande sur votre application bancaire. La validation de votre bénéficiaire peut prendre plusieurs minutes.' ))
def new_recipient(self, recipient, **params): if 'sms_password' in params: return self.end_sms_recipient(recipient, **params) if 'otp_sms' in params: transactionid = re.search(r'transactionID=(.*)', self.page.url).group(1) self.request_sms.go(param=transactionid) validation = {} validation['validate'] = {} key = self.page.validate_key() validation['validate'][key] = [] inner_param = {} inner_param['id'] = self.page.validation_id(key) inner_param['type'] = 'SMS' inner_param['otp_sms'] = params['otp_sms'] validation['validate'][key].append(inner_param) headers = { 'Content-Type': 'application/json', 'Accept': 'application/json, text/plain, */*' } self.location(self.url + '/step', data=json.dumps(validation), headers=headers) saml = self.page.get_saml() action = self.page.get_action() self.location(action, data={'SAMLResponse': saml}) if self.authent.is_here(): self.page.go_on() return self.facto_post_recip(recipient) self.pre_transfer( next(acc for acc in self.get_accounts_list() if acc.type in (Account.TYPE_CHECKING, Account.TYPE_SAVINGS))) # This send sms to user. self.page.go_add_recipient() if self.sms_option.is_here(): raise AddRecipientStep( self.get_recipient_obj(recipient), Value( 'otp_sms', label= u'Veuillez renseigner le mot de passe unique qui vous a été envoyé par SMS dans le champ réponse.' )) else: self.page.check_canceled_auth() self.page.set_browser_form() raise AddRecipientStep( self.get_recipient_obj(recipient), Value('sms_password', label=self.page.get_prompt_text()))
def new_recipient(self, recipient, **params): if 'code' in params: return self.send_code(recipient, **params) if recipient.iban[:2] not in ('FR', 'MC'): raise AddRecipientBankError( message=u"LCL n'accepte que les iban commençant par MC ou FR.") for _ in range(2): self.add_recip.go() if self.add_recip.is_here(): break if self.no_perm.is_here() and self.page.get_error_msg(): raise AddRecipientBankError(message=self.page.get_error_msg()) assert self.add_recip.is_here(), 'Navigation failed: not on add_recip' self.page.validate(recipient.iban, recipient.label) assert self.recip_confirm.is_here( ), 'Navigation failed: not on recip_confirm' self.page.check_values(recipient.iban, recipient.label) # Send sms to user. self.open('/outil/UWBE/Otp/envoiCodeOtp?telChoisi=MOBILE') raise AddRecipientStep( self.get_recipient_object(recipient.iban, recipient.label), Value('code', label='Saisissez le code.'))
def new_recipient(self, recipient, **kwargs): if 'code' in kwargs: assert self.rcpt_page.is_here() assert self.page.is_confirm_sms() self.page.confirm_sms(kwargs['code']) return self.rcpt_after_sms() account = None for account in self.get_accounts_list(): if account.url: break suffix = 'virements/comptes-externes/nouveau' if account.url.endswith('/'): target = account.url + suffix else: target = account.url + '/' + suffix self.location(target) assert self.page.is_charac() self.page.submit_recipient(recipient) if self.page.is_send_sms(): self.page.send_sms() assert self.page.is_confirm_sms() raise AddRecipientStep( self.build_recipient(recipient), Value('code', label='Veuillez saisir le code')) # if the add recipient is restarted after the sms has been confirmed recently, the sms step is not presented again return self.rcpt_after_sms()
def new_recipient(self, recipient, **params): if 'code' in params: return self.send_code(recipient, **params) try: assert recipient.iban[:2] in ['FR', 'MC'] except AssertionError: raise AddRecipientError( u"LCL n'accepte que les iban commençant par MC ou FR.") for _ in range(2): self.add_recip.go() if self.add_recip.is_here(): break try: assert self.add_recip.is_here() except AssertionError: raise AddRecipientError('Navigation failed: not on add_recip.') self.page.validate(recipient.iban, recipient.label) try: assert self.recip_confirm.is_here() except AssertionError: raise AddRecipientError('Navigation failed: not on recip_confirm.') self.page.check_values(recipient.iban, recipient.label) # Send sms to user. self.open('/outil/UWBE/Otp/envoiCodeOtp?telChoisi=MOBILE') raise AddRecipientStep( self.get_recipient_object(recipient.iban, recipient.label), Value('code', label='Saisissez le code.'))
def new_recipient(self, recipient, **params): if 'sms_password' in params: return self.end_sms_recipient(recipient, **params) if 'otp_sms' in params: self.otp_sms_validation(params['otp_sms']) if self.authent.is_here(): self.page.go_on() return self.facto_post_recip(recipient) if 'pro_password' in params: return self.end_pro_recipient(recipient, **params) self.pre_transfer( next(acc for acc in self.get_accounts_list() if acc.type in (Account.TYPE_CHECKING, Account.TYPE_SAVINGS))) # This send sms to user. self.page.go_add_recipient() if self.sms_option.is_here(): self.is_send_sms = True raise AddRecipientStep( self.get_recipient_obj(recipient), Value( 'otp_sms', label= 'Veuillez renseigner le mot de passe unique qui vous a été envoyé par SMS dans le champ réponse.' )) # pro add recipient. elif self.page.need_auth(): self.page.set_browser_form() raise AddRecipientStep( self.get_recipient_obj(recipient), Value('pro_password', label=self.page.get_prompt_text())) else: self.page.check_canceled_auth() self.page.set_browser_form() raise AddRecipientStep( self.get_recipient_obj(recipient), Value('sms_password', label=self.page.get_prompt_text()))
def send_sms_to_user(self, recipient): """Add recipient with OTP SMS authentication""" data = {} data['csa_op'] = 'sign' data['context'] = self.context self.open(self.absurl('/sec/csa/send.json'), data=data) raise AddRecipientStep( recipient, Value( 'code', label='Cette opération doit être validée par un Code Sécurité.' ))
def send_notif_to_user(self, recipient): """Add recipient with 'pass sécurité' authentication""" data = {} data['b64_jeton_transaction'] = self.context r = self.open(self.absurl('/sec/oob_sendoob.json'), data=data) self.id_transaction = r.page.get_transaction_id() raise AddRecipientStep( recipient, ValueBool( 'pass', label= 'Valider cette opération sur votre applicaton société générale' ))
def new_recipient(self, recipient, **params): if 'sms_password' in params: return self.end_sms_recipient(recipient, **params) self.pre_transfer( next(acc for acc in self.get_accounts_list() if acc.type in (Account.TYPE_CHECKING, Account.TYPE_SAVINGS))) # This send sms to user. self.page.go_add_recipient() self.page.check_canceled_auth() self.page.set_browser_form() raise AddRecipientStep( self.get_recipient_obj(recipient), Value('sms_password', label=self.page.get_prompt_text()))
def new_recipient(self, recipient, **params): if 'code' in params: return self.send_code(recipient, **params) # needed to get the phone number, enabling the possibility to send sms. self.recipients.go(data=JSON({'type': 'TOUS'})) # post recipient data sending sms with same request data = {} data['adresseBeneficiaire'] = '' data['iban'] = recipient.iban data['libelleBeneficiaire'] = recipient.label data['notification'] = True data['typeBeneficiaire'] = '' data['typeEnvoi'] = 'SMS' recipient = self.add_recip.go(data=json.dumps(data), headers={'Content-Type': 'application/json'}).get_recipient(recipient) raise AddRecipientStep(recipient, Value('code', label='Saississez le code.'))
def send_sms_to_user(self, recipient, sms_info): """Add recipient with OTP SMS authentication""" data = { 'channelType': sms_info['type'], 'externalAccountsRequest': self.add_recipient_info, 'sensitiveOperationAction': 'ADD_TRANSFER_BENEFICIARY', } phone_id = sms_info['phone'] data['channelValue'] = phone_id self.add_recipient_info['phoneUid'] = phone_id self.location(self.absurl('/secure/api-v1/sca/sendOtp', base=True), json=data) self.need_reload_state = True raise AddRecipientStep(recipient, Value('code', label='Veuillez saisir le code temporaire envoyé par SMS'))
def new_recipient(self, recipient, **params): if self.currentSubBank is None: self.getCurrentSubBank() self.recipients_list.go(subbank=self.currentSubBank) if self.page.has_list(): assert recipient.category in self.page.get_recipients_list(), \ 'Recipient category is not on the website available list.' self.page.go_list(recipient.category) self.page.go_to_add() if self.verify_pass.is_here(): self.recipient_form = self.page.get_recipient_form() raise AddRecipientStep(self.get_recipient_object(recipient), Value('Clé', label=self.page.get_question())) else: return self.continue_new_recipient(recipient, **params)
def new_recipient(self, recipient, is_bp_account=False, **kwargs): if 'code' in kwargs: assert self.rcpt_code.is_here() self.post_code(kwargs['code']) self.recipient_form = None assert self.rcpt_summary.is_here() return self.build_recipient(recipient) self.create_recipient.go().choose_country(recipient, is_bp_account) self.page.populate(recipient) if self.page.is_bp_account(): return self.new_recipient(recipient, is_bp_account=True, **kwargs) # send sms self.location(self.page.get_confirm_link()) self.page.set_browser_form() raise AddRecipientStep(self.build_recipient(recipient), Value('code', label='Veuillez saisir votre code de validation'))
def new_recipient(self, recipient, **params): if 'code' in params: # to drop and use self.add_recipient_form instead in send_code() recipient_form = json.loads(self.add_recipient_form) self.send_code(recipient_form, params['code']) if self.page.rcpt_after_sms(): self.need_reload_state = None return self.copy_recipient(recipient) elif self.page.is_code_expired(): self.need_reload_state = True raise AddRecipientStep( recipient, Value( 'code', label= 'Le code sécurité est expiré. Veuillez saisir le nouveau code reçu qui sera valable 5 minutes.' )) assert False, self.page.get_error() return self.new_recipient_before_otp(recipient, **params)
def new_recipient(self, recipient, **params): if self.currentSubBank is None: self.getCurrentSubBank() if 'Bic' in params: return self.post_with_bic(recipient, **params) if 'code' in params: return self.end_new_recipient(recipient, **params) if u'Clé' in params: return self.continue_new_recipient(recipient, **params) self.recipients_list.go(subbank=self.currentSubBank) if self.page.has_list(): if recipient.category not in self.page.get_recipients_list(): raise AddRecipientError( 'Recipient category is not on the website available list.') self.page.go_list(recipient.category) self.page.go_to_add() if self.verify_pass.is_here(): raise AddRecipientStep( self.get_recipient_object(recipient), Value(u'Clé', label=self.page.get_question())) else: return self.continue_new_recipient(recipient, **params)
def new_recipient(self, recipient, **params): if 'code' in params: self.page.send_code(params['code']) return self.rcpt_after_sms(recipient) self.recipients.go() self.page.go_add_new_recipient_page() if self.recipient_confirmation_page.is_here(): # Confirm that user want to add recipient self.page.continue_new_recipient() if self.recipient_confirmation_page.is_here(): self.page.check_errors() assert self.add_recipient.is_here() self.page.set_new_recipient_iban(recipient.iban) rcpt = self.copy_recipient_obj(recipient) # This send the sms to user self.page.set_new_recipient_label(recipient.label) raise AddRecipientStep(rcpt, Value('code', label='Veuillez entrer le code reçu par SMS.'))
def new_recipient_before_otp(self, recipient, **params): self.recipients.go() self.page.check_external_iban_form(recipient) self.page.check_recipient_iban() # fill form self.page.fill_recipient_form(recipient) rcpt = self.page.get_new_recipient(recipient) # get first part of confirm form send_code_form = self.page.get_send_code_form() data = { 'appelAjax': 'true', 'domicileUpdated': 'false', 'numeroSelectionne.value': '', 'portableUpdated': 'false', 'proUpdated': 'false', 'typeOperationSensible': 'AJOUT_BENEFICIAIRE' } # this send sms to user self.location(self.absurl( '/fr/prive/appel-securite-forte-otp-bankone.jsp', base=True), data=data) # get second part of confirm form send_code_form.update(self.page.get_send_code_form_input()) # save form value and url for statesmixin self.add_recipient_form = dict(send_code_form) self.add_recipient_form.update({'url': send_code_form.url}) # storage can't handle dict with '.' in key # to drop when dict with '.' in key is handled self.add_recipient_form = json.dumps(self.add_recipient_form) self.need_reload_state = True raise AddRecipientStep( rcpt, Value('code', label='Veuillez saisir le code reçu.'))
def init_new_recipient(self, recipient): self.recipient_form = None # so it is reset when a new recipient is added # get url account = None for account in self.get_accounts_list(): if account.url: break suffix = 'virements/comptes-externes/nouveau' if account.url.endswith('/'): target = account.url + suffix else: target = account.url + '/' + suffix self.location(target) assert self.page.is_charac(), 'Not on the page to add recipients.' # fill recipient form self.page.submit_recipient(recipient) recipient.origin_account_id = account.id # confirm sending sms assert self.page.is_confirm_send_sms(), 'Cannot reach the page asking to send a sms.' self.page.confirm_send_sms() if self.page.is_send_sms(): # send sms self.page.send_sms() assert self.page.is_confirm_sms(), 'The sms was not send.' self.recipient_form = self.page.get_confirm_sms_form() self.recipient_form['account_url'] = account.url raise AddRecipientStep(recipient, Value('code', label='Veuillez saisir le code')) # if the add recipient is restarted after the sms has been confirmed recently, the sms step is not presented again return self.rcpt_after_sms()
def new_recipient(self, recipient, **params): if not re.match(u"^[-+.,:/?() éèêëïîñàâäãöôòõùûüÿ0-9a-z']+$", recipient.label, re.I): raise RecipientInvalidLabel( 'Recipient label contains invalid characters') if 'sms_code' in params and not re.match(r'^[a-z0-9]{6}$', params['sms_code'], re.I): raise AddRecipientError('SMS verification code is invalid') self.transfer_init_page.go(sag=self.sag) self.location(self.page.url_list_recipients()) self.location(self.page.url_add_recipient()) if not ('sms_code' in params and self.page.can_send_code()): self.page.send_sms() # go to a GET page, so StatesMixin can reload it self.location(self.accounts_url.format(self.sag)) raise AddRecipientStep( self.build_recipient(recipient), Value('sms_code', label='Veuillez saisir le code SMS')) else: self.page.submit_code(params['sms_code']) err = hasattr(self.page, 'get_sms_error') and self.page.get_sms_error() if err: raise AddRecipientError(message=err) self.page.submit_recipient(recipient.label, recipient.iban) self.page.confirm_recipient() self.page.check_recipient_error() res = self.page.find_recipient(recipient.iban) if res is None: raise AddRecipientError('Recipient could not be found') return res
def new_recipient(self, recipient, **params): if 'code' in params: self.validate_rcpt_with_sms(params['code']) return self.page.rcpt_after_sms(recipient) data = { 'n_nbOccurences': 1000, 'n_nbOccurences_affichees': 0, 'n_rang': 0, } self.recipients.go(data=data) step_urls = { 'first_recipient_check': self.absurl('/ord-web/ord//ord-valider-destinataire-avant-maj.json', base=True), 'get_bic': self.absurl('/ord-web/ord//ord-tiers-calcul-bic.json', base=True), 'get_token': self.absurl('/ord-web/ord//ord-preparer-signature-destinataire.json', base=True), 'get_sign_info': self.absurl('/sec/getsigninfo.json', base=True), 'send_otp_to_user': self.absurl('/sec/csa/send.json', base=True), } self.add_recipient.go(method='POST', headers={'Content-Type': 'application/json;charset=UTF-8'}) countries = self.page.get_countries() # first recipient check data = { 'an_codeAction': 'ajout_tiers', 'an_refSICoordonnee': '', 'an_refSITiers': '', 'cl_iban': recipient.iban, 'cl_raisonSociale': recipient.label, } self.location(step_urls['first_recipient_check'], data=data) # get bic data = { 'an_activateCMU': 'true', 'an_codePaysBanque': '', 'an_nature': 'C', 'an_numeroCompte': recipient.iban, 'an_topIBAN': 'true', 'cl_adresse': '', 'cl_adresseBanque': '', 'cl_codePays': recipient.iban[:2], 'cl_libellePaysBanque': '', 'cl_libellePaysDestinataire': countries[recipient.iban[:2]], 'cl_nomBanque': '', 'cl_nomRaisonSociale': recipient.label, 'cl_ville': '', 'cl_villeBanque': '', } self.location(step_urls['get_bic'], data=data) bic = self.page.get_response_data() # get token data = { 'an_coordonnee_codePaysBanque': '', 'an_coordonnee_nature': 'C', 'an_coordonnee_numeroCompte': recipient.iban, 'an_coordonnee_topConfidentiel': 'false', 'an_coordonnee_topIBAN': 'true', 'an_refSICoordonnee': '', 'an_refSIDestinataire': '', 'cl_adresse': '', 'cl_codePays': recipient.iban[:2], 'cl_coordonnee_adresseBanque': '', 'cl_coordonnee_bic': bic, 'cl_coordonnee_categories_libelle': '', 'cl_coordonnee_categories_refSi': '', 'cl_coordonnee_libellePaysBanque': '', 'cl_coordonnee_nomBanque': '', 'cl_coordonnee_villeBanque': '', 'cl_libellePaysDestinataire': countries[recipient.iban[:2]], 'cl_nomRaisonSociale': recipient.label, 'cl_ville': '', } self.location(step_urls['get_token'], data=data) self.new_rcpt_validate_form = data payload = self.page.get_response_data() # get sign info data = { 'b64_jeton_transaction': payload['jeton'], 'action_level': payload['sensibilite'], } self.location(step_urls['get_sign_info'], data=data) # send otp to user data = { 'context': payload['jeton'], 'csa_op': 'sign' } self.location(step_urls['send_otp_to_user'], data=data) self.new_rcpt_validate_form.update(data) rcpt = self.copy_recipient_obj(recipient) raise AddRecipientStep(rcpt, Value('code', label='Veuillez entrer le code reçu par SMS.'))
def new_recipient(self, recipient, **params): if not re.match(u"^[-+.,:/?() éèêëïîñàâäãöôòõùûüÿ0-9a-z']+$", recipient.label, re.I): raise RecipientInvalidLabel( 'Recipient label contains invalid characters') if 'sms_code' in params and not re.match(r'^[a-z0-9]{6}$', params['sms_code'], re.I): # check before send sms code because it can crash website if code is invalid raise AddRecipientBankError("SMS code %s is invalid" % params['sms_code']) # avoid `iter_accounts` if there is only one perimeter if len(self.perimeters) > 1: accounts = list(self.iter_accounts()) assert recipient.origin_account_id, 'Origin account id is mandatory for multispace' account = find_object(accounts, id=recipient.origin_account_id, error=AccountNotFound) self.go_to_perimeter(account._perimeter) self.transfer_init_page.go() assert self.transfer_init_page.is_here() if not self.page.add_recipient_is_allowed(): if not [ rec for rec in self.page.iter_recipients() if rec.category == 'Externe' ]: raise AddRecipientBankError( 'Vous ne pouvez pas ajouter de bénéficiaires, veuillez contacter votre banque.' ) assert False, 'Xpath for a recipient add is not catched' self.location(self.page.url_list_recipients()) # there are 2 pages from where we can add a new recipient: # - RecipientListPage, but the link is sometimes missing # - TransferPage, start making a transfer with a new recipient but don't complete the transfer # but it seems dangerous since we have to set an amount, etc. # so we implement it in 2 ways with a preference for RecipientListPage if self.page.url_add_recipient(): self.logger.debug( 'good, we can add a recipient from the recipient list') else: # in this case, the link was missing self.logger.warning( 'cannot add a recipient from the recipient list page, pretending to make a transfer in order to add it' ) self.transfer_init_page.go() assert self.transfer_init_page.is_here() self.location(self.page.url_add_recipient()) if not ('sms_code' in params and self.page.can_send_code()): self.page.send_sms() # go to a GET page, so StatesMixin can reload it self.accounts.go() raise AddRecipientStep( self.build_recipient(recipient), Value('sms_code', label='Veuillez saisir le code SMS')) else: self.page.submit_code(params['sms_code']) err = hasattr(self.page, 'get_sms_error') and self.page.get_sms_error() if err: raise AddRecipientBankError(message=err) self.page.submit_recipient(recipient.label, recipient.iban) self.page.confirm_recipient() self.page.check_recipient_error() if self.transfer_page.is_here(): # in this case, we were pretending to make a transfer, just to add the recipient # go back to transfer page to abort the transfer and see the new recipient self.transfer_init_page.go() assert self.transfer_init_page.is_here() res = self.page.find_recipient(recipient.iban) assert res, 'Recipient with iban %s could not be found' % recipient.iban return res