Exemple #1
0
def receive_tip_v3(request, key, txid, network):
    """Handle the receiving of a tip (the POST).

    Returns:
        TemplateResponse: the UI with the tip confirmed.

    """
    these_tips = Tip.objects.filter(web3_type='v3', txid=txid, network=network)
    tips = these_tips.filter(metadata__reference_hash_for_receipient=key) | these_tips.filter(metadata__reference_hash_for_funder=key)
    tip = tips.first()
    is_authed = request.user.username.lower() == tip.username.lower() or request.user.username.lower() == tip.from_username.lower() or not tip.username
    not_mined_yet = get_web3(tip.network).eth.getBalance(Web3.toChecksumAddress(tip.metadata['address'])) == 0
    did_fail = False
    if not_mined_yet:
        tip.update_tx_status()
        did_fail = tip.tx_status in ['dropped', 'unknown', 'na', 'error']

    if not request.user.is_authenticated or request.user.is_authenticated and not getattr(
        request.user, 'profile', None
    ):
        login_redirect = redirect('/login/github?next=' + request.get_full_path())
        return login_redirect
    num_redemptions = tip.metadata.get("num_redemptions", 0)
    max_redemptions = tip.metadata.get("max_redemptions", 0)
    is_redeemable = not (tip.receive_txid and (num_redemptions >= max_redemptions)) and is_authed
    has_this_user_redeemed = request.user.profile.tip_payouts.filter(tip=tip).count()
    if has_this_user_redeemed:
        is_redeemable = False
    if not is_redeemable:
        messages.info(request, 'This tip has been received already')
    elif not is_authed:
        messages.error(request, f'This tip is for @{tip.username} but you are logged in as @{request.user.username}.  Please logout and log back in as {tip.username}.')
    elif did_fail:
        messages.info(request, f'This tx {tip.txid}, failed.  Please contact the sender and ask them to send the tx again.')
    elif not_mined_yet:
        messages.info(request, f'This tx {tip.txid}, is still mining.  Please wait a moment before submitting the receive form.')
    elif request.POST.get('receive_txid') and is_redeemable:
        params = request.POST

        # db mutations
        try:
            profile = get_profile(tip.username)
            eth_address = params['forwarding_address']
            if not is_valid_eth_address(eth_address):
                eth_address = profile.preferred_payout_address
            if params['save_addr']:
                if profile:
                    profile.preferred_payout_address = eth_address
                    profile.save()
            tip.receive_txid = params['receive_txid']
            tip.receive_tx_status = 'pending'
            tip.receive_address = eth_address
            tip.received_on = timezone.now()
            num_redemptions = tip.metadata.get("num_redemptions", 0)
            # note to future self: to create a tip like this in the future set
            # tip.username
            # tip.metadata.max_redemptions
            # tip.metadata.override_send_amount
            # tip.amount to the amount you want to send 
            # ,"override_send_amount":1,"max_redemptions":29

            num_redemptions += 1
            tip.metadata["num_redemptions"] = num_redemptions
            tip.save()
            record_user_action(tip.from_username, 'receive_tip', tip)
            record_tip_activity(tip, tip.username, 'receive_tip')
            TipPayout.objects.create(
                txid=tip.receive_txid,
                profile=request.user.profile,
                tip=tip,
                )
            messages.success(request, 'This tip has been received')
            is_redeemable = False
            has_this_user_redeemed = True
        except Exception as e:
            messages.error(request, str(e))
            logger.exception(e)

    params = {
        'issueURL': request.GET.get('source'),
        'class': 'receive',
        'title': _('Receive Tip'),
        'gas_price': round(recommend_min_gas_price_to_confirm_in_time(120), 1),
        'tip': tip,
        'has_this_user_redeemed': has_this_user_redeemed,
        'key': key,
        'is_redeemable': is_redeemable,
        'is_authed': is_authed,
        'disable_inputs': not is_redeemable or not is_authed,
    }

    return TemplateResponse(request, 'onepager/receive.html', params)
