def get(self): code = self.request.GET.get('code', None) state = self.request.GET.get('state', None) try: if not (code and state): logging.debug('Code or state are missing.\nCode: %s\nState:%s', code, state) raise HttpBadRequestException() refresh_state = OauthState.create_key(state).get() if not refresh_state: logging.debug('Refresh state not found') raise HttpBadRequestException() except HttpException as e: render_error_page(self.response, e.http_code, e.error) return try: jwt, username, scopes = get_jwt(code, refresh_state, '%s/refresh/callback' % get_server_url()) create_session(username, scopes, jwt, secret=username) params = {'success': 'OK'} except HttpException as e: params = { 'error': e.error, 'error_description': 'An error occurred. Please try again.' } url = '%s?%s' % (refresh_state.app_redirect_uri, urllib.urlencode(params)) logging.info('Redirecting to %s', url) self.redirect(str(url))
def _set_token_count(agreement, token_count_float=None, precision=2): # type: (InvestmentAgreement) -> None stats = get_global_stats(agreement.token) logging.info('Setting token count for agreement %s', agreement.to_dict()) if agreement.status == InvestmentAgreement.STATUS_CREATED: if agreement.currency == 'USD': agreement.token_count = long( (agreement.amount / stats.value) * pow(10, precision)) else: currency_stats = filter(lambda s: s.currency == agreement.currency, stats.currencies)[0] if not currency_stats: raise HttpBadRequestException( 'Could not find currency conversion for currency %s' % agreement.currency) agreement.token_count = long( (agreement.amount / currency_stats.value) * pow(10, precision)) # token_count can be overwritten when marking the investment as paid for BTC elif agreement.status == InvestmentAgreement.STATUS_SIGNED: if agreement.currency == 'BTC': if not token_count_float: raise HttpBadRequestException( 'token_count_float must be provided when setting token count for BTC' ) # The course of BTC changes how much tokens are granted if agreement.token_count: logging.debug( 'Overwriting token_count for investment agreement %s from %s to %s', agreement.id, agreement.token_count, token_count_float) agreement.token_count = long(token_count_float * pow(10, precision)) agreement.token_precision = precision
def put_investment_agreement(agreement_id, agreement, admin_user): admin_app_user = create_app_user_by_email( admin_user.email(), get_config(NAMESPACE).rogerthat.app_id) # type: (long, InvestmentAgreement, users.User) -> InvestmentAgreement agreement_model = InvestmentAgreement.get_by_id( agreement_id) # type: InvestmentAgreement if not agreement_model: raise HttpNotFoundException('investment_agreement_not_found') if agreement_model.status == InvestmentAgreement.STATUS_CANCELED: raise HttpBadRequestException('order_canceled') if agreement.status not in (InvestmentAgreement.STATUS_SIGNED, InvestmentAgreement.STATUS_CANCELED): raise HttpBadRequestException('invalid_status') # Only support updating the status for now agreement_model.status = agreement.status if agreement_model.status == InvestmentAgreement.STATUS_CANCELED: agreement_model.cancel_time = now() elif agreement_model.status == InvestmentAgreement.STATUS_SIGNED: agreement_model.paid_time = now() if agreement.currency == 'BTC': _set_token_count(agreement_model, agreement.token_count_float) deferred.defer(_send_ito_agreement_to_admin, agreement_model.key, admin_app_user) agreement_model.put() return agreement_model
def put_node_order(order_id, order): # type: (long, NodeOrderTO) -> NodeOrder order_model = get_node_order(order_id) if order_model.status == NodeOrderStatus.CANCELED: raise HttpBadRequestException('order_canceled') if order.status not in (NodeOrderStatus.CANCELED, NodeOrderStatus.SENT, NodeOrderStatus.APPROVED, NodeOrderStatus.PAID): raise HttpBadRequestException('invalid_status') # Only support updating the status for now if order_model.status != order.status: if not _can_change_status(order_model.status, order.status): raise HttpBadRequestException( 'cannot_change_status', { 'from': order_model.status, 'to': order.status, 'allowed_new_statuses': _get_allowed_status( order_model.status) }) order_model.status = order.status human_user, app_id = get_app_user_tuple(order_model.app_user) if order_model.status == NodeOrderStatus.CANCELED: order_model.cancel_time = now() if order_model.odoo_sale_order_id: deferred.defer(update_odoo_quotation, order_model.odoo_sale_order_id, {'state': QuotationState.CANCEL.value}) deferred.defer(update_hoster_progress, human_user.email(), app_id, HosterSteps.NODE_POWERED) # nuke todo list deferred.defer(set_hoster_status_in_user_data, order_model.app_user, _countdown=2) elif order_model.status == NodeOrderStatus.SENT: if not order_model.odoo_sale_order_id or not get_nodes_from_odoo( order_model.odoo_sale_order_id): raise HttpBadRequestException( 'cannot_mark_sent_no_serial_number_configured_yet', {'sale_order': order_model.odoo_sale_order_id}) order_model.send_time = now() deferred.defer(update_hoster_progress, human_user.email(), app_id, HosterSteps.NODE_SENT) deferred.defer(_send_node_order_sent_message, order_id) elif order_model.status == NodeOrderStatus.APPROVED: deferred.defer(_create_node_order_pdf, order_id) elif order_model.status == NodeOrderStatus.PAID: deferred.defer(confirm_odoo_quotation, order_model.odoo_sale_order_id) else: logging.debug('Status was already %s, not doing anything', order_model.status) order_model.put() return order_model
def create_node_order(data): # type: (CreateNodeOrderTO) -> NodeOrder if data.status not in (NodeOrderStatus.SIGNED, NodeOrderStatus.SENT, NodeOrderStatus.ARRIVED, NodeOrderStatus.PAID): data.sign_time = MISSING if data.status not in (NodeOrderStatus.SENT, NodeOrderStatus.ARRIVED): data.send_time = MISSING app_user = users.User(data.app_user) order_count = NodeOrder.list_by_so(data.odoo_sale_order_id).count() if order_count > 0: raise OrderAlreadyExistsException(data.odoo_sale_order_id) try: nodes = get_nodes_from_odoo(data.odoo_sale_order_id) except (IndexError, TypeError): logging.warn('Could not get nodes from odoo for order id %s' % data.odoo_sale_order_id, exc_info=True) raise HttpBadRequestException('cannot_find_so_x', {'id': data.odoo_sale_order_id}) if not nodes: raise HttpBadRequestException('no_serial_number_configured_yet', {'sale_order': data.odoo_sale_order_id}) prefix, doc_content_base64 = data.document.split(',') content_type = prefix.split(';')[0].replace('data:', '') if content_type != 'application/pdf': raise InvalidContentTypeException(content_type, ['application/pdf']) doc_content = base64.b64decode(doc_content_base64) order_key = NodeOrder.create_key() pdf_name = NodeOrder.filename(order_key.id()) pdf_url = upload_to_gcs(pdf_name, doc_content, content_type) order = NodeOrder(key=order_key, app_user=app_user, **data.to_dict(exclude=['document', 'app_user'])) order.put() iyo_username = get_iyo_username(app_user) email, app_id = get_app_user_tuple(app_user) deferred.defer(add_nodes_to_profile, iyo_username, nodes) deferred.defer(set_hoster_status_in_user_data, order.app_user, False) deferred.defer(add_user_to_role, UserDetailsTO(email=email.email(), app_id=app_id), RogerthatRoles.HOSTERS) deferred.defer(tag_intercom_users, IntercomTags.HOSTER, [iyo_username]) deferred.defer(_order_node_iyo_see, order.app_user, order.id, pdf_url, len(doc_content), create_quotation=False) return order
def _create_investment_agreement(amount, currency, token, token_count_float, username, version, app_user, **kwargs): tff_profile = get_tff_profile(username) if tff_profile.kyc.status != KYCStatus.VERIFIED: raise HttpBadRequestException('cannot_invest_not_kyc_verified') applicant = get_applicant(tff_profile.kyc.applicant_id) name = '%s %s ' % (applicant.first_name, applicant.last_name) address = '%s %s' % (applicant.addresses[0].street, applicant.addresses[0].building_number) address += '\n%s %s' % (applicant.addresses[0].postcode, applicant.addresses[0].town) country = filter(lambda c: c['value'] == applicant.addresses[0].country, country_choices)[0]['label'] address += '\n%s' % country precision = 2 reference = user_code(username) agreement = InvestmentAgreement(creation_time=now(), app_user=app_user, token=token, amount=amount, token_count=long(token_count_float * pow(10, precision)), token_precision=precision, currency=currency, name=name, address=address, version=version, reference=reference, **kwargs) return agreement
def run(self, f, args, kwargs): """ Args: f (any) args (tuple) kwargs (dict) Returns: callable """ if f.meta['custom_auth_method']: if not f.meta['custom_auth_method'](f, self): self.abort(httplib.FORBIDDEN) elif f.meta['authentication'] == AUTHENTICATED: INJECTED_FUNCTIONS.validate_authentication(self, f, args, kwargs) for hook in _precall_hooks: hook(f, *args, **kwargs) try: result = run(f, args, kwargs) except HttpException as http_exception: return ErrorResponse(http_exception) except MissingArgumentException as e: logging.debug(e) return ErrorResponse(HttpBadRequestException(e.message)) except Exception as e: for hook in _postcall_hooks: hook(f, False, kwargs, e) raise for hook in _postcall_hooks: hook(f, True, kwargs, result) return result
def _get_currency_conversions(currencies, dollar_value): # type: (list[CurrencyValueTO | CurrencyValue], int) -> list[CurrencyValue] currency_result = _get_current_currency_rates() result_list = [] invalid_currencies = [c.currency for c in currencies if c.currency not in currency_result] if invalid_currencies: raise HttpBadRequestException('invalid_currencies', {'currencies': invalid_currencies}) for currency in currencies: if currency.auto_update: value_of_one_usd = currency_result.get(currency.currency) currency.value = dollar_value / value_of_one_usd currency.timestamp = now() result_list.append(CurrencyValue(currency=currency.currency, value=currency.value, timestamp=currency.timestamp, auto_update=currency.auto_update)) return result_list
def api_list_audit_logs(page_size=100, cursor=None, type=None, user_id=None, include_reference=True): page_size = min(1000, page_size) if type and type not in AuditLogMapping: raise HttpBadRequestException( 'invalid_type', {'allowed_types': AuditLogMapping.keys()}) if type and user_id: query_results = list_audit_logs_by_type_and_user( type, user_id, page_size, cursor) elif type: query_results = list_audit_logs_by_type(type, page_size, cursor) elif user_id: query_results = list_audit_logs_by_user(user_id, page_size, cursor) else: query_results = list_audit_logs(page_size, cursor) return list_audit_logs_details(query_results, include_reference)
def set_kyc_status(username, payload, current_user_id): # type: (unicode, SetKYCPayloadTO, unicode) -> TffProfile logging.debug('Updating KYC status to %s', KYCStatus(payload.status)) profile = get_tff_profile(username) if not can_change_kyc_status(profile.kyc.status, payload.status): raise HttpBadRequestException('invalid_status') comment = payload.comment if payload.comment is not MISSING else None profile.kyc.set_status(payload.status, current_user_id, comment=comment) if payload.status == KYCStatus.PENDING_SUBMIT: deferred.defer(send_kyc_flow, profile.app_user, payload.comment) if payload.status == KYCStatus.INFO_SET: update_applicant(profile.kyc.applicant_id, deserialize(payload.data, Applicant)) elif payload.status == KYCStatus.PENDING_APPROVAL: deferred.defer(_create_check, profile.kyc.applicant_id) elif payload.status == KYCStatus.VERIFIED: deferred.defer(_send_kyc_approved_message, profile.key) profile.put() deferred.defer(store_kyc_in_user_data, profile.app_user, _countdown=2) deferred.defer(index_profile, Profile.create_key(username), _countdown=2) return profile
def get(self): app_redirect_uri = self.request.GET.get('app_redirect_uri', None) try: if not app_redirect_uri: logging.debug('app_redirect_uri is missing') raise HttpBadRequestException() except HttpException as e: render_error_page(self.response, e.http_code, e.error) return auth_plugin = get_auth_plugin() assert isinstance(auth_plugin, ItsYouOnlineAuthPlugin) config = auth_plugin.configuration if config.required_scopes and config.required_scopes is not MISSING: scope = config.required_scopes else: scope = '' organization_id = config.root_organization.name params = { 'response_type': 'code', 'client_id': config.root_organization.name, 'redirect_uri': '%s/refresh/callback' % get_server_url(), 'scope': scope, 'state': str(uuid.uuid4()) } refresh_state = OauthState(key=OauthState.create_key(params['state'])) refresh_state.populate(timestamp=now(), organization_id=organization_id, source=SOURCE_APP, app_redirect_uri=app_redirect_uri, completed=False) refresh_state.put() oauth_url = '%s/authorize?%s' % (auth_plugin.oauth_base_url, urllib.urlencode(params)) logging.info('Redirecting to %s', oauth_url) self.redirect(str(oauth_url))
def create_investment_agreement(agreement): # type: (CreateInvestmentAgreementTO) -> InvestmentAgreement app_user = users.User(agreement.app_user) username = get_iyo_username(app_user) tff_profile = get_tff_profile(username) if tff_profile.kyc.status != KYCStatus.VERIFIED: raise HttpBadRequestException('cannot_invest_not_kyc_verified') token_count_float = get_token_count(agreement.currency, agreement.amount) agreement_model = _create_investment_agreement(agreement.amount, agreement.currency, agreement.token, token_count_float, username, 'manually_created', app_user, status=agreement.status, paid_time=agreement.paid_time, sign_time=agreement.sign_time) prefix, doc_content_base64 = agreement.document.split(',') content_type = prefix.split(';')[0].replace('data:', '') doc_content = base64.b64decode(doc_content_base64) agreement_model.put() pdf_name = InvestmentAgreement.filename(agreement_model.id) pdf_url = upload_to_gcs(pdf_name, doc_content, content_type) deferred.defer(_create_investment_agreement_iyo_see_doc, agreement_model.key, app_user, pdf_url, content_type, send_sign_message=False, pdf_size=len(doc_content)) return agreement_model
def transfer_genesis_coins_to_user(app_user, token_type, amount, memo=None, epoch=0): validate_token_type(token_type) if amount <= 0: raise HttpBadRequestException('invalid_amount') # Validate that this user has a profile get_profile(get_iyo_username(app_user)) if epoch > 0: date_signed = datetime.utcfromtimestamp(epoch) else: date_signed = datetime.now() if TokenType.A == token_type: token = TOKEN_TFT unlock_timestamps = [0] unlock_amounts = [amount] elif TokenType.B == token_type: token = TOKEN_TFT d = date_signed + relativedelta(months=6) unlock_timestamps = [get_epoch_from_datetime(d)] unlock_amounts = [amount] elif TokenType.C == token_type: token = TOKEN_TFT unlock_timestamps = [] unlock_amounts = [] a = amount / 48 for i in xrange(0, 39): d = date_signed + relativedelta(months=48 - i) unlock_timestamps = [get_epoch_from_datetime(d) ] + unlock_timestamps unlock_amounts = [a] + unlock_amounts d = date_signed + relativedelta(months=9) unlock_timestamps = [get_epoch_from_datetime(d)] + unlock_timestamps unlock_amounts = [amount - sum(unlock_amounts)] + unlock_amounts elif TokenType.D == token_type: token = TOKEN_TFT_CONTRIBUTOR unlock_timestamps = [0] unlock_amounts = [amount] elif TokenType.I == token_type: token = TOKEN_ITFT unlock_timestamps = [0] unlock_amounts = [amount] else: raise Exception(u"Unknown token type") key = ThreeFoldWallet.create_key(app_user) wallet = key.get() if not wallet: wallet = ThreeFoldWallet(key=key, tokens=[]) if token not in wallet.tokens: wallet.tokens.append(token) if unlock_timestamps[0] > 0 and ( not wallet.next_unlock_timestamp or unlock_timestamps[0] < wallet.next_unlock_timestamp): wallet.next_unlock_timestamp = unlock_timestamps[0] wallet.put() transaction_id = unicode(uuid.uuid4()) pt = ThreeFoldPendingTransaction( key=ThreeFoldPendingTransaction.create_key(transaction_id), timestamp=now(), unlock_timestamps=unlock_timestamps, unlock_amounts=unlock_amounts, token=token, token_type=token_type, amount=amount, memo=memo, app_users=[app_user], from_user=None, to_user=app_user, synced=False, synced_status=ThreeFoldPendingTransaction.STATUS_PENDING) pt.put() return pt
def validate_token_type(token_type): if token_type not in TokenType.all(): raise HttpBadRequestException( u'invalid_token_type', {'possible_token_types': TokenType.all()})