internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: svthalia/concrexit

Issue:
URL's from Events API are not always full URL's
### Describe the bug
The `google_maps_url` from the Events API is not always a full URL.

### How to reproduce
Steps to reproduce the behaviour:
1. On staging, go to `https://staging.thalia.nu/api/v1/events/147/` and see that the `google_maps_url` is not a full URL but a relative one.

### Expected behaviour
The `google_maps_url` should always be a full URL.




Discussion:

Resolving patch:
diff --git a/website/utils/snippets.py b/website/utils/snippets.py
--- a/website/utils/snippets.py
+++ b/website/utils/snippets.py
@@ -43,9 +43,9 @@ def datetime_to_lectureyear(date):
 
 def create_google_maps_url(location, zoom, size):
     if location.lower().strip() == "online":
-        return static("img/locations/online.png")
+        return settings.BASE_URL + static("img/locations/online.png")
     if location.lower().strip() == "discord":
-        return static("img/locations/discord.png")
+        return settings.BASE_URL + static("img/locations/discord.png")
 
     maps_url = (
         f"/maps/api/staticmap?"


Test patch:
Repository: svthalia/concrexit

Issue:
Event registrations api returns 500
### Describe the bug
`/api/v1/events/{pk}/registrations/` returns a 500

### How to reproduce
1. Register for an event
2. Go to `/api/v1/events/{pk}/registrations/`
3. See a 500

### Expected behaviour
No 500



Discussion:

Resolving patch:
diff --git a/website/events/api/v1/serializers/event_registrations/list.py b/website/events/api/v1/serializers/event_registrations/list.py
--- a/website/events/api/v1/serializers/event_registrations/list.py
+++ b/website/events/api/v1/serializers/event_registrations/list.py
@@ -73,7 +73,7 @@ def _is_late_cancellation(self, instance):
 
     def _queue_position(self, instance):
         pos = instance.queue_position
-        return pos if pos > 0 else None
+        return pos if pos and pos > 0 else None
 
     def _is_cancelled(self, instance):
         return instance.date_cancelled is not None


Test patch:
Repository: svthalia/concrexit

Issue:
Anonymous API calls crash because of throttling
### Describe the bug

Anonymous API calls crash because of throttling.

### How to reproduce
Steps to reproduce the behaviour:
1. Create an API application with server credentials without user attached to it
2. Do an API call
3. Instant crash because the throttling expects a user 

### Expected behaviour
Not crash, but do throttle



Discussion:

Resolving patch:
diff --git a/website/thaliawebsite/api/throttling.py b/website/thaliawebsite/api/throttling.py
new file mode 100644
--- /dev/null
+++ b/website/thaliawebsite/api/throttling.py
@@ -0,0 +1,38 @@
+from rest_framework.throttling import SimpleRateThrottle
+
+
+class AnonRateThrottle(SimpleRateThrottle):
+    """Limits the rate of API calls that may be made by a anonymous users.
+
+    The IP address of the request will be used as the unique cache key.
+    """
+
+    scope = "anon"
+
+    def get_cache_key(self, request, view):
+        if request.user and request.user.is_authenticated:
+            return None  # Only throttle unauthenticated requests.
+
+        return self.cache_format % {
+            "scope": self.scope,
+            "ident": self.get_ident(request),
+        }
+
+
+class UserRateThrottle(SimpleRateThrottle):
+    """Limits the rate of API calls that may be made by a given user.
+
+    The user id will be used as a unique cache key if the user is
+    authenticated.  For anonymous requests, the IP address of the request will
+    be used.
+    """
+
+    scope = "user"
+
+    def get_cache_key(self, request, view):
+        if request.user and request.user.is_authenticated:
+            ident = request.user.pk
+        else:
+            ident = self.get_ident(request)
+
+        return self.cache_format % {"scope": self.scope, "ident": ident}
diff --git a/website/thaliawebsite/settings.py b/website/thaliawebsite/settings.py
--- a/website/thaliawebsite/settings.py
+++ b/website/thaliawebsite/settings.py
@@ -560,8 +560,8 @@ def from_env(
     "DEFAULT_VERSIONING_CLASS": "rest_framework.versioning.NamespaceVersioning",
     "DEFAULT_SCHEMA_CLASS": "thaliawebsite.api.openapi.OAuthAutoSchema",
     "DEFAULT_THROTTLE_CLASSES": [
-        "rest_framework.throttling.AnonRateThrottle",
-        "rest_framework.throttling.UserRateThrottle",
+        "thaliawebsite.api.throttling.AnonRateThrottle",
+        "thaliawebsite.api.throttling.UserRateThrottle",
     ],
     "DEFAULT_THROTTLE_RATES": {"anon": "100/day", "user": "1000/day"},
 }


Test patch:
Repository: svthalia/concrexit

Issue:
CSRF in /admin/payments/batch/new_filled/
### Describe the bug
The admin page to create a new batch is on the url /admin/payments/batch/new_filled/, but this works with a GET request and is thus vulnerable to cross site request forgery. I believe no csrf token is checked

### How to reproduce
Steps to reproduce the behaviour:
1. Go to /admin/payments/batch/new_filled/
2. A new batch is created without user action

### Expected behaviour
Some action on the concrexit site should create a POST request, preferably including a csrf token



Discussion:

Resolving patch:
diff --git a/website/payments/admin_views.py b/website/payments/admin_views.py
--- a/website/payments/admin_views.py
+++ b/website/payments/admin_views.py
@@ -220,7 +220,7 @@ def post(self, request, *args, **kwargs):
 class BatchNewFilledAdminView(View):
     """View that adds a new batch filled with all payments that where not already in a batch."""
 
-    def get(self, request, *args, **kwargs):
+    def post(self, request, *args, **kwargs):
         batch = Batch()
         batch.save()
 


Test patch:
diff --git a/website/payments/tests/test_admin_views.py b/website/payments/tests/test_admin_views.py
--- a/website/payments/tests/test_admin_views.py
+++ b/website/payments/tests/test_admin_views.py
@@ -594,18 +594,18 @@ def _give_user_permissions(self):
 
     def test_permission(self):
         url = "/admin/payments/batch/new_filled/"
-        response = self.client.get(url)
+        response = self.client.post(url)
         self.assertRedirects(response, f"/admin/login/?next={url}")
 
         self._give_user_permissions()
 
-        response = self.client.get(url)
+        response = self.client.post(url)
 
         b = Batch.objects.exclude(id=self.batch.id).first()
         self.assertRedirects(response, f"/admin/payments/batch/{b.id}/change/")
 
     @freeze_time("2020-03-01")
-    def test_get(self):
+    def test_post(self):
         self._give_user_permissions()
 
         Payment.objects.bulk_create(
@@ -649,7 +649,7 @@ def test_get(self):
             ]
         )
 
