From 7d36df7af06faaf7613d89da602240cc331c143f Mon Sep 17 00:00:00 2001 From: JisanAR03 Date: Wed, 14 Feb 2024 20:51:25 +0600 Subject: [PATCH 1/6] update issue 2 page for edit issue and delete --- website/templates/issue2.html | 111 ++++++++++++++++++++++++++++++++-- 1 file changed, 107 insertions(+), 4 deletions(-) diff --git a/website/templates/issue2.html b/website/templates/issue2.html index c38ff89da..c0f5481a3 100644 --- a/website/templates/issue2.html +++ b/website/templates/issue2.html @@ -23,12 +23,30 @@

Reported on - {{ object.url }} + {{ object.url }}

-

+

{{ object.description }}

+ @@ -160,6 +178,18 @@ {% endif %} + +
+

Delete Issue:

+ +
+ +
+

Edit Issue:

+ Yes +
{% endif %} @@ -376,8 +406,81 @@

}) }) - + function sanitizeURL(url) { + var a = document.createElement('a'); + a.href = encodeURI(url); + return a.href; + } - + var label = "{{object.label}}"; + $(document).on('click', '.edit-issue', function (e) { + $issue_desc = $('.issue-desc').text().trim(); + $('.form input[name=description]').val($issue_desc); + $('.form input[name=domain]').val($('.issue-domain').text()); + $('.form select').val(label); + $('.editables').hide(); + $('.form').show(); + }); + + $(document).on('click', '.cancel-edit', function (e) { + $('.form').hide(); + $('.editables').show(); + }); + + $(document).on('click', '.save-issue', function (e) { + e.preventDefault(); + + if ($('.form input[name=description]').val().trim().length == 0 || + $('.form input[name=domain]').val().trim().length == 0) { + return; + } + var dom_regex = /[-a-zA-Z0-9@:%_\+.~#?&//=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9@:%_\+.~#?&//=]*)?/gi; + dom_regex = new RegExp(dom_regex); + var domain_url = $('.form input[name=domain]').val(); + if (domain_url.match(dom_regex) == null) { + alert('Enter a valid url'); + return; + } + + + $.ajax({ + type: 'POST', + url: '/issue/edit/', + data: { + issue_pk: $('#issue_pk').val(), + domain: $('.form input[name=domain]').val(), + description: $('.form input[name=description]').val(), + label: $('.form select').val(), + csrfmiddlewaretoken: $('.form input[name=csrfmiddlewaretoken]').val(), + }, + success: function (data) { + $('.issue-desc').text($('.form input[name=description]').val()); + $('.issue-domain').text($('.form input[name=domain]').val()); + var sanitizedDomain = sanitizeURL($('.form input[name=domain]').val()); + $('.issue-domain').attr("href", sanitizedDomain); + label = $('.form select').val(); + var l = $(".form select option[value='" + label + "']").text(); + $('.bug-label').text(l); + $('.form').hide(); + $('.editables').show(); + $.notify("Issue updated!", { + style: "custom", + className: "success" + }); + if (data === "Domain Created") + $.notify("Domain Added!", { + style: "custom", + className: "success" + }); + }, + error: function () { + $.notify("Some error occurred!", { + style: "custom", + className: "danger" + }); + } + }); + }); + {% endblock %} From 3256ccc5e64cd914f6badfe2bc1fdcd5cda21510 Mon Sep 17 00:00:00 2001 From: JisanAR03 Date: Sat, 17 Feb 2024 19:59:22 +0600 Subject: [PATCH 2/6] apply limit is issue creation --- blt/settings.py | 14 ++++++---- .../management/commands/create_cachetable.py | 18 ++++++++++++ website/views.py | 28 +++++++++++++++++++ 3 files changed, 54 insertions(+), 6 deletions(-) create mode 100644 website/management/commands/create_cachetable.py diff --git a/blt/settings.py b/blt/settings.py index 5de1e2c93..e8bc211bc 100644 --- a/blt/settings.py +++ b/blt/settings.py @@ -193,12 +193,14 @@ # SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' -# CACHES = { -# 'default': { -# 'BACKEND': 'django.core.cache.backends.db.DatabaseCache', -# 'LOCATION': 'cache_table', -# } -# } +CACHES = { + 'default': { + 'BACKEND': 'django.core.cache.backends.db.DatabaseCache', + 'LOCATION': 'django_cache', # Change 'my_cache_table' to your cache table name if it's not the default + }, +} + + REST_AUTH = { 'SESSION_LOGIN': False } diff --git a/website/management/commands/create_cachetable.py b/website/management/commands/create_cachetable.py new file mode 100644 index 000000000..b4edf80d0 --- /dev/null +++ b/website/management/commands/create_cachetable.py @@ -0,0 +1,18 @@ +from django.core.management.base import BaseCommand +from django.core.management import call_command +from django.db import connection + +class Command(BaseCommand): + help = 'Creates the cache table if it does not exist' + + def handle(self, *args, **options): + # Assuming the default cache table name; change if yours is different + table_name = 'django_cache' + table_exists = table_name in connection.introspection.table_names() + + if table_exists: + self.stdout.write(self.style.SUCCESS(f"'{table_name}' table already exists.")) + else: + # Create the cache table + call_command('createcachetable') + self.stdout.write(self.style.SUCCESS(f"'{table_name}' table created.")) diff --git a/website/views.py b/website/views.py index 0558bbc19..4f04fc21c 100644 --- a/website/views.py +++ b/website/views.py @@ -87,6 +87,9 @@ from django.core.validators import URLValidator from django.core.exceptions import ValidationError from django.http import HttpRequest +from django.core.cache import cache +from django.utils.timezone import now +from django.http import HttpResponseForbidden def is_valid_https_url(url): validate = URLValidator(schemes=['https']) # Only allow HTTPS URLs @@ -607,6 +610,20 @@ def process_issue(self, user, obj, created, domain, tokenauth=False, score=3): ) return HttpResponseRedirect("/") + + +def get_client_ip(request): + """Extract the client's IP address from the request.""" + x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR') + if x_forwarded_for: + ip = x_forwarded_for.split(',')[0] + else: + ip = request.META.get('REMOTE_ADDR') + + print("*"*50) + print(f"Client IP: {ip}") + print("*"*50) + return ip class IssueCreate(IssueBaseCreate, CreateView): model = Issue @@ -717,6 +734,14 @@ def post(self, request, *args, **kwargs): return super().post(request, *args, **kwargs) def form_valid(self, form): + user_or_ip = self.request.user.get_username() if self.request.user.is_authenticated else get_client_ip(self.request) + limit = 2 if self.request.user.is_authenticated else 5 # Your set limits + cache_key = f"issue_create_{user_or_ip}_{now().date()}" + issue_count = cache.get(cache_key, 0) + + if issue_count >= limit: + messages.error(self.request, "You have reached your issue creation limit for today.") + return HttpResponseRedirect("/report/") @atomic def create_issue(self,form): @@ -870,6 +895,7 @@ def create_issue(self,form): self.request.session["created"] = domain_exists self.request.session["domain"] = domain.id login_url = reverse("account_login") + cache.set(cache_key, issue_count + 1, 86400) # Increment the count messages.success(self.request, "Bug added!") return HttpResponseRedirect("{}?next={}".format(login_url, redirect_url)) @@ -877,9 +903,11 @@ def create_issue(self,form): self.process_issue( User.objects.get(id=token.user_id), obj, domain_exists, domain, True ) + cache.set(cache_key, issue_count + 1, 86400) # Increment the count return JsonResponse("Created", safe=False) else: self.process_issue(self.request.user, obj, domain_exists, domain) + cache.set(cache_key, issue_count + 1, 86400) # Increment the count return HttpResponseRedirect(redirect_url + "/") return create_issue(self,form) From 7621a700e7e8ce471e9e758f48e6d418d69c5c1d Mon Sep 17 00:00:00 2001 From: JisanAR03 Date: Sat, 17 Feb 2024 20:00:14 +0600 Subject: [PATCH 3/6] limit increase --- website/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/views.py b/website/views.py index 4f04fc21c..b577b7a13 100644 --- a/website/views.py +++ b/website/views.py @@ -735,7 +735,7 @@ def post(self, request, *args, **kwargs): def form_valid(self, form): user_or_ip = self.request.user.get_username() if self.request.user.is_authenticated else get_client_ip(self.request) - limit = 2 if self.request.user.is_authenticated else 5 # Your set limits + limit = 50 if self.request.user.is_authenticated else 30 # Your set limits cache_key = f"issue_create_{user_or_ip}_{now().date()}" issue_count = cache.get(cache_key, 0) From 585e2832b0be3f22d46d59f6b0b30973b09404f7 Mon Sep 17 00:00:00 2001 From: JisanAR03 Date: Sat, 17 Feb 2024 20:22:46 +0600 Subject: [PATCH 4/6] added new changes --- blt/settings.py | 2 +- website/management/commands/create_cachetable.py | 1 - website/views.py | 4 ---- 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/blt/settings.py b/blt/settings.py index e8bc211bc..5a8388bc0 100644 --- a/blt/settings.py +++ b/blt/settings.py @@ -196,7 +196,7 @@ CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.db.DatabaseCache', - 'LOCATION': 'django_cache', # Change 'my_cache_table' to your cache table name if it's not the default + 'LOCATION': 'django_cache', }, } diff --git a/website/management/commands/create_cachetable.py b/website/management/commands/create_cachetable.py index b4edf80d0..c086412f8 100644 --- a/website/management/commands/create_cachetable.py +++ b/website/management/commands/create_cachetable.py @@ -6,7 +6,6 @@ class Command(BaseCommand): help = 'Creates the cache table if it does not exist' def handle(self, *args, **options): - # Assuming the default cache table name; change if yours is different table_name = 'django_cache' table_exists = table_name in connection.introspection.table_names() diff --git a/website/views.py b/website/views.py index b577b7a13..d5a9a4d91 100644 --- a/website/views.py +++ b/website/views.py @@ -619,10 +619,6 @@ def get_client_ip(request): ip = x_forwarded_for.split(',')[0] else: ip = request.META.get('REMOTE_ADDR') - - print("*"*50) - print(f"Client IP: {ip}") - print("*"*50) return ip class IssueCreate(IssueBaseCreate, CreateView): From 8d410574675bd28de640c9a254c088491494dcc6 Mon Sep 17 00:00:00 2001 From: JisanAR03 Date: Sun, 18 Feb 2024 01:37:33 +0600 Subject: [PATCH 5/6] update store system --- blt/settings.py | 12 ++++++------ .../management/commands/create_cachetable.py | 17 ----------------- .../0082_issue_reporter_ip_address.py | 17 +++++++++++++++++ website/models.py | 1 + website/views.py | 19 +++++++++---------- 5 files changed, 33 insertions(+), 33 deletions(-) delete mode 100644 website/management/commands/create_cachetable.py create mode 100644 website/migrations/0082_issue_reporter_ip_address.py diff --git a/blt/settings.py b/blt/settings.py index 5a8388bc0..f077d72ff 100644 --- a/blt/settings.py +++ b/blt/settings.py @@ -193,12 +193,12 @@ # SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' -CACHES = { - 'default': { - 'BACKEND': 'django.core.cache.backends.db.DatabaseCache', - 'LOCATION': 'django_cache', - }, -} +# CACHES = { +# 'default': { +# 'BACKEND': 'django.core.cache.backends.db.DatabaseCache', +# 'LOCATION': 'cache_table', +# } +# } REST_AUTH = { diff --git a/website/management/commands/create_cachetable.py b/website/management/commands/create_cachetable.py deleted file mode 100644 index c086412f8..000000000 --- a/website/management/commands/create_cachetable.py +++ /dev/null @@ -1,17 +0,0 @@ -from django.core.management.base import BaseCommand -from django.core.management import call_command -from django.db import connection - -class Command(BaseCommand): - help = 'Creates the cache table if it does not exist' - - def handle(self, *args, **options): - table_name = 'django_cache' - table_exists = table_name in connection.introspection.table_names() - - if table_exists: - self.stdout.write(self.style.SUCCESS(f"'{table_name}' table already exists.")) - else: - # Create the cache table - call_command('createcachetable') - self.stdout.write(self.style.SUCCESS(f"'{table_name}' table created.")) diff --git a/website/migrations/0082_issue_reporter_ip_address.py b/website/migrations/0082_issue_reporter_ip_address.py new file mode 100644 index 000000000..6f12c68b8 --- /dev/null +++ b/website/migrations/0082_issue_reporter_ip_address.py @@ -0,0 +1,17 @@ +# Generated by Django 4.2.8 on 2024-02-17 19:32 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("website", "0081_userprofile_issue_downvoted"), + ] + + operations = [ + migrations.AddField( + model_name="issue", + name="reporter_ip_address", + field=models.GenericIPAddressField(blank=True, null=True), + ), + ] diff --git a/website/models.py b/website/models.py index 8d10944a3..ea7a8be76 100644 --- a/website/models.py +++ b/website/models.py @@ -252,6 +252,7 @@ class Issue(models.Model): modified = models.DateTimeField(auto_now=True) is_hidden = models.BooleanField(default=False) rewarded = models.PositiveIntegerField(default=0) # money rewarded by the company + reporter_ip_address = models.GenericIPAddressField(null=True, blank=True) def __unicode__(self): diff --git a/website/views.py b/website/views.py index d5a9a4d91..8bee8bfb2 100644 --- a/website/views.py +++ b/website/views.py @@ -87,9 +87,7 @@ from django.core.validators import URLValidator from django.core.exceptions import ValidationError from django.http import HttpRequest -from django.core.cache import cache from django.utils.timezone import now -from django.http import HttpResponseForbidden def is_valid_https_url(url): validate = URLValidator(schemes=['https']) # Only allow HTTPS URLs @@ -730,14 +728,18 @@ def post(self, request, *args, **kwargs): return super().post(request, *args, **kwargs) def form_valid(self, form): - user_or_ip = self.request.user.get_username() if self.request.user.is_authenticated else get_client_ip(self.request) - limit = 50 if self.request.user.is_authenticated else 30 # Your set limits - cache_key = f"issue_create_{user_or_ip}_{now().date()}" - issue_count = cache.get(cache_key, 0) + reporter_ip = get_client_ip(self.request) + form.instance.reporter_ip_address = reporter_ip + + #implement rate limit + limit = 50 if self.request.user.is_authenticated else 30 + today = now().date() + recent_issues_count = Issue.objects.filter(reporter_ip_address=reporter_ip, created__date=today).count() - if issue_count >= limit: + if recent_issues_count >= limit: messages.error(self.request, "You have reached your issue creation limit for today.") return HttpResponseRedirect("/report/") + form.instance.reporter_ip_address = reporter_ip @atomic def create_issue(self,form): @@ -891,7 +893,6 @@ def create_issue(self,form): self.request.session["created"] = domain_exists self.request.session["domain"] = domain.id login_url = reverse("account_login") - cache.set(cache_key, issue_count + 1, 86400) # Increment the count messages.success(self.request, "Bug added!") return HttpResponseRedirect("{}?next={}".format(login_url, redirect_url)) @@ -899,11 +900,9 @@ def create_issue(self,form): self.process_issue( User.objects.get(id=token.user_id), obj, domain_exists, domain, True ) - cache.set(cache_key, issue_count + 1, 86400) # Increment the count return JsonResponse("Created", safe=False) else: self.process_issue(self.request.user, obj, domain_exists, domain) - cache.set(cache_key, issue_count + 1, 86400) # Increment the count return HttpResponseRedirect(redirect_url + "/") return create_issue(self,form) From 6304582d0fc9448f94a11e0b411a901c68a464a1 Mon Sep 17 00:00:00 2001 From: JisanAR03 Date: Sun, 18 Feb 2024 02:02:29 +0600 Subject: [PATCH 6/6] remove whitespace --- website/views.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/website/views.py b/website/views.py index 8bee8bfb2..a9def2998 100644 --- a/website/views.py +++ b/website/views.py @@ -608,8 +608,6 @@ def process_issue(self, user, obj, created, domain, tokenauth=False, score=3): ) return HttpResponseRedirect("/") - - def get_client_ip(request): """Extract the client's IP address from the request.""" x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')