示例#1
0
    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))
示例#2
0
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
示例#3
0
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
示例#4
0
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
示例#5
0
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
示例#6
0
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
示例#7
0
    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
示例#8
0
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
示例#9
0
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)
示例#10
0
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
示例#11
0
    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))
示例#12
0
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
示例#13
0
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
示例#14
0
def validate_token_type(token_type):
    if token_type not in TokenType.all():
        raise HttpBadRequestException(
            u'invalid_token_type', {'possible_token_types': TokenType.all()})