From caeaf8d5a97bb588ef10a308cde365b8334519d1 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Sat, 9 May 2020 23:20:20 +0200 Subject: [PATCH] stages/identification: optimise User lookup query --- .../migrations/0003_auto_20200509_2025.py | 26 +++++++++++++++++++ passbook/stages/identification/stage.py | 15 ++++++----- 2 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 passbook/stages/identification/migrations/0003_auto_20200509_2025.py diff --git a/passbook/stages/identification/migrations/0003_auto_20200509_2025.py b/passbook/stages/identification/migrations/0003_auto_20200509_2025.py new file mode 100644 index 000000000..5f9672350 --- /dev/null +++ b/passbook/stages/identification/migrations/0003_auto_20200509_2025.py @@ -0,0 +1,26 @@ +# Generated by Django 3.0.3 on 2020-05-09 20:25 + +import django.contrib.postgres.fields +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("passbook_stages_identification", "0002_auto_20200509_1916"), + ] + + operations = [ + migrations.AlterField( + model_name="identificationstage", + name="user_fields", + field=django.contrib.postgres.fields.ArrayField( + base_field=models.CharField( + choices=[("email", "E Mail"), ("username", "Username")], + max_length=100, + ), + help_text="Fields of the user object to match against.", + size=None, + ), + ), + ] diff --git a/passbook/stages/identification/stage.py b/passbook/stages/identification/stage.py index 1bbd32143..dfe4965b7 100644 --- a/passbook/stages/identification/stage.py +++ b/passbook/stages/identification/stage.py @@ -2,6 +2,7 @@ from typing import List, Optional from django.contrib import messages +from django.db.models import Q from django.http import HttpResponse from django.utils.translation import gettext as _ from django.views.generic import FormView @@ -20,7 +21,6 @@ LOGGER = get_logger() class IdentificationStageView(FormView, AuthenticationStage): """Form to identify the user""" - template_name = "login/form.html" form_class = IdentificationForm def get_template_names(self) -> List[str]: @@ -31,6 +31,7 @@ class IdentificationStageView(FormView, AuthenticationStage): kwargs["config"] = CONFIG.y("passbook") kwargs["title"] = _("Log in to your account") kwargs["primary_action"] = _("Log in") + # TODO: show this based on the existence of an enrollment flow kwargs["show_sign_up_notice"] = CONFIG.y("passbook.sign_up.enabled") kwargs["sources"] = [] sources = ( @@ -42,14 +43,16 @@ class IdentificationStageView(FormView, AuthenticationStage): kwargs["sources"].append(ui_login_button) return super().get_context_data(**kwargs) - def get_user(self, uid_value) -> Optional[User]: + def get_user(self, uid_value: str) -> Optional[User]: """Find user instance. Returns None if no user was found.""" current_stage: IdentificationStage = self.executor.current_stage + query = Q() for search_field in current_stage.user_fields: - users = User.objects.filter(**{search_field: uid_value}) - if users.exists(): - LOGGER.debug("Found user", user=users.first(), uid_field=search_field) - return users.first() + query |= Q(**{search_field: uid_value}) + users = User.objects.filter(query) + if users.exists(): + LOGGER.debug("Found user", user=users.first(), query=query) + return users.first() return None def form_valid(self, form: IdentificationForm) -> HttpResponse: