Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / forms.py @ 27993be5

History | View | Annotate | Download (8.9 kB)

1 aba1e498 Antony Chazapis
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2 64cd4730 Antony Chazapis
# 
3 64cd4730 Antony Chazapis
# Redistribution and use in source and binary forms, with or
4 64cd4730 Antony Chazapis
# without modification, are permitted provided that the following
5 64cd4730 Antony Chazapis
# conditions are met:
6 64cd4730 Antony Chazapis
# 
7 64cd4730 Antony Chazapis
#   1. Redistributions of source code must retain the above
8 64cd4730 Antony Chazapis
#      copyright notice, this list of conditions and the following
9 64cd4730 Antony Chazapis
#      disclaimer.
10 64cd4730 Antony Chazapis
# 
11 64cd4730 Antony Chazapis
#   2. Redistributions in binary form must reproduce the above
12 64cd4730 Antony Chazapis
#      copyright notice, this list of conditions and the following
13 64cd4730 Antony Chazapis
#      disclaimer in the documentation and/or other materials
14 64cd4730 Antony Chazapis
#      provided with the distribution.
15 64cd4730 Antony Chazapis
# 
16 64cd4730 Antony Chazapis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 64cd4730 Antony Chazapis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 64cd4730 Antony Chazapis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 64cd4730 Antony Chazapis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 64cd4730 Antony Chazapis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 64cd4730 Antony Chazapis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 64cd4730 Antony Chazapis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 64cd4730 Antony Chazapis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 64cd4730 Antony Chazapis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 64cd4730 Antony Chazapis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 64cd4730 Antony Chazapis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 64cd4730 Antony Chazapis
# POSSIBILITY OF SUCH DAMAGE.
28 64cd4730 Antony Chazapis
# 
29 64cd4730 Antony Chazapis
# The views and conclusions contained in the software and
30 64cd4730 Antony Chazapis
# documentation are those of the authors and should not be
31 64cd4730 Antony Chazapis
# interpreted as representing official policies, either expressed
32 64cd4730 Antony Chazapis
# or implied, of GRNET S.A.
33 64cd4730 Antony Chazapis
34 64cd4730 Antony Chazapis
from django import forms
35 64cd4730 Antony Chazapis
from django.utils.translation import ugettext as _
36 e2125441 Sofia Papagiannaki
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm, PasswordResetForm
37 e2125441 Sofia Papagiannaki
from django.core.mail import send_mail
38 e2125441 Sofia Papagiannaki
from django.contrib.auth.tokens import default_token_generator
39 e2125441 Sofia Papagiannaki
from django.template import Context, loader
40 e2125441 Sofia Papagiannaki
from django.utils.http import int_to_base36
41 374611bc Sofia Papagiannaki
from django.core.urlresolvers import reverse
42 5ed6816e Sofia Papagiannaki
43 0905ccd2 Sofia Papagiannaki
from astakos.im.models import AstakosUser
44 eeb3fe84 Sofia Papagiannaki
from astakos.im.settings import INVITATIONS_PER_LEVEL, DEFAULT_FROM_EMAIL, BASEURL, SITENAME
45 64cd4730 Antony Chazapis
46 3bf924ec Sofia Papagiannaki
import logging
47 64cd4730 Antony Chazapis
48 e015e9e6 Sofia Papagiannaki
logger = logging.getLogger(__name__)
49 e015e9e6 Sofia Papagiannaki
50 15efc749 Sofia Papagiannaki
class LocalUserCreationForm(UserCreationForm):
51 890b0eaf Sofia Papagiannaki
    """
52 890b0eaf Sofia Papagiannaki
    Extends the built in UserCreationForm in several ways:
53 64cd4730 Antony Chazapis
    
54 af4eb974 Sofia Papagiannaki
    * Adds email, first_name and last_name field.
55 5ed6816e Sofia Papagiannaki
    * The username field isn't visible and it is assigned a generated id.
56 af4eb974 Sofia Papagiannaki
    * User created is not active. 
57 890b0eaf Sofia Papagiannaki
    """
58 890b0eaf Sofia Papagiannaki
    
59 794852f2 Sofia Papagiannaki
    class Meta:
60 794852f2 Sofia Papagiannaki
        model = AstakosUser
61 5ed6816e Sofia Papagiannaki
        fields = ("email", "first_name", "last_name")
62 64cd4730 Antony Chazapis
    
63 64cd4730 Antony Chazapis
    def __init__(self, *args, **kwargs):
64 64cd4730 Antony Chazapis
        """
65 890b0eaf Sofia Papagiannaki
        Changes the order of fields, and removes the username field.
66 64cd4730 Antony Chazapis
        """
67 15efc749 Sofia Papagiannaki
        super(LocalUserCreationForm, self).__init__(*args, **kwargs)
68 890b0eaf Sofia Papagiannaki
        self.fields.keyOrder = ['email', 'first_name', 'last_name',
69 890b0eaf Sofia Papagiannaki
                                'password1', 'password2']
70 64cd4730 Antony Chazapis
    
71 af4eb974 Sofia Papagiannaki
    def clean_email(self):
72 af4eb974 Sofia Papagiannaki
        email = self.cleaned_data['email']
73 881c856c Sofia Papagiannaki
        if not email:
74 881c856c Sofia Papagiannaki
            raise forms.ValidationError(_("This field is required"))
75 af4eb974 Sofia Papagiannaki
        try:
76 af4eb974 Sofia Papagiannaki
            AstakosUser.objects.get(email = email)
77 af4eb974 Sofia Papagiannaki
            raise forms.ValidationError(_("Email is reserved"))
78 af4eb974 Sofia Papagiannaki
        except AstakosUser.DoesNotExist:
79 af4eb974 Sofia Papagiannaki
            return email
80 af4eb974 Sofia Papagiannaki
    
81 890b0eaf Sofia Papagiannaki
    def save(self, commit=True):
82 64cd4730 Antony Chazapis
        """
83 890b0eaf Sofia Papagiannaki
        Saves the email, first_name and last_name properties, after the normal
84 890b0eaf Sofia Papagiannaki
        save behavior is complete.
85 890b0eaf Sofia Papagiannaki
        """
86 15efc749 Sofia Papagiannaki
        user = super(LocalUserCreationForm, self).save(commit=False)
87 3bf924ec Sofia Papagiannaki
        user.renew_token()
88 9fb8e808 Sofia Papagiannaki
        if commit:
89 9fb8e808 Sofia Papagiannaki
            user.save()
90 e015e9e6 Sofia Papagiannaki
        logger.info('Created user %s', user)
91 890b0eaf Sofia Papagiannaki
        return user
92 64cd4730 Antony Chazapis
93 15efc749 Sofia Papagiannaki
class InvitedLocalUserCreationForm(LocalUserCreationForm):
94 890b0eaf Sofia Papagiannaki
    """
95 15efc749 Sofia Papagiannaki
    Extends the LocalUserCreationForm: adds an inviter readonly field.
96 890b0eaf Sofia Papagiannaki
    """
97 3bf924ec Sofia Papagiannaki
    
98 3bf924ec Sofia Papagiannaki
    inviter = forms.CharField(widget=forms.TextInput(), label=_('Inviter Real Name'))
99 64cd4730 Antony Chazapis
    
100 794852f2 Sofia Papagiannaki
    class Meta:
101 794852f2 Sofia Papagiannaki
        model = AstakosUser
102 5ed6816e Sofia Papagiannaki
        fields = ("email", "first_name", "last_name")
103 64cd4730 Antony Chazapis
    
104 64cd4730 Antony Chazapis
    def __init__(self, *args, **kwargs):
105 64cd4730 Antony Chazapis
        """
106 3bf924ec Sofia Papagiannaki
        Changes the order of fields, and removes the username field.
107 64cd4730 Antony Chazapis
        """
108 15efc749 Sofia Papagiannaki
        super(InvitedLocalUserCreationForm, self).__init__(*args, **kwargs)
109 9fb8e808 Sofia Papagiannaki
        self.fields.keyOrder = ['email', 'inviter', 'first_name',
110 5ed6816e Sofia Papagiannaki
                                'last_name', 'password1', 'password2']
111 64cd4730 Antony Chazapis
        #set readonly form fields
112 64cd4730 Antony Chazapis
        self.fields['inviter'].widget.attrs['readonly'] = True
113 794852f2 Sofia Papagiannaki
        self.fields['email'].widget.attrs['readonly'] = True
114 794852f2 Sofia Papagiannaki
        self.fields['username'].widget.attrs['readonly'] = True
115 9fb8e808 Sofia Papagiannaki
    
116 9fb8e808 Sofia Papagiannaki
    def save(self, commit=True):
117 15efc749 Sofia Papagiannaki
        user = super(InvitedLocalUserCreationForm, self).save(commit=False)
118 881c856c Sofia Papagiannaki
        level = user.invitation.inviter.level + 1
119 881c856c Sofia Papagiannaki
        user.level = level
120 92defad4 Sofia Papagiannaki
        user.invitations = INVITATIONS_PER_LEVEL[level]
121 9fb8e808 Sofia Papagiannaki
        if commit:
122 9fb8e808 Sofia Papagiannaki
            user.save()
123 9fb8e808 Sofia Papagiannaki
        return user
