misc: unserialize attribute in registration view (#45710)
Registration view pass attribute values in JSON tokens, so we need to get a JSON compatible serialization of attribute values for the token using their serialization function.
This commit is contained in:
parent
d1b30f213c
commit
079102d851
|
@ -355,11 +355,15 @@ def get_form_field(kind, **kwargs):
|
|||
return defn['field_class'](**kwargs)
|
||||
|
||||
|
||||
def identity(x):
|
||||
return x
|
||||
|
||||
|
||||
def get_kind(kind):
|
||||
d = get_attribute_kinds()[kind]
|
||||
d.setdefault('default', None)
|
||||
d.setdefault('serialize', lambda x: x)
|
||||
d.setdefault('deserialize', lambda x: x)
|
||||
d.setdefault('serialize', identity)
|
||||
d.setdefault('deserialize', identity)
|
||||
rest_field_kwargs = d.setdefault('rest_framework_field_kwargs', {})
|
||||
if 'rest_framework_field_class' not in d:
|
||||
d['rest_framework_field_class'] = serializers.CharField
|
||||
|
|
|
@ -53,6 +53,12 @@ def get_attributes_map():
|
|||
return mapping
|
||||
|
||||
|
||||
def iter_attributes():
|
||||
for key, value in get_attributes_map().items():
|
||||
if isinstance(key, str):
|
||||
yield value
|
||||
|
||||
|
||||
class Attributes(object):
|
||||
def __init__(self, owner, verified=None):
|
||||
self.__dict__['owner'] = owner
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
import collections
|
||||
from email.utils import parseaddr
|
||||
import logging
|
||||
import random
|
||||
import re
|
||||
|
||||
from ratelimit.utils import is_ratelimited
|
||||
|
@ -28,8 +27,7 @@ from django.template.loader import render_to_string
|
|||
from django.views.generic.edit import UpdateView, FormView
|
||||
from django.views.generic import TemplateView
|
||||
from django.views.generic.base import View
|
||||
from django.contrib.auth import SESSION_KEY
|
||||
from django import http, shortcuts
|
||||
from django import shortcuts
|
||||
from django.core import signing
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.contrib import messages
|
||||
|
@ -42,7 +40,6 @@ from django.contrib.auth.views import PasswordChangeView as DjPasswordChangeView
|
|||
from django.http import (HttpResponseRedirect, HttpResponseForbidden, HttpResponse)
|
||||
from django.views.decorators.csrf import csrf_exempt, ensure_csrf_cookie
|
||||
from django.views.decorators.cache import never_cache
|
||||
from django.views.decorators.debug import sensitive_post_parameters
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.db.models.fields import FieldDoesNotExist
|
||||
from django.db.models.query import Q
|
||||
|
@ -54,9 +51,10 @@ from django.forms import CharField
|
|||
from django.http import HttpResponseBadRequest
|
||||
from django.template import loader
|
||||
|
||||
from authentic2.custom_user.models import iter_attributes
|
||||
from authentic2.compat.misc import default_token_generator
|
||||
from . import (utils, app_settings, decorators, constants,
|
||||
models, cbv, hooks, validators)
|
||||
models, cbv, hooks, validators, attribute_kinds)
|
||||
from .utils import switch_user
|
||||
from .a2_rbac.utils import get_default_ou
|
||||
from .a2_rbac.models import OrganizationalUnit as OU
|
||||
|
@ -1082,7 +1080,14 @@ class RegistrationCompletionView(CreateView):
|
|||
and ('email' not in self.token or self.request.POST['email'] != self.token['email'])
|
||||
and not self.token.get('skip_email_check')):
|
||||
# If an email is submitted it must be validated or be the same as in the token
|
||||
data = form.cleaned_data
|
||||
data = form.cleaned_data.copy()
|
||||
# handle complex attributes
|
||||
for attribute in iter_attributes():
|
||||
kind = attribute.get_kind()
|
||||
if kind['serialize'] == attribute_kinds.identity:
|
||||
continue
|
||||
data[attribute.name] = kind['serialize'](data[attribute.name])
|
||||
|
||||
data['no_password'] = self.token.get('no_password', False)
|
||||
utils.send_registration_mail(
|
||||
self.request,
|
||||
|
|
|
@ -15,8 +15,6 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import re
|
||||
|
||||
from django.contrib.auth import get_user_model, REDIRECT_FIELD_NAME
|
||||
from django.urls import reverse
|
||||
from django.utils.http import urlquote
|
||||
|
@ -28,6 +26,9 @@ from authentic2.validators import EmailValidator
|
|||
from .utils import get_link_from_mail
|
||||
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
def test_registration(app, db, settings, mailoutbox, external_redirect):
|
||||
next_url, good_next_url = external_redirect
|
||||
|
||||
|
@ -37,7 +38,6 @@ def test_registration(app, db, settings, mailoutbox, external_redirect):
|
|||
# disable existing attributes
|
||||
models.Attribute.objects.update(disabled=True)
|
||||
|
||||
User = get_user_model()
|
||||
url = utils.make_url('registration_register', params={REDIRECT_FIELD_NAME: next_url})
|
||||
response = app.get(url)
|
||||
response.form.set('email', 'testbot@entrouvert.com')
|
||||
|
@ -109,7 +109,6 @@ def test_registration_realm(app, db, settings, mailoutbox):
|
|||
# disable existing attributes
|
||||
models.Attribute.objects.update(disabled=True)
|
||||
|
||||
User = get_user_model()
|
||||
next_url = 'http://relying-party.org/'
|
||||
url = utils.make_url('registration_register', params={REDIRECT_FIELD_NAME: next_url})
|
||||
|
||||
|
@ -494,7 +493,6 @@ def test_email_is_unique_multiple_objects_returned(app, db, settings, mailoutbox
|
|||
settings.A2_REGISTRATION_EMAIL_IS_UNIQUE = True
|
||||
|
||||
# Create two user objects
|
||||
User = get_user_model()
|
||||
User.objects.create(email='testbot@entrouvert.com')
|
||||
User.objects.create(email='testbot@entrouvert.com')
|
||||
|
||||
|
@ -518,7 +516,6 @@ def test_username_is_unique_multiple_objects_returned(app, db, settings, mailout
|
|||
settings.A2_REQUIRED_FIELDS = ['username', 'first_name', 'last_name']
|
||||
|
||||
# Create two user objects
|
||||
User = get_user_model()
|
||||
User.objects.create(username='testbot', email='testbot1@entrouvert.com')
|
||||
User.objects.create(username='testbot', email='testbot2@entrouvert.com')
|
||||
|
||||
|
@ -550,7 +547,6 @@ def test_registration_redirect(app, db, settings, mailoutbox, external_redirect)
|
|||
# disable existing attributes
|
||||
models.Attribute.objects.update(disabled=True)
|
||||
|
||||
User = get_user_model()
|
||||
url = utils.make_url('registration_register', params={REDIRECT_FIELD_NAME: next_url})
|
||||
response = app.get(url)
|
||||
response.form.set('email', 'testbot@entrouvert.com')
|
||||
|
@ -674,8 +670,42 @@ def test_registration_with_email_suggestions(app, db, settings):
|
|||
assert "email_domains_suggestions.js" in response.text
|
||||
assert "field-live-hint" in response.text
|
||||
|
||||
|
||||
settings.A2_SUGGESTED_EMAIL_DOMAINS = []
|
||||
response = app.get(url)
|
||||
assert "email_domains_suggestions.js" not in response.text
|
||||
assert "field-live-hint" not in response.text
|
||||
|
||||
|
||||
def test_registration_no_email_full_profile_no_password(app, db, rf, mailoutbox):
|
||||
models.Attribute.objects.create(
|
||||
kind='birthdate',
|
||||
name='birthdate',
|
||||
label='birthdate',
|
||||
required=True)
|
||||
|
||||
data = {
|
||||
'email': 'john.doe@example.com',
|
||||
'first_name': 'John',
|
||||
'last_name': 'Doe',
|
||||
'confirm_data': 'required',
|
||||
'no_password': True,
|
||||
'valid_email': False,
|
||||
'franceconnect': True,
|
||||
'authentication_method': 'france-connect',
|
||||
}
|
||||
|
||||
activation_url = utils.build_activation_url(
|
||||
rf.post('/accounts/register/'),
|
||||
next_url='/',
|
||||
**data)
|
||||
|
||||
response = app.get(activation_url)
|
||||
response.form.set('first_name', data['first_name'])
|
||||
response.form.set('last_name', data['last_name'])
|
||||
response.form.set('birthdate', '1981-01-01')
|
||||
response.form.set('email', 'john.doe2@example.com')
|
||||
response = response.form.submit().follow()
|
||||
link = get_link_from_mail(mailoutbox[0])
|
||||
response = app.get(link)
|
||||
assert response.location == '/'
|
||||
assert User.objects.count() == 1
|
||||
|
|
Loading…
Reference in New Issue