prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  API: `/api/users/by_email` returns 404 error for email addresses with dots before the @
  **Describe the bug**
  A clear and concise description of what the bug is.
  
  **To Reproduce**
  Steps to reproduce the behavior:
  1. Go to `[ephios-url]/api/users/by_email/vorname.nachname@url.de/`
  
  **Expected behaviour**
  Assuming the user exists, the information about the user should be returned.
  
  **Screenshots**
  Instead the page 404s.
  
  <img width="1511" alt="Screenshot 2024-03-27 at 18 54 08" src="https://github.com/ephios-dev/ephios/assets/2546622/1383feee-28b0-4825-a31e-c39e2cc3f2ab">
  
  **Environment**
  State which device, operating system, browser and browser version you are using.
  MacOS 14.2.1 (23C71), Version 17.2.1 (19617.1.17.11.12)
  
  **Additional context**
  * The problem does not appear for the test emails `usaaa@localhost/`, `admin@localhost/` or `user@localhost.com`.
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `ephios/api/views/users.py`
  Content:
  ```
  1 from django.db.models import Q
  2 from django.utils import timezone
  3 from django_filters.rest_framework import DjangoFilterBackend
  4 from oauth2_provider.contrib.rest_framework import IsAuthenticatedOrTokenHasScope
  5 from rest_framework import viewsets
  6 from rest_framework.exceptions import PermissionDenied
  7 from rest_framework.fields import SerializerMethodField
  8 from rest_framework.filters import SearchFilter
  9 from rest_framework.generics import RetrieveAPIView
  10 from rest_framework.mixins import RetrieveModelMixin
  11 from rest_framework.permissions import DjangoObjectPermissions
  12 from rest_framework.relations import SlugRelatedField
  13 from rest_framework.schemas.openapi import AutoSchema
  14 from rest_framework.serializers import ModelSerializer
  15 from rest_framework.viewsets import GenericViewSet
  16 from rest_framework_guardian.filters import ObjectPermissionsFilter
  17 
  18 from ephios.api.views.events import ParticipationSerializer
  19 from ephios.core.models import LocalParticipation, Qualification, UserProfile
  20 from ephios.core.services.qualification import collect_all_included_qualifications
  21 
  22 
  23 class QualificationSerializer(ModelSerializer):
  24     category = SlugRelatedField(slug_field="uuid", read_only=True)
  25     includes = SerializerMethodField()
  26 
  27     class Meta:
  28         model = Qualification
  29         fields = [
  30             "uuid",
  31             "title",
  32             "abbreviation",
  33             "category",
  34             "includes",
  35         ]
  36 
  37     def get_includes(self, obj):
  38         return [q.uuid for q in collect_all_included_qualifications(obj.includes.all())]
  39 
  40 
  41 class UserProfileSerializer(ModelSerializer):
  42     qualifications = SerializerMethodField()
  43 
  44     class Meta:
  45         model = UserProfile
  46         fields = [
  47             "id",
  48             "display_name",
  49             "date_of_birth",
  50             "email",
  51             "qualifications",
  52         ]
  53 
  54     def get_qualifications(self, obj):
  55         return QualificationSerializer(
  56             Qualification.objects.filter(
  57                 Q(grants__user=obj)
  58                 & (Q(grants__expires__gte=timezone.now()) | Q(grants__expires__isnull=True))
  59             ),
  60             many=True,
  61         ).data
  62 
  63 
  64 class UserProfileMeView(RetrieveAPIView):
  65     serializer_class = UserProfileSerializer
  66     queryset = UserProfile.objects.all()
  67     permission_classes = [IsAuthenticatedOrTokenHasScope]
  68     required_scopes = ["ME_READ"]
  69     schema = AutoSchema(operation_id_base="OwnUserProfile")
  70 
  71     def get_object(self):
  72         if self.request.user is None:
  73             raise PermissionDenied()
  74         return self.request.user
  75 
  76 
  77 class UserViewSet(viewsets.ReadOnlyModelViewSet):
  78     serializer_class = UserProfileSerializer
  79     queryset = UserProfile.objects.all()
  80     permission_classes = [IsAuthenticatedOrTokenHasScope, DjangoObjectPermissions]
  81     required_scopes = ["CONFIDENTIAL_READ"]
  82     search_fields = ["display_name", "email"]
  83 
  84     filter_backends = [
  85         DjangoFilterBackend,
  86         SearchFilter,
  87         ObjectPermissionsFilter,
  88     ]
  89 
  90 
  91 class UserByMailView(RetrieveModelMixin, GenericViewSet):
  92     serializer_class = UserProfileSerializer
  93     queryset = UserProfile.objects.all()
  94     permission_classes = [IsAuthenticatedOrTokenHasScope, DjangoObjectPermissions]
  95     required_scopes = ["CONFIDENTIAL_READ"]
  96     filter_backends = [ObjectPermissionsFilter]
  97     lookup_url_kwarg = "email"
  98     lookup_field = "email"
  99     schema = AutoSchema(operation_id_base="UserProfileByMail")
  100 
  101 
  102 class UserParticipationView(viewsets.ReadOnlyModelViewSet):
  103     serializer_class = ParticipationSerializer
  104     permission_classes = [IsAuthenticatedOrTokenHasScope]
  105     filter_backends = [ObjectPermissionsFilter, DjangoFilterBackend]
  106     filterset_fields = ["state"]
  107     required_scopes = ["CONFIDENTIAL_READ"]
  108 
  109     def get_queryset(self):
  110         return LocalParticipation.objects.filter(user=self.kwargs.get("user"))
  111
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/ephios/api/views/users.py b/ephios/api/views/users.py
  --- a/ephios/api/views/users.py
  +++ b/ephios/api/views/users.py
  @@ -96,6 +96,7 @@
       filter_backends = [ObjectPermissionsFilter]
       lookup_url_kwarg = "email"
       lookup_field = "email"
  +    lookup_value_regex = "[^/]+"  # customize to allow dots (".") in the lookup value
       schema = AutoSchema(operation_id_base="UserProfileByMail")
  
verification_info: {"golden_diff": "diff --git a/ephios/api/views/users.py b/ephios/api/views/users.py\n--- a/ephios/api/views/users.py\n+++ b/ephios/api/views/users.py\n@@ -96,6 +96,7 @@\n     filter_backends = [ObjectPermissionsFilter]\n     lookup_url_kwarg = \"email\"\n     lookup_field = \"email\"\n+    lookup_value_regex = \"[^/]+\"  # customize to allow dots (\".\") in the lookup value\n     schema = AutoSchema(operation_id_base=\"UserProfileByMail\")\n", "issue": "API: `/api/users/by_email` returns 404 error for email addresses with dots before the @\n**Describe the bug**\r\nA clear and concise description of what the bug is.\r\n\r\n**To Reproduce**\r\nSteps to reproduce the behavior:\r\n1. Go to `[ephios-url]/api/users/by_email/vorname.nachname@url.de/`\r\n\r\n**Expected behaviour**\r\nAssuming the user exists, the information about the user should be returned.\r\n\r\n**Screenshots**\r\nInstead the page 404s.\r\n\r\n<img width=\"1511\" alt=\"Screenshot 2024-03-27 at 18 54 08\" src=\"https://github.com/ephios-dev/ephios/assets/2546622/1383feee-28b0-4825-a31e-c39e2cc3f2ab\">\r\n\r\n**Environment**\r\nState which device, operating system, browser and browser version you are using.\r\nMacOS 14.2.1 (23C71), Version 17.2.1 (19617.1.17.11.12)\r\n\r\n**Additional context**\r\n* The problem does not appear for the test emails `usaaa@localhost/`, `admin@localhost/` or `user@localhost.com`.\n", "before_files": [{"content": "from django.db.models import Q\nfrom django.utils import timezone\nfrom django_filters.rest_framework import DjangoFilterBackend\nfrom oauth2_provider.contrib.rest_framework import IsAuthenticatedOrTokenHasScope\nfrom rest_framework import viewsets\nfrom rest_framework.exceptions import PermissionDenied\nfrom rest_framework.fields import SerializerMethodField\nfrom rest_framework.filters import SearchFilter\nfrom rest_framework.generics import RetrieveAPIView\nfrom rest_framework.mixins import RetrieveModelMixin\nfrom rest_framework.permissions import DjangoObjectPermissions\nfrom rest_framework.relations import SlugRelatedField\nfrom rest_framework.schemas.openapi import AutoSchema\nfrom rest_framework.serializers import ModelSerializer\nfrom rest_framework.viewsets import GenericViewSet\nfrom rest_framework_guardian.filters import ObjectPermissionsFilter\n\nfrom ephios.api.views.events import ParticipationSerializer\nfrom ephios.core.models import LocalParticipation, Qualification, UserProfile\nfrom ephios.core.services.qualification import collect_all_included_qualifications\n\n\nclass QualificationSerializer(ModelSerializer):\n    category = SlugRelatedField(slug_field=\"uuid\", read_only=True)\n    includes = SerializerMethodField()\n\n    class Meta:\n        model = Qualification\n        fields = [\n            \"uuid\",\n            \"title\",\n            \"abbreviation\",\n            \"category\",\n            \"includes\",\n        ]\n\n    def get_includes(self, obj):\n        return [q.uuid for q in collect_all_included_qualifications(obj.includes.all())]\n\n\nclass UserProfileSerializer(ModelSerializer):\n    qualifications = SerializerMethodField()\n\n    class Meta:\n        model = UserProfile\n        fields = [\n            \"id\",\n            \"display_name\",\n            \"date_of_birth\",\n            \"email\",\n            \"qualifications\",\n        ]\n\n    def get_qualifications(self, obj):\n        return QualificationSerializer(\n            Qualification.objects.filter(\n                Q(grants__user=obj)\n                & (Q(grants__expires__gte=timezone.now()) | Q(grants__expires__isnull=True))\n            ),\n            many=True,\n        ).data\n\n\nclass UserProfileMeView(RetrieveAPIView):\n    serializer_class = UserProfileSerializer\n    queryset = UserProfile.objects.all()\n    permission_classes = [IsAuthenticatedOrTokenHasScope]\n    required_scopes = [\"ME_READ\"]\n    schema = AutoSchema(operation_id_base=\"OwnUserProfile\")\n\n    def get_object(self):\n        if self.request.user is None:\n            raise PermissionDenied()\n        return self.request.user\n\n\nclass UserViewSet(viewsets.ReadOnlyModelViewSet):\n    serializer_class = UserProfileSerializer\n    queryset = UserProfile.objects.all()\n    permission_classes = [IsAuthenticatedOrTokenHasScope, DjangoObjectPermissions]\n    required_scopes = [\"CONFIDENTIAL_READ\"]\n    search_fields = [\"display_name\", \"email\"]\n\n    filter_backends = [\n        DjangoFilterBackend,\n        SearchFilter,\n        ObjectPermissionsFilter,\n    ]\n\n\nclass UserByMailView(RetrieveModelMixin, GenericViewSet):\n    serializer_class = UserProfileSerializer\n    queryset = UserProfile.objects.all()\n    permission_classes = [IsAuthenticatedOrTokenHasScope, DjangoObjectPermissions]\n    required_scopes = [\"CONFIDENTIAL_READ\"]\n    filter_backends = [ObjectPermissionsFilter]\n    lookup_url_kwarg = \"email\"\n    lookup_field = \"email\"\n    schema = AutoSchema(operation_id_base=\"UserProfileByMail\")\n\n\nclass UserParticipationView(viewsets.ReadOnlyModelViewSet):\n    serializer_class = ParticipationSerializer\n    permission_classes = [IsAuthenticatedOrTokenHasScope]\n    filter_backends = [ObjectPermissionsFilter, DjangoFilterBackend]\n    filterset_fields = [\"state\"]\n    required_scopes = [\"CONFIDENTIAL_READ\"]\n\n    def get_queryset(self):\n        return LocalParticipation.objects.filter(user=self.kwargs.get(\"user\"))\n", "path": "ephios/api/views/users.py"}], "after_files": [{"content": "from django.db.models import Q\nfrom django.utils import timezone\nfrom django_filters.rest_framework import DjangoFilterBackend\nfrom oauth2_provider.contrib.rest_framework import IsAuthenticatedOrTokenHasScope\nfrom rest_framework import viewsets\nfrom rest_framework.exceptions import PermissionDenied\nfrom rest_framework.fields import SerializerMethodField\nfrom rest_framework.filters import SearchFilter\nfrom rest_framework.generics import RetrieveAPIView\nfrom rest_framework.mixins import RetrieveModelMixin\nfrom rest_framework.permissions import DjangoObjectPermissions\nfrom rest_framework.relations import SlugRelatedField\nfrom rest_framework.schemas.openapi import AutoSchema\nfrom rest_framework.serializers import ModelSerializer\nfrom rest_framework.viewsets import GenericViewSet\nfrom rest_framework_guardian.filters import ObjectPermissionsFilter\n\nfrom ephios.api.views.events import ParticipationSerializer\nfrom ephios.core.models import LocalParticipation, Qualification, UserProfile\nfrom ephios.core.services.qualification import collect_all_included_qualifications\n\n\nclass QualificationSerializer(ModelSerializer):\n    category = SlugRelatedField(slug_field=\"uuid\", read_only=True)\n    includes = SerializerMethodField()\n\n    class Meta:\n        model = Qualification\n        fields = [\n            \"uuid\",\n            \"title\",\n            \"abbreviation\",\n            \"category\",\n            \"includes\",\n        ]\n\n    def get_includes(self, obj):\n        return [q.uuid for q in collect_all_included_qualifications(obj.includes.all())]\n\n\nclass UserProfileSerializer(ModelSerializer):\n    qualifications = SerializerMethodField()\n\n    class Meta:\n        model = UserProfile\n        fields = [\n            \"id\",\n            \"display_name\",\n            \"date_of_birth\",\n            \"email\",\n            \"qualifications\",\n        ]\n\n    def get_qualifications(self, obj):\n        return QualificationSerializer(\n            Qualification.objects.filter(\n                Q(grants__user=obj)\n                & (Q(grants__expires__gte=timezone.now()) | Q(grants__expires__isnull=True))\n            ),\n            many=True,\n        ).data\n\n\nclass UserProfileMeView(RetrieveAPIView):\n    serializer_class = UserProfileSerializer\n    queryset = UserProfile.objects.all()\n    permission_classes = [IsAuthenticatedOrTokenHasScope]\n    required_scopes = [\"ME_READ\"]\n    schema = AutoSchema(operation_id_base=\"OwnUserProfile\")\n\n    def get_object(self):\n        if self.request.user is None:\n            raise PermissionDenied()\n        return self.request.user\n\n\nclass UserViewSet(viewsets.ReadOnlyModelViewSet):\n    serializer_class = UserProfileSerializer\n    queryset = UserProfile.objects.all()\n    permission_classes = [IsAuthenticatedOrTokenHasScope, DjangoObjectPermissions]\n    required_scopes = [\"CONFIDENTIAL_READ\"]\n    search_fields = [\"display_name\", \"email\"]\n\n    filter_backends = [\n        DjangoFilterBackend,\n        SearchFilter,\n        ObjectPermissionsFilter,\n    ]\n\n\nclass UserByMailView(RetrieveModelMixin, GenericViewSet):\n    serializer_class = UserProfileSerializer\n    queryset = UserProfile.objects.all()\n    permission_classes = [IsAuthenticatedOrTokenHasScope, DjangoObjectPermissions]\n    required_scopes = [\"CONFIDENTIAL_READ\"]\n    filter_backends = [ObjectPermissionsFilter]\n    lookup_url_kwarg = \"email\"\n    lookup_field = \"email\"\n    lookup_value_regex = \"[^/]+\"  # customize to allow dots (\".\") in the lookup value\n    schema = AutoSchema(operation_id_base=\"UserProfileByMail\")\n\n\nclass UserParticipationView(viewsets.ReadOnlyModelViewSet):\n    serializer_class = ParticipationSerializer\n    permission_classes = [IsAuthenticatedOrTokenHasScope]\n    filter_backends = [ObjectPermissionsFilter, DjangoFilterBackend]\n    filterset_fields = [\"state\"]\n    required_scopes = [\"CONFIDENTIAL_READ\"]\n\n    def get_queryset(self):\n        return LocalParticipation.objects.filter(user=self.kwargs.get(\"user\"))\n", "path": "ephios/api/views/users.py"}]}