a8693242781d8be9467456d6eeb613476e2d52b7
[astakos] / astakos / im / forms.py
1 # Copyright 2011 GRNET S.A. All rights reserved.
2
3 # Redistribution and use in source and binary forms, with or
4 # without modification, are permitted provided that the following
5 # conditions are met:
6
7 #   1. Redistributions of source code must retain the above
8 #      copyright notice, this list of conditions and the following
9 #      disclaimer.
10
11 #   2. Redistributions in binary form must reproduce the above
12 #      copyright notice, this list of conditions and the following
13 #      disclaimer in the documentation and/or other materials
14 #      provided with the distribution.
15
16 # THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 # POSSIBILITY OF SUCH DAMAGE.
28
29 # The views and conclusions contained in the software and
30 # documentation are those of the authors and should not be
31 # interpreted as representing official policies, either expressed
32 # or implied, of GRNET S.A.
33
34 from django import forms
35 from django.utils.translation import ugettext as _
36 from django.contrib.auth.forms import UserCreationForm
37 from django.conf import settings
38 from hashlib import new as newhasher
39
40 from astakos.im.models import AstakosUser
41 from astakos.im.util import get_or_create_user
42
43 class UniqueUserEmailField(forms.EmailField):
44     """
45     An EmailField which only is valid if no User has that email.
46     """
47     def validate(self, value):
48         super(forms.EmailField, self).validate(value)
49         try:
50             AstakosUser.objects.get(email = value)
51             raise forms.ValidationError("Email already exists")
52         except AstakosUser.MultipleObjectsReturned:
53             raise forms.ValidationError("Email already exists")
54         except AstakosUser.DoesNotExist:
55             pass
56
57 class ExtendedUserCreationForm(UserCreationForm):
58     """
59     Extends the built in UserCreationForm in several ways:
60     
61     * Adds an email field, which uses the custom UniqueUserEmailField,
62       that is, the form does not validate if the email address already exists
63       in the User table.
64     * The username field is generated based on the email, and isn't visible.
65     * first_name and last_name fields are added.
66     * Data not saved by the default behavior of UserCreationForm is saved.
67     """
68     
69     username = forms.CharField(required = False, max_length = 30)
70     email = UniqueUserEmailField(required = True, label = 'Email address')
71     first_name = forms.CharField(required = False, max_length = 30)
72     last_name = forms.CharField(required = False, max_length = 30)
73     
74     def __init__(self, *args, **kwargs):
75         """
76         Changes the order of fields, and removes the username field.
77         """
78         super(UserCreationForm, self).__init__(*args, **kwargs)
79         self.fields.keyOrder = ['email', 'first_name', 'last_name',
80                                 'password1', 'password2']
81     
82     def clean(self, *args, **kwargs):
83         """
84         Normal cleanup + username generation.
85         """
86         cleaned_data = super(UserCreationForm, self).clean(*args, **kwargs)
87         if cleaned_data.has_key('email'):
88             #cleaned_data['username'] = self.__generate_username(
89             #                                            cleaned_data['email'])
90             cleaned_data['username'] = cleaned_data['email']
91         return cleaned_data
92         
93     def save(self, commit=True):
94         """
95         Saves the email, first_name and last_name properties, after the normal
96         save behavior is complete.
97         """
98         user = super(UserCreationForm, self).save(commit)
99         if user:
100             kwargs = {}
101             for field in self.fields:
102                 if hasattr(AstakosUser(), field):
103                     kwargs[field] = self.cleaned_data[field]
104             user = get_or_create_user(username=self.cleaned_data['email'], **kwargs)
105         return user
106
107 class InvitedExtendedUserCreationForm(ExtendedUserCreationForm):
108     """
109     Subclass of ``RegistrationForm`` for registring a invited user. Adds a
110     readonly field for inviter's name. The email is also readonly since
111     it will be the invitation username.
112     """
113     inviter = forms.CharField(widget=forms.TextInput(),
114                                 label=_('Inviter Real Name'))
115     
116     def __init__(self, *args, **kwargs):
117         super(RegisterForm, self).__init__(*args, **kwargs)
118         
119         #set readonly form fields
120         self.fields['inviter'].widget.attrs['readonly'] = True
121
122 class ProfileForm(forms.ModelForm):
123     """
124     Subclass of ``ModelForm`` for permiting user to edit his/her profile.
125     Most of the fields are readonly since the user is not allowed to change them.
126     
127     The class defines a save method which sets ``is_verified`` to True so as the user
128     during the next login will not to be redirected to profile page.
129     """
130     class Meta:
131         model = AstakosUser
132         exclude = ('groups', 'user_permissions')
133     
134     def __init__(self, *args, **kwargs):
135         super(ProfileForm, self).__init__(*args, **kwargs)
136         instance = getattr(self, 'instance', None)
137         ro_fields = ('username','date_joined', 'updated', 'auth_token',
138                      'auth_token_created', 'auth_token_expires', 'invitations',
139                      'level', 'last_login', 'email', 'is_active', 'is_superuser',
140                      'is_staff')
141         if instance and instance.id:
142             for field in ro_fields:
143                 if isinstance(self.fields[field].widget, forms.CheckboxInput):
144                     self.fields[field].widget.attrs['disabled'] = True
145                 self.fields[field].widget.attrs['readonly'] = True
146     
147     def save(self, commit=True):
148         user = super(ProfileForm, self).save(commit=False)
149         user.is_verified = True
150         if commit:
151             user.save()
152         return user
153
154
155 class FeedbackForm(forms.Form):
156     """
157     Form for writing feedback.
158     """
159     feedback_msg = forms.CharField(widget=forms.Textarea(),
160                                 label=u'Message', required=False)
161     feedback_data = forms.CharField(widget=forms.Textarea(),
162                                 label=u'Data', required=False)
163