Projet

Général

Profil

0001-django-registration-dependency-removed-with-however-.patch

Serghei Mihai (congés, retour 15/05), 09 septembre 2014 14:56

Télécharger (33,2 ko)

Voir les différences:

Subject: [PATCH 1/2] django-registration dependency removed with, however,
 some concepts taken from it

 authentic2/app_settings.py                         |   8 +-
 authentic2/registration_backend/__init__.py        |  59 -----------
 .../registration_backend/default/__init__.py       |   0
 authentic2/registration_backend/default/forms.py   |  83 +++++++++++++++
 authentic2/registration_backend/default/models.py  |  73 ++++++++++++++
 authentic2/registration_backend/default/views.py   |  58 +++++++++++
 authentic2/registration_backend/forms.py           |  90 ++---------------
 authentic2/registration_backend/models.py          |  56 +++++++++++
 authentic2/registration_backend/urls.py            |  34 +++----
 authentic2/registration_backend/views.py           | 112 ++++++++-------------
 authentic2/utils.py                                |   5 +
 requirements.txt                                   |   1 -
 setup.py                                           |   1 -
 13 files changed, 342 insertions(+), 238 deletions(-)
 create mode 100644 authentic2/registration_backend/default/__init__.py
 create mode 100644 authentic2/registration_backend/default/forms.py
 create mode 100644 authentic2/registration_backend/default/models.py
 create mode 100644 authentic2/registration_backend/default/views.py
 create mode 100644 authentic2/registration_backend/models.py
authentic2/app_settings.py
88 88
            'See http://www.openssl.org/docs/apps/verify.html#item__CApath'),
89 89
    A2_REGISTRATION_URLCONF = Setting(default='authentic2.registration_backend.urls',
90 90
                definition='Root urlconf for the /accounts endpoints'),
