Exemple #1
0
class Nubank:
    feed_url = None
    query_url = None
    bills_url = None

    def __init__(self):
        self.client = HttpClient()
        self.discovery = Discovery(self.client)

    @staticmethod
    def _get_query(query_name):
        root = os.path.abspath(os.path.dirname(__file__))
        gql_file = query_name + '.gql'
        path = os.path.join(root, 'queries', gql_file)
        with open(path) as gql:
            return gql.read()

    def _make_graphql_request(self, graphql_object, variables=None):
        if variables is None:
            variables = {}

        body = {
            'variables': variables,
            'query': self._get_query(graphql_object)
        }

        return self.client.post(self.query_url, json=body)

    def _password_auth(self, cpf: str, password: str):
        payload = {
            "grant_type": "password",
            "login": cpf,
            "password": password,
            "client_id": "other.conta",
            "client_secret": "yQPeLzoHuJzlMMSAjC-LgNUJdUecx8XO"
        }
        return self.client.post(self.discovery.get_url('login'), json=payload)

    def _save_auth_data(self, auth_data: dict) -> None:
        self.client.set_header('Authorization',
                               f'Bearer {auth_data["access_token"]}')
        self.feed_url = auth_data['_links']['events']['href']
        self.query_url = auth_data['_links']['ghostflame']['href']
        self.bills_url = auth_data['_links']['bills_summary']['href']

    def get_qr_code(self) -> Tuple[str, QRCode]:
        content = str(uuid.uuid4())
        qr = QRCode()
        qr.add_data(content)
        return content, qr

    def authenticate_with_qr_code(self, cpf: str, password, uuid: str):
        auth_data = self._password_auth(cpf, password)
        self.client.set_header('Authorization',
                               f'Bearer {auth_data["access_token"]}')

        payload = {'qr_code_id': uuid, 'type': 'login-webapp'}

        response = self.client.post(self.discovery.get_app_url('lift'),
                                    json=payload)

        self._save_auth_data(response)

    def authenticate_with_cert(self, cpf: str, password: str, cert_path: str):
        self.client.set_cert(cert_path)
        url = self.discovery.get_app_url('token')
        payload = {
            'grant_type': 'password',
            'client_id': 'legacy_client_id',
            'client_secret': 'legacy_client_secret',
            'login': cpf,
            'password': password
        }

        response = self.client.post(url, json=payload)

        self._save_auth_data(response)

        return response.get('refresh_token')

    def authenticate_with_refresh_token(self, refresh_token: str,
                                        cert_path: str):
        self.client.set_cert(cert_path)

        url = self.discovery.get_app_url('token')
        payload = {
            'grant_type': 'refresh_token',
            'client_id': 'legacy_client_id',
            'client_secret': 'legacy_client_secret',
            'refresh_token': refresh_token,
        }

        response = self.client.post(url, json=payload)

        self._save_auth_data(response)

    def get_card_feed(self):
        return self.client.get(self.feed_url)

    def get_card_statements(self):
        feed = self.get_card_feed()
        return list(
            filter(lambda x: x['category'] == 'transaction', feed['events']))

    def get_bills(self):
        request = self.client.get(self.bills_url)
        return request['bills']

    def get_bill_details(self, bill):
        return self.client.get(bill['_links']['self']['href'])

    def get_account_feed(self):
        data = self._make_graphql_request('account_feed')
        return data['data']['viewer']['savingsAccount']['feed']

    def get_account_statements(self):
        feed = self.get_account_feed()
        return list(
            filter(lambda x: x['__typename'] in PAYMENT_EVENT_TYPES, feed))

    def get_account_balance(self):
        data = self._make_graphql_request('account_balance')
        return data['data']['viewer']['savingsAccount'][
            'currentSavingsBalance']['netAmount']

    def create_boleto(self, amount: float) -> str:
        customer_id_response = self._make_graphql_request('account_id')
        customer_id = customer_id_response['data']['viewer']['id']

        payload = {"input": {"amount": str(amount), "customerId": customer_id}}

        boleto_response = self._make_graphql_request('create_boleto', payload)

        barcode = boleto_response['data']['createTransferInBoleto']['boleto'][
            'readableBarcode']

        return barcode