Exemple #2
0
def job_settings(request):
    """Display and save user's Account settings.

    Returns:
        TemplateResponse: The user's Account settings template response.

    """
    msg = ''
    profile, es, user, is_logged_in = settings_helper_get_auth(request)

    if not user or not profile or not is_logged_in:
        login_redirect = redirect('/login/github?next=' +
                                  request.get_full_path())
        return login_redirect

    if request.POST:

        if 'preferred_payout_address' in request.POST.keys():
            eth_address = request.POST.get('preferred_payout_address', '')
            if not is_valid_eth_address(eth_address):
                eth_address = profile.preferred_payout_address
            profile.preferred_payout_address = eth_address
            profile.save()
            msg = _('Updated your Address')
        elif request.POST.get('disconnect', False):
            profile.github_access_token = ''
            profile = record_form_submission(request, profile,
                                             'account-disconnect')
            profile.email = ''
            profile.save()
            create_user_action(profile.user, 'account_disconnected', request)
            messages.success(
                request, _('Your account has been disconnected from Github'))
            logout_redirect = redirect(reverse('logout') + '?next=/')
            return logout_redirect
        elif request.POST.get('delete', False):

            # remove profile
            profile.hide_profile = True
            profile = record_form_submission(request, profile,
                                             'account-delete')
            profile.email = ''
            profile.save()

            # remove email
            delete_user_from_mailchimp(es.email)

            if es:
                es.delete()
            request.user.delete()
            AccountDeletionRequest.objects.create(
                handle=profile.handle.lower(),
                profile={
                    'ip': get_ip(request),
                })
            profile.delete()
            messages.success(request, _('Your account has been deleted.'))
            logout_redirect = redirect(reverse('logout') + '?next=/')
            return logout_redirect
        else:
            msg = _('Error: did not understand your request')

    context = {
        'is_logged_in': is_logged_in,
        'nav': 'home',
        'active': '/settings/job',
        'title': _('Job Settings'),
        'navs': get_settings_navs(request),
        'es': es,
        'profile': profile,
        'msg': msg,
    }
    return TemplateResponse(request, 'settings/job.html', context)
Exemple #3
0
def receive(request, key, txid, network):
    """Handle the receiving of a kudos (the POST).

    Returns:
        TemplateResponse: the UI with the kudos confirmed

    """
    these_kudos_transfers = KudosTransfer.objects.filter(web3_type='v3',
                                                         txid=txid,
                                                         network=network)
    kudos_transfers = these_kudos_transfers.filter(
        Q(metadata__reference_hash_for_receipient=key)
        | Q(metadata__reference_hash_for_funder=key))
    kudos_transfer = kudos_transfers.first()
    if not kudos_transfer:
        raise Http404

    is_authed = kudos_transfer.trust_url or request.user.username.replace(
        '@', '').lower() in [
            kudos_transfer.username.replace('@', '').lower(),
            kudos_transfer.from_username.replace('@', '').lower()
        ]
    not_mined_yet = get_web3(kudos_transfer.network).eth.getBalance(
        Web3.toChecksumAddress(kudos_transfer.metadata['address'])) == 0
    did_fail = False
    if not_mined_yet:
        kudos_transfer.update_tx_status()
        did_fail = kudos_transfer.tx_status in [
            'dropped', 'unknown', 'na', 'error'
        ]

    if not kudos_transfer.trust_url:
        if not request.user.is_authenticated or request.user.is_authenticated and not getattr(
                request.user, 'profile', None):
            login_redirect = redirect('/login/github/?next=' +
                                      request.get_full_path())
            return login_redirect

    if kudos_transfer.receive_txid:
        messages.info(request, _('This kudos has been received'))
    elif not is_authed:
        messages.error(
            request,
            f'This kudos is for {kudos_transfer.username} but you are logged in as {request.user.username}.  Please logout and log back in as {kudos_transfer.username}.'
        )
    elif did_fail:
        messages.info(
            request,
            f'This tx {kudos_transfer.txid}, failed.  Please contact the sender and ask them to send the tx again.'
        )
    elif not_mined_yet and not request.GET.get('receive_txid'):
        message = mark_safe(
            f'The <a href="https://etherscan.io/tx/{txid}">transaction</a> is still mining.  '
            'Please wait a moment before submitting the receive form.')
        messages.info(request, message)
    elif request.POST.get('receive_txid') and not kudos_transfer.receive_txid:
        params = request.POST
        # db mutations
        try:
            profile = get_profile(kudos_transfer.username.replace('@', ''))
            eth_address = params['forwarding_address']
            if not is_valid_eth_address(eth_address):
                eth_address = profile.preferred_payout_address
            if params['save_addr']:
                if profile:
                    # TODO: Does this mean that the address the user enters in the receive form
                    # Will overwrite an already existing preferred_payout_address?  Should we
                    # ask the user to confirm this?
                    profile.preferred_payout_address = eth_address
                    profile.save()
            kudos_transfer.receive_txid = params['receive_txid']
            kudos_transfer.receive_address = eth_address
            kudos_transfer.received_on = timezone.now()
            if request.user.is_authenticated:
                kudos_transfer.recipient_profile = request.user.profile
            kudos_transfer.save()
            record_user_action(kudos_transfer.username, 'new_kudos',
                               kudos_transfer)
            record_user_action(kudos_transfer.from_username, 'receive_kudos',
                               kudos_transfer)
            record_kudos_email_activity(kudos_transfer,
                                        kudos_transfer.username,
                                        'receive_kudos')
            record_kudos_activity(kudos_transfer, kudos_transfer.username,
                                  'receive_kudos')
            messages.success(request, _('This kudos has been received'))
        except Exception as e:
            messages.error(request, str(e))
            logger.exception(e)

    params = {
        'issueURL':
        request.GET.get('source'),
        'class':
        'receive',
        'gas_price':
        round(recommend_min_gas_price_to_confirm_in_time(120), 1),
        'kudos_transfer':
        kudos_transfer,
        'title':
        f"Receive {kudos_transfer.kudos_token_cloned_from.humanized_name} Kudos"
        if kudos_transfer and kudos_transfer.kudos_token_cloned_from else
        _('Receive Kudos'),
        'avatar_url':
        kudos_transfer.kudos_token_cloned_from.img_url
        if kudos_transfer and kudos_transfer.kudos_token_cloned_from else None,
        'card_desc':
        f"You've received a {kudos_transfer.kudos_token_cloned_from.humanized_name} kudos!"
        if kudos_transfer and kudos_transfer.kudos_token_cloned_from else
        _('You\'ve received a kudos'),
        'key':
        key,
        'is_authed':
        is_authed,
        'disable_inputs':
        kudos_transfer.receive_txid or not_mined_yet or not is_authed,
        'tweet_text':
        urllib.parse.quote_plus(
            f"I just got a {kudos_transfer.kudos_token_cloned_from.humanized_name} Kudos on @gitcoin.  "
        )
    }

    return TemplateResponse(request, 'transaction/receive.html', params)
