auth_fc: ignore invalid emails (#49623) #191

Merged
bdauvergne merged 1 commits from wip/49623-comme-adresse-email-IndexError into main 2023-11-29 14:00:56 +01:00
3 changed files with 49 additions and 1 deletions

View File

@ -27,6 +27,7 @@ import uuid
import requests
from django.conf import settings
from django.core.exceptions import ValidationError
from django.shortcuts import resolve_url
from django.urls import reverse
from django.utils.encoding import force_bytes, force_str
@ -36,6 +37,7 @@ from django.utils.translation import gettext_lazy as _
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry # pylint: disable=import-error
from authentic2.validators import email_validator
from authentic2_auth_oidc.utils import parse_timestamp
from . import app_settings
@ -148,6 +150,13 @@ def apply_user_info_mappings(user, user_info):
if mapping.get('if-tag') and mapping['if-tag'] not in tags:
continue
if attribute == 'email':
try:
email_validator(value)
except ValidationError:
logger.warning('auth_fc: invalid email "%s" was ignored', value)
continue
if attribute == 'password':
if mapping.get('if-empty') and user.has_usable_password():
continue

View File

@ -23,7 +23,7 @@ from django.contrib import messages
from django.contrib.auth import get_user_model
from django.contrib.auth.views import update_session_auth_hash
from django.core.cache import cache
from django.core.exceptions import PermissionDenied
from django.core.exceptions import PermissionDenied, ValidationError
from django.db import IntegrityError, transaction
from django.forms import Form
from django.http import Http404, HttpResponseRedirect
@ -45,6 +45,7 @@ from authentic2.utils import hooks
from authentic2.utils import misc as utils_misc
from authentic2.utils import views as utils_views
from authentic2.utils.crypto import check_hmac_url, hash_chain, hmac_url
from authentic2.validators import email_validator
from . import app_settings, models, utils
from .utils import (
@ -436,6 +437,12 @@ class LoginOrLinkView(View):
def create_account(self, request, sub, token, user_info):
email = user_info.get('email')
try:
email_validator(email)
except ValidationError:
logger.warning('auth_fc: invalid email "%s" was ignored on creation', email)
email = None
if email:
# try to create or find an user with this email
try:

View File

@ -16,6 +16,7 @@
import datetime
import json
import logging
import os
import re
import urllib.parse
@ -877,3 +878,34 @@ def test_fc_authenticator_data_migration_fixup(migration, settings):
authenticator = FcAuthenticator.objects.get()
assert authenticator.slug == 'fc-authenticator'
assert authenticator.client_id == '211286433e39cce01db448d80181bdfd005554b19cd51b3fe7943f6b3b86ab6k'
def test_bad_email_handling(settings, app, franceconnect, caplog):
caplog.set_level(logging.WARNING)
# On creation
franceconnect.user_info['email'] = '@'
response = app.get('/login/?next=/idp/')
response = response.click(href='callback')
response = franceconnect.handle_authorization(app, response.location, status=302)
user = User.objects.get()
assert user.email == ''
assert caplog.text.count('invalid email')
caplog.clear()
app.session.flush()
user.email = 'john.doe@example.com'
user.save()
# On update
response = app.get('/login/?next=/idp/')
response = response.click(href='callback')
response = franceconnect.handle_authorization(app, response.location, status=302)
user = User.objects.get()
assert user.email == 'john.doe@example.com'
assert caplog.text.count('invalid email')