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

b/snf-astakos-app/astakos/im/forms.py
49 49

  
50 50
from astakos.im.models import (AstakosUser, EmailChange, AstakosGroup,
51 51
                               Invitation, Membership, GroupKind, Resource,
52
                               get_latest_terms)
52
                               get_latest_terms, RESOURCE_SEPARATOR)
53 53
from astakos.im.settings import (INVITATIONS_PER_LEVEL, BASEURL, SITENAME,
54 54
                                 RECAPTCHA_PRIVATE_KEY, RECAPTCHA_ENABLED,
55 55
                                 DEFAULT_CONTACT_EMAIL, LOGGING_LEVEL,
56
                                 PASSWORD_RESET_EMAIL_SUBJECT)
57

  
56
                                 PASSWORD_RESET_EMAIL_SUBJECT,
57
                                 NEWPASSWD_INVALIDATE_TOKEN)
58 58
from astakos.im.widgets import DummyWidget, RecaptchaWidget
59 59
from astakos.im.functions import send_change_email
60 60

  
......
176 176
        ro = ('email', 'username',)
177 177
        for f in ro:
178 178
            self.fields[f].widget.attrs['readonly'] = True
179
    
179

  
180 180
    def save(self, commit=True):
181 181
        user = super(InvitedLocalUserCreationForm, self).save(commit=False)
182 182
        level = user.invitation.inviter.level + 1
......
193 193
        model = AstakosUser
194 194
        fields = ("email", "first_name", "last_name",
195 195
                  "third_party_identifier", "has_signed_terms")
196
    
196

  
197 197
    def __init__(self, *args, **kwargs):
198 198
        """
199 199
        Changes the order of fields, and removes the username field.
......
218 218
                % (reverse('latest_terms'), _("the terms"))
219 219
            self.fields['has_signed_terms'].label = \
220 220
                mark_safe("I agree with %s" % terms_link_html)
221
    
221

  
222 222
    def clean_email(self):
223 223
        email = self.cleaned_data['email']
224 224
        if not email:
......
273 273
class ShibbolethUserCreationForm(ThirdPartyUserCreationForm):
274 274
    additional_email = forms.CharField(
275 275
        widget=forms.HiddenInput(), label='', required=False)
276
    
276

  
277 277
    def __init__(self, *args, **kwargs):
278 278
        super(ShibbolethUserCreationForm, self).__init__(*args, **kwargs)
279 279
        self.fields.keyOrder.append('additional_email')
......
282 282
        field = self.fields[name]
283 283
        self.initial['additional_email'] = self.initial.get(name,
284 284
                                                            field.initial)
285
    
285

  
286 286
    def clean_email(self):
287 287
        email = self.cleaned_data['email']
288 288
        for user in AstakosUser.objects.filter(email=email):
......
304 304
    recaptcha_challenge_field = forms.CharField(widget=DummyWidget)
305 305
    recaptcha_response_field = forms.CharField(
306 306
        widget=RecaptchaWidget, label='')
307
    
307

  
308 308
    def __init__(self, *args, **kwargs):
309 309
        was_limited = kwargs.get('was_limited', False)
310 310
        request = kwargs.get('request', None)
......
322 322
        if was_limited and RECAPTCHA_ENABLED:
323 323
            self.fields.keyOrder.extend(['recaptcha_challenge_field',
324 324
                                         'recaptcha_response_field', ])
325
    
325

  
326
    def clean_username(self):
327
        if 'username' in self.cleaned_data:
328
            return self.cleaned_data['username'].lower()
329

  
326 330
    def clean_recaptcha_response_field(self):
327 331
        if 'recaptcha_challenge_field' in self.cleaned_data:
328 332
            self.validate_captcha()
......
340 344
        if not check.is_valid:
341 345
            raise forms.ValidationError(
342 346
                _('You have not entered the correct words'))
343
    
347

  
344 348
    def clean(self):
345 349
        super(LoginForm, self).clean()
346 350
        if self.user_cache and self.user_cache.provider not in ('local', ''):
......
515 519
        super(ExtendedPasswordChangeForm, self).__init__(user, *args, **kwargs)
516 520

  
517 521
    def save(self, commit=True):
518
        user = super(ExtendedPasswordChangeForm, self).save(commit=False)
519
        if self.cleaned_data.get('renew'):
520
            user.renew_token()
521
        if commit:
522
            user.save()
523
        return user
522
        if NEWPASSWD_INVALIDATE_TOKEN or self.cleaned_data.get('renew'):
523
            self.user.renew_token()
524
        return super(ExtendedPasswordChangeForm, self).save(commit=commit)
524 525

  
525 526

  
526 527
class AstakosGroupCreationForm(forms.ModelForm):
......
532 533
    name = forms.URLField()
533 534
    moderation_enabled = forms.BooleanField(
534 535
        help_text="Check if you want to approve members participation manually",
535
        required=False   
536
        required=False
537
    )
538
    max_participants = forms.IntegerField(
539
        widget=forms.HiddenInput(), label='', required=False
536 540
    )
537
    
541

  
538 542
    class Meta:
539 543
        model = AstakosGroup
540 544

  
541 545
    def __init__(self, *args, **kwargs):
542
        try:
543
            resources = kwargs.pop('resources')
544
        except KeyError:
545
            resources = {}
546
        #update QueryDict
547
        args = list(args)
548
        qd = args.pop(0).copy()
549
        members_unlimited = qd.pop('members_unlimited', False)
550
        members_uplimit = qd.pop('members_uplimit', None)
551
        max_participants = None if members_unlimited else members_uplimit
552
        qd['max_participants']= max_participants.pop(0) if max_participants else None
553
        
554
        #substitue QueryDict
555
        args.insert(0, qd)
556
        
546 557
        super(AstakosGroupCreationForm, self).__init__(*args, **kwargs)
547
        self.fields.keyOrder = ['kind', 'name', 'homepage', 'desc', 'issue_date',
548
                                'expiration_date', 'estimated_participants',
549
                                'moderation_enabled']
550
        for id, r in resources.iteritems():
551
            self.fields['resource_%s' % id] = forms.IntegerField(
552
                label=r,
558
        self.fields.keyOrder = ['kind', 'name', 'homepage', 'desc',
559
                                'issue_date', 'expiration_date',
560
                                'moderation_enabled', 'max_participants']
561
        
562
        def add_field((k, v)):
563
            self.fields[k] = forms.IntegerField(
553 564
                required=False,
554
                help_text=_('Leave it blank for no additional quota.')
565
                widget=forms.HiddenInput()
555 566
            )
567
        map(add_field,
568
            ((k, v) for k,v in qd.iteritems() if k.endswith('_uplimit'))
569
        )
570
        
571
    def policies(self):
572
        for name, uplimit in self.cleaned_data.iteritems():
573
            subs = name.split('_uplimit')
574
            if len(subs) == 2:
575
                prefix, suffix = subs
576
#               # yield only those having a value
577
#                    if not value:
578
#                        continue
579
                s, r = prefix.split(RESOURCE_SEPARATOR)
580
                yield dict(service=s, resource=r, uplimit=uplimit)
556 581

  
557
    def resources(self):
558
        for name, value in self.cleaned_data.items():
559
            prefix, delimiter, suffix = name.partition('resource_')
560
            if suffix:
561
                # yield only those having a value
562
                if not value:
563
                    continue
564
                yield (suffix, value)
565 582

  
566 583
class AstakosGroupUpdateForm(forms.ModelForm):
567 584
    class Meta:
568 585
        model = AstakosGroup
569 586
        fields = ('homepage', 'desc')
570 587

  
588

  
571 589
class AddGroupMembersForm(forms.Form):
572
    q = forms.CharField(max_length=800, widget=forms.Textarea, label=_('Search users'),
573
                        help_text=_('Add comma separated user emails'),
574
                        required=True)
575
    
590
    q = forms.CharField(
591
        max_length=800, widget=forms.Textarea, label=_('Search users'),
592
        help_text=_('Add comma separated user emails'),
593
        required=True)
594

  
576 595
    def clean(self):
577 596
        q = self.cleaned_data.get('q') or ''
578 597
        users = q.split(',')
......
584 603
                _('Unknown users: %s' % ','.join(unknown)))
585 604
        self.valid_users = db_entries
586 605
        return self.cleaned_data
587
    
606

  
588 607
    def get_valid_users(self):
589 608
        """Should be called after form cleaning"""
590 609
        try:
......
596 615
class AstakosGroupSearchForm(forms.Form):
597 616
    q = forms.CharField(max_length=200, label='Search group')
598 617

  
618

  
599 619
class TimelineForm(forms.Form):
600 620
#    entity = forms.CharField(
601 621
#        widget=forms.HiddenInput(), label='')
602 622
    entity = forms.ModelChoiceField(
603
        queryset=AstakosUser.objects.filter(is_active = True)
623
        queryset=AstakosUser.objects.filter(is_active=True)
604 624
    )
605 625
    resource = forms.ModelChoiceField(
606 626
        queryset=Resource.objects.all()
......
609 629
    end_date = forms.DateTimeField()
610 630
    details = forms.BooleanField(required=False, label="Detailed Listing")
611 631
    operation = forms.ChoiceField(
612
                        label   = 'Charge Method',
613
                        choices = ( ('',                '-------------'),
614
                                    ('charge_usage',    'Charge Usage'),
615
                                    ('charge_traffic',  'Charge Traffic'), )
616
                )
632
        label='Charge Method',
633
        choices=(('', '-------------'),
634
                 ('charge_usage', 'Charge Usage'),
635
                 ('charge_traffic', 'Charge Traffic'), )
636
    )
637

  
617 638
    def clean(self):
618 639
        super(TimelineForm, self).clean()
619 640
        d = self.cleaned_data
620 641
        if 'resource' in d:
621 642
            d['resource'] = str(d['resource'])
622 643
        if 'start_date' in d:
623
            d['start_date'] = d['start_date'].strftime("%Y-%m-%dT%H:%M:%S.%f")[:24]
644
            d['start_date'] = d['start_date'].strftime(
645
                "%Y-%m-%dT%H:%M:%S.%f")[:24]
624 646
        if 'end_date' in d:
625 647
            d['end_date'] = d['end_date'].strftime("%Y-%m-%dT%H:%M:%S.%f")[:24]
626
	if 'entity' in d:
648
        if 'entity' in d:
627 649
            d['entity'] = d['entity'].email
628 650
        return d
629 651

  
652

  
630 653
class AstakosGroupSortForm(forms.Form):
631 654
    sort_by = forms.ChoiceField(label='Sort by',
632 655
                                choices=(('groupname', 'Name'),
633 656
                                         ('kindname', 'Type'),
634 657
                                         ('issue_date', 'Issue Date'),
635
                                         ('expiration_date', 'Expiration Date'),
636
                                         ('approved_members_num', 'Participants'),
658
                                         ('expiration_date',
659
                                          'Expiration Date'),
660
                                         ('approved_members_num',
661
                                          'Participants'),
637 662
                                         ('is_enabled', 'Status'),
638 663
                                         ('moderation_enabled', 'Moderation'),
639
                                         ('membership_status','Enrollment Status')
664
                                         ('membership_status',
665
                                          'Enrollment Status')
640 666
                                         ),
641 667
                                required=False)
642 668

  
669

  
643 670
class MembersSortForm(forms.Form):
644 671
    sort_by = forms.ChoiceField(label='Sort by',
645 672
                                choices=(('person__email', 'User Id'),
......
648 675
                                         ),
649 676
                                required=False)
650 677

  
678

  
651 679
class PickResourceForm(forms.Form):
652 680
    resource = forms.ModelChoiceField(
653 681
        queryset=Resource.objects.select_related().all()
654 682
    )
655
    resource.widget.attrs["onchange"]="this.form.submit()"
683
    resource.widget.attrs["onchange"] = "this.form.submit()"
684

  
685

  
686
class ExtendedSetPasswordForm(SetPasswordForm):
687
    """
688
    Extends SetPasswordForm by enabling user
689
    to optionally renew also the token.
690
    """
691
    if not NEWPASSWD_INVALIDATE_TOKEN:
692
        renew = forms.BooleanField(label='Renew token', required=False,
693
                                   initial=True,
694
                                   help_text='Unsetting this may result in security risk.')
695

  
696
    def __init__(self, user, *args, **kwargs):
697
        super(ExtendedSetPasswordForm, self).__init__(user, *args, **kwargs)
698

  
699
    def save(self, commit=True):
700
        if NEWPASSWD_INVALIDATE_TOKEN or self.cleaned_data.get('renew'):
701
            if isinstance(self.user, AstakosUser):
702
                self.user.renew_token()
703
        return super(ExtendedSetPasswordForm, self).save(commit=commit)

Also available in: Unified diff