Exemple #4
0
def account_settings(request):
    """Display and save user's Account settings.

    Returns:
        TemplateResponse: The user's Account settings template response.

    """
    msg = ''
    profile, es, user, is_logged_in = settings_helper_get_auth(request)

    if not user or not profile or not is_logged_in:
        login_redirect = redirect('/login/github?next=' +
                                  request.get_full_path())
        return login_redirect

    if request.POST:
        if 'persona_is_funder' or 'persona_is_hunter' in request.POST.keys():
            profile.persona_is_funder = bool(
                request.POST.get('persona_is_funder', False))
            profile.persona_is_hunter = bool(
                request.POST.get('persona_is_hunter', False))
            profile.save()

        if 'preferred_payout_address' in request.POST.keys():
            eth_address = request.POST.get('preferred_payout_address', '')
            if not is_valid_eth_address(eth_address):
                eth_address = profile.preferred_payout_address
            profile.preferred_payout_address = eth_address
            profile.save()
            msg = _('Updated your Address')
        elif request.POST.get('export', False):
            export_type = request.POST.get('export_type', False)

            response = HttpResponse(content_type='text/csv')
            name = f"gitcoin_{export_type}_{timezone.now().strftime('%Y_%m_%dT%H_00_00')}"
            response[
                'Content-Disposition'] = f'attachment; filename="{name}.csv"'

            writer = csv.writer(response)
            writer.writerow([
                'id', 'date', 'From', 'From Location', 'To', 'To Location',
                'Type', 'Value In USD', 'url', 'txid', 'token_name',
                'token_value'
            ])
            profile = request.user.profile
            earnings = profile.earnings if export_type == 'earnings' else profile.sent_earnings
            earnings = earnings.filter(
                network='mainnet').order_by('-created_on')
            for earning in earnings:
                writer.writerow([
                    earning.pk,
                    earning.created_on.strftime("%Y-%m-%dT%H:00:00"),
                    earning.from_profile.handle
                    if earning.from_profile else '*',
                    earning.from_profile.data.get('location', 'Unknown')
                    if earning.from_profile else 'Unknown',
                    earning.to_profile.handle if earning.to_profile else '*',
                    earning.to_profile.data.get('location', 'Unknown')
                    if earning.to_profile else 'Unknown',
                    earning.source_type.model_class(),
                    earning.value_usd,
                    earning.txid,
                    earning.token_name,
                    earning.token_value,
                    earning.url,
                ])

            return response
        elif request.POST.get('disconnect', False):
            profile.github_access_token = ''
            profile = record_form_submission(request, profile,
                                             'account-disconnect')
            profile.email = ''
            profile.save()
            create_user_action(profile.user, 'account_disconnected', request)
            redirect_url = f'https://www.github.com/settings/connections/applications/{settings.GITHUB_CLIENT_ID}'
            logout(request)
            logout_redirect = redirect(redirect_url)
            logout_redirect[
                'Cache-Control'] = 'max-age=0 no-cache no-store must-revalidate'
            return logout_redirect
        elif request.POST.get('delete', False):

            # remove profile
            profile.hide_profile = True
            profile = record_form_submission(request, profile,
                                             'account-delete')
            profile.email = ''
            profile.save()

            # remove email
            delete_user_from_mailchimp(es.email)

            if es:
                es.delete()
            request.user.delete()
            AccountDeletionRequest.objects.create(
                handle=profile.handle.lower(),
                profile={
                    'ip': get_ip(request),
                })
            profile.avatar_baseavatar_related.all().delete()
            try:
                profile.delete()
            except:
                profile.github_access_token = ''
                profile.user = None
                profile.hide_profile = True
                profile.save()
            messages.success(request, _('Your account has been deleted.'))
            logout_redirect = redirect(reverse('logout') + '?next=/')
            return logout_redirect
        else:
            msg = _('Error: did not understand your request')

    context = {
        'is_logged_in': is_logged_in,
        'nav': 'home',
        'active': '/settings/account',
        'title': _('Account Settings'),
        'navs': get_settings_navs(request),
        'es': es,
        'profile': profile,
        'msg': msg,
    }
    return TemplateResponse(request, 'settings/account.html', context)
