diff --git a/authentik/stages/identification/migrations/0008_alter_identificationstage_user_fields.py b/authentik/stages/identification/migrations/0008_alter_identificationstage_user_fields.py new file mode 100644 index 000000000..d9a810e2b --- /dev/null +++ b/authentik/stages/identification/migrations/0008_alter_identificationstage_user_fields.py @@ -0,0 +1,27 @@ +# Generated by Django 3.2 on 2021-04-29 22:56 + +import django.contrib.postgres.fields +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("authentik_stages_identification", "0007_remove_identificationstage_template"), + ] + + 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, + ), + blank=True, + help_text="Fields of the user object to match against. (Hold shift to select multiple options)", + size=None, + ), + ), + ] diff --git a/authentik/stages/identification/models.py b/authentik/stages/identification/models.py index c00f3e2b8..db7b78e3d 100644 --- a/authentik/stages/identification/models.py +++ b/authentik/stages/identification/models.py @@ -22,6 +22,7 @@ class IdentificationStage(Stage): user_fields = ArrayField( models.CharField(max_length=100, choices=UserFields.choices), + blank=True, help_text=_( ( "Fields of the user object to match against. " diff --git a/authentik/stages/identification/stage.py b/authentik/stages/identification/stage.py index fb56cc21b..8a1b677c6 100644 --- a/authentik/stages/identification/stage.py +++ b/authentik/stages/identification/stage.py @@ -7,7 +7,7 @@ from django.db.models import Q from django.http import HttpResponse from django.urls import reverse from django.utils.translation import gettext as _ -from rest_framework.fields import CharField +from rest_framework.fields import CharField, ListField from rest_framework.serializers import ValidationError from structlog.stdlib import get_logger @@ -28,7 +28,7 @@ LOGGER = get_logger() class IdentificationChallenge(Challenge): """Identification challenges with all UI elements""" - input_type = CharField() + user_fields = ListField(CharField(), allow_empty=True, allow_null=True) application_pre = CharField(required=False) enroll_url = CharField(required=False) @@ -83,11 +83,9 @@ class IdentificationStageView(ChallengeStageView): "type": ChallengeTypes.NATIVE.value, "component": "ak-stage-identification", "primary_action": _("Log in"), - "input_type": "text", + "user_fields": current_stage.user_fields, } ) - if current_stage.user_fields == [UserFields.E_MAIL]: - challenge.initial_data["input_type"] = "email" # If the user has been redirected to us whilst trying to access an # application, SESSION_KEY_APPLICATION_PRE is set in the session if SESSION_KEY_APPLICATION_PRE in self.request.session: diff --git a/swagger.yaml b/swagger.yaml index 0269141a2..b5ee65cab 100755 --- a/swagger.yaml +++ b/swagger.yaml @@ -17950,7 +17950,6 @@ definitions: IdentificationStage: required: - name - - user_fields type: object properties: pk: diff --git a/web/src/flows/stages/identification/IdentificationStage.ts b/web/src/flows/stages/identification/IdentificationStage.ts index c44511052..8dc3035a6 100644 --- a/web/src/flows/stages/identification/IdentificationStage.ts +++ b/web/src/flows/stages/identification/IdentificationStage.ts @@ -22,7 +22,7 @@ export const PasswordManagerPrefill: { export interface IdentificationChallenge extends Challenge { - input_type: string; + user_fields?: string[]; primary_action: string; sources?: UILoginButton[]; @@ -154,6 +154,43 @@ export class IdentificationStage extends BaseStage { `; } + renderInput(): TemplateResult { + let label = ""; + let type = "text"; + if (!this.challenge?.user_fields) { + return html`

+ ${t`Select one of the sources below to login.`} +

`; + } + if (this.challenge?.user_fields === ["email"]) { + label = t`Email`; + type = "email"; + } else if (this.challenge?.user_fields === ["username"]) { + label = t`Username`; + } else { + label = t`Email or username`; + } + return html` + + + +
+ +
`; + } + render(): TemplateResult { if (!this.challenge) { return html``: html``} - - - - - -
- -
+ ${this.renderInput()}