From 8b29f81a5ba678de337534242194c864c8c2c714 Mon Sep 17 00:00:00 2001 From: srahulbadami Date: Mon, 16 Jul 2018 17:51:46 +0530 Subject: [PATCH 1/2] Changed IssueCreate View to make it Compatible with the Mobile App --- bugheist/urls.py | 4 +- website/views.py | 163 +++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 139 insertions(+), 28 deletions(-) diff --git a/bugheist/urls.py b/bugheist/urls.py index 56d1e76fb..f6a33c149 100644 --- a/bugheist/urls.py +++ b/bugheist/urls.py @@ -14,7 +14,7 @@ from website.views import (UserProfileDetailView, IssueCreate, UploadCreate, EmailDetailView, InboundParseWebhookView, LeaderboardView, IssueView, AllIssuesView, SpecificIssuesView, HuntCreate, DomainDetailView, StatsDetailView, InviteCreate, CreateInviteFriend, - ScoreboardView,get_score,CustomObtainAuthToken,create_tokens) + ScoreboardView,get_score,CustomObtainAuthToken,create_tokens,issue_count) from rest_framework.authtoken import views favicon_view = RedirectView.as_view(url='/static/favicon.ico', permanent=True) @@ -77,6 +77,8 @@ url(r'^api/v1/userscore$', website.views.get_score), url(r'^authenticate/', CustomObtainAuthToken.as_view()), url(r'^api/v1/create_tokens/$', website.views.create_tokens), + url(r'^api/v1/count/$', website.views.issue_count), + url(r'^api/v1/createissues/$', csrf_exempt(IssueCreate.as_view()), name="issuecreate"), ] if settings.DEBUG: diff --git a/website/views.py b/website/views.py index ea0888413..d85e06cfb 100644 --- a/website/views.py +++ b/website/views.py @@ -11,6 +11,11 @@ import requests import requests.exceptions +import base64 +import six +import uuid + +from django.core.files.uploadedfile import InMemoryUploadedFile from allauth.account.models import EmailAddress from allauth.account.signals import user_logged_in from bs4 import BeautifulSoup @@ -48,7 +53,6 @@ from .forms import FormInviteFriend, UserProfileForm - def index(request, template="index.html"): try: domains = random.sample(Domain.objects.all(), 3) @@ -170,7 +174,7 @@ def form_valid(self, form): obj.save() p = Points.objects.create(user=self.request.user, issue=obj, score=score) - def process_issue(self, user, obj, created, domain, score=3): + def process_issue(self, user, obj, created, domain, tokenauth=False, score=3): p = Points.objects.create(user=user, issue=obj, score=score) messages.success(self.request, 'Bug added! +' + str(score)) @@ -204,23 +208,40 @@ def process_issue(self, user, obj, created, domain, score=3): name = "support" domain.email = email_to domain.save() - - msg_plain = render_to_string('email/bug_added.txt', { - 'domain': domain.name, - 'name': name, - 'username': self.request.user, - 'id': obj.id, - 'description': obj.description, - 'label': obj.get_label_display, - }) - msg_html = render_to_string('email/bug_added.txt', { - 'domain': domain.name, - 'name': name, - 'username': self.request.user, - 'id': obj.id, - 'description': obj.description, - 'label': obj.get_label_display, - }) + if tokenauth == False : + msg_plain = render_to_string('email/bug_added.txt', { + 'domain': domain.name, + 'name': name, + 'username': self.request.user, + 'id': obj.id, + 'description': obj.description, + 'label': obj.get_label_display, + }) + msg_html = render_to_string('email/bug_added.txt', { + 'domain': domain.name, + 'name': name, + 'username': self.request.user, + 'id': obj.id, + 'description': obj.description, + 'label': obj.get_label_display, + }) + else : + msg_plain = render_to_string('email/bug_added.txt', { + 'domain': domain.name, + 'name': name, + 'username': user, + 'id': obj.id, + 'description': obj.description, + 'label': obj.get_label_display, + }) + msg_html = render_to_string('email/bug_added.txt', { + 'domain': domain.name, + 'name': name, + 'username': user, + 'id': obj.id, + 'description': obj.description, + 'label': obj.get_label_display, + }) send_mail( 'Bug found on ' + domain.name, msg_plain, @@ -231,26 +252,70 @@ def process_issue(self, user, obj, created, domain, score=3): return HttpResponseRedirect("/") - class IssueCreate(IssueBaseCreate, CreateView): model = Issue fields = ['url', 'description', 'screenshot', 'domain', 'label'] template_name = "report.html" - def get_initial(self): + try: + json_data = json.loads(self.request.body) + if not self.request.GET._mutable: + self.request.POST._mutable = True + self.request.POST['url'] = json_data['url'] + self.request.POST['description'] = json_data['description'] + self.request.POST['file'] = json_data['file'] + self.request.POST['label'] = json_data['label'] + self.request.POST['token'] = json_data['token'] + self.request.POST['type'] = json_data['type'] + if self.request.POST.get('file'): + if isinstance(self.request.POST.get('file'), six.string_types): + import imghdr + # Check if the base64 string is in the "data:" format + data = "data:image/"+ self.request.POST.get('type') + ";base64," + self.request.POST.get('file') + data = data.replace(" ", "") + data += "=" * ((4 - len(data) % 4) % 4) + if 'data:' in data and ';base64,' in data: + # Break out the header from the base64 content + header, data = data.split(';base64,') + + # Try to decode the file. Return validation error if it fails. + try: + decoded_file = base64.b64decode(data) + except TypeError: + TypeError('invalid_image') + + # Generate file name: + file_name = str(uuid.uuid4())[:12] # 12 characters are more than enough. + # Get the file name extension: + extension = imghdr.what(file_name, decoded_file) + extension = "jpg" if extension == "jpeg" else extension + file_extension = extension + + complete_file_name = "%s.%s" % (file_name, file_extension, ) + + self.request.FILES['screenshot'] = ContentFile(decoded_file, name=complete_file_name) + except: + tokenauth = False initial = super(IssueCreate, self).get_initial() if self.request.POST.get('screenshot-hash'): initial['screenshot'] = 'uploads\/' + self.request.POST.get('screenshot-hash') + '.png' return initial def form_valid(self, form): + tokenauth = False obj = form.save(commit=False) if self.request.user.is_authenticated: obj.user = self.request.user + if not self.request.user.is_authenticated: + for token in Token.objects.all(): + if self.request.POST.get('token') == token.key: + obj.user = User.objects.get(id = token.user_id) + tokenauth = True + domain, created = Domain.objects.get_or_create(name=obj.domain_name.replace("www.", ""), defaults={ 'url': "http://" + obj.domain_name.replace("www.", "")}) obj.domain = domain - if created and self.request.user.is_authenticated: + if created and (self.request.user.is_authenticated or tokenauth): p = Points.objects.create(user=self.request.user, domain=domain, score=1) messages.success(self.request, 'Domain added! + 1') @@ -275,6 +340,20 @@ def form_valid(self, form): user_prof.save() + if tokenauth: + total_issues = Issue.objects.filter(user = User.objects.get(id = token.user_id)).count() + user_prof = UserProfile.objects.get(user = User.objects.get(id = token.user_id)) + if total_issues <= 10: + user_prof.title = 1 + elif total_issues <= 50: + user_prof.title = 2 + elif total_issues <= 200: + user_prof.title = 3 + else: + user_prof.title = 4 + + user_prof.save() + if domain.github and os.environ.get("GITHUB_PASSWORD"): from giturlparse import parse from requests.auth import HTTPBasicAuth @@ -296,7 +375,7 @@ def form_valid(self, form): redirect_url = '/report' # redirect users to login - if not self.request.user.is_authenticated: + if not (self.request.user.is_authenticated or tokenauth): # we store the issue id on the user session to assign it as soon as he login/register self.request.session['issue'] = obj.id self.request.session['created'] = created @@ -305,8 +384,12 @@ def form_valid(self, form): return HttpResponseRedirect('{}?next={}'.format(login_url, redirect_url)) # assign issue - self.process_issue(self.request.user, obj, created, domain) - return HttpResponseRedirect(self.request.META.get('HTTP_REFERER')) + if tokenauth: + self.process_issue(User.objects.get(id = token.user_id), obj, created, domain, True) + return JsonResponse("Created", safe=False) + else: + self.process_issue(self.request.user, obj, created, domain) + return HttpResponseRedirect(self.request.META.get('HTTP_REFERER')) def get_context_data(self, **kwargs): context = super(IssueCreate, self).get_context_data(**kwargs) @@ -317,7 +400,6 @@ def get_context_data(self, **kwargs): total_score=Sum('points__score')).order_by('-total_score')[:10], return context - class UploadCreate(View): template_name = "index.html" @@ -1043,4 +1125,31 @@ def post(self, request, *args, **kwargs): def create_tokens(request): for user in User.objects.all(): Token.objects.get_or_create(user=user) - return JsonResponse("Created", safe=False) \ No newline at end of file + return JsonResponse("Created", safe=False) + +def issue_count(request): + open_issue = Issue.objects.filter(status="open").count() + close_issue = Issue.objects.filter(status="closed").count() + return JsonResponse({'open': open_issue , 'closed': close_issue},safe=False) + +def upload(request): + url = "http://192.168.0.102:8000/api/v1/createissues/" + + payload = "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"url\"\r\n\r\nwww.asdmaskdnj.com\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"description\"\r\n\r\nsdads\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"label\"\r\n\r\n3\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"screenshot\"; filename=\"C:\\Users\\srahu\\Desktop\\New folder\\Picture.jpg\"\r\nContent-Type: image/jpeg\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"token\"\r\n\r\na9e6e6c4dd554bb9914488db3b5d18bb20c0e640\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--" + headers = { + 'content-type': "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW", + 'Cache-Control': "no-cache", + 'Postman-Token': "2888b8bf-bdc1-4b57-bec7-70eb05b9388e" + } + + response = requests.request("POST", url, data=payload, headers=headers) + + return HttpResponse("Done") + +def get_file_extension(self, file_name, decoded_file): + import imghdr + + extension = imghdr.what(file_name, decoded_file) + extension = "jpg" if extension == "jpeg" else extension + + return extension \ No newline at end of file From fc2da560c96270d0a67f1a7e8c5f8a4d4ca7d7f0 Mon Sep 17 00:00:00 2001 From: srahulbadami Date: Mon, 16 Jul 2018 22:04:59 +0530 Subject: [PATCH 2/2] Minor Changes --- website/views.py | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/website/views.py b/website/views.py index d85e06cfb..f68276d60 100644 --- a/website/views.py +++ b/website/views.py @@ -1131,25 +1131,3 @@ def issue_count(request): open_issue = Issue.objects.filter(status="open").count() close_issue = Issue.objects.filter(status="closed").count() return JsonResponse({'open': open_issue , 'closed': close_issue},safe=False) - -def upload(request): - url = "http://192.168.0.102:8000/api/v1/createissues/" - - payload = "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"url\"\r\n\r\nwww.asdmaskdnj.com\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"description\"\r\n\r\nsdads\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"label\"\r\n\r\n3\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"screenshot\"; filename=\"C:\\Users\\srahu\\Desktop\\New folder\\Picture.jpg\"\r\nContent-Type: image/jpeg\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"token\"\r\n\r\na9e6e6c4dd554bb9914488db3b5d18bb20c0e640\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--" - headers = { - 'content-type': "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW", - 'Cache-Control': "no-cache", - 'Postman-Token': "2888b8bf-bdc1-4b57-bec7-70eb05b9388e" - } - - response = requests.request("POST", url, data=payload, headers=headers) - - return HttpResponse("Done") - -def get_file_extension(self, file_name, decoded_file): - import imghdr - - extension = imghdr.what(file_name, decoded_file) - extension = "jpg" if extension == "jpeg" else extension - - return extension \ No newline at end of file