def test_is_github_token_valid(self): """Test the github utility is_github_token_valid method.""" now = timezone.now() expired = (now - timedelta(hours=2)).isoformat() return_false = is_github_token_valid() return_valid = is_github_token_valid(self.user_oauth_token, now.isoformat()) params = build_auth_dict(self.user_oauth_token) url = TOKEN_URL.format(**params) responses.add(responses.GET, url, headers=HEADERS, status=200) return_expired = is_github_token_valid(self.user_oauth_token, expired) assert responses.calls[0].request.url == url assert return_false is False assert return_valid is True assert return_expired is True
def bounty_details(request, ghuser='', ghrepo='', ghissue=0): """Display the bounty details.""" _access_token = request.session.get('access_token') profile_id = request.session.get('profile_id') issueURL = 'https://github.com/' + ghuser + '/' + ghrepo + '/issues/' + ghissue if ghissue else request.GET.get( 'url') # try the /pulls url if it doesnt exist in /issues try: assert Bounty.objects.current().filter(github_url=issueURL).exists() except: issueURL = 'https://github.com/' + ghuser + '/' + ghrepo + '/pull/' + ghissue if ghissue else request.GET.get( 'url') print(issueURL) pass bounty_url = issueURL params = { 'issueURL': issueURL, 'title': 'Issue Details', 'card_title': 'Funded Issue Details | Gitcoin', 'avatar_url': static('v2/images/helmet.png'), 'active': 'bounty_details', 'is_github_token_valid': is_github_token_valid(_access_token), 'github_auth_url': get_auth_url(request.path), 'profile_interested': False, "newsletter_headline": "Be the first to know about new funded issues." } if bounty_url: try: bounties = Bounty.objects.current().filter(github_url=bounty_url) if bounties: bounty = bounties.order_by('pk').first() # Currently its not finding anyting in the database if bounty.title and bounty.org_name: params[ 'card_title'] = f'{bounty.title} | {bounty.org_name} Funded Issue Detail | Gitcoin' params['title'] = params['card_title'] params['card_desc'] = ellipses( bounty.issue_description_text, 255) params['bounty_pk'] = bounty.pk params[ 'interested_profiles'] = bounty.interested.select_related( 'profile').all() params['avatar_url'] = bounty.local_avatar_url if profile_id: profile_ids = list( params['interested_profiles'].values_list('profile_id', flat=True)) params['profile_interested'] = request.session.get( 'profile_id') in profile_ids except Bounty.DoesNotExist: pass except Exception as e: print(e) logging.error(e) return TemplateResponse(request, 'bounty_details.html', params)
def remove_interest(request, bounty_id): """Unclaim work from the Bounty. :request method: POST post_id (int): ID of the Bounty. Returns: dict: The success key with a boolean value and accompanying error. """ access_token = request.GET.get('token') if access_token and is_github_token_valid(access_token): helper_handle_access_token(request, access_token) profile_id = request.session.get('profile_id') if not profile_id: return JsonResponse( { 'error': 'You must be authenticated via github to use this feature!' }, status=401) try: bounty = Bounty.objects.get(pk=bounty_id) except Bounty.DoesNotExist: return JsonResponse({'errors': ['Bounty doesn\'t exist!']}, status=401) try: interest = Interest.objects.get(profile_id=profile_id, bounty=bounty) record_user_action( Profile.objects.get(pk=profile_id).handle, 'stop_work', interest) bounty.interested.remove(interest) interest.delete() maybe_market_to_slack(bounty, 'stop_work') maybe_market_to_twitter(bounty, 'stop_work') except Interest.DoesNotExist: return JsonResponse( { 'errors': ['You haven\'t expressed interest on this bounty.'], 'success': False }, status=401) except Interest.MultipleObjectsReturned: interest_ids = bounty.interested \ .filter( profile_id=profile_id, bounty=bounty ).values_list('id', flat=True) \ .order_by('-created') bounty.interested.remove(*interest_ids) Interest.objects.filter(pk__in=list(interest_ids)).delete() return JsonResponse({'success': True})
def bounty_details(request): """Display the bounty details.""" _access_token = request.session.get('access_token') profile_id = request.session.get('profile_id') bounty_url = request.GET.get('url') params = { 'issueURL': request.GET.get('issue_'), 'title': 'Issue Details', 'card_title': 'Funded Issue Details | Gitcoin', 'avatar_url': 'https://gitcoin.co/static/v2/images/helmet.png', 'active': 'bounty_details', 'is_github_token_valid': is_github_token_valid(_access_token), 'github_auth_url': get_auth_url(request.path), 'profile_interested': False, "newsletter_headline": "Be the first to know about new funded issues." } if bounty_url: try: bounties = Bounty.objects.current().filter(github_url=bounty_url) if bounties: bounty = bounties.order_by('pk').first() # Currently its not finding anyting in the database if bounty.title and bounty.org_name: params[ 'card_title'] = f'{bounty.title} | {bounty.org_name} Funded Issue Detail | Gitcoin' params['title'] = params['card_title'] params['card_desc'] = ellipses( bounty.issue_description_text, 255) params['bounty_pk'] = bounty.pk params[ 'interested_profiles'] = bounty.interested.select_related( 'profile').all() params['avatar_url'] = bounty.local_avatar_url params[ 'is_legacy'] = bounty.is_legacy # TODO: Remove this following legacy contract sunset. if profile_id: profile_ids = list( params['interested_profiles'].values_list('profile_id', flat=True)) params['profile_interested'] = request.session.get( 'profile_id') in profile_ids except Bounty.DoesNotExist: pass except Exception as e: print(e) logging.error(e) return TemplateResponse(request, 'bounty_details.html', params)
def process_response(self, request, response): """Perform the check on request.""" token = request.session.get('access_token') expiration = request.session.get('access_token_last_validated') handle = request.session.get('handle') if token and handle: is_valid = is_github_token_valid(token, expiration) if is_valid: request.session['access_token_last_validated'] = now().isoformat() else: request.session.pop('access_token', '') request.session.pop('handle', '') request.session.pop('access_token_last_validated', '') Profile.objects.filter(handle=handle).update(github_access_token='') request.session.modified = True return response
def bounty_details(request, ghuser='', ghrepo='', ghissue=0, stdbounties_id=None): """Display the bounty details. Args: ghuser (str): The Github user. Defaults to an empty string. ghrepo (str): The Github repository. Defaults to an empty string. ghissue (int): The Github issue number. Defaults to: 0. Raises: Exception: The exception is raised for any exceptions in the main query block. Returns: django.template.response.TemplateResponse: The Bounty details template response. """ is_user_authenticated = request.user.is_authenticated if is_user_authenticated and hasattr(request.user, 'profile'): _access_token = request.user.profile.get_access_token() else: _access_token = request.session.get('access_token') issue_url = 'https://github.com/' + ghuser + '/' + ghrepo + '/issues/' + ghissue if ghissue else request.GET.get( 'url') # try the /pulls url if it doesnt exist in /issues try: assert Bounty.objects.current().filter(github_url=issue_url).exists() except Exception: issue_url = 'https://github.com/' + ghuser + '/' + ghrepo + '/pull/' + ghissue if ghissue else request.GET.get( 'url') print(issue_url) params = { 'issueURL': issue_url, 'title': _('Issue Details'), 'card_title': _('Funded Issue Details | Gitcoin'), 'avatar_url': static('v2/images/helmet.png'), 'active': 'bounty_details', 'is_github_token_valid': is_github_token_valid(_access_token), 'github_auth_url': get_auth_url(request.path), "newsletter_headline": _("Be the first to know about new funded issues."), 'is_staff': request.user.is_staff, } if issue_url: try: bounties = Bounty.objects.current().filter(github_url=issue_url) if stdbounties_id: bounties.filter(standard_bounties_id=stdbounties_id) if bounties: bounty = bounties.order_by('-pk').first() if bounties.count() > 1 and bounties.filter( network='mainnet').count() > 1: bounty = bounties.filter( network='mainnet').order_by('-pk').first() # Currently its not finding anyting in the database if bounty.title and bounty.org_name: params[ 'card_title'] = f'{bounty.title} | {bounty.org_name} Funded Issue Detail | Gitcoin' params['title'] = params['card_title'] params['card_desc'] = ellipses( bounty.issue_description_text, 255) params['bounty_pk'] = bounty.pk params['network'] = bounty.network params['stdbounties_id'] = bounty.standard_bounties_id params[ 'interested_profiles'] = bounty.interested.select_related( 'profile').all() params['avatar_url'] = bounty.get_avatar_url(True) snooze_days = int(request.GET.get('snooze', 0)) if snooze_days: is_funder = bounty.is_funder(request.user.username.lower()) is_staff = request.user.is_staff if is_funder or is_staff: bounty.snooze_warnings_for_days = snooze_days bounty.save() messages.success( request, _(f'Warning messages have been snoozed for {snooze_days} days' )) else: messages.warning( request, _('Only the funder of this bounty may snooze warnings.' )) except Bounty.DoesNotExist: pass except Exception as e: print(e) logging.error(e) return TemplateResponse(request, 'bounty_details.html', params)
def toolbox(request): access_token = request.GET.get('token') if access_token and is_github_token_valid(access_token): helper_handle_access_token(request, access_token) tools = Tool.objects.prefetch_related('votes').all() actors = [{ "title": _("Basics"), "description": _("Accelerate your dev workflow with Gitcoin\'s incentivization tools." ), "tools": tools.filter(category=Tool.CAT_BASIC) }, { "title": _("Advanced"), "description": _("Take your OSS game to the next level!"), "tools": tools.filter(category=Tool.CAT_ADVANCED) }, { "title": _("Community"), "description": _("Friendship, mentorship, and community are all part of the process." ), "tools": tools.filter(category=Tool.CAT_COMMUNITY) }, { "title": _("Tools to BUIDL Gitcoin"), "description": _("Gitcoin is built using Gitcoin. Purdy cool, huh? "), "tools": tools.filter(category=Tool.CAT_BUILD) }, { "title": _("Tools in Alpha"), "description": _("These fresh new tools are looking for someone to test ride them!"), "tools": tools.filter(category=Tool.CAT_ALPHA) }, { "title": _("Tools Coming Soon"), "description": _("These tools will be ready soon. They'll get here sooner if you help BUIDL them :)" ), "tools": tools.filter(category=Tool.CAT_COMING_SOON) }, { "title": _("Just for Fun"), "description": _("Some tools that the community built *just because* they should exist." ), "tools": tools.filter(category=Tool.CAT_FOR_FUN) }] # setup slug for key in range(0, len(actors)): actors[key]['slug'] = slugify(actors[key]['title']) profile_up_votes_tool_ids = '' profile_down_votes_tool_ids = '' profile_id = request.user.profile.pk if request.user.is_authenticated and hasattr( request.user, 'profile') else None if profile_id: ups = list( request.user.profile.votes.filter(value=1).values_list('tool', flat=True)) profile_up_votes_tool_ids = ','.join(str(x) for x in ups) downs = list( request.user.profile.votes.filter(value=-1).values_list('tool', flat=True)) profile_down_votes_tool_ids = ','.join(str(x) for x in downs) context = { "active": "tools", 'title': _("Toolbox"), 'card_title': _("Gitcoin Toolbox"), 'avatar_url': static('v2/images/tools/api.jpg'), "card_desc": _("Accelerate your dev workflow with Gitcoin\'s incentivization tools." ), 'actors': actors, 'newsletter_headline': _("Don't Miss New Tools!"), 'profile_up_votes_tool_ids': profile_up_votes_tool_ids, 'profile_down_votes_tool_ids': profile_down_votes_tool_ids } return TemplateResponse(request, 'toolbox.html', context)
def new_interest(request, bounty_id): """Claim Work for a Bounty. :request method: POST Args: post_id (int): ID of the Bounty. Returns: dict: The success key with a boolean value and accompanying error. """ access_token = request.GET.get('token') if access_token and is_github_token_valid(access_token): helper_handle_access_token(request, access_token) profile_id = request.session.get('profile_id') if not profile_id: return JsonResponse( { 'error': 'You must be authenticated via github to use this feature!' }, status=401) try: bounty = Bounty.objects.get(pk=bounty_id) except Bounty.DoesNotExist: raise Http404 num_issues = 3 active_bounties = Bounty.objects.current().filter( idx_status__in=['open', 'started']) num_active = Interest.objects.filter(profile_id=profile_id, bounty__in=active_bounties).count() is_working_on_too_much_stuff = num_active >= num_issues if is_working_on_too_much_stuff: return JsonResponse( { 'error': f'You may only work on max of {num_issues} issues at once.', 'success': False }, status=401) try: Interest.objects.get(profile_id=profile_id, bounty=bounty) return JsonResponse( { 'error': 'You have already expressed interest in this bounty!', 'success': False }, status=401) except Interest.DoesNotExist: interest = Interest.objects.create(profile_id=profile_id) bounty.interested.add(interest) record_user_action( Profile.objects.get(pk=profile_id).handle, 'start_work', interest) maybe_market_to_slack(bounty, 'start_work') maybe_market_to_twitter(bounty, 'start_work') except Interest.MultipleObjectsReturned: bounty_ids = bounty.interested \ .filter(profile_id=profile_id) \ .values_list('id', flat=True) \ .order_by('-created')[1:] Interest.objects.filter(pk__in=list(bounty_ids)).delete() return JsonResponse( { 'error': 'You have already expressed interest in this bounty!', 'success': False }, status=401) return JsonResponse({ 'success': True, 'profile': ProfileSerializer(interest.profile).data })
def save(request): status = 422 message = 'Please use a POST' body = {} try: body = json.loads(request.body) except Exception: status = 400 message = 'Bad Request' if body.get('bounty_id', False): access_token = body.get('token') github_username = body.get('github_username') try: github_user_data = get_github_user_data(access_token) except: github_user_data = {} access_token_invalid = not access_token or not is_github_token_valid( access_token) or github_user_data.get('login') != github_username if access_token_invalid: status = 405 message = f'Not authorized or invalid github token for github user {github_username}' else: # handle a POST bounty_id = body.get('bounty_id') email_address = body.get('email_address') direction = body.get('direction') # do validation validation_failed = False # email try: validate_email(email_address) except ValidationError: validation_failed = 'email' # bounty if not Bounty.objects.filter(pk=bounty_id).exists(): validation_failed = 'bounty does not exist' # direction if direction not in ['+', '-']: validation_failed = 'direction must be either + or -' # github_username if not github_username: validation_failed = 'no github_username' # handle validation failures if validation_failed: status = 422 message = 'Validation failed: {}'.format(validation_failed) else: bounty = Bounty.objects.get(pk=bounty_id) # save obj Match.objects.create( bounty=bounty, email=email_address, direction=direction, github_username=github_username, ) try: profile = Profile.objects.get(handle=github_username) create_new_interest_helper(bounty, profile.pk) except Exception as e: print('could not get profile {}'.format(e)) logging.exception(e) # send match email if direction == '+': to_emails = [email_address, bounty.bounty_owner_email] new_match(to_emails, bounty, github_username) # response status = 200 message = 'Success' response = { 'status': status, 'message': message, } return JsonResponse(response, status=status)
def bounty_details(request, ghuser='', ghrepo='', ghissue=0): """Display the bounty details. Args: ghuser (str): The Github user. Defaults to an empty string. ghrepo (str): The Github repository. Defaults to an empty string. ghissue (int): The Github issue number. Defaults to: 0. Raises: Exception: The exception is raised for any exceptions in the main query block. Returns: django.template.response.TemplateResponse: The Bounty details template response. """ is_user_authenticated = request.user.is_authenticated if is_user_authenticated and hasattr(request.user, 'profile'): _access_token = request.user.profile.get_access_token() else: _access_token = request.session.get('access_token') issue_url = 'https://github.com/' + ghuser + '/' + ghrepo + '/issues/' + ghissue if ghissue else request.GET.get('url') # try the /pulls url if it doesnt exist in /issues try: assert Bounty.objects.current().filter(github_url=issue_url).exists() except Exception: issue_url = 'https://github.com/' + ghuser + '/' + ghrepo + '/pull/' + ghissue if ghissue else request.GET.get('url') print(issue_url) params = { 'issueURL': issue_url, 'title': _('Issue Details'), 'card_title': _('Funded Issue Details | Gitcoin'), 'avatar_url': static('v2/images/helmet.png'), 'active': 'bounty_details', 'is_github_token_valid': is_github_token_valid(_access_token), 'github_auth_url': get_auth_url(request.path), "newsletter_headline": _("Be the first to know about new funded issues."), } if issue_url: try: bounties = Bounty.objects.current().filter(github_url=issue_url) if bounties: bounty = bounties.order_by('pk').first() # Currently its not finding anyting in the database if bounty.title and bounty.org_name: params['card_title'] = f'{bounty.title} | {bounty.org_name} Funded Issue Detail | Gitcoin' params['title'] = params['card_title'] params['card_desc'] = ellipses(bounty.issue_description_text, 255) params['bounty_pk'] = bounty.pk params['interested_profiles'] = bounty.interested.select_related('profile').all() params['avatar_url'] = bounty.local_avatar_url except Bounty.DoesNotExist: pass except Exception as e: print(e) logging.error(e) return TemplateResponse(request, 'bounty_details.html', params)