-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Connexion: Nouveau parcours pour les candidats [GEN-2012] #5288
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,9 @@ | ||
{# django-allauth template override. #} | ||
{% extends "layout/base.html" %} | ||
{% load static %} | ||
{% load django_bootstrap5 %} | ||
{% load redirection_fields %} | ||
{% load buttons_form %} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔡 |
||
|
||
{% block title %}Connexion candidat {{ block.super }}{% endblock %} | ||
|
||
|
@@ -12,31 +15,41 @@ | |
<div class="s-section__row row"> | ||
<div class="s-section__col col-12 col-lg-6"> | ||
<div class="c-form mb-5"> | ||
<p class="h4">Se connecter avec FranceConnect</p> | ||
{% if show_france_connect %} | ||
<div class="mt-4">{% include "signup/includes/france_connect_button.html" %}</div> | ||
{% else %} | ||
<div class="alert alert-info" role="status"> | ||
<p class="mb-0">FranceConnect est désactivé.</p> | ||
</div> | ||
{% endif %} | ||
<hr class="my-5" data-it-text="ou"> | ||
<p class="h4 text-primary">Quelle adresse mail utilisez-vous ?</p> | ||
<p class="text-secondary fs-sm"> | ||
Si vous avec un compte <strong>France Travail</strong> ou <strong>FranceConnect</strong> et que vous souhaitez vous connecter avec ce compte, | ||
merci de renseigner dans ce champs l’adresse e-mail qui y est associé. | ||
</p> | ||
|
||
<form method="post" class="js-prevent-multiple-submit"> | ||
{% csrf_token %} | ||
{% redirection_input_field value=redirect_field_value %} | ||
|
||
<p class="h4">Se connecter avec France Travail</p> | ||
{% if show_peamu %} | ||
<div class="row mt-3"> | ||
<div class="col-sm"> | ||
<div class="text-center">{% include "signup/includes/peamu_button.html" %}</div> | ||
<div class="form-group mb-1 form-group-required text-primary"> | ||
{% bootstrap_label "Adresse e-mail" label_for="id_email" %} | ||
{% bootstrap_field form.email wrapper_class="form-group mb-0" show_label=False %} | ||
<div class="form-text mb-3"> | ||
<div class="text-end mt-1"> | ||
<a href="#" class="fs-sm text-secondary" data-bs-toggle="modal" data-bs-target="#no-email-modal">Pas d'adresse e-mail ?</a> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pour contrôler une modale, plutôt utiliser un |
||
</div> | ||
{% include "signup/includes/no_email_link.html" with exclude_button=True only %} | ||
</div> | ||
</div> | ||
{% else %} | ||
<div class="alert alert-info" role="status"> | ||
<p class="mb-0">France Travail est désactivé.</p> | ||
</div> | ||
{% endif %} | ||
<hr class="my-5" data-it-text="ou"> | ||
{% url 'home:hp' as reset_url %} | ||
{% itou_buttons_form primary_label="Suivant" reset_url=reset_url %} | ||
|
||
{% include "account/includes/login_form.html" %} | ||
<div class="mt-5 mb-5 text-end text-primary"> | ||
<p> | ||
Vous n'avez pas de compte ? <a href="{% url 'signup:job_seeker_situation' %}">Inscription</a> | ||
</p> | ||
</div> | ||
</form> | ||
</div> | ||
</div> | ||
<!-- Hide left column on small devices. --> | ||
<div class="d-none d-lg-inline-flex align-items-center col-lg-6 justify-content-center"> | ||
<div class="w-75"> | ||
<img class="img-fluid img-fitcover" src="{% static 'img/login.svg' %}" alt=""> | ||
</div> | ||
</div> | ||
</div> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{% load static %} | ||
{% load theme_inclusion %} | ||
{% load django_bootstrap5 %} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔤 |
||
|
||
<div class="modal-dialog modal-dialog-centered"> | ||
<div class="modal-content"> | ||
<div class="modal-header"> | ||
<h3 class="modal-title" id="message-modal-{{ forloop.counter }}-label"> | ||
{% if "email_does_not_exist" in message.extra_tags %} | ||
Adresse e-mail inconnue | ||
{% else %} | ||
Le connexion a échoué | ||
{% endif %} | ||
</h3> | ||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button> | ||
</div> | ||
{{ message }} | ||
</div> | ||
</div> |
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -1,13 +1,57 @@ | ||||||||||
from allauth.account.forms import LoginForm | ||||||||||
from django import forms | ||||||||||
from django.conf import settings | ||||||||||
from django.contrib import messages | ||||||||||
from django.core.exceptions import ValidationError | ||||||||||
from django.urls import reverse | ||||||||||
from django.utils.html import format_html | ||||||||||
from django.utils.safestring import mark_safe | ||||||||||
|
||||||||||
from itou.openid_connect.errors import format_error_modal_content | ||||||||||
from itou.users.enums import IdentityProvider | ||||||||||
from itou.users.models import User | ||||||||||
|
||||||||||
|
||||||||||
class FindExistingUserViaEmailForm(forms.Form): | ||||||||||
""" | ||||||||||
Validates only the email field. Displays a modal to user if email not in use | ||||||||||
""" | ||||||||||
|
||||||||||
email = forms.EmailField( | ||||||||||
label="Adresse e-mail", | ||||||||||
required=True, | ||||||||||
widget=forms.TextInput( | ||||||||||
attrs={"type": "email", "placeholder": "[email protected]", "autocomplete": "email", "autofocus": True} | ||||||||||
), | ||||||||||
) | ||||||||||
|
||||||||||
def __init__(self, *args, **kwargs): | ||||||||||
self.request = kwargs.pop("request", None) | ||||||||||
Comment on lines
+28
to
+29
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
super().__init__(*args, **kwargs) | ||||||||||
|
||||||||||
def clean_email(self): | ||||||||||
email = self.cleaned_data.get("email") | ||||||||||
self.user = User.objects.filter(email__iexact=email).first() | ||||||||||
if self.user is None: | ||||||||||
messages.error( | ||||||||||
self.request, | ||||||||||
format_error_modal_content( | ||||||||||
mark_safe( | ||||||||||
"<p>Cette adresse e-mail est inconnue de nos services.</p>" | ||||||||||
"<p>Si vous êtes déjà inscrit(e), " | ||||||||||
"assurez-vous de saisir correctement votre adresse e-mail.</p>" | ||||||||||
"<p>Si vous n'êtes pas encore inscrit(e), " | ||||||||||
"nous vous invitons à cliquer sur Inscription pour créer votre compte.</p>" | ||||||||||
), | ||||||||||
reverse("signup:job_seeker_situation"), | ||||||||||
"Inscription", | ||||||||||
), | ||||||||||
extra_tags="modal login_failure email_does_not_exist", | ||||||||||
) | ||||||||||
raise ValidationError("Cette adresse e-mail est inconnue. Veuillez soumettre une autre, ou vous inscrire.") | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
return email | ||||||||||
|
||||||||||
|
||||||||||
class ItouLoginForm(LoginForm): | ||||||||||
# Hidden field allowing demo prescribers and employers to log in using the banner form | ||||||||||
demo_banner_account = forms.BooleanField(widget=forms.HiddenInput(), required=False) | ||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -196,7 +196,6 @@ def __init__(self, prior_cleaned_data, *args, **kwargs): | |
self.fields["birthdate"].initial = prior_cleaned_data.get("birthdate") | ||
self.fields["nir"].initial = prior_cleaned_data.get("nir") | ||
|
||
# self.fields["password1"].help_text = CnilCompositionPasswordValidator().get_help_text() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👀 |
||
for password_field in [self.fields["password1"], self.fields["password2"]]: | ||
password_field.widget.attrs["placeholder"] = "**********" | ||
self.fields["password1"].help_text = CnilCompositionPasswordValidator().get_help_text() | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -208,19 +208,36 @@ def test_login(self, client): | |
assertRedirects(response, reverse("account_email_verification_sent")) | ||
|
||
|
||
class TestJopbSeekerLogin: | ||
def test_login(self, client): | ||
class TestJobSeekerPreLogin: | ||
def test_pre_login_email_invalid(self, client): | ||
form_data = {"email": "emailinvalid"} | ||
response = client.post(reverse("login:job_seeker"), data=form_data) | ||
assert response.status_code == 200 | ||
assert response.context["form"].errors["email"] == ["Saisissez une adresse e-mail valide."] | ||
|
||
def test_pre_login_redirects_to_existing_user(self, client): | ||
user = JobSeekerFactory() | ||
url = reverse("login:job_seeker") | ||
response = client.get(url) | ||
assert response.status_code == 200 | ||
|
||
form_data = { | ||
"login": user.email, | ||
"password": DEFAULT_PASSWORD, | ||
} | ||
form_data = {"email": user.email} | ||
response = client.post(url, data=form_data) | ||
assertRedirects(response, reverse("account_email_verification_sent")) | ||
assertRedirects(response, f'{reverse("login:existing_user", args=(user.public_id,))}?back_url={url}') | ||
|
||
def test_pre_login_email_unknown(self, client, snapshot): | ||
url = reverse("login:job_seeker") | ||
response = client.get(url) | ||
|
||
form_data = {"email": "[email protected]"} | ||
response = client.post(url, data=form_data) | ||
assert response.status_code == 200 | ||
|
||
assert response.context["form"].errors["email"] == [ | ||
"Cette adresse e-mail est inconnue. Veuillez soumettre une autre, ou vous inscrire." | ||
] | ||
assertMessages(response, [messages.Message(messages.ERROR, snapshot)]) | ||
assertContains(response, reverse("signup:job_seeker_situation")) | ||
|
||
@respx.mock | ||
@override_settings( | ||
|
@@ -290,6 +307,19 @@ def test_login(self, client, snapshot, identity_provider): | |
assertNotContains(response, self.UNSUPPORTED_IDENTITY_PROVIDER_TEXT) | ||
assert str(parse_response_to_soup(response, selector=".c-form")) == snapshot | ||
|
||
def test_login_django(self, client): | ||
user = JobSeekerFactory(identity_provider=IdentityProvider.DJANGO) | ||
url = reverse("login:existing_user", args=(user.public_id,)) | ||
response = client.get(url) | ||
assert response.status_code == 200 | ||
|
||
form_data = { | ||
"login": user.email, | ||
"password": DEFAULT_PASSWORD, | ||
} | ||
response = client.post(url, data=form_data) | ||
assertRedirects(response, reverse("account_email_verification_sent")) | ||
|
||
@pytest.mark.parametrize( | ||
"identity_provider", | ||
[ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
J'ai l'impression qu'une partie de mise à jour de wording (et d'image) pourrait facilement être sortie dans un commit séparé (voir même une PR ?) .