Beispiel #1
0
    def setup_context(self, reset_config_if_needed=True):
        if isfile(self.conf):
            self._BUNQ_CONF_CUSTOM = self.conf
            pass  # Config is already present
        elif isfile(self.determine_bunq_conf_filename()):
            pass  # Config is already present
        elif self.env == ApiEnvironmentType.SANDBOX:
            sandbox_user = self.generate_new_sandbox_user()
            ApiContext.create(ApiEnvironmentType.SANDBOX, sandbox_user.api_key,
                              socket.gethostname()).save(
                                  self.determine_bunq_conf_filename())
        else:
            raise BunqException(self._ERROR_COULD_NOT_DETIRMINE_CONF)

        try:
            api_context = ApiContext.restore(
                self.determine_bunq_conf_filename())
            api_context.ensure_session_active()
            api_context.save(self.determine_bunq_conf_filename())

            BunqContext.load_api_context(api_context)
        except ForbiddenException as forbidden_exception:
            if reset_config_if_needed:
                self.__handle_forbidden_exception(forbidden_exception)
            else:
                raise forbidden_exception
Beispiel #2
0
    def _request(self, method: str, uri_relative: str, request_bytes: bytes,
                 params: Dict[str, str],
                 custom_headers: Dict[str, str]) -> BunqResponseRaw:
        from bunq.sdk.context.bunq_context import BunqContext

        uri_relative_with_params = self._append_params_to_uri(
            uri_relative, params)
        if uri_relative not in self._URIS_NOT_REQUIRING_ACTIVE_SESSION:
            if self._api_context.ensure_session_active():
                BunqContext.update_api_context(self._api_context)

        all_headers = self._get_all_headers(request_bytes, custom_headers)

        response = requests.request(
            method,
            self._get_uri_full(uri_relative_with_params),
            data=request_bytes,
            headers=all_headers,
            proxies={self.FIELD_PROXY_HTTPS: self._api_context.proxy_url},
        )

        self._assert_response_success(response)

        if self._api_context.installation_context is not None:
            security.validate_response(
                self._api_context.installation_context.public_key_server,
                response.status_code, response.content, response.headers)

        return self._create_bunq_response_raw(response)
    def test_bad_request_with_response_id(self):
        """
        """
        BunqContext.load_api_context(self._get_api_context())

        with self.assertRaises(ApiException) as caught_exception:
            MonetaryAccountBank.get(self._INVALID_MONETARY_ACCOUNT_ID)
        self.assertIsNotNone(caught_exception.exception.response_id)
Beispiel #4
0
    def setUpClass(cls):
        cls._PAYMENT_LISTING_PAGE_SIZE = 2
        cls._PAYMENT_REQUIRED_COUNT_MINIMUM = cls._PAYMENT_LISTING_PAGE_SIZE * 2
        cls._NUMBER_ZERO = 0
        cls._PAYMENT_AMOUNT_EUR = '0.01'
        cls._PAYMENT_CURRENCY = 'EUR'
        cls._PAYMENT_DESCRIPTION = 'Python test Payment'

        BunqContext.load_api_context(cls._get_api_context())
    def setup_test_data(cls) -> None:
        if not os.path.isfile(cls._FILE_TEST_CONFIGURATION_PATH_FULL):
            try:
                BunqContext.load_api_context(cls._create_api_context())
            except FileNotFoundError:
                return

        api_context = ApiContext.restore(
            cls._FILE_TEST_CONFIGURATION_PATH_FULL)
        BunqContext.load_api_context(api_context)
Beispiel #6
0
    def alias_first(self) -> Pointer:
        if BunqContext.user_context().is_only_user_company_set():
            return BunqContext.user_context().user_company.alias[
                self._FIRST_INDEX]

        if BunqContext.user_context().is_only_user_person_set():
            return BunqContext.user_context().user_person.alias[
                self._FIRST_INDEX]

        raise BunqException(self.__ERROR_COULD_NOT_DETERMINE_USER)
    def test_create_psd2_context(self) -> None:
        if os.path.isfile(self._FILE_TEST_CONFIGURATION_PATH_FULL):
            return

        try:
            api_context = self._create_api_context()
            BunqContext.load_api_context(api_context)

            self.assertTrue(
                os.path.isfile(self._FILE_TEST_CONFIGURATION_PATH_FULL))

        except AssertionError:
            raise AssertionError