-        self.client.get("/admin/payments/batch/new_filled/")
+        self.client.post("/admin/payments/batch/new_filled/")
 
         b = Batch.objects.exclude(id=self.batch.id).first()
Repository: svthalia/concrexit

Issue:
Changing registration start after event publishing is always blocked
### Describe the bug

When trying to change the registration start date after publishing the event it will never be possible to change it anymore even though registration _has not_ started yet.

### How to reproduce
Steps to reproduce the behaviour:
1. Create an event with registrations in the _future_
2. Publish the event 
3. Try to change the registration start date
4. See error that says the registration date cannot be changed because registration has already opened

### Expected behaviour

It should actually matter what the date is and if the registration is open for this error to appear.

### Screenshots

<img width="612" alt="Screenshot 2021-04-02 at 21 17 26" src="https://user-images.githubusercontent.com/1799914/113446776-dafb3200-93f8-11eb-85c4-a4eca78b29bb.png">


### Additional context
Add any other context about the problem here.



Discussion:

Resolving patch:
diff --git a/website/events/models/event.py b/website/events/models/event.py
--- a/website/events/models/event.py
+++ b/website/events/models/event.py
@@ -279,22 +279,20 @@ def clean_changes(self, changed_data):
         """
         errors = {}
         if self.published:
-            if "price" in changed_data:
-                errors.update(
-                    {
-                        "price": _(
-                            "You cannot change this field after the registration has started."
-                        )
-                    }
-                )
-            if "registration_start" in changed_data:
-                errors.update(
-                    {
-                        "registration_start": _(
-                            "You cannot change this field after the registration has started."
-                        )
-                    }
-                )
+            for field in ("price", "registration_start"):
+                if (
+                    field in changed_data
+                    and self.registration_start
+                    and self.registration_start <= timezone.now()
+                ):
+                    errors.update(
+                        {
+                            field: _(
+                                "You cannot change this field after "
+                                "the registration has started."
+                            )
+                        }
+                    )
 
         if errors:
             raise ValidationError(errors)


Test patch:
Repository: svthalia/concrexit

Issue:
Mailto link in event admin that automatically puts addresses in bcc
### Is your feature request related to a problem? Please describe.
Now, if people want to send an email to all registered members of an event, they export their email addresses and send an email to them. The problem is that it happens too often that these email addresses are not put in bcc...

### Describe the solution you'd like
A mailto link in the event admin that automatically puts the email addresses in the bcc.

### Motivation
To avoid data leaks :)

### Describe alternatives you've considered
Asking people to please not put addresses in cc.

### Additional context
Possibly other solutions exists, like allowing to email from admin itself through a form. But for now this will work I think.



Discussion:

Resolving patch:
diff --git a/website/events/admin.py b/website/events/admin.py
--- a/website/events/admin.py
+++ b/website/events/admin.py
@@ -293,13 +293,6 @@ def get_urls(self):
                 ),
                 name="events_event_export",
             ),
-            path(
-                "<int:pk>/export-email/",
-                self.admin_site.admin_view(
-                    admin_views.EventRegistrationEmailsExport.as_view()
-                ),
-                name="events_event_export_email",
-            ),
             path(
                 "<int:pk>/message/",
                 self.admin_site.admin_view(
diff --git a/website/events/admin_views.py b/website/events/admin_views.py
--- a/website/events/admin_views.py
+++ b/website/events/admin_views.py
@@ -13,7 +13,7 @@
 from django.utils.translation import pgettext_lazy
 from django.utils.translation import gettext_lazy as _
 from django.views import View
-from django.views.generic import DetailView, TemplateView, FormView
+from django.views.generic import DetailView, FormView
 
 from events import services
 from events.decorators import organiser_only
@@ -291,24 +291,3 @@ def get(self, request, pk):
             slugify(event.title)
         )
         return response
-
-
-@method_decorator(staff_member_required, name="dispatch")
-@method_decorator(organiser_only, name="dispatch")
-class EventRegistrationEmailsExport(TemplateView, PermissionRequiredMixin):
-    """Renders a page that outputs all email addresses of registered members for an event."""
-
-    template_name = "events/admin/email_export.html"
-    permission_required = "events.view_event"
-
-    def get_context_data(self, **kwargs):
-        context = super().get_context_data(**kwargs)
-        event = get_object_or_404(Event, pk=kwargs["pk"])
-        registrations = event.eventregistration_set.filter(date_cancelled=None)
-        registrations = registrations[: event.max_participants]
-        addresses = [r.member.email for r in registrations if r.member]
-        no_addresses = [r.name for r in registrations if not r.member]
-        context["event"] = event
-        context["addresses"] = addresses
-        context["no_addresses"] = no_addresses
-        return context


Test patch:
Repository: svthalia/concrexit

Issue:
Warnings about DEFAULT_AUTO_FIELD setting since Django 3.2
<!--

Please add the appropriate label for what change should be made:
docs: changes to the documentation)
refactor: refactoring production code, eg. renaming a variable or rewriting a function
test: adding missing tests, refactoring tests; no production code change
chore: updating poetry etc; no production code change

-->

### Describe the change
In Django 3.2 a new setting [`DEFAULT_AUTO_FIELD`](https://docs.djangoproject.com/en/3.2/releases/3.2/#customizing-type-of-auto-created-primary-keys) was introduced, which let's you set a default field for the primary key. It now spams a lot of warnings when you run the server since this setting isn't set by us yet.

### Motivation
Django will changes the setting from `django.db.models.AutoField` to `django.db.models.BigAutoField` in the future which can lead to a lot of unwanted migrations.

### Current implementation
`django.db.models.AutoField` is now used but it still gives a warning since we didn't overwrite the setting.



Discussion:

Resolving patch:
diff --git a/website/thaliawebsite/settings.py b/website/thaliawebsite/settings.py
--- a/website/thaliawebsite/settings.py
+++ b/website/thaliawebsite/settings.py
@@ -228,6 +228,9 @@ def from_env(
 # https://docs.djangoproject.com/en/dev/ref/settings/#csrf-cookie-secure
 CSRF_COOKIE_SECURE = setting(development=False, production=True)
 
+# https://docs.djangoproject.com/en/dev/ref/settings/#default-auto-field
+DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
+
 ###############################################################################
 # Email settings
 # https://docs.djangoproject.com/en/dev/ref/settings/#email-backend


Test patch:
Repository: svthalia/concrexit

Issue:
Move TODOs to issues
<!--

Please add the appropriate label for what change should be made:
docs: changes to the documentation)
refactor: refactoring production code, eg. renaming a variable or rewriting a function
test: adding missing tests, refactoring tests; no production code change
chore: updating poetry etc; no production code change

-->

### Describe the change
Move all `TODO`s in the code to issues.

### Motivation
`TODO`s in the code means that there is some issue to solve. These issues are not easily visible by developers. It would be better to have them as issues on GitHub (along with all other issues).

### Additional context
```
$ grep -ir TODO --exclude="*.pyc" --exclude="*fullcalendar*" --exclude-dir="docs" --exclude-dir="*font*"
website/registrations/models.py:            @todo: Remove usage of this property
website/utils/translation.py:            # TODO consider implementing this when there is a need for it.
website/members/models/profile.py:            @todo: Remove usage of this property
website/payments/templates/payments/bankaccount_list.html:{#            TODO: Add a mention to payments functionality when we build it  #}
website/thabloid/models.py:        # TODO reconsider if this resolution / quality is sufficient
website/thaliawebsite/menus.py:                # TODO: Remove submenu when the new template is implemented
```



Discussion:

Resolving patch:
diff --git a/website/members/models/profile.py b/website/members/models/profile.py
--- a/website/members/models/profile.py
+++ b/website/members/models/profile.py
@@ -210,7 +210,6 @@ class Profile(models.Model):
 
     @property
     def language(self):
-        # todo: Remove usage of this property.
         return "en"
 
     receive_optin = models.BooleanField(
diff --git a/website/registrations/models.py b/website/registrations/models.py
--- a/website/registrations/models.py
+++ b/website/registrations/models.py
@@ -192,7 +192,6 @@ class Registration(Entry):
 
     @property
     def language(self):
-        """@todo: Remove usage of this property."""
         return "en"
 
     # ---- Contact information -----
diff --git a/website/sales/admin/order_admin.py b/website/sales/admin/order_admin.py
--- a/website/sales/admin/order_admin.py
+++ b/website/sales/admin/order_admin.py
@@ -336,7 +336,6 @@ def changelist_view(self, request, extra_context=None):
     def change_view(self, request, object_id, form_url="", extra_context=None):
         object_id
         return super().change_view(request, object_id, form_url, extra_context)
-        # @todo WARN WHEN ORDER IS AGE RESTRICTED AND PAYER IS UNDERAGE
 
     def order_description(self, obj):
         if obj.order_description:


Test patch:
Repository: svthalia/concrexit

Issue:
Bug: 'view site' from event detail admin forwards to wrong url
In GitLab by @JobDoesburg on Dec 4, 2019, 19:43

<!--
    You want something new.
-->

### One-sentence description

Improve navigation between admin views for event admin

### Motivation

Currently it works terrible. 

### Desired functionality

On save, go to the view that makes sense instead of very often go back to the event overview. 

Also maybe provide buttons that take you to the event detail overview page, or to the frontend view, etc etc

I don't yet have clear suggestions but I think everyone can think of their own what makes sense.


### Suggested implementation

<!--
    If you have any notes on how we could achieve this feature,
    share them here.
-->


Discussion:
In GitLab by @se-bastiaan on Dec 18, 2019, 19:14

This should be specified better. The edit view currently goes back to the previous page where you clicked on 'edit'. And there is a 'view on site' option in the edit view already?
I have just found the exact bug again:

When I hit this 'view site' button from the event detail admin:

<img width="594" alt="image" src="https://user-images.githubusercontent.com/7915741/117675005-79bf3f00-b1ac-11eb-9011-27ba5d4c92b5.png">

I get this error:

<img width="594" alt="image" src="https://user-images.githubusercontent.com/7915741/117674876-58f6e980-b1ac-11eb-93bc-4a3e896e5513.png">

The forward is not correct (I think it can just be fixed by setting the object url or something like that)

Resolving patch:
diff --git a/website/events/admin_views.py b/website/events/admin_views.py
--- a/website/events/admin_views.py
+++ b/website/events/admin_views.py
@@ -37,7 +37,7 @@ class EventAdminDetails(DetailView, PermissionRequiredMixin):
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)
 
-        context.update({"payment": Payment, "has_permission": True, "site_url": True})
+        context.update({"payment": Payment, "has_permission": True, "site_url": "/"})
 
         return context
 


Test patch:
Repository: svthalia/concrexit

Issue:
Show non-current FoodEvents in API v2.
### Describe the bug
The `api/v2/food/events/` and `api/v2/food/events/<pk>/` endpoints currently do not return FoodEvents that are not current. 

I think to change that we’d only need to replace some `FoodEvent.current_objects.all()`s with `FoodEvent.objects.all()`.



Discussion:

Resolving patch:
diff --git a/website/pizzas/api/v2/views.py b/website/pizzas/api/v2/views.py
--- a/website/pizzas/api/v2/views.py
+++ b/website/pizzas/api/v2/views.py
@@ -28,7 +28,7 @@ class FoodEventListView(ListAPIView):
     """Returns an overview of all food events."""
 
     serializer_class = FoodEventSerializer
-    queryset = FoodEvent.current_objects.all()
+    queryset = FoodEvent.objects.all()
     filter_backends = (
         framework_filters.OrderingFilter,
         filters.FoodEventDateFilterBackend,
@@ -45,7 +45,7 @@ class FoodEventDetailView(RetrieveAPIView):
     """Returns one single food event."""
 
     serializer_class = FoodEventSerializer
-    queryset = FoodEvent.current_objects.all()
+    queryset = FoodEvent.objects.all()
     permission_classes = [
         IsAuthenticatedOrTokenHasScope,
         DjangoModelPermissionsOrAnonReadOnly,


Test patch:
Repository: svthalia/concrexit

Issue:
Unpublishing or removing events orphans scheduled messages
### Describe the bug
Unpublishing or removing events orphans scheduled messages.

### How to reproduce
Steps to reproduce the behaviour:
1. Go to events
2. Create a new one, published
3. Check scheduled messages
4. Unpublish the event
5. Check the normal messages
6. See that the message that existed before has moved from scheduled to non-scheduled

### Expected behaviour
The message should actually be deleted.




Discussion:

Resolving patch:
diff --git a/website/events/models/event.py b/website/events/models/event.py
--- a/website/events/models/event.py
+++ b/website/events/models/event.py
@@ -438,7 +438,7 @@ def save(self, **kwargs):
                     self.registration_reminder = registration_reminder
                     self.registration_reminder.users.set(Member.current_members.all())
                 elif registration_reminder.pk is not None:
-                    delete_collector.add([self.registration_reminder])
+                    delete_collector.collect([self.registration_reminder])
                     self.registration_reminder = None
 
             start_reminder_time = self.start - timezone.timedelta(hours=1)
@@ -460,18 +460,18 @@ def save(self, **kwargs):
                 else:
                     self.start_reminder.users.set(Member.current_members.all())
             elif start_reminder.pk is not None:
-                delete_collector.add([self.start_reminder])
+                delete_collector.collect([self.start_reminder])
                 self.start_reminder = None
         else:
             if (
                 self.registration_reminder is not None
                 and not self.registration_reminder.sent
             ):
-                delete_collector.add([self.registration_reminder])
+                delete_collector.collect([self.registration_reminder])
                 self.registration_reminder = None
 
             if self.start_reminder is not None and not self.start_reminder.sent:
-                delete_collector.add([self.start_reminder])
+                delete_collector.collect([self.start_reminder])
                 self.start_reminder = None
 
         super().save()
@@ -486,9 +486,9 @@ def delete(self, using=None, keep_parents=False):
             self.registration_reminder is not None
             and not self.registration_reminder.sent
         ):
-            collector.add([self.registration_reminder])
+            collector.collect([self.registration_reminder], keep_parents=keep_parents)
         if self.start_reminder is not None and not self.start_reminder.sent:
-            collector.add([self.start_reminder])
+            collector.collect([self.start_reminder], keep_parents=keep_parents)
         if self.has_food_event:
             collector.add([self.food_event])
 


Test patch: