stages/identification: optimise User lookup query

This commit is contained in:
Jens Langhammer 2020-05-09 23:20:20 +02:00
parent c46f0781fc
commit caeaf8d5a9
2 changed files with 35 additions and 6 deletions

View File

@ -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,
),
),
]

View File

@ -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: