diff --git a/apps/note/api/views.py b/apps/note/api/views.py index d4021210..5096d238 100644 --- a/apps/note/api/views.py +++ b/apps/note/api/views.py @@ -1,5 +1,6 @@ # Copyright (C) 2018-2021 by BDE ENS Paris-Saclay # SPDX-License-Identifier: GPL-3.0-or-later +import re from django.conf import settings from django.db.models import Q @@ -133,23 +134,31 @@ class ConsumerViewSet(ReadOnlyProtectedModelViewSet): if settings.DATABASES[queryset.db]["ENGINE"] == 'django.db.backends.postgresql' else queryset alias = self.request.query_params.get("alias", None) + # Check if this is a valid regex. If not, we won't check regex + try: + re.compile(alias) + valid_regex = True + except re.error: + valid_regex = False + suffix = '__iregex' if valid_regex else '__istartswith' + alias_prefix = '^' if valid_regex else '' queryset = queryset.prefetch_related('note') if alias: # We match first an alias if it is matched without normalization, # then if the normalized pattern matches a normalized alias. queryset = queryset.filter( - name__iregex="^" + alias + **{f'name{suffix}': alias_prefix + alias} ).union( queryset.filter( - Q(normalized_name__iregex="^" + Alias.normalize(alias)) - & ~Q(name__iregex="^" + alias) + Q(**{f'normalized_name{suffix}': alias_prefix + Alias.normalize(alias)}) + & ~Q(**{f'name{suffix}': alias_prefix + alias}) ), all=True).union( queryset.filter( - Q(normalized_name__iregex="^" + alias.lower()) - & ~Q(normalized_name__iregex="^" + Alias.normalize(alias)) - & ~Q(name__iregex="^" + alias) + Q(**{f'normalized_name{suffix}': alias_prefix + alias.lower()}) + & ~Q(**{f'normalized_name{suffix}': alias_prefix + Alias.normalize(alias)}) + & ~Q(**{f'name{suffix}': alias_prefix + alias}) ), all=True)