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)
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)
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
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)
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()
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)
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
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)
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
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
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
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
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
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))
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
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)
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}.' )
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')
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()
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
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()
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
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")
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()
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)
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()
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()