Beispiel #1
0
    def _filter_by_column_value(cls, query, column, value):

        def return_(e):
            return query.filter(e)

        import_value = getattr(cls, 'import_value')
        if not isinstance(value, str):
            raise HttpBadRequest()

        in_operator_match = FILTERING_IN_OPERATOR_REGEX.match(value)
        if in_operator_match:
            not_ = value.startswith('!')
            items = in_operator_match.groupdict()['items'].split(',')
            items = [i for i in items if i.strip() != '']
            if not len(items):
                raise HttpBadRequest('Invalid query string: %s' % value)
            expression = column.in_([import_value(column, j) for j in items])
            if not_:
                expression = ~expression

            return return_(expression)

        between_operator_match = FILTERING_BETWEEN_OPERATOR_REGEX.match(value)
        if between_operator_match:
            not_ = value.startswith('!')
            groups = between_operator_match.groupdict()
            start, end = groups['min'].strip(), groups['max'].strip()
            if not (start or end):
                raise HttpBadRequest('Invalid query string: %s' % value)
            expression = between(column, start, end)
            if not_:
                expression = ~expression

            return return_(expression)

        if value == 'null':
            expression = column.is_(None)
        elif value == '!null':
            expression = column.isnot(None)
        elif value.startswith('!'):
            expression = column != import_value(column, value[1:])
        elif value.startswith('>='):
            expression = column >= import_value(column, value[2:])
        elif value.startswith('>'):
            expression = column > import_value(column, value[1:])
        elif value.startswith('<='):
            expression = column <= import_value(column, value[2:])
        elif value.startswith('<'):
            expression = column < import_value(column, value[1:])

        # LIKE
        elif '%' in value:
            func, actual_value = (column.ilike, value[1:]) if value.startswith('~') else (column.like, value)
            expression = func(import_value(column, actual_value))

        # EQUAL
        else:
            expression = column == import_value(column, value)

        return return_(expression)
Beispiel #2
0
    def create(self):
        client_id = context.identity.id

        market = Market.query.filter(
            Market.name == context.form['marketName']).one_or_none()
        if market is None:
            raise HttpBadRequest('Market not found', 'market-not-found')

        side = 1 if (context.form['side'] == 'sell') else 2

        amount = market.base_currency.input_to_normalized(
            context.form['amount'])
        price = market.quote_currency.input_to_normalized(
            context.form.get('price', None))
        market.validate_ranges(type_=context.form['side'],
                               total_amount=amount,
                               price=price)

        try:
            if context.form['type'] == 'market':
                if price is not None:
                    raise HttpBadRequest(
                        'Price should not be sent in market orders',
                        'bad-price')

                order = stexchange_client.order_put_market(
                    user_id=client_id,
                    market=market.name,
                    side=side,
                    amount=Currency.format_normalized_string(amount),
                    taker_fee_rate=market.taker_commission_rate,
                    source="nothing",  # FIXME
                )
            elif context.form['type'] == 'limit':
                if price is None:
                    raise HttpBadRequest(
                        'Price should be sent in market orders', 'bad-price')

                order = stexchange_client.order_put_limit(
                    user_id=client_id,
                    market=market.name,
                    side=side,
                    amount=Currency.format_normalized_string(amount),
                    price=Currency.format_normalized_string(price),
                    taker_fee_rate=market.taker_commission_rate,
                    maker_fee_rate=market.maker_commission_rate,
                    source="nothing",  # FIXME
                )
            else:
                raise HttpNotFound('Bad status.')

            return order_to_dict(market, order)

        except StexchangeException as e:
            raise stexchange_http_exception_handler(e)
Beispiel #3
0
    def paginate_by_request(cls, query=None):
        # noinspection PyUnresolvedReferences
        query = query or cls.query

        try:
            take = int(
                context.query_string.get('take')
                or context.environ.get(cls.__take_header_key__)
                or cls.__max_take__)
        except ValueError:
            take = cls.__max_take__

        try:
            skip = int(
                context.query_string.get('skip')
                or context.environ.get(cls.__skip_header_key__) or 0)
        except ValueError:
            skip = 0

        if take > cls.__max_take__:
            raise HttpBadRequest()

        context.response_headers.add_header('X-Pagination-Take', str(take))
        context.response_headers.add_header('X-Pagination-Skip', str(skip))
        context.response_headers.add_header('X-Pagination-Count',
                                            str(query.count()))
        return query.offset(skip).limit(
            take)  # [skip:skip + take] Commented by vahid
