Revision d2633501 snf-astakos-app/astakos/im/forms.py

b/snf-astakos-app/astakos/im/forms.py
47 47
from django.contrib import messages
48 48
from django.utils.encoding import smart_str
49 49
from django.forms.models import fields_for_model
50
from django.db import transaction
50 51

  
51 52
from astakos.im.models import (
52 53
    AstakosUser, Invitation, get_latest_terms,
......
55 56
from astakos.im.settings import (INVITATIONS_PER_LEVEL, DEFAULT_FROM_EMAIL,
56 57
    BASEURL, SITENAME, RECAPTCHA_PRIVATE_KEY, DEFAULT_CONTACT_EMAIL,
57 58
    RECAPTCHA_ENABLED, LOGGING_LEVEL, PASSWORD_RESET_EMAIL_SUBJECT,
58
    NEWPASSWD_INVALIDATE_TOKEN
59
    NEWPASSWD_INVALIDATE_TOKEN, MODERATION_ENABLED
59 60
)
61
from astakos.im import settings
60 62
from astakos.im.widgets import DummyWidget, RecaptchaWidget
61 63
from astakos.im.functions import send_change_email
62 64

  
......
70 72

  
71 73
logger = logging.getLogger(__name__)
72 74

  
73
class LocalUserCreationForm(UserCreationForm):
75
class StoreUserMixin(object):
76

  
77
    @transaction.commit_on_success
78
    def store_user(self, user, request):
79
        user.save()
80
        self.post_store_user(user, request)
81
        return user
82

  
83
    def post_store_user(self, user, request):
84
        """
85
        Interface method for descendant backends to be able to do stuff within
86
        the transaction enabled by store_user.
87
        """
88
        pass
89

  
90

  
91
class LocalUserCreationForm(UserCreationForm, StoreUserMixin):
74 92
    """
75 93
    Extends the built in UserCreationForm in several ways:
76 94

  
......
113 131
                    mark_safe("I agree with %s" % terms_link_html)
114 132

  
115 133
    def clean_email(self):
116
        email = self.cleaned_data['email']
134
        email = self.cleaned_data['email'].lower()
117 135
        if not email:
118 136
            raise forms.ValidationError(_("This field is required"))
119 137
        if reserved_email(email):
......
143 161
        if not check.is_valid:
144 162
            raise forms.ValidationError(_('You have not entered the correct words'))
145 163

  
164
    def post_store_user(self, user, request):
165
        """
166
        Interface method for descendant backends to be able to do stuff within
167
        the transaction enabled by store_user.
168
        """
169
        user.add_auth_provider('local', auth_backend='astakos')
170
        user.set_password(self.cleaned_data['password1'])
171

  
146 172
    def save(self, commit=True):
147 173
        """
148 174
        Saves the email, first_name and last_name properties, after the normal
149 175
        save behavior is complete.
150 176
        """
151 177
        user = super(LocalUserCreationForm, self).save(commit=False)
178
        user.renew_token()
152 179
        if commit:
153 180
            user.save()
154 181
            logger._log(LOGGING_LEVEL, 'Created user %s' % user.email, [])
......
176 203

  
177 204
    def save(self, commit=True):
178 205
        user = super(InvitedLocalUserCreationForm, self).save(commit=False)
179
        level = user.invitation.inviter.level + 1
180
        user.level = level
181
        user.invitations = INVITATIONS_PER_LEVEL.get(level, 0)
206
        user.update_invitations_level()
182 207
        user.email_verified = True
183 208
        if commit:
184 209
            user.save()
185 210
        return user
186 211

  
187
class ThirdPartyUserCreationForm(forms.ModelForm):
212

  
213
class ThirdPartyUserCreationForm(forms.ModelForm, StoreUserMixin):
188 214
    id = forms.CharField(
189 215
        widget=forms.HiddenInput(),
190 216
        label='',
......
224 250
                    mark_safe("I agree with %s" % terms_link_html)
225 251
    
226 252
    def clean_email(self):
227
        email = self.cleaned_data['email']
253
        email = self.cleaned_data['email'].lower()
228 254
        if not email:
229 255
            raise forms.ValidationError(_("This field is required"))
230 256
        return email
......
235 261
            raise forms.ValidationError(_('You have to agree with the terms'))
236 262
        return has_signed_terms
237 263

  
264
    def post_store_user(self, user, request):
265
        pending = PendingThirdPartyUser.objects.get(
266
                                token=request.POST.get('third_party_token'),
267
                                third_party_identifier= \
268
            self.cleaned_data.get('third_party_identifier'))
269
        return user.add_pending_auth_provider(pending)
270

  
271

  
238 272
    def save(self, commit=True):
239 273
        user = super(ThirdPartyUserCreationForm, self).save(commit=False)
240 274
        user.set_unusable_password()
241
        user.provider = get_query(self.request).get('provider')
275
        user.is_local = False
276
        user.renew_token()
242 277
        if commit:
243 278
            user.save()
244 279
            logger._log(LOGGING_LEVEL, 'Created user %s' % user.email, [])
......
261 296

  
262 297
    def save(self, commit=True):
263 298
        user = super(InvitedThirdPartyUserCreationForm, self).save(commit=False)
264
        level = user.invitation.inviter.level + 1
265
        user.level = level
266
        user.invitations = INVITATIONS_PER_LEVEL.get(level, 0)
299
        user.set_invitation_level()
267 300
        user.email_verified = True
268 301
        if commit:
269 302
            user.save()
......
279 312
        field = self.fields[name]
280 313
        self.initial['additional_email'] = self.initial.get(name, field.initial)
281 314
        self.initial['email'] = None
282
    
315

  
283 316
    def clean_email(self):
284
        email = self.cleaned_data['email']
317
        email = self.cleaned_data['email'].lower()
285 318
        if self.instance:
286 319
            if self.instance.email == email:
287 320
                raise forms.ValidationError(_("This is your current email."))
......
296 329
                raise forms.ValidationError(_("This email is already used"))
297 330
        super(ShibbolethUserCreationForm, self).clean_email()
298 331
        return email
299
    
300
    def save(self, commit=True):
301
        user = super(ShibbolethUserCreationForm, self).save(commit=False)
302
        try:
303
            p = PendingThirdPartyUser.objects.get(
304
                provider=user.provider,
305
                third_party_identifier=user.third_party_identifier
306
            )
307
        except:
308
            pass
309
        else:
310
            p.delete()
311
        return user
332

  
312 333

  
313 334
class InvitedShibbolethUserCreationForm(ShibbolethUserCreationForm, InvitedThirdPartyUserCreationForm):
314 335
    pass
......
433 454
            user = AstakosUser.objects.get(email=email, is_active=True)
434 455
            if not user.has_usable_password():
435 456
                raise forms.ValidationError(_("This account has not a usable password."))
457

  
458
            if not user.can_change_password():
459
                raise forms.ValidationError(_('Password change for this account'
460
                                              ' is not supported.'))
461

  
436 462
        except AstakosUser.DoesNotExist, e:
437
            raise forms.ValidationError(_('That e-mail address doesn\'t have an associated user account. Are you sure you\'ve registered?'))
463
            raise forms.ValidationError(_('That e-mail address doesn\'t have an'
464
                                          ' associated user account. Are you sure'
465
                                          ' you\'ve registered?'))
438 466
        return email
439 467

  
440 468
    def save(self, domain_override=None, email_template_name='registration/password_reset_email.html',
......
443 471
        Generates a one-use only link for resetting password and sends to the user.
444 472
        """
445 473
        for user in self.users_cache:
446
            url = reverse('django.contrib.auth.views.password_reset_confirm',
447
                          kwargs={'uidb36':int_to_base36(user.id),
448
                                  'token':token_generator.make_token(user)})
474
            url = user.astakosuser.get_password_reset_url(token_generator)
449 475
            url = urljoin(BASEURL, url)
450 476
            t = loader.get_template(email_template_name)
451 477
            c = {
......
468 494
    def clean_new_email_address(self):
469 495
        addr = self.cleaned_data['new_email_address']
470 496
        if AstakosUser.objects.filter(email__iexact=addr):
471
            raise forms.ValidationError(_(u'This email address is already in use. Please supply a different email address.'))
497
            raise forms.ValidationError(_(u"This email address is already "
498
                                           "in use. Please supply a "
499
                                           "different email address."))
472 500
        return addr
473 501

  
474 502
    def save(self, email_template_name, request, commit=True):
......
552 580
    
553 581
    def __init__(self, user, *args, **kwargs):
554 582
        super(ExtendedSetPasswordForm, self).__init__(user, *args, **kwargs)
555
    
583

  
584
    @transaction.commit_on_success()
556 585
    def save(self, commit=True):
557 586
        try:
558 587
            self.user = AstakosUser.objects.get(id=self.user.id)
559 588
            if NEWPASSWD_INVALIDATE_TOKEN or self.cleaned_data.get('renew'):
560 589
                self.user.renew_token()
561
            self.user.flush_sessions()
590
            #self.user.flush_sessions()
591
            if not self.user.has_auth_provider('local'):
592
                self.user.add_auth_provider('local', auth_backend='astakos')
593

  
562 594
        except BaseException, e:
563 595
            logger.exception(e)
564 596
            pass

Also available in: Unified diff