Exemple #2
0
class Nubank:
    feed_url = None
    query_url = None
    bills_url = None
    customer_url = None

    def __init__(self, client=HttpClient()):
        self.client = client
        self.discovery = Discovery(self.client)

    def _make_graphql_request(self, graphql_object, variables=None):
        return self.client.post(self.query_url,
                                json=prepare_request_body(
                                    graphql_object, variables))

    def _password_auth(self, cpf: str, password: str):
        payload = {
            "grant_type": "password",
            "login": cpf,
            "password": password,
            "client_id": "other.conta",
            "client_secret": "yQPeLzoHuJzlMMSAjC-LgNUJdUecx8XO"
        }
        return self.client.post(self.discovery.get_url('login'), json=payload)

    def _find_url(self, known_keys: set, links: dict) -> str:
        intersection = known_keys.intersection(links)
        iterator = iter(intersection)
        key = next(iterator, None)
        return links.get(key, {}).get('href', None)

    def _save_auth_data(self, auth_data: dict) -> None:
        self.client.set_header('Authorization',
                               f'Bearer {auth_data["access_token"]}')

        links = auth_data['_links']
        self.query_url = links['ghostflame']['href']

        feed_url_keys = {'events', 'magnitude'}
        bills_url_keys = {'bills_summary'}
        customer_url_keys = {'customer'}

        self.feed_url = self._find_url(feed_url_keys, links)
        self.bills_url = self._find_url(bills_url_keys, links)
        self.customer_url = self._find_url(customer_url_keys, links)

    def get_qr_code(self) -> Tuple[str, QRCode]:
        content = str(uuid.uuid4())
        qr = QRCode()
        qr.add_data(content)
        return content, qr

    def authenticate_with_qr_code(self, cpf: str, password, uuid: str):
        auth_data = self._password_auth(cpf, password)
        self.client.set_header('Authorization',
                               f'Bearer {auth_data["access_token"]}')

        payload = {'qr_code_id': uuid, 'type': 'login-webapp'}

        response = self.client.post(self.discovery.get_app_url('lift'),
                                    json=payload)

        self._save_auth_data(response)

    def authenticate_with_cert(self, cpf: str, password: str, cert_path: str):
        self.client.set_cert(cert_path)
        url = self.discovery.get_app_url('token')
        payload = {
            'grant_type': 'password',
            'client_id': 'legacy_client_id',
            'client_secret': 'legacy_client_secret',
            'login': cpf,
            'password': password
        }

        response = self.client.post(url, json=payload)

        self._save_auth_data(response)

        return response.get('refresh_token')

    def authenticate_with_refresh_token(self, refresh_token: str,
                                        cert_path: str):
        self.client.set_cert(cert_path)

        url = self.discovery.get_app_url('token')
        payload = {
            'grant_type': 'refresh_token',
            'client_id': 'legacy_client_id',
            'client_secret': 'legacy_client_secret',
            'refresh_token': refresh_token,
        }

        response = self.client.post(url, json=payload)

        self._save_auth_data(response)

    def get_card_feed(self):
        return self.client.get(self.feed_url)

    def get_card_statements(self):
        feed = self.get_card_feed()
        return list(
            filter(lambda x: x['category'] == 'transaction', feed['events']))

    def get_bills(self):
        if self.bills_url is not None:
            request = self.client.get(self.bills_url)
            return request['bills']
        else:
            raise NuMissingCreditCard

    def get_customer(self):
        request = self.client.get(self.customer_url)
        return request['customer']

    def get_bill_details(self, bill: dict):
        return self.client.get(bill['_links']['self']['href'])

    def get_account_feed(self):
        data = self._make_graphql_request('account_feed')
        return data['data']['viewer']['savingsAccount']['feed']

    def get_account_statements(self):
        feed = self.get_account_feed()
        return list(
            filter(lambda x: x['__typename'] in PAYMENT_EVENT_TYPES, feed))

    def get_account_balance(self):
        data = self._make_graphql_request('account_balance')
        return data['data']['viewer']['savingsAccount'][
            'currentSavingsBalance']['netAmount']

    def get_account_investments_details(self):
        data = self._make_graphql_request('account_investments')
        return data['data']['viewer']['savingsAccount']['redeemableDeposits']

    def create_boleto(self, amount: float) -> str:
        customer_id_response = self._make_graphql_request('account_id')
        customer_id = customer_id_response['data']['viewer']['id']

        payload = {"input": {"amount": str(amount), "customerId": customer_id}}

        boleto_response = self._make_graphql_request('create_boleto', payload)

        barcode = boleto_response['data']['createTransferInBoleto']['boleto'][
            'readableBarcode']

        return barcode

    def create_money_request(self, amount: float) -> str:
        account_data = self._make_graphql_request('account_feed')
        account_id = account_data['data']['viewer']['savingsAccount']['id']
        payload = {'input': {'amount': amount, 'savingsAccountId': account_id}}

        money_request_response = self._make_graphql_request(
            'create_money_request', payload)

        return money_request_response['data']['createMoneyRequest'][
            'moneyRequest']['url']

    def get_available_pix_keys(self):
        response = self._make_graphql_request('get_pix_keys')
        savings_acount = response['data']['viewer']['savingsAccount']

        return {
            'keys': savings_acount['dict']['keys'],
            'account_id': savings_acount['id']
        }

    def create_pix_payment_qrcode(self, account_id: str, amount: float,
                                  pix_key: dict) -> dict:
        payload = {
            'createPaymentRequestInput': {
                'amount': amount,
                'pixAlias': pix_key.get('value'),
                "savingsAccountId": account_id
            }
        }

        response = self._make_graphql_request('create_pix_money_request',
                                              payload)

        data = response['data']['createPaymentRequest']['paymentRequest']
        qr = QRCode()
        qr.add_data(data['brcode'])

        return {'payment_url': data['url'], 'qr_code': qr}