Beispiel #4
0
    def history(self):
        currency = Currency.query.filter(Currency.symbol == context.query_string.get('asset', None)).one_or_none()
        if currency is None:
            raise HttpBadRequest('Currency not found', 'market-not-found')
        try:
            return [
                {
                    'time': format_iso_datetime(
                        datetime.utcfromtimestamp(int(x['timestamp']))) if 'timestamp' in x else None,
                    'asset': x['asset'],
                    'currency': currency.to_dict(),
                    'business': x['business'],
                    'change': currency.normalized_to_output(x['change']),
                    'balance': currency.normalized_to_output(x['balance']),
                    'detail': x['detail'],
                } for x in stexchange_client.balance_history(
                    context.identity.id,
                    asset=context.query_string.get('asset', None),
                    limit=context.query_string.get('take', self.PAGE_SIZE),
                    business='deposit,withdraw,cashin,cashout,cashback',
                    offset=context.query_string.get('skip', self.PAGE_SIZE * context.query_string.get('page', 0))
                )['records']
            ]

        except StexchangeException as e:
            raise stexchange_http_exception_handler(e)
Beispiel #5
0
    def authenticate_request(self):
        if self.token_key not in context.environ:
            self.bad()
            return

        encoded_token = context.environ[self.token_key]
        if encoded_token is None or not encoded_token.strip():
            self.bad()
            return

        try:
            self.ok(self.verify_token(encoded_token))

        except itsdangerous.SignatureExpired as ex:
            # The token has expired. So we're trying to restore it using refresh-token.
            session_id = ex.payload.get('sessionId')
            if session_id:
                self.try_refresh_token(session_id)
            else:
                self.bad()
                raise HttpUnauthorized()
        except itsdangerous.BadData:
            # The token is Malformed
            self.bad()
            raise HttpBadRequest()
Beispiel #6
0
    def _filter_by_column_value(cls, query, column, value):

        import_value = getattr(cls, 'import_value')
        if not isinstance(value, str):
            raise HttpBadRequest()

        if value.startswith('^') or value.startswith('!^'):
            value = value.split(',')
            not_ = value[0].startswith('!^')
            first_item = value[0][2 if not_ else 1:]
            items = [first_item] + value[1:]
            items = [i for i in items if i.strip()]
            if not len(items):
                raise HttpBadRequest('Invalid query string: %s' % value)
            expression = column.in_([import_value(column, j) for j in items])
            if not_:
                expression = ~expression

        elif value.startswith('~'):
            values = value[1:].split(',')
            start, end = [import_value(column, v) for v in values]
            expression = between(column, start, end)

        elif value == 'null':
            expression = column.is_(None)
        elif value == '!null':
            expression = column.isnot(None)
        elif value.startswith('!'):
            expression = column != import_value(column, value[1:])
        elif value.startswith('>='):
            expression = column >= import_value(column, value[2:])
        elif value.startswith('>'):
            expression = column > import_value(column, value[1:])
        elif value.startswith('<='):
            expression = column <= import_value(column, value[2:])
        elif value.startswith('<'):
            expression = column < import_value(column, value[1:])
        elif value.startswith('%~'):
            expression = column.ilike('%%%s%%' %
                                      import_value(column, value[2:]))
        elif value.startswith('%'):
            expression = column.like('%%%s%%' %
                                     import_value(column, value[1:]))
        else:
            expression = column == import_value(column, value)

        return query.filter(expression)
Beispiel #7
0
 def _validate_pattern(self, value):
     if value is None:
         return
     if not re.match(self.info['pattern'], value):
         raise HttpBadRequest(
             'Cannot match field: %s with value "%s" by acceptable pattern'
             % (self.name, value))
     return value
    def validate_credentials(self, credentials):
        email, password = credentials
        member = Member.query.filter(Member.email == email).one_or_none()

        if member is None or not member.validate_password(password):
            logger.info(
                f'Login failed (bad-email-or-password): "{email}" "{password}"'
            )
            raise HttpBadRequest('Invalid email or password',
                                 'bad-email-or-password')

        if member.is_active is False:
            logger.info(f'Login failed (account-deactivated): "{email}"')
            raise HttpBadRequest('Your account has been deactivated.',
                                 'account-deactivated')

        return member
Beispiel #9
0
 def _set_password(self, password):
     """Hash ``password`` on the fly and store its hashed version."""
     min_length = self.__class__.password.info['min_length']
     if len(password) < min_length:
         raise HttpBadRequest(
             'Please enter at least %d characters for password.' %
             min_length)
     self._password = self._hash_password(password)
Beispiel #10
0
    def __fetch_market(self):
        market = Market.query \
            .filter(Market.name == context.query_string.get("marketName")) \
            .one_or_none()

        if market is None:
            raise HttpBadRequest('Bad marketName')

        return market
