diff --git a/blt/settings.py b/blt/settings.py index f72218173..814fa42a5 100644 --- a/blt/settings.py +++ b/blt/settings.py @@ -199,6 +199,8 @@ # 'LOCATION': 'cache_table', # } # } + + REST_AUTH = { 'SESSION_LOGIN': False } 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 76f2026ed..7df9c8c36 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 9bcdccf16..d0a711f6d 100644 --- a/website/views.py +++ b/website/views.py @@ -89,6 +89,7 @@ from django.core.validators import URLValidator from django.core.exceptions import ValidationError from django.http import HttpRequest +from django.utils.timezone import now def is_valid_https_url(url): validate = URLValidator(schemes=['https']) # Only allow HTTPS URLs @@ -626,6 +627,14 @@ 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') + return ip class IssueCreate(IssueBaseCreate, CreateView): model = Issue @@ -736,6 +745,18 @@ def post(self, request, *args, **kwargs): return super().post(request, *args, **kwargs) def form_valid(self, form): + 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 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):