Exemple #5
0
def account_settings(request):
    """Display and save user's Account settings.

    Returns:
        TemplateResponse: The user's Account settings template response.

    """
    msg = ''
    profile, es, user, is_logged_in = settings_helper_get_auth(request)

    if not user or not profile or not is_logged_in:
        login_redirect = redirect('/login/github/?next=' +
                                  request.get_full_path())
        return login_redirect

    if request.POST:
        if 'persona_is_funder' or 'persona_is_hunter' in request.POST.keys():
            profile.persona_is_funder = bool(
                request.POST.get('persona_is_funder', False))
            profile.persona_is_hunter = bool(
                request.POST.get('persona_is_hunter', False))
            profile.save()

        if 'preferred_payout_address' in request.POST.keys():
            eth_address = request.POST.get('preferred_payout_address', '')
            if not is_valid_eth_address(eth_address):
                eth_address = profile.preferred_payout_address
            profile.preferred_payout_address = eth_address
            profile.save()
            msg = _('Updated your Address')
        elif request.POST.get('export', False):
            export_type = request.POST.get('export_type', False)

            profile = request.user.profile
            earnings = profile.earnings if export_type == 'earnings' else profile.sent_earnings
            earnings = earnings.filter(
                network='mainnet').order_by('-created_on')
            return export_earnings_csv(earnings, export_type)
        elif request.POST.get('disconnect', False):
            profile.github_access_token = ''
            profile = record_form_submission(request, profile,
                                             'account-disconnect')
            profile.email = ''
            profile.save()
            create_user_action(profile.user, 'account_disconnected', request)
            redirect_url = f'https://www.github.com/settings/connections/applications/{settings.GITHUB_CLIENT_ID}'
            logout(request)
            logout_redirect = redirect(redirect_url)
            logout_redirect[
                'Cache-Control'] = 'max-age=0 no-cache no-store must-revalidate'
            return logout_redirect
        elif request.POST.get('delete', False):

            # remove profile
            profile.hide_profile = True
            profile = record_form_submission(request, profile,
                                             'account-delete')
            profile.email = ''
            profile.save()

            # remove email
            mautic_proxy_backend('POST',
                                 f'contacts/{profile.mautic_id}/delete')

            if es:
                es.delete()
            request.user.delete()
            AccountDeletionRequest.objects.create(
                handle=profile.handle.lower(),
                profile={
                    'ip': get_ip(request),
                })
            profile.avatar_baseavatar_related.all().delete()
            try:
                profile.delete()
            except:
                profile.github_access_token = ''
                profile.user = None
                profile.hide_profile = True
                profile.save()
            messages.success(request, _('Your account has been deleted.'))
            logout_redirect = redirect(reverse('logout') + '?next=/')
            return logout_redirect
        else:
            msg = _('Error: did not understand your request')

    context = {
        'is_logged_in': is_logged_in,
        'nav': 'home',
        'active': '/settings/account',
        'title': _('Account Settings'),
        'navs': get_settings_navs(request),
        'es': es,
        'profile': profile,
        'msg': msg,
    }
    return TemplateResponse(request, 'settings/account.html', context)