Beispiel #11
0
    def accept(self, shaparak_out_id: int):
        reference_id = context.form.get('referenceId')

        shaparak_out = Cashout.query.filter(
            Cashout.id == shaparak_out_id).one_or_none()

        if shaparak_out is None:
            raise HttpNotFound()

        if shaparak_out.reference_id is not None:
            raise HttpBadRequest('This transaction already accepted.')

        if shaparak_out.error is not None:
            raise HttpBadRequest('This transaction already has an error.')

        shaparak_out.reference_id = reference_id

        return shaparak_out
Beispiel #12
0
    def __fetch_cryptocurrency(self):
        cryptocurrency = Cryptocurrency.query \
            .filter(Cryptocurrency.symbol == context.query_string.get("cryptocurrencySymbol")) \
            .one_or_none()

        if cryptocurrency is None:
            raise HttpBadRequest('Bad cryptocurrencySymbol')

        return cryptocurrency
Beispiel #13
0
    def create(self):
        title = context.form.get('title')
        department_id = context.form.get('departmentId')
        message = context.form.get('message')
        attachment = context.form.get('attachment', None)
        client_id = context.form.get('clientId', None)

        if TicketDepartment.query.filter(
                TicketDepartment.id == department_id).count() == 0:
            raise HttpBadRequest('Bad department_id')

        ticket = Ticket()
        ticket.member_id = context.identity.id if context.identity.is_in_roles(
            'client') else client_id
        ticket.department_id = department_id
        ticket.title = title

        ticket_message = TicketMessage()
        ticket_message.ticket = ticket
        ticket_message.member_id = context.identity.id
        ticket_message.text = message

        try:
            ticket_message.attachment = attachment

        except AspectRatioValidationError as ex:
            raise HttpBadRequest(str(ex), reason='invalid-aspectratio')

        except DimensionValidationError as ex:
            raise HttpBadRequest(str(ex), reason='invalid-dimensions')

        except (AnalyzeError, ContentTypeValidationError) as ex:
            raise HttpBadRequest(str(ex), reason='invalid-type')

        DBSession.add(ticket)
        DBSession.add(ticket_message)

        # FIXME: These are not good:
        DBSession.flush()
        result = ticket.to_dict()
        result['firstMessage'] = ticket_message.to_dict()

        return result
Beispiel #14
0
    def safe_member_lookup(condition):
        member = Member.exclude_deleted().filter(condition).one_or_none()

        if member is None:
            raise HttpBadRequest()

        if not member.is_active:
            raise HttpConflict(reason='user-deactivated')

        return member
Beispiel #15
0
    def _validate_length(self, value, min_length, max_length):
        if value is None:
            return

        if not isinstance(value, str):
            raise HttpBadRequest('Invalid type: %s for field: %s' %
                                 (type(value), self.name))

        value_length = len(value)
        if min_length is not None:
            if value_length < min_length:
                raise HttpBadRequest(
                    'Please enter at least %d characters for field: %s.' %
                    (min_length, self.name))

        if max_length is not None:
            if value_length > max_length:
                raise HttpBadRequest(
                    'Cannot enter more that : %d in field: %s.' %
                    (max_length, self.name))
Beispiel #16
0
    def __fetch_market(self, market_name=None) -> Market:
        market_name = (market_name or context.query_string.get("marketName", None)) \
                      or context.form.get("marketName", None)
        market = Market.query \
            .filter(Market.name == market_name) \
            .one_or_none()

        if market is None:
            raise HttpBadRequest('Bad market', 'bad-market')

        return market
Beispiel #17
0
    def get(self, hash_id):
        try:
            db_id, = hashids.decode(hash_id)
        except ValueError:
            raise HttpBadRequest()

        url = DBSession.query(Url).filter_by(id=db_id).one_or_none()
        if url is None:
            raise HttpNotFound()

        raise HttpFound(url.url)
Beispiel #18
0
    def _validate_length(self, value, min_length, max_length):
        if value is None:
            return

        if not isinstance(value, str):
            raise HttpBadRequest(info='Invalid type: %s for field: %s' % (type(value), self.name))

        value_length = len(value)
        if min_length is not None:
            if value_length < min_length:
                raise HttpBadRequest(
                    reason=f'insufficient-{self.name}-length',
                    info=f'Please enter at least {min_length} characters for field: {self.name}.'
                )

        if max_length is not None:
            if value_length > max_length:
                raise HttpBadRequest(
                    reason=f'extra-{self.name}-length',
                    info=f'Cannot enter more than: {max_length} in field: {self.name}.'
                )