124 5ed6816e Sofia Papagiannaki
125 5ed6816e Sofia Papagiannaki
class LoginForm(AuthenticationForm):
126 5ed6816e Sofia Papagiannaki
    username = forms.EmailField(label=_("Email"))
127 64cd4730 Antony Chazapis
128 890b0eaf Sofia Papagiannaki
class ProfileForm(forms.ModelForm):
129 890b0eaf Sofia Papagiannaki
    """
130 890b0eaf Sofia Papagiannaki
    Subclass of ``ModelForm`` for permiting user to edit his/her profile.
131 890b0eaf Sofia Papagiannaki
    Most of the fields are readonly since the user is not allowed to change them.
132 890b0eaf Sofia Papagiannaki
    
133 890b0eaf Sofia Papagiannaki
    The class defines a save method which sets ``is_verified`` to True so as the user
134 890b0eaf Sofia Papagiannaki
    during the next login will not to be redirected to profile page.
135 890b0eaf Sofia Papagiannaki
    """
136 c301698f Sofia Papagiannaki
    renew = forms.BooleanField(label='Renew token', required=False)
137 c301698f Sofia Papagiannaki
    
138 890b0eaf Sofia Papagiannaki
    class Meta:
139 890b0eaf Sofia Papagiannaki
        model = AstakosUser
140 a196eb7e Sofia Papagiannaki
        fields = ('email', 'first_name', 'last_name', 'auth_token', 'auth_token_expires')
141 64cd4730 Antony Chazapis
    
142 64cd4730 Antony Chazapis
    def __init__(self, *args, **kwargs):
143 890b0eaf Sofia Papagiannaki
        super(ProfileForm, self).__init__(*args, **kwargs)
144 890b0eaf Sofia Papagiannaki
        instance = getattr(self, 'instance', None)
145 a196eb7e Sofia Papagiannaki
        ro_fields = ('auth_token', 'auth_token_expires', 'email')
146 890b0eaf Sofia Papagiannaki
        if instance and instance.id:
147 890b0eaf Sofia Papagiannaki
            for field in ro_fields:
148 890b0eaf Sofia Papagiannaki
                self.fields[field].widget.attrs['readonly'] = True
149 890b0eaf Sofia Papagiannaki
    
150 890b0eaf Sofia Papagiannaki
    def save(self, commit=True):
151 890b0eaf Sofia Papagiannaki
        user = super(ProfileForm, self).save(commit=False)
152 890b0eaf Sofia Papagiannaki
        user.is_verified = True
153 c301698f Sofia Papagiannaki
        if self.cleaned_data.get('renew'):
154 c301698f Sofia Papagiannaki
            user.renew_token()
155 890b0eaf Sofia Papagiannaki
        if commit:
156 890b0eaf Sofia Papagiannaki
            user.save()
157 890b0eaf Sofia Papagiannaki
        return user
158 64cd4730 Antony Chazapis
159 15efc749 Sofia Papagiannaki
class ThirdPartyUserCreationForm(ProfileForm):
160 15efc749 Sofia Papagiannaki
    class Meta:
161 15efc749 Sofia Papagiannaki
        model = AstakosUser
162 15efc749 Sofia Papagiannaki
        fields = ('email', 'last_name', 'first_name', 'affiliation', 'provider', 'third_party_identifier')
163 15efc749 Sofia Papagiannaki
    
164 15efc749 Sofia Papagiannaki
    def __init__(self, *args, **kwargs):
165 15efc749 Sofia Papagiannaki
        super(ThirdPartyUserCreationForm, self).__init__(*args, **kwargs)
166 15efc749 Sofia Papagiannaki
        self.fields.keyOrder = ['email']
167 15efc749 Sofia Papagiannaki
    
168 15efc749 Sofia Papagiannaki
    def clean_email(self):
169 15efc749 Sofia Papagiannaki
        email = self.cleaned_data['email']
170 15efc749 Sofia Papagiannaki
        if not email:
171 15efc749 Sofia Papagiannaki
            raise forms.ValidationError(_("This field is required"))
172 15efc749 Sofia Papagiannaki
        try:
173 15efc749 Sofia Papagiannaki
            user = AstakosUser.objects.get(email = email)
174 15efc749 Sofia Papagiannaki
            raise forms.ValidationError(_("Email is reserved"))
175 15efc749 Sofia Papagiannaki
        except AstakosUser.DoesNotExist:
176 15efc749 Sofia Papagiannaki
            return email
177 15efc749 Sofia Papagiannaki
    
178 15efc749 Sofia Papagiannaki
    def save(self, commit=True):
179 15efc749 Sofia Papagiannaki
        user = super(ThirdPartyUserCreationForm, self).save(commit=False)