Beispiel #8
0
    def test_auto_bunq_context_update(self):
        """
        Tests the auto update of BunqContext.
        """

        api_context: ApiContext = BunqContext.api_context()
        api_context_json: object = json.loads(api_context.to_json())

        api_context_json[self.__FIELD_SESSION_CONTEXT][
            self.__FIELD_EXPIRE_TIME] = self.__TIME_STAMP_IN_PAST

        expired_api_context = ApiContext.from_json(
            json.dumps(api_context_json))

        self.assertNotEqual(api_context.session_context.expiry_time,
                            expired_api_context.session_context.expiry_time)
        self.assertEqual(BunqContext.api_context().session_context.expiry_time,
                         api_context.session_context.expiry_time)

        BunqContext.update_api_context(expired_api_context)
        BunqContext.user_context().refresh_user_context()

        self.assertNotEqual(
            BunqContext.api_context().session_context.expiry_time,
            api_context.session_context.expiry_time)
        self.assertFalse(BunqContext.api_context().ensure_session_active())
Beispiel #9
0
def init(api_key_fn):
    AnchorObjectAdapter._override_field_map.update({
        'ScheduledPaymentBatch':
        'SchedulePaymentBatch',
        'TransferwisePayment':
        'TransferwiseTransfer',
    })
    if CONTEXTFILE.exists():
        context = ApiContext.restore(str(CONTEXTFILE))
    else:
        context = ApiContext.create(ApiEnvironmentType.PRODUCTION,
                                    api_key_fn(), DEVICE_DESCRIPTION)
        context.save(str(CONTEXTFILE))
    BunqContext.load_api_context(context)
Beispiel #10
0
    def setup_context(self):
        if isfile(self.determine_bunq_conf_filename()):
            pass  # Config is already present
        elif self.env == ApiEnvironmentType.SANDBOX:
            sandbox_user = self.generate_new_sandbox_user()
            ApiContext.create(ApiEnvironmentType.SANDBOX, sandbox_user.api_key, socket.gethostname()).save(
                self.determine_bunq_conf_filename())
        else:
            raise BunqException(self._ERROR_COULD_NOT_DETIRMINE_CONF)

        api_context = ApiContext.restore(self.determine_bunq_conf_filename())
        api_context.ensure_session_active()
        api_context.save(self.determine_bunq_conf_filename())

        BunqContext.load_api_context(api_context)
Beispiel #11
0
def main(ctx, iban: str, api_key: str, sandbox: bool, currency: str):
    """
    \b
     ____                    _
    | __ ) _   _  __ _ _   _| |_
    |  _ \| | | |/ _` | | | | __|
    | |_) | |_| | (_| | |_| | |_
    |____/ \__,_|\__,_|\__,_|\__|

    Buaut are several Bunq automations in a
    convenient CLI tool.

    Enable autocomplete for Bash (.bashrc):
      eval "$(_BUAUT_COMPLETE=source buaut)"

    Enable autocomplete for ZSH (.zshrc):
      eval "$(_BUAUT_COMPLETE=source_zsh buaut)"
    """
    # Set Bunq context
    context = ApiEnvironmentType.SANDBOX if sandbox \
        else ApiEnvironmentType.PRODUCTION

    # Setup Bunq authentication
    api_context = ApiContext.create(context, api_key, socket.gethostname())
    api_context.ensure_session_active()

    # Load api context into BunqContext used for subsequent calls
    BunqContext.load_api_context(api_context)

    if validators.iban(iban):
        try:
            # Set monetary_account
            monetary_account: int = utils.get_monetary_account(
                value_type='IBAN', value=iban)
        except:
            # TODO: Exit nicely
            exit(1)
    else:
        # TODO: Exit nicely
        exit(1)

    # Append to ctx object to have available in commands
    ctx.obj = {}
    ctx.obj['args'] = {}
    ctx.obj['args']['iban'] = iban
    ctx.obj['args']['api_key'] = api_key
    ctx.obj['monetary_account'] = monetary_account
    ctx.obj['currency'] = currency
Beispiel #12
0
    def setup_context(self):
        if 'bunq-conf' in self.config.value:
            LOGGER.debug('Found existing api context config. Restoring.')
            api_context = ApiContext.from_json(self.config.value['bunq-conf'])
            api_context.ensure_session_active()
        else:
            LOGGER.debug('Did not find existing api context config. creating.')
            api_context = ApiContext.create(
                ApiEnvironmentType.PRODUCTION,
                self.config.value['bunq']['api_token'],
                self.DEVICE_DESCRIPTION)
            self.config.value['bunq-conf'] = api_context.to_json()
            LOGGER.info('persisting new api context config')
            self.config.save(self.config.value)

        BunqContext.load_api_context(api_context)