91
    A2_REGISTRATION_FORM_CLASS = Setting(default='authentic2.registration_backend.forms.RegistrationForm',
91
    A2_REGISTRATION_BACKEND = Setting(default='default',
92
                definition='Backend for user\'s registration'),
93
    A2_REGISTRATION_FORM_CLASS = Setting(default='authentic2.registration_backend.default.forms.RegistrationForm',
92 94
                definition='Default registration form'),
93
    A2_REGISTRATION_SET_PASSWORD_FORM_CLASS = Setting(default='authentic2.registration_backend.forms.SetPasswordForm',
95
    A2_REGISTRATION_SET_PASSWORD_FORM_CLASS = Setting(default='authentic2.registration_backend.default.forms.SetPasswordForm',
94 96
                definition='Default set password form'),
95
    A2_REGISTRATION_CHANGE_PASSWORD_FORM_CLASS = Setting(default='authentic2.registration_backend.forms.PasswordChangeForm',
97
    A2_REGISTRATION_CHANGE_PASSWORD_FORM_CLASS = Setting(default='authentic2.registration_backend.default.forms.PasswordChangeForm',
96 98
                definition='Default change password form'),
97 99
    A2_REGISTRATION_CAN_DELETE_ACCOUNT = Setting(default=True,
98 100
                definition='Can user self delete their account and all their data'),
authentic2/registration_backend/__init__.py
1
from django.conf import settings
2
from django.template.loader import render_to_string
3 1

  
4
from registration.models import RegistrationProfile
5

  
6
def send_activation_email(self, site):
7
    """
8
    Send an activation email to the user associated with this
9
    ``RegistrationProfile``.
10
    
11
    The activation email will make use of two templates:
12

  
13
    ``registration/activation_email_subject.txt``
14
        This template will be used for the subject line of the
15
        email. Because it is used as the subject line of an email,
16
        this template's output **must** be only a single line of
17
        text; output longer than one line will be forcibly joined
18
        into only a single line.
19

  
20
    ``registration/activation_email.txt``
21
        This template will be used for the body of the email.
22

  
23
    These templates will each receive the following context
24
    variables:
25

  
26
    ``user``
27
        The new user account
28

  
29
    ``activation_key``
30
        The activation key for the new account.
31

  
32
    ``expiration_days``
33
        The number of days remaining during which the account may
34
        be activated.
35

  
36
    ``site``
37
        An object representing the site on which the user
38
        registered; depending on whether ``django.contrib.sites``
39
        is installed, this may be an instance of either
40
        ``django.contrib.sites.models.Site`` (if the sites
41
        application is installed) or
42
        ``django.contrib.sites.models.RequestSite`` (if
43
        not). Consult the documentation for the Django sites
44
        framework for details regarding these objects' interfaces.
45

  
46
    """
47
    ctx_dict = {'activation_key': self.activation_key,
48
                'user': self.user,
49
                'expiration_days': settings.ACCOUNT_ACTIVATION_DAYS,
50
                'site': site}
51
    subject = render_to_string('registration/activation_email_subject.txt',
52
                               ctx_dict)
53
    # Email subject *must not* contain newlines
54
    subject = ''.join(subject.splitlines())
55
    
56
    message = render_to_string('registration/activation_email.txt',
57
                               ctx_dict)
58
    
59
    self.user.email_user(subject, message, settings.DEFAULT_FROM_EMAIL)
60
RegistrationProfile.send_activation_email = send_activation_email
authentic2/registration_backend/default/forms.py
1
from django.core.exceptions import ValidationError
2
from django.utils.translation import ugettext_lazy as _
3
from django.utils.datastructures import SortedDict
4
from django.db.models import FieldDoesNotExist
5

  
6
from authentic2 import app_settings, compat, forms, utils, validators
7
from ..forms import RegistrationForm as BaseRegistrationForm, SetPasswordForm, PasswordChangeForm
8

  
9
class RegistrationForm(forms.UserAttributeFormMixin, BaseRegistrationForm):
10

  
11
    def __init__(self, *args, **kwargs):
12
        """
13
        Inject required fields in registration form
14
        """
15
        super(RegistrationForm, self).__init__(*args, **kwargs)
16
        User = compat.get_user_model()
17
        insert_idx = 0
18
        field_names = compat.get_registration_fields()
19
        required_fields = set(compat.get_required_fields())
20
        for field_name in field_names:
21
            if field_name not in self.fields:
22
                try:
23
                    model_field = User._meta.get_field(field_name)
24
                except FieldDoesNotExist:
25
                    pass
26
                else:
27
                    kwargs = {}
28
                    if hasattr(model_field, 'validators'):
29
                        kwargs['validators'] = model_field.validators
30
                    field = model_field.formfield(**kwargs)
31
                    self.fields.insert(insert_idx, field_name, field)
32
                    insert_idx += 1
33
        for field_name in self.fields:
34
            if field_name in required_fields:
35
                self.fields[field_name].required = True
36
        # reorder fields obeying A2_REGISTRATION_FIELDS
37
        new_fields = SortedDict()
38
        for field_name in utils.field_names(app_settings.A2_REGISTRATION_FIELDS):
39
            if field_name in self.fields:
40
                new_fields[field_name] = self.fields[field_name]
41
        for field_name in self.fields:
42
            if field_name not in new_fields:
43
                new_fields[field_name] = self.fields[field_name]
44
        # override titles
45
        for field in app_settings.A2_REGISTRATION_FIELDS:
46
            if isinstance(field, (list, tuple)):
47
                if len(field) > 1:
48
                    self.fields[field[0]].label = field[1]
49

  
50
        self.fields = new_fields
51
        if 'username' in self.fields:
52
            self.fields['username'].regex = app_settings.A2_REGISTRATION_FORM_USERNAME_REGEX
53
            self.fields['username'].help_text = app_settings.A2_REGISTRATION_FORM_USERNAME_HELP_TEXT
54
            self.fields['username'].label = app_settings.A2_REGISTRATION_FORM_USERNAME_LABEL
55

  
56
    def clean_username(self):
57
        """
58
        Validate that the username is alphanumeric and is not already
59
        in use.
60
        """
61
        User = compat.get_user_model()
62
        username = self.cleaned_data['username']
63
        if app_settings.A2_REGISTRATION_REALM:
64
            if '@' in username:
65
                raise ValidationError(_('The character @ is forbidden in usernames.'))
66
            username = u'{0}@{1}'.format(username, app_settings.A2_REGISTRATION_REALM)
67
            self.cleaned_data['username'] = username
68
        existing = User.objects.filter(username__iexact=self.cleaned_data['username'])
69
        if existing.exists():
70
            raise ValidationError(_("A user with that username already exists."))
71
        else:
72
            return self.cleaned_data['username']
73

  
74
    def clean_email(self):
75
        """
76
        Verify if email is unique
77
        """
78
        User = compat.get_user_model()
79
        if app_settings.A2_REGISTRATION_EMAIL_IS_UNIQUE:
80
            if User.objects.filter(email__iexact=self.cleaned_data['email']):
81
                raise ValidationError(_('This email address is already in '
82
                    'use. Please supply a different email address.'))
83
        return self.cleaned_data['email']
authentic2/registration_backend/default/models.py
1
from django.utils.translation import ugettext_lazy as _
2
from django.contrib.sites.models import RequestSite
3
from django.contrib.sites.models import Site
4
from django.contrib.auth.models import BaseUserManager, Group
5
from django.db import models
6

  
7
from authentic2 import app_settings, compat, models as a2_models
8

  
9
from ..models import RegistrationProfile as BaseRegistrationProfile
10
from ..models import ACTIVATION_KEY_RE
11

  
12
User = compat.get_user_model()
13

  
14
class RegistrationProfile(BaseRegistrationProfile, models.Model):
15
    user = models.ForeignKey(User, unique=True, related_name='profile')
16
    activation_key = models.CharField(_(u'User\'s activation key'),
17
                                      max_length=64, db_index=True)
18

  
19
    def activate_user(self, activation_key):
20
        if ACTIVATION_KEY_RE.search(activation_key):
21
            try:
22
                self = RegistrationProfile.objects.get(activation_key=activation_key)
23
                if not self.activation_key_expired():
24
                    self.user.is_active = True
25
                    self.user.save()
26
                    self.activation_key = self.model.ACTIVATED
27
                    self.save()
28
                    return self.user
29
            except self.DoesNotExist:
30
                return False
31
        return False
32

  
33
    def create_profile(self, user, site):
34
        self.user = user
35
        self.activation_key = self.activation_token
36
        self.save()
37
        self.send_activation_email(site)
38

  
39
    def create_inactive_user(self, request, **cleaned_data):
40
        User = compat.get_user_model()
41
        if Site._meta.installed:
42
            site = Site.objects.get_current()
43
        else:
44
            site = RequestSite(request)
45
        user_fields = {}
46
        for field in compat.get_registration_fields():
47
            # save User model fields
48
            try:
49
                User._meta.get_field(field)
50
            except models.FieldDoesNotExist:
51
                continue
52
            if field.startswith('password'):
53
                continue
54
            user_fields[field] = cleaned_data[field]
55
            if field == 'email':
56
                user_fields[field] = BaseUserManager.normalize_email(user_fields[field])
57

  
58
        new_user = User(is_active=False, **user_fields)
59
        new_user.clean()
60
        new_user.set_password(cleaned_data['password1'])
61
        new_user.save()
62
        attributes = a2_models.Attribute.objects.filter(
63
            asked_on_registration=True)
64
        if attributes:
65
            for attribute in attributes:
66
                attribute.set_value(new_user, cleaned_data[attribute.name])
67
        if app_settings.A2_REGISTRATION_GROUPS:
68
            groups = []
69
            for name in app_settings.A2_REGISTRATION_GROUPS:
70
                group, created = Group.objects.get_or_create(name=name)
71
                groups.append(group)
72
            new_user.groups = groups
73
        return new_user, site
authentic2/registration_backend/default/views.py
1
import logging
2

  
3
from django.shortcuts import redirect, render
4
from django.utils.translation import ugettext as _
5
from django.contrib import messages
6
from django.contrib.auth.decorators import login_required
7
from django.contrib.auth import views as auth_views
8
from django.conf import settings
9

  
10
from authentic2 import app_settings, models
11

  
12
from ..views import RegistrationView as BaseRegistrationView
13
from ..views import ActivationView as BaseActivationView
14
from .models import RegistrationProfile
15
from .forms import RegistrationForm
16

  
17
logger = logging.getLogger(__name__)
18

  
19
class RegistrationView(BaseRegistrationView):
20

  
21
    form_class = RegistrationForm
22

  
23
    def register(self, request, **cleaned_data):
24
        profile = RegistrationProfile()
25
        new_user = profile.create_user(request, **cleaned_data)
26
        return new_user
27

  
28
register = RegistrationView.as_view()
29

  
30
class ActivationView(BaseActivationView):
31
    def activate(self, request, activation_key):
32
        profile = RegistrationProfile()
33
        return profile.activate_user(activation_key)
34

  
35
activate = ActivationView.as_view()
36

  
37

  
38
@login_required
39
def delete(request, next_url='/'):
40
    next_url = request.build_absolute_uri(request.META.get('HTTP_REFERER') or next_url)
41
    if not app_settings.A2_REGISTRATION_CAN_DELETE_ACCOUNT:
42
        return redirect(next_url)
43
    if request.method == 'POST':
44
        if 'submit' in request.POST:
45
            models.DeletedUser.objects.delete_user(request.user)
46
            logger.info(u'deletion of account %s requested' % request.user)
47
            messages.info(request, _('Your account has been scheduled for deletion. You cannot use it anymore.'))
48
            return redirect('auth_logout')
49
        else:
50
            return redirect(next_url)
51
    return render(request, 'registration/delete_account.html')
52

  
53
password_change = auth_views.password_change
54
password_change_done = auth_views.password_change_done
55
password_reset = auth_views.password_reset
56
password_reset_confirm = auth_views.password_reset_confirm
57
password_reset_complete = auth_views.password_reset_complete
58
password_reset_done = auth_views.password_reset_done
authentic2/registration_backend/forms.py
1
from django.core.exceptions import ValidationError
2
from django.utils.translation import ugettext_lazy as _
3 1
from django.forms import Form, CharField, PasswordInput
4
from django.utils.datastructures import SortedDict
5
from django.db.models import FieldDoesNotExist
6

  
7
from django.contrib.auth import forms as auth_forms
2
from django.utils.translation import ugettext_lazy as _
8 3

  
9
from .. import app_settings, compat, forms, utils, validators
4
from django.contrib.auth import forms
10 5

  
6
from authentic2 import validators
11 7

  
12
class RegistrationForm(forms.UserAttributeFormMixin, Form):
8
class RegistrationForm(Form):
13 9
    error_css_class = 'form-field-error'
14 10
    required_css_class = 'form-field-required'
15 11

  
......
17 13
            validators=[validators.validate_password])
18 14
    password2 = CharField(widget=PasswordInput, label=_("Password (again)"))
19 15

  
20
    def __init__(self, *args, **kwargs):
21
        """
22
        Inject required fields in registration form
23
        """
24
        super(RegistrationForm, self).__init__(*args, **kwargs)
25
        User = compat.get_user_model()
26
        insert_idx = 0
27
        field_names = compat.get_registration_fields()
28
        required_fields = set(compat.get_required_fields())
29
        for field_name in field_names:
30
            if field_name not in self.fields:
31
                try:
32
                    model_field = User._meta.get_field(field_name)
33
                except FieldDoesNotExist:
34
                    pass
35
                else:
36
                    kwargs = {}
37
                    if hasattr(model_field, 'validators'):
38
                        kwargs['validators'] = model_field.validators
39
                    field = model_field.formfield(**kwargs)
40
                    self.fields.insert(insert_idx, field_name, field)
41
                    insert_idx += 1
42
        for field_name in self.fields:
43
            if field_name in required_fields:
44
                self.fields[field_name].required = True
45
        # reorder fields obeying A2_REGISTRATION_FIELDS
46
        new_fields = SortedDict()
47
        for field_name in utils.field_names(app_settings.A2_REGISTRATION_FIELDS):
48
            if field_name in self.fields:
49
                new_fields[field_name] = self.fields[field_name]
50
        for field_name in self.fields:
51
            if field_name not in new_fields:
52
                new_fields[field_name] = self.fields[field_name]
53
        # override titles
54
        for field in app_settings.A2_REGISTRATION_FIELDS:
55
            if isinstance(field, (list, tuple)):
56
                if len(field) > 1:
57
                    self.fields[field[0]].label = field[1]
58

  
59
        self.fields = new_fields
60
        if 'username' in self.fields:
61
            self.fields['username'].regex = app_settings.A2_REGISTRATION_FORM_USERNAME_REGEX
62
            self.fields['username'].help_text = app_settings.A2_REGISTRATION_FORM_USERNAME_HELP_TEXT
63
            self.fields['username'].label = app_settings.A2_REGISTRATION_FORM_USERNAME_LABEL
64

  
65 16
    def clean_username(self):
66
        """
67
        Validate that the username is alphanumeric and is not already
68
        in use.
69
        """
70
        User = compat.get_user_model()
71
        username = self.cleaned_data['username']
72
        if app_settings.A2_REGISTRATION_REALM:
73
            if '@' in username:
74
                raise ValidationError(_('The character @ is forbidden in usernames.'))
75
            username = u'{0}@{1}'.format(username, app_settings.A2_REGISTRATION_REALM)
76
            self.cleaned_data['username'] = username
77
        existing = User.objects.filter(username__iexact=self.cleaned_data['username'])
78
        if existing.exists():
79
            raise ValidationError(_("A user with that username already exists."))
80
        else:
81
            return self.cleaned_data['username']
17
        raise NotImplementedError
82 18

  
83 19
    def clean_email(self):
84
        """
85
        Verify if email is unique
86
        """
87
        User = compat.get_user_model()
88
        if app_settings.A2_REGISTRATION_EMAIL_IS_UNIQUE:
89
            if User.objects.filter(email__iexact=self.cleaned_data['email']):
90
                raise ValidationError(_('This email address is already in '
91
                    'use. Please supply a different email address.'))
92
        return self.cleaned_data['email']
20
        raise NotImplementedError
93 21

  
94 22
    def clean(self):
95 23
        """
......
103 31
                raise ValidationError(_("The two password fields didn't match."))
104 32
        return self.cleaned_data
105 33

  
106
class SetPasswordForm(auth_forms.SetPasswordForm):
34
class SetPasswordForm(forms.SetPasswordForm):
107 35
    new_password1 = CharField(label=_("New password"),
108 36
                                    widget=PasswordInput,
109 37
                                    validators=[validators.validate_password])
110 38

  
111
class PasswordChangeForm(auth_forms.PasswordChangeForm):
39
class PasswordChangeForm(forms.PasswordChangeForm):
112 40
    new_password1 = CharField(label=_("New password"),
113 41
                                    widget=PasswordInput,
114 42
                                    validators=[validators.validate_password])
115

  
116

  
authentic2/registration_backend/models.py
1
import hashlib
2
import random
3
import re
4
from datetime import datetime, timedelta
5

  
6
from django.conf import settings
7
from django.template.loader import render_to_string
8
from django.core.mail import send_mail
9

  
10
ACTIVATION_KEY_RE = re.compile('^[a-f0-9]{40}$')
11

  
12
class RegistrationProfile(object):
13
    ACTIVATED = 'ACTIVATED'
14

  
15
    def __unicode__(self):
16
        return u"Registration information for %s" % self.user
17

  
18
    @property
19
    def activation_token(self):
20
        salt = hashlib.sha1(str(random.random())).hexdigest()[:5]
21
        now = datetime.now().isoformat()
22
        activation_key = hashlib.sha1(salt+now).hexdigest()
23
        return activation_key
24

  
25
    def create_profile(self, user, site):
26
        raise NotImplementedError
27

  
28
    def create_inactive_user(self, request, **cleaned_data):
29
        raise NotImplementedError
30

  
31
    def create_user(self, *args, **kwargs):
32
        user, site = self.create_inactive_user(*args, **kwargs)
33
        self.create_profile(user, site)
34
        return user
35

  
36
    def activate_user(self, activation_key):
37
        raise NotImplementedError
38

  
39
    def activation_key_expired(self):
40
        expiration_date = timedelta(days=settings.ACCOUNT_ACTIVATION_DAYS)
41
        return self.activation_key == self.ACTIVATED or \
42
               (self.user.date_joined + expiration_date <= datetime.now())
43
    activation_key_expired.boolean = True
44

  
45
    def send_activation_email(self, site):
46
        ctx_dict = {'activation_key': self.activation_key,
47
                    'user': self.user,
48
                    'expiration_days': settings.ACCOUNT_ACTIVATION_DAYS,
49
                    'site': site}
50
        subject = render_to_string('registration/activation_email_subject.txt',
51
                                   ctx_dict)
52
        subject = ''.join(subject.splitlines())
53
        message = render_to_string('registration/activation_email.txt',
54
                                   ctx_dict)
55
        send_mail(subject, message, settings.DEFAULT_FROM_EMAIL,
56
                  [self.user.email], fail_silently=True)
authentic2/registration_backend/urls.py
1 1
from django.conf.urls import patterns
2 2
from django.conf.urls import url
3
from django.utils.importlib import import_module
4
from django.contrib.auth import views as auth_views
5 3
from django.views.generic.base import TemplateView
6 4

  
7

  
8 5
from .. import app_settings
9

  
10
from registration.backends.default.views import ActivationView
11

  
12

  
13
def get_form_class(form_class):
14
    module, form_class = form_class.rsplit('.', 1)
15
    module = import_module(module)
16
    return getattr(module, form_class)
17

  
6
from ..utils import get_form_class
18 7

  
19 8
SET_PASSWORD_FORM_CLASS = get_form_class(
20 9
        app_settings.A2_REGISTRATION_SET_PASSWORD_FORM_CLASS)
21 10
CHANGE_PASSWORD_FORM_CLASS = get_form_class(
22 11
        app_settings.A2_REGISTRATION_CHANGE_PASSWORD_FORM_CLASS)
23 12

  
13
REGISTRATION_BACKEND = app_settings.A2_REGISTRATION_BACKEND
24 14

  
25
urlpatterns = patterns('authentic2.registration_backend.views',
15
urlpatterns = patterns('authentic2.registration_backend.%s.views' % REGISTRATION_BACKEND,
26 16
                       url(r'^activate/complete/$',
27 17
                           TemplateView.as_view(template_name='registration/activation_complete.html'),
28 18
                           name='registration_activation_complete'),
......
31 21
                       # that way it can return a sensible "invalid key" message instead of a
32 22
                       # confusing 404.
33 23
                       url(r'^activate/(?P<activation_key>\w+)/$',
34
                           ActivationView.as_view(),
24
                           'activate',
35 25
                           name='registration_activate'),
36 26
                       url(r'^register/$',
37 27
                           'register',
......
43 33
                           TemplateView.as_view(template_name='registration/registration_closed.html'),
44 34
                           name='registration_disallowed'),
45 35
                       url(r'^password/change/$',
46
                           auth_views.password_change,
47
                           {'password_change_form': CHANGE_PASSWORD_FORM_CLASS},
36
                           'password_change',
37
                           {'password_change_form': CHANGE_PASSWORD_FORM_CLASS,
38
                            'post_change_redirect': 'done'},
48 39
                           name='auth_password_change'),
49 40
                       url(r'^password/change/done/$',
50
                           auth_views.password_change_done,
41
                           'password_change_done',
51 42
                           name='auth_password_change_done'),
52 43
                       url(r'^password/reset/$',
53
                           auth_views.password_reset,
44
                           'password_reset',
45
                           {'post_reset_redirect': 'done'},
54 46
                           name='auth_password_reset'),
55 47
                       url(r'^password/reset/confirm/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$',
56
                           auth_views.password_reset_confirm,
48
                           'password_reset_confirm',
57 49
                           {'set_password_form': SET_PASSWORD_FORM_CLASS},
58 50
                           name='auth_password_reset_confirm'),
59 51
                       url(r'^password/reset/complete/$',
60
                           auth_views.password_reset_complete,
52
                           'password_reset_complete',
61 53
                           name='auth_password_reset_complete'),
62 54
                       url(r'^password/reset/done/$',
63
                           auth_views.password_reset_done,
55
                           'password_reset_done',
64 56
                           name='auth_password_reset_done'),
65 57
                       url(r'^delete/$',
66 58
                           'delete',
authentic2/registration_backend/views.py
1 1
import logging
2 2

  
3

  
4 3
from django.shortcuts import redirect, render
5 4
from django.utils.translation import ugettext as _
6 5
from django.contrib import messages
7 6
from django.contrib.auth.decorators import login_required
8
from django.contrib.sites.models import RequestSite
9
from django.contrib.sites.models import Site
10
from django.contrib.auth.models import BaseUserManager, Group
11 7
from django.conf import settings
12
from django.db.models import FieldDoesNotExist
8
from django.views.generic.edit import FormView
9
from django.views.generic.base import TemplateView
10
from django.shortcuts import redirect
13 11

  
12
from .. import models, app_settings, compat
14 13

  
15
from registration.views import RegistrationView as BaseRegistrationView
16
from registration.models import RegistrationProfile
17
from registration import signals
14
logger = logging.getLogger(__name__)
18 15

  
19
from .. import models, app_settings, compat
20
from . import urls
21 16

  
17
class RegistrationView(FormView):
22 18

  
23
logger = logging.getLogger(__name__)
19
    disallowed_url = 'registration_disallowed'
20
    template_name = 'registration/registration_form.html'
24 21

  
22
    def dispatch(self, request, *args, **kwargs):
23
        if not self.registration_allowed(request):
24
            return redirect(self.disallowed_url)
25
        return super(RegistrationView, self).dispatch(request, *args, **kwargs)
25 26

  
26
class RegistrationView(BaseRegistrationView):
27
    form_class = urls.get_form_class(app_settings.A2_REGISTRATION_FORM_CLASS)
27
    def post(self, request, *args, **kwargs):
28
        form_class = self.get_form_class()
29
        form = self.get_form(form_class)
30
        if form.is_valid():
31
            return self.form_valid(request, form)
32
        else:
33
            return self.form_invalid(form)
28 34

  
29 35
    def register(self, request, **cleaned_data):
30
        User = compat.get_user_model()
31
        if Site._meta.installed:
32
            site = Site.objects.get_current()
33
        else:
34
            site = RequestSite(request)
35
        user_fields = {}
36
        for field in compat.get_registration_fields():
37
            # save User model fields
38
            try:
39
                User._meta.get_field(field)
40
            except FieldDoesNotExist:
41
                continue
42
            if field.startswith('password'):
43
                continue
44
            user_fields[field] = cleaned_data[field]
45
            if field == 'email':
46
                user_fields[field] = BaseUserManager.normalize_email(user_fields[field])
47
        new_user = User(is_active=False, **user_fields)
48
        new_user.clean()
49
        new_user.set_password(cleaned_data['password1'])
50
        new_user.save()
51
        attributes = models.Attribute.objects.filter(
52
                asked_on_registration=True)
53
        if attributes:
54
            for attribute in attributes:
55
                attribute.set_value(new_user, cleaned_data[attribute.name])
56
        if app_settings.A2_REGISTRATION_GROUPS:
57
            groups = []
58
            for name in app_settings.A2_REGISTRATION_GROUPS:
59
                group, created = Group.objects.get_or_create(name=name)
60
                groups.append(group)
61
            new_user.groups = groups
62
        registration_profile = RegistrationProfile.objects.create_profile(new_user)
63
        registration_profile.send_activation_email(site)
64

  
65
        signals.user_registered.send(sender=self.__class__,
66
                                     user=new_user,
67
                                     request=request)
68
        return new_user
36
        raise NotImplementedError
69 37

  
70 38
    def registration_allowed(self, request):
71
        """
72
        Indicate whether account registration is currently permitted,
73
        based on the value of the setting ``REGISTRATION_OPEN``. This
74
        is determined as follows:
75

  
76
        * If ``REGISTRATION_OPEN`` is not specified in settings, or is
77
          set to ``True``, registration is permitted.
78

  
79
        * If ``REGISTRATION_OPEN`` is both specified and set to
80
          ``False``, registration is not permitted.
81
        
82
        """
83 39
        return getattr(settings, 'REGISTRATION_OPEN', True)
84 40

  
85
    def get_success_url(self, request, user):
86
        """
87
        Return the name of the URL to redirect to after successful
88
        user registration.
89
        
90
        """
91
        return ('registration_complete', (), {})
41
    def get_success_url(self):
42
        return ('registration_complete')
43

  
44
    def form_valid(self, request, form):
45
        self.register(request, **form.cleaned_data)
46
        return redirect(self.get_success_url())
92 47

  
93 48
register = RegistrationView.as_view()
94 49

  
50
class ActivationView(TemplateView):
51
    http_method_names = ['get']
52
    template_name = 'registration/activate.html'
53

  
54
    def get(self, request, *args, **kwargs):
55
        activated_user = self.activate(request, *args, **kwargs)
56
        if activated_user:
57
            return redirect(self.get_success_url())
58

  
59
    def activate(self, request, *args, **kwargs):
60
        raise NotImplementedError
61

  
62
    def get_success_url(self):
63
        return ('registration_activation_complete')
64

  
95 65

  
96 66
@login_required
97 67
def delete(request, next_url='/'):
authentic2/utils.py
206 206
            yield t
207 207
        else:
208 208
            yield t[0]
209

  
210
def get_form_class(form_class):
211
    module, form_class = form_class.rsplit('.', 1)
212
    module = import_module(module)
213
    return getattr(module, form_class)
requirements.txt
2 2
south>=0.8.4,<0.9
3 3
requests
4 4
django-model-utils
5
django-registration>=1
6 5
django-debug-toolbar>=1.2,<1.3
7 6
--allow-external django-admin-tools
8 7
--allow-unverified django-admin-tools
setup.py
117 117
        'south>=0.8.4,<0.9',
118 118
        'requests',
119 119
        'django-model-utils',
120
        'django-registration>=1',
121 120
        'django-admin-tools>=0.5.1',
122 121
        'django-debug-toolbar>=1.2,<1.3',
123 122
        'dnspython',
124
-