180 15efc749 Sofia Papagiannaki
        user.verified = False
181 15efc749 Sofia Papagiannaki
        user.renew_token()
182 15efc749 Sofia Papagiannaki
        if commit:
183 15efc749 Sofia Papagiannaki
            user.save()
184 e015e9e6 Sofia Papagiannaki
        logger.info('Created user %s', user)
185 15efc749 Sofia Papagiannaki
        return user
186 15efc749 Sofia Papagiannaki
187 15efc749 Sofia Papagiannaki
class InvitedThirdPartyUserCreationForm(ThirdPartyUserCreationForm):
188 15efc749 Sofia Papagiannaki
    def __init__(self, *args, **kwargs):
189 15efc749 Sofia Papagiannaki
        super(InvitedThirdPartyUserCreationForm, self).__init__(*args, **kwargs)
190 15efc749 Sofia Papagiannaki
        #set readonly form fields
191 15efc749 Sofia Papagiannaki
        self.fields['email'].widget.attrs['readonly'] = True
192 64cd4730 Antony Chazapis
193 890b0eaf Sofia Papagiannaki
class FeedbackForm(forms.Form):
194 890b0eaf Sofia Papagiannaki
    """
195 890b0eaf Sofia Papagiannaki
    Form for writing feedback.
196 890b0eaf Sofia Papagiannaki
    """
197 890b0eaf Sofia Papagiannaki
    feedback_msg = forms.CharField(widget=forms.Textarea(),
198 890b0eaf Sofia Papagiannaki
                                label=u'Message', required=False)
199 92defad4 Sofia Papagiannaki
    feedback_data = forms.CharField(widget=forms.HiddenInput(),
200 92defad4 Sofia Papagiannaki
                                label='', required=False)
201 5ed6816e Sofia Papagiannaki
202 5ed6816e Sofia Papagiannaki
class SendInvitationForm(forms.Form):
203 5ed6816e Sofia Papagiannaki
    """
204 5ed6816e Sofia Papagiannaki
    Form for sending an invitations
205 5ed6816e Sofia Papagiannaki
    """
206 5ed6816e Sofia Papagiannaki
    
207 5ed6816e Sofia Papagiannaki
    email = forms.EmailField(required = True, label = 'Email address')
208 5ed6816e Sofia Papagiannaki
    first_name = forms.EmailField(label = 'First name')
209 5ed6816e Sofia Papagiannaki
    last_name = forms.EmailField(label = 'Last name')
210 e2125441 Sofia Papagiannaki
211 e2125441 Sofia Papagiannaki
class ExtendedPasswordResetForm(PasswordResetForm):
212 e2125441 Sofia Papagiannaki
    """
213 e2125441 Sofia Papagiannaki
    Extends PasswordResetForm by overriding save method:
214 e2125441 Sofia Papagiannaki
    passes a custom from_email in send_mail.
215 e2125441 Sofia Papagiannaki
    
216 e2125441 Sofia Papagiannaki
    Since Django 1.3 this is useless since ``django.contrib.auth.views.reset_password``
217 e2125441 Sofia Papagiannaki
    accepts a from_email argument.
218 e2125441 Sofia Papagiannaki
    """
219 e2125441 Sofia Papagiannaki
    def save(self, domain_override=None, email_template_name='registration/password_reset_email.html',
220 e2125441 Sofia Papagiannaki
             use_https=False, token_generator=default_token_generator, request=None):
221 e2125441 Sofia Papagiannaki
        """
222 e2125441 Sofia Papagiannaki
        Generates a one-use only link for resetting password and sends to the user.
223 e2125441 Sofia Papagiannaki
        """
224 e2125441 Sofia Papagiannaki
        for user in self.users_cache:
225 e2125441 Sofia Papagiannaki
            t = loader.get_template(email_template_name)
226 e2125441 Sofia Papagiannaki
            c = {
227 e2125441 Sofia Papagiannaki
                'email': user.email,
228 eeb3fe84 Sofia Papagiannaki
                'domain': BASEURL,
229 374611bc Sofia Papagiannaki
                'site_name': SITENAME,
230 e2125441 Sofia Papagiannaki
                'uid': int_to_base36(user.id),
231 e2125441 Sofia Papagiannaki
                'user': user,
232 374611bc Sofia Papagiannaki
                'token': token_generator.make_token(user)
233 e2125441 Sofia Papagiannaki
            }
234 d552ecb7 Antony Chazapis
            from_email = DEFAULT_FROM_EMAIL
235 374611bc Sofia Papagiannaki
            send_mail(_("Password reset on %s") % SITENAME,
236 e2125441 Sofia Papagiannaki
                t.render(Context(c)), from_email, [user.email])