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 }}
+
+ {% csrf_token %}
+
+
+
+
+
+
+
@@ -160,6 +178,18 @@
{% endif %}
+
+
+
+
{% 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')