Beispiel #13
0
    def create(cls, grant_type: OauthGrantType, oauth_code: str,
               redirect_uri: str, client: OauthClient) -> OauthAccessToken:
        api_client = AnonymousApiClient(BunqContext.api_context())
        response_raw = api_client.post(
            cls.create_token_uri(grant_type.value, oauth_code, redirect_uri,
                                 client), bytearray(), {})

        return cls.from_json(OauthAccessToken, response_raw).value
Beispiel #14
0
    def _determine_monetary_account_id(cls,
                                       monetary_account_id: int = None) -> int:
        from bunq.sdk.context.bunq_context import BunqContext

        if monetary_account_id is None:
            return BunqContext.user_context().primary_monetary_account.id_

        return monetary_account_id
Beispiel #15
0
    def test_session_delete(self):
        """
        Tests the deletion and resetting of the current active session

        This test has no assertion as of its testing to see if the code runs
        without errors.

        Notes
        -----
            time.sleep() is needed  as of you can only make 1 POST call to
            Session endpoint per second.
        """

        Session.delete(self._SESSION_ID)
        time.sleep(2)
        BunqContext.api_context().reset_session()
        BunqContext.api_context().save(self._BUNQ_CONFIG_FILE)
Beispiel #16
0
    def determine_auth_uri_format(cls) -> str:
        environment_type = BunqContext.api_context().environment_type

        if ApiEnvironmentType.PRODUCTION == environment_type:
            return cls.TOKEN_URI_FORMAT_PRODUCTION

        if ApiEnvironmentType.SANDBOX == environment_type:
            return cls.TOKEN_URI_FORMAT_SANDBOX

        raise BunqException(cls.ERROR_ENVIRONMENT_TYPE_NOT_SUPPORTED)
Beispiel #17
0
    def test_create_and_update_tab(self):
        """
        Tests the creation of a Tab, adds a tab item to it and updates this tab

        This test has no assertion as of its testing to see if the code runs
        without errors
        """

        if BunqContext.user_context().is_only_user_person_set():
            return unittest.skip(self._ERROR_ONLY_USER_COMPANY_CAN_CREATE_TAB)

        tab_uuid = TabUsageSingle.create(
            self._get_cash_register_id(), self._TAB_DESCRIPTION,
            self._STATUS_OPEN, Amount(self._AMOUNT_EUR, self._CURRENCY)).value

        self._add_item_to_tab(tab_uuid)
        self._update_tab(tab_uuid)
Beispiel #18
0
    def test_order_debit_card(self):
        """
        Tests ordering a new card and checks if the fields we have entered
        are indeed correct by retrieving the card from the card endpoint and
        checks this date against the data we have submitted
        """

        second_line = self.second_line_random
        pin_code_assignment = CardPinAssignment(
            self._PIN_CODE_ASSIGNMENT_TYPE_PRIMARY, self._CARD_PIN_CODE,
            BunqContext.user_context().primary_monetary_account.id_)
        card_debit = CardDebit.create(second_line, self.card_name_allowed,
                                      self._CARD_TYPE_MAESTRO,
                                      self.alias_first,
                                      self._PRODUCT_TYPE_MAESTRO_DEBIT,
                                      [pin_code_assignment]).value
        card = Card.get(card_debit.id_).value

        self.assertEqual(self.card_name_allowed, card.name_on_card)
        self.assertEqual(second_line, card.second_line)
        self.assertEqual(card_debit.created, card.created)
Beispiel #19
0
 def __should_request_spending_money(self):
     return self.env == ApiEnvironmentType.SANDBOX \
             and float(BunqContext.user_context().primary_monetary_account.balance.value) <= self._ZERO_BALANCE
Beispiel #20
0
 def update_context(self):
     BunqContext.api_context().save(self.determine_bunq_conf_filename())
Beispiel #21
0
    def _get_api_context(cls) -> ApiContext:
        from bunq.sdk.context.bunq_context import BunqContext

        return BunqContext.api_context()
Beispiel #22
0
 def setUp(self):
     self.__set_second_monetary_account()
     self.__request_spending_money()
     time.sleep(self.__TIME_OUT_AUTO_ACCEPT_SPENDING_MONEY)
     BunqContext.user_context().refresh_user_context()
Beispiel #23
0
    def _determine_user_id(cls) -> int:
        from bunq.sdk.context.bunq_context import BunqContext

        return BunqContext.user_context().user_id
 def get_primary_monetary_account():
     return BunqContext.user_context().primary_monetary_account
 def setUpClass(cls) -> None:
     BunqContext.load_api_context(cls._get_api_context())