diff --git a/passbook/stages/identification/api.py b/passbook/stages/identification/api.py index f40c329e3..07f432497 100644 --- a/passbook/stages/identification/api.py +++ b/passbook/stages/identification/api.py @@ -15,6 +15,7 @@ class IdentificationStageSerializer(ModelSerializer): "pk", "name", "user_fields", + "case_insensitive_matching", "template", "enrollment_flow", "recovery_flow", diff --git a/passbook/stages/identification/forms.py b/passbook/stages/identification/forms.py index faf8389e6..a8827abd9 100644 --- a/passbook/stages/identification/forms.py +++ b/passbook/stages/identification/forms.py @@ -27,7 +27,14 @@ class IdentificationStageForm(forms.ModelForm): class Meta: model = IdentificationStage - fields = ["name", "user_fields", "template", "enrollment_flow", "recovery_flow"] + fields = [ + "name", + "user_fields", + "case_insensitive_matching", + "template", + "enrollment_flow", + "recovery_flow", + ] widgets = { "name": forms.TextInput(), "user_fields": FilteredSelectMultiple( diff --git a/passbook/stages/identification/migrations/0004_identificationstage_case_insensitive_matching.py b/passbook/stages/identification/migrations/0004_identificationstage_case_insensitive_matching.py new file mode 100644 index 000000000..43f6d591a --- /dev/null +++ b/passbook/stages/identification/migrations/0004_identificationstage_case_insensitive_matching.py @@ -0,0 +1,21 @@ +# Generated by Django 3.1.1 on 2020-09-30 21:44 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("passbook_stages_identification", "0003_auto_20200615_1641"), + ] + + operations = [ + migrations.AddField( + model_name="identificationstage", + name="case_insensitive_matching", + field=models.BooleanField( + default=True, + help_text="When enabled, user fields are matched regardless of their casing.", + ), + ), + ] diff --git a/passbook/stages/identification/models.py b/passbook/stages/identification/models.py index f4e6dccf5..70fc139f1 100644 --- a/passbook/stages/identification/models.py +++ b/passbook/stages/identification/models.py @@ -34,6 +34,13 @@ class IdentificationStage(Stage): ) template = models.TextField(choices=Templates.choices) + case_insensitive_matching = models.BooleanField( + default=True, + help_text=_( + "When enabled, user fields are matched regardless of their casing." + ), + ) + enrollment_flow = models.ForeignKey( Flow, on_delete=models.SET_DEFAULT, diff --git a/passbook/stages/identification/stage.py b/passbook/stages/identification/stage.py index 0394a9e47..2617e5bc3 100644 --- a/passbook/stages/identification/stage.py +++ b/passbook/stages/identification/stage.py @@ -70,7 +70,12 @@ class IdentificationStageView(FormView, StageView): current_stage: IdentificationStage = self.executor.current_stage query = Q() for search_field in current_stage.user_fields: - query |= Q(**{search_field: uid_value}) + model_field = search_field + if current_stage.case_insensitive_matching: + model_field += "__iexact" + else: + model_field += "__exact" + query |= Q(**{model_field: uid_value}) users = User.objects.filter(query) if users.exists(): LOGGER.debug("Found user", user=users.first(), query=query)