Beispiel #19
0
    def validate_ranges(self, type_, total_amount, price=None):

        # TODO: Review and rewrite the price threshold validator
        # threshold = Decimal(settings.trader.price_threshold_permille)
        # price_rate = Decimal(1000 * (price or self.get_last_price()) / self.get_last_price()) - Decimal(1000)

        if type_ == 'buy':
            # if price_rate > threshold:
            #     raise HttpBadRequest('Price not in valid range', 'price-not-in-range')

            if total_amount < self.buy_amount_min or \
                    (self.buy_amount_max != 0 and total_amount > self.buy_amount_max):
                raise HttpBadRequest('Amount not in range',
                                     'amount-not-in-range')

        elif type_ == 'sell':
            # if price_rate < -threshold:
            #     raise HttpBadRequest('Price not in valid range', 'price-not-in-range')

            if total_amount < self.sell_amount_min or \
                    (self.sell_amount_max != 0 and total_amount > self.sell_amount_max):
                raise HttpBadRequest('Amount not in range',
                                     'amount-not-in-range')
Beispiel #20
0
 def post(self):
     if '4/AAA' in context.form.get('code'):
         return dict(
             access_token='ya29.GlzVBYKNxVGGMl6euQ6U-_QIhylTdqoYXxW3MHOXL7\
             r6WmO2xx_wkBht6TT6OIP0eoDjcQIm3Y6JXmAExohf7GU3xuhs6cF9EcL5DbT\
             owmmH-nBlVE6Uop2IftiFtQ',
             refresh_token='1/Yn_cvrK7qeJ9yNQcl77dHNqrqO1Q_ySU5MhibfXkvOo3\
             vZct44-X5rUdvCRM9jJE')
     elif '5/AAA' in context.form.get('code'):
         return dict(
             access_token='ya30.GlzVBYKNxVGGMl6euQ6U-_QIhylTdqoYXxW3MHOXL7\
             r6WmO2xx_wkBht6TT6OIP0eoDjcQIm3Y6JXmAExohf7GU3xuhs6cF9EcL5DbT\
             owmmH-nBlVE6Uop2IftiFtQ')
     else:
         raise HttpBadRequest()
Beispiel #21
0
    def reject(self, shaparak_out_id: int):
        error = context.form.get('error')

        shaparak_out = Cashout.query.filter(
            Cashout.id == shaparak_out_id).one_or_none()

        if shaparak_out is None:
            raise HttpNotFound()

        if shaparak_out.reference_id is not None:
            raise HttpBadRequest('This transaction already accepted.')

        if shaparak_out.error is not None:
            raise HttpBadRequest('This transaction already has an error.')

        payment_gateway = shaparak_out.payment_gateway

        shaparak_out.error = error

        try:
            # Cash back (without commission) FIXME: Really without commission?
            stexchange_client.balance_update(
                user_id=shaparak_out.member_id,
                asset=shaparak_out.payment_gateway.fiat_symbol,  # FIXME
                business='cashback',  # FIXME
                business_id=shaparak_out.id,
                change=payment_gateway.fiat.format_normalized_string(
                    shaparak_out.amount),
                detail=shaparak_out.to_dict(),
            )
            # FIXME: Important !!!! : rollback the updated balance if
            #  DBSession.commit() was not successful
        except StexchangeException as e:
            raise stexchange_http_exception_handler(e)

        return shaparak_out
Beispiel #22
0
    def get(self, card_number: str = None):
        if card_number in valid_mock_cards:
            return {
                "result": {
                    "destCard": "xxxx-xxxx-xxxx-3899",
                    "name": "علی آقایی",
                    "result": "0",
                    "description": "موفق",
                    "doTime": "1396/06/15 12:32:04"
                },
                "status": "DONE",
                "trackId": "get-cardInfo-0232"
            }

        raise HttpBadRequest()
Beispiel #23
0
    def append(self, ticket_id: int):
        message = context.form.get('message')
        attachment = context.form.get('attachment', None)

        ticket = Ticket.query.filter(Ticket.id == ticket_id)
        if context.identity.is_in_roles('client'):
            ticket = ticket.filter(Ticket.member_id == context.identity.id)
        ticket = ticket.one_or_none()

        if ticket is None:
            raise HttpNotFound('Ticket not found')

        ticket_message = TicketMessage()
        ticket_message.ticket_id = ticket.id
        ticket_message.member_id = context.identity.id
        ticket_message.text = message
        ticket_message.is_answer = True if ticket.member_id != context.identity.id else False

        try:
            ticket_message.attachment = attachment

        except AspectRatioValidationError as ex:
            raise HttpBadRequest(str(ex), reason='invalid-aspectratio')

        except DimensionValidationError as ex:
            raise HttpBadRequest(str(ex), reason='invalid-dimensions')

        except (AnalyzeError, ContentTypeValidationError) as ex:
            raise HttpBadRequest(str(ex), reason='invalid-type')

        DBSession.add(ticket_message)

        if ticket.is_closed is True:
            ticket.is_closed = False

        return ticket_message
Beispiel #24
0
 def renew(self):
     cryptocurrency = self.__fetch_cryptocurrency()
     try:
         return invoice_to_dict(stawallet_client.post_invoice(
             wallet_id=cryptocurrency.wallet_id,
             user_id=context.identity.id,
             force=False
         )[-1])
     except StawalletHttpException as e:
         if e.http_status_code == 409:
             raise HttpBadRequest('Address has not been used', 'address-not-used')
         else:
             logger.info('Wallet access error: ' + e.message)
             raise HttpInternalServerError("Wallet access error")
     except StawalletException as e:
         raise HttpInternalServerError("Wallet access error")
Beispiel #25
0
    def post(self):
        if context.form.get('url') is None:
            raise HttpBadRequest()

        url = context.form.get('url')
        if not url.startswith('http'):
            url = f'http://{url}'

        url_exist = DBSession.query(Url).filter_by(url=url).one_or_none()

        if url_exist is None:
            url_exist = Url(url=url)
            DBSession.add(url_exist)
            DBSession.commit()

        hash_id = hashids.encode(url_exist.id)

        return dict(shortener_url=f'http://localhost:8080/urls/{hash_id}')
    def try_refresh_token(self, session_id):
        morsel = context.cookies.get(self.refresh_token_key)
        if not morsel or morsel.value is None or not morsel.value.strip():
            self.bad()
            return

        refresh_token_encoded = morsel.value
        # Decoding the refresh token
        try:
            refresh_principal = JwtRefreshToken.load(refresh_token_encoded)
            self.ok(self.create_principal(member_id=refresh_principal.id,
                                          session_id=session_id),
                    setup_header=True)
        except itsdangerous.SignatureExpired:
            self.bad()
        except itsdangerous.BadData:
            self.bad()
            raise HttpBadRequest()
Beispiel #27
0
    def input_to_normalized(self, number: str, strict=True):
        """
        :return:
        """
        if number is None:
            return None

        if strict and \
                (
                        (not (self.smallest_unit_scale >= 0 and len(number.split('.')) == 1))
                        and (len(number.split('.')) == 1 or len(number.split('.')[1]) != -self.smallest_unit_scale)
                ):
            raise HttpBadRequest(f'This number is in {self.symbol} unit and this currency should be presented with '
                                 f'the exact ${-self.smallest_unit_scale} digits behind the floating-point',
                                 'bad-number-format')

        number = Decimal(number)

        return number.scaleb(-self.normalization_scale)
Beispiel #28
0
    def get(self):
        iban = context.query_string.get('iban')
        if iban in valid_mock_ibans:
            return {
                "trackId": "get-iban-inquiry-029",
                "result": {
                    "IBAN": "IR910800005000115426432001",
                    "bankName": "قرض الحسنه رسالت",
                    "deposit": "10.6423499.1",
                    "depositDescription": "حساب فعال است",
                    "depositComment":
                    "سپرده حقيقي قرض الحسنه پس انداز حقيقي ريالی شیما کیایی",
                    "depositOwners": [{
                        "firstName": "شیما",
                        "lastName": "کیایی"
                    }],
                    "depositStatus": "02",
                    "errorDescription": "بدون خطا"
                },
                "status": "DONE"
            }

        raise HttpBadRequest()
Beispiel #29
0
    def get(self):
        card = context.query_string.get('card')
        if card in valid_mock_cards:
            return {
                "trackId": "cardToIban-029",
                "result": {
                    "IBAN": "IR910800005000115426432001",
                    "bankName": "قرض الحسنه رسالت",
                    "deposit": "10.6423499.1",
                    "card": "6362141081734437",
                    "depositStatus": "02",
                    "depositDescription": "حساب فعال است",
                    "depositComment":
                    "سپرده حقيقي قرض الحسنه پس انداز حقيقي ريالی شیما کیایی",
                    "depositOwners": [{
                        "firstName": "شیما",
                        "lastName": "کیایی"
                    }],
                    "alertCode": "01"
                },
                "status": "DONE"
            }

        raise HttpBadRequest()
 def login(self):
     principal = context.application.__authenticator__.login(
         (context.form['email'], context.form['password']))
     if principal:
         return dict(token=principal.dump())
     raise HttpBadRequest()