Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / forms.py @ a5373d5f

History | View | Annotate | Download (26.3 kB)

1 aba1e498 Antony Chazapis
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2 18ffbee1 Sofia Papagiannaki
#
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 18ffbee1 Sofia Papagiannaki
#
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 18ffbee1 Sofia Papagiannaki
#
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 18ffbee1 Sofia Papagiannaki
#
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 18ffbee1 Sofia Papagiannaki
#
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 8f378756 Sofia Papagiannaki
from urlparse import urljoin
34 64cd4730 Antony Chazapis
35 64cd4730 Antony Chazapis
from django import forms
36 64cd4730 Antony Chazapis
from django.utils.translation import ugettext as _
37 aab4d540 Sofia Papagiannaki
from django.contrib.auth.forms import (UserCreationForm, AuthenticationForm,
38 485c713e Sofia Papagiannaki
                                       PasswordResetForm, PasswordChangeForm,
39 485c713e Sofia Papagiannaki
                                       SetPasswordForm)
40 e2125441 Sofia Papagiannaki
from django.core.mail import send_mail
41 e2125441 Sofia Papagiannaki
from django.contrib.auth.tokens import default_token_generator
42 e2125441 Sofia Papagiannaki
from django.template import Context, loader
43 e2125441 Sofia Papagiannaki
from django.utils.http import int_to_base36
44 374611bc Sofia Papagiannaki
from django.core.urlresolvers import reverse
45 18ffbee1 Sofia Papagiannaki
from django.utils.safestring import mark_safe
46 49790d9d Sofia Papagiannaki
from django.utils.encoding import smart_str
47 8e45d6fd Sofia Papagiannaki
from django.forms.extras.widgets import SelectDateWidget
48 1cbce16f Sofia Papagiannaki
from django.conf import settings
49 5ed6816e Sofia Papagiannaki
50 54213d7a Sofia Papagiannaki
from astakos.im.models import (AstakosUser, EmailChange, AstakosGroup,
51 54213d7a Sofia Papagiannaki
                               Invitation, Membership, GroupKind, Resource,
52 54213d7a Sofia Papagiannaki
                               get_latest_terms)
53 1cbce16f Sofia Papagiannaki
from astakos.im.settings import (INVITATIONS_PER_LEVEL, BASEURL, SITENAME,
54 54213d7a Sofia Papagiannaki
                                 RECAPTCHA_PRIVATE_KEY, RECAPTCHA_ENABLED,
55 8cc49f4d Sofia Papagiannaki
                                 DEFAULT_CONTACT_EMAIL, LOGGING_LEVEL,
56 485c713e Sofia Papagiannaki
                                 PASSWORD_RESET_EMAIL_SUBJECT, 
57 485c713e Sofia Papagiannaki
                                 NEWPASSWD_INVALIDATE_TOKEN)
58 45f8d9ff Sofia Papagiannaki
from astakos.im.widgets import DummyWidget, RecaptchaWidget
59 49790d9d Sofia Papagiannaki
from astakos.im.functions import send_change_email
60 270dd48d Sofia Papagiannaki
61 aab4d540 Sofia Papagiannaki
from astakos.im.util import reserved_email, get_query
62 64cd4730 Antony Chazapis
63 3bf924ec Sofia Papagiannaki
import logging
64 49790d9d Sofia Papagiannaki
import hashlib
65 db7fecd9 Sofia Papagiannaki
import recaptcha.client.captcha as captcha
66 49790d9d Sofia Papagiannaki
from random import random
67 64cd4730 Antony Chazapis
68 e015e9e6 Sofia Papagiannaki
logger = logging.getLogger(__name__)
69 e015e9e6 Sofia Papagiannaki
70 5ce3ce4f Sofia Papagiannaki
71 15efc749 Sofia Papagiannaki
class LocalUserCreationForm(UserCreationForm):
72 890b0eaf Sofia Papagiannaki
    """
73 890b0eaf Sofia Papagiannaki
    Extends the built in UserCreationForm in several ways:
74 18ffbee1 Sofia Papagiannaki

75 8316698a Sofia Papagiannaki
    * Adds email, first_name, last_name, recaptcha_challenge_field, recaptcha_response_field field.
76 5ed6816e Sofia Papagiannaki
    * The username field isn't visible and it is assigned a generated id.
77 18ffbee1 Sofia Papagiannaki
    * User created is not active.
78 890b0eaf Sofia Papagiannaki
    """
79 db7fecd9 Sofia Papagiannaki
    recaptcha_challenge_field = forms.CharField(widget=DummyWidget)
80 5ce3ce4f Sofia Papagiannaki
    recaptcha_response_field = forms.CharField(
81 5ce3ce4f Sofia Papagiannaki
        widget=RecaptchaWidget, label='')
82 18ffbee1 Sofia Papagiannaki
83 794852f2 Sofia Papagiannaki
    class Meta:
84 794852f2 Sofia Papagiannaki
        model = AstakosUser
85 5ce3ce4f Sofia Papagiannaki
        fields = ("email", "first_name", "last_name",
86 5ce3ce4f Sofia Papagiannaki
                  "has_signed_terms", "has_signed_terms")
87 18ffbee1 Sofia Papagiannaki
88 64cd4730 Antony Chazapis
    def __init__(self, *args, **kwargs):
89 64cd4730 Antony Chazapis
        """
90 890b0eaf Sofia Papagiannaki
        Changes the order of fields, and removes the username field.
91 64cd4730 Antony Chazapis
        """
92 672d445a Sofia Papagiannaki
        request = kwargs.get('request', None)
93 672d445a Sofia Papagiannaki
        if request:
94 672d445a Sofia Papagiannaki
            kwargs.pop('request')
95 672d445a Sofia Papagiannaki
            self.ip = request.META.get('REMOTE_ADDR',
96 672d445a Sofia Papagiannaki
                                       request.META.get('HTTP_X_REAL_IP', None))
97 5ce3ce4f Sofia Papagiannaki
98 15efc749 Sofia Papagiannaki
        super(LocalUserCreationForm, self).__init__(*args, **kwargs)
99 890b0eaf Sofia Papagiannaki
        self.fields.keyOrder = ['email', 'first_name', 'last_name',
100 d8f63346 Sofia Papagiannaki
                                'password1', 'password2']
101 1b3398a0 Olga Brani
102 53bf2659 Sofia Papagiannaki
        if RECAPTCHA_ENABLED:
103 53bf2659 Sofia Papagiannaki
            self.fields.keyOrder.extend(['recaptcha_challenge_field',
104 5ce3ce4f Sofia Papagiannaki
                                         'recaptcha_response_field', ])
105 1b3398a0 Olga Brani
        if get_latest_terms():
106 1b3398a0 Olga Brani
            self.fields.keyOrder.append('has_signed_terms')
107 5ce3ce4f Sofia Papagiannaki
108 18ffbee1 Sofia Papagiannaki
        if 'has_signed_terms' in self.fields:
109 18ffbee1 Sofia Papagiannaki
            # Overriding field label since we need to apply a link
110 18ffbee1 Sofia Papagiannaki
            # to the terms within the label
111 18ffbee1 Sofia Papagiannaki
            terms_link_html = '<a href="%s" target="_blank">%s</a>' \
112 5ce3ce4f Sofia Papagiannaki
                % (reverse('latest_terms'), _("the terms"))
113 18ffbee1 Sofia Papagiannaki
            self.fields['has_signed_terms'].label = \
114 5ce3ce4f Sofia Papagiannaki
                mark_safe("I agree with %s" % terms_link_html)
115 18ffbee1 Sofia Papagiannaki
116 af4eb974 Sofia Papagiannaki
    def clean_email(self):
117 af4eb974 Sofia Papagiannaki
        email = self.cleaned_data['email']
118 881c856c Sofia Papagiannaki
        if not email:
119 881c856c Sofia Papagiannaki
            raise forms.ValidationError(_("This field is required"))
120 0a569195 Sofia Papagiannaki
        if reserved_email(email):
121 c37263ea Sofia Papagiannaki
            raise forms.ValidationError(_("This email is already used"))
122 0a569195 Sofia Papagiannaki
        return email
123 18ffbee1 Sofia Papagiannaki
124 270dd48d Sofia Papagiannaki
    def clean_has_signed_terms(self):
125 270dd48d Sofia Papagiannaki
        has_signed_terms = self.cleaned_data['has_signed_terms']
126 270dd48d Sofia Papagiannaki
        if not has_signed_terms:
127 270dd48d Sofia Papagiannaki
            raise forms.ValidationError(_('You have to agree with the terms'))
128 270dd48d Sofia Papagiannaki
        return has_signed_terms
129 18ffbee1 Sofia Papagiannaki
130 db7fecd9 Sofia Papagiannaki
    def clean_recaptcha_response_field(self):
131 db7fecd9 Sofia Papagiannaki
        if 'recaptcha_challenge_field' in self.cleaned_data:
132 db7fecd9 Sofia Papagiannaki
            self.validate_captcha()
133 db7fecd9 Sofia Papagiannaki
        return self.cleaned_data['recaptcha_response_field']
134 db7fecd9 Sofia Papagiannaki
135 db7fecd9 Sofia Papagiannaki
    def clean_recaptcha_challenge_field(self):
136 db7fecd9 Sofia Papagiannaki
        if 'recaptcha_response_field' in self.cleaned_data:
137 db7fecd9 Sofia Papagiannaki
            self.validate_captcha()
138 db7fecd9 Sofia Papagiannaki
        return self.cleaned_data['recaptcha_challenge_field']
139 db7fecd9 Sofia Papagiannaki
140 db7fecd9 Sofia Papagiannaki
    def validate_captcha(self):
141 db7fecd9 Sofia Papagiannaki
        rcf = self.cleaned_data['recaptcha_challenge_field']
142 db7fecd9 Sofia Papagiannaki
        rrf = self.cleaned_data['recaptcha_response_field']
143 db7fecd9 Sofia Papagiannaki
        check = captcha.submit(rcf, rrf, RECAPTCHA_PRIVATE_KEY, self.ip)
144 db7fecd9 Sofia Papagiannaki
        if not check.is_valid:
145 5ce3ce4f Sofia Papagiannaki
            raise forms.ValidationError(
146 5ce3ce4f Sofia Papagiannaki
                _('You have not entered the correct words'))
147 18ffbee1 Sofia Papagiannaki
148 890b0eaf Sofia Papagiannaki
    def save(self, commit=True):
149 64cd4730 Antony Chazapis
        """
150 890b0eaf Sofia Papagiannaki
        Saves the email, first_name and last_name properties, after the normal
151 890b0eaf Sofia Papagiannaki
        save behavior is complete.
152 890b0eaf Sofia Papagiannaki
        """
153 15efc749 Sofia Papagiannaki
        user = super(LocalUserCreationForm, self).save(commit=False)
154 3bf924ec Sofia Papagiannaki
        user.renew_token()
155 9fb8e808 Sofia Papagiannaki
        if commit:
156 9fb8e808 Sofia Papagiannaki
            user.save()
157 aab4d540 Sofia Papagiannaki
            logger.log(LOGGING_LEVEL, 'Created user %s' % user.email)
158 890b0eaf Sofia Papagiannaki
        return user
159 64cd4730 Antony Chazapis
160 5ce3ce4f Sofia Papagiannaki
161 15efc749 Sofia Papagiannaki
class InvitedLocalUserCreationForm(LocalUserCreationForm):
162 890b0eaf Sofia Papagiannaki
    """
163 062c970c Sofia Papagiannaki
    Extends the LocalUserCreationForm: email is readonly.
164 890b0eaf Sofia Papagiannaki
    """
165 794852f2 Sofia Papagiannaki
    class Meta:
166 794852f2 Sofia Papagiannaki
        model = AstakosUser
167 270dd48d Sofia Papagiannaki
        fields = ("email", "first_name", "last_name", "has_signed_terms")
168 18ffbee1 Sofia Papagiannaki
169 64cd4730 Antony Chazapis
    def __init__(self, *args, **kwargs):
170 64cd4730 Antony Chazapis
        """
171 3bf924ec Sofia Papagiannaki
        Changes the order of fields, and removes the username field.
172 64cd4730 Antony Chazapis
        """
173 15efc749 Sofia Papagiannaki
        super(InvitedLocalUserCreationForm, self).__init__(*args, **kwargs)
174 18ffbee1 Sofia Papagiannaki
175 64cd4730 Antony Chazapis
        #set readonly form fields
176 062c970c Sofia Papagiannaki
        ro = ('email', 'username',)
177 4e30244e Sofia Papagiannaki
        for f in ro:
178 4e30244e Sofia Papagiannaki
            self.fields[f].widget.attrs['readonly'] = True
179 4f78c22c Sofia Papagiannaki
    
180 9fb8e808 Sofia Papagiannaki
    def save(self, commit=True):
181 15efc749 Sofia Papagiannaki
        user = super(InvitedLocalUserCreationForm, self).save(commit=False)
182 881c856c Sofia Papagiannaki
        level = user.invitation.inviter.level + 1
183 881c856c Sofia Papagiannaki
        user.level = level
184 8316698a Sofia Papagiannaki
        user.invitations = INVITATIONS_PER_LEVEL.get(level, 0)
185 8316698a Sofia Papagiannaki
        user.email_verified = True
186 9fb8e808 Sofia Papagiannaki
        if commit:
187 9fb8e808 Sofia Papagiannaki
            user.save()
188 9fb8e808 Sofia Papagiannaki
        return user
189 5ed6816e Sofia Papagiannaki
190 5ce3ce4f Sofia Papagiannaki
191 18ffbee1 Sofia Papagiannaki
class ThirdPartyUserCreationForm(forms.ModelForm):
192 8f5a3a06 Sofia Papagiannaki
    class Meta:
193 8f5a3a06 Sofia Papagiannaki
        model = AstakosUser
194 5ce3ce4f Sofia Papagiannaki
        fields = ("email", "first_name", "last_name",
195 5ce3ce4f Sofia Papagiannaki
                  "third_party_identifier", "has_signed_terms")
196 4f78c22c Sofia Papagiannaki
    
197 8f5a3a06 Sofia Papagiannaki
    def __init__(self, *args, **kwargs):
198 8f5a3a06 Sofia Papagiannaki
        """
199 8f5a3a06 Sofia Papagiannaki
        Changes the order of fields, and removes the username field.
200 8f5a3a06 Sofia Papagiannaki
        """
201 0a569195 Sofia Papagiannaki
        self.request = kwargs.get('request', None)
202 0a569195 Sofia Papagiannaki
        if self.request:
203 0a569195 Sofia Papagiannaki
            kwargs.pop('request')
204 8f5a3a06 Sofia Papagiannaki
        super(ThirdPartyUserCreationForm, self).__init__(*args, **kwargs)
205 5ce3ce4f Sofia Papagiannaki
        self.fields.keyOrder = ['email', 'first_name', 'last_name',
206 5ce3ce4f Sofia Papagiannaki
                                'third_party_identifier']
207 8f5a3a06 Sofia Papagiannaki
        if get_latest_terms():
208 8f5a3a06 Sofia Papagiannaki
            self.fields.keyOrder.append('has_signed_terms')
209 18ffbee1 Sofia Papagiannaki
        #set readonly form fields
210 ca828a10 Sofia Papagiannaki
        ro = ["third_party_identifier"]
211 18ffbee1 Sofia Papagiannaki
        for f in ro:
212 18ffbee1 Sofia Papagiannaki
            self.fields[f].widget.attrs['readonly'] = True
213 5ce3ce4f Sofia Papagiannaki
214 18ffbee1 Sofia Papagiannaki
        if 'has_signed_terms' in self.fields:
215 18ffbee1 Sofia Papagiannaki
            # Overriding field label since we need to apply a link
216 18ffbee1 Sofia Papagiannaki
            # to the terms within the label
217 18ffbee1 Sofia Papagiannaki
            terms_link_html = '<a href="%s" target="_blank">%s</a>' \
218 5ce3ce4f Sofia Papagiannaki
                % (reverse('latest_terms'), _("the terms"))
219 18ffbee1 Sofia Papagiannaki
            self.fields['has_signed_terms'].label = \
220 5ce3ce4f Sofia Papagiannaki
                mark_safe("I agree with %s" % terms_link_html)
221 4f78c22c Sofia Papagiannaki
    
222 18ffbee1 Sofia Papagiannaki
    def clean_email(self):
223 18ffbee1 Sofia Papagiannaki
        email = self.cleaned_data['email']
224 18ffbee1 Sofia Papagiannaki
        if not email:
225 18ffbee1 Sofia Papagiannaki
            raise forms.ValidationError(_("This field is required"))
226 0a569195 Sofia Papagiannaki
        return email
227 5ce3ce4f Sofia Papagiannaki
228 18ffbee1 Sofia Papagiannaki
    def clean_has_signed_terms(self):
229 18ffbee1 Sofia Papagiannaki
        has_signed_terms = self.cleaned_data['has_signed_terms']
230 18ffbee1 Sofia Papagiannaki
        if not has_signed_terms:
231 18ffbee1 Sofia Papagiannaki
            raise forms.ValidationError(_('You have to agree with the terms'))
232 18ffbee1 Sofia Papagiannaki
        return has_signed_terms
233 5ce3ce4f Sofia Papagiannaki
234 8f5a3a06 Sofia Papagiannaki
    def save(self, commit=True):
235 8f5a3a06 Sofia Papagiannaki
        user = super(ThirdPartyUserCreationForm, self).save(commit=False)
236 8f5a3a06 Sofia Papagiannaki
        user.set_unusable_password()
237 18ffbee1 Sofia Papagiannaki
        user.renew_token()
238 0a569195 Sofia Papagiannaki
        user.provider = get_query(self.request).get('provider')
239 8f5a3a06 Sofia Papagiannaki
        if commit:
240 8f5a3a06 Sofia Papagiannaki
            user.save()
241 aab4d540 Sofia Papagiannaki
            logger.log(LOGGING_LEVEL, 'Created user %s' % user.email)
242 8f5a3a06 Sofia Papagiannaki
        return user
243 8f5a3a06 Sofia Papagiannaki
244 5ce3ce4f Sofia Papagiannaki
245 8f5a3a06 Sofia Papagiannaki
class InvitedThirdPartyUserCreationForm(ThirdPartyUserCreationForm):
246 4e30244e Sofia Papagiannaki
    """
247 062c970c Sofia Papagiannaki
    Extends the ThirdPartyUserCreationForm: email is readonly.
248 4e30244e Sofia Papagiannaki
    """
249 8f5a3a06 Sofia Papagiannaki
    def __init__(self, *args, **kwargs):
250 4e30244e Sofia Papagiannaki
        """
251 4e30244e Sofia Papagiannaki
        Changes the order of fields, and removes the username field.
252 4e30244e Sofia Papagiannaki
        """
253 5ce3ce4f Sofia Papagiannaki
        super(
254 5ce3ce4f Sofia Papagiannaki
            InvitedThirdPartyUserCreationForm, self).__init__(*args, **kwargs)
255 4e30244e Sofia Papagiannaki
256 8f5a3a06 Sofia Papagiannaki
        #set readonly form fields
257 062c970c Sofia Papagiannaki
        ro = ('email',)
258 4e30244e Sofia Papagiannaki
        for f in ro:
259 4e30244e Sofia Papagiannaki
            self.fields[f].widget.attrs['readonly'] = True
260 5ce3ce4f Sofia Papagiannaki
261 4e30244e Sofia Papagiannaki
    def save(self, commit=True):
262 5ce3ce4f Sofia Papagiannaki
        user = super(
263 5ce3ce4f Sofia Papagiannaki
            InvitedThirdPartyUserCreationForm, self).save(commit=False)
264 4e30244e Sofia Papagiannaki
        level = user.invitation.inviter.level + 1
265 4e30244e Sofia Papagiannaki
        user.level = level
266 4e30244e Sofia Papagiannaki
        user.invitations = INVITATIONS_PER_LEVEL.get(level, 0)
267 4e30244e Sofia Papagiannaki
        user.email_verified = True
268 4e30244e Sofia Papagiannaki
        if commit:
269 4e30244e Sofia Papagiannaki
            user.save()
270 4e30244e Sofia Papagiannaki
        return user
271 8f5a3a06 Sofia Papagiannaki
272 5ce3ce4f Sofia Papagiannaki
273 18ffbee1 Sofia Papagiannaki
class ShibbolethUserCreationForm(ThirdPartyUserCreationForm):
274 5ce3ce4f Sofia Papagiannaki
    additional_email = forms.CharField(
275 5ce3ce4f Sofia Papagiannaki
        widget=forms.HiddenInput(), label='', required=False)
276 4f78c22c Sofia Papagiannaki
    
277 ca828a10 Sofia Papagiannaki
    def __init__(self, *args, **kwargs):
278 ca828a10 Sofia Papagiannaki
        super(ShibbolethUserCreationForm, self).__init__(*args, **kwargs)
279 ca828a10 Sofia Papagiannaki
        self.fields.keyOrder.append('additional_email')
280 ca828a10 Sofia Papagiannaki
        # copy email value to additional_mail in case user will change it
281 ca828a10 Sofia Papagiannaki
        name = 'email'
282 ca828a10 Sofia Papagiannaki
        field = self.fields[name]
283 5ce3ce4f Sofia Papagiannaki
        self.initial['additional_email'] = self.initial.get(name,
284 5ce3ce4f Sofia Papagiannaki
                                                            field.initial)
285 4f78c22c Sofia Papagiannaki
    
286 18ffbee1 Sofia Papagiannaki
    def clean_email(self):
287 18ffbee1 Sofia Papagiannaki
        email = self.cleaned_data['email']
288 5ce3ce4f Sofia Papagiannaki
        for user in AstakosUser.objects.filter(email=email):
289 0a569195 Sofia Papagiannaki
            if user.provider == 'shibboleth':
290 18ffbee1 Sofia Papagiannaki
                raise forms.ValidationError(_("This email is already associated with another shibboleth account."))
291 591d0505 Sofia Papagiannaki
            elif not user.is_active:
292 591d0505 Sofia Papagiannaki
                raise forms.ValidationError(_("This email is already associated with an inactive account. \
293 591d0505 Sofia Papagiannaki
                                              You need to wait to be activated before being able to switch to a shibboleth account."))
294 ab8f7956 Sofia Papagiannaki
        super(ShibbolethUserCreationForm, self).clean_email()
295 0a569195 Sofia Papagiannaki
        return email
296 4e30244e Sofia Papagiannaki
297 5ce3ce4f Sofia Papagiannaki
298 a5373d5f Sofia Papagiannaki
class InvitedShibbolethUserCreationForm(ShibbolethUserCreationForm,
299 a5373d5f Sofia Papagiannaki
                                        InvitedThirdPartyUserCreationForm):
300 4e30244e Sofia Papagiannaki
    pass
301 5ce3ce4f Sofia Papagiannaki
302 5ce3ce4f Sofia Papagiannaki
303 5ed6816e Sofia Papagiannaki
class LoginForm(AuthenticationForm):
304 5ed6816e Sofia Papagiannaki
    username = forms.EmailField(label=_("Email"))
305 672d445a Sofia Papagiannaki
    recaptcha_challenge_field = forms.CharField(widget=DummyWidget)
306 5ce3ce4f Sofia Papagiannaki
    recaptcha_response_field = forms.CharField(
307 5ce3ce4f Sofia Papagiannaki
        widget=RecaptchaWidget, label='')
308 4f78c22c Sofia Papagiannaki
    
309 672d445a Sofia Papagiannaki
    def __init__(self, *args, **kwargs):
310 672d445a Sofia Papagiannaki
        was_limited = kwargs.get('was_limited', False)
311 672d445a Sofia Papagiannaki
        request = kwargs.get('request', None)
312 672d445a Sofia Papagiannaki
        if request:
313 672d445a Sofia Papagiannaki
            self.ip = request.META.get('REMOTE_ADDR',
314 672d445a Sofia Papagiannaki
                                       request.META.get('HTTP_X_REAL_IP', None))
315 5ce3ce4f Sofia Papagiannaki
316 672d445a Sofia Papagiannaki
        t = ('request', 'was_limited')
317 672d445a Sofia Papagiannaki
        for elem in t:
318 672d445a Sofia Papagiannaki
            if elem in kwargs.keys():
319 672d445a Sofia Papagiannaki
                kwargs.pop(elem)
320 672d445a Sofia Papagiannaki
        super(LoginForm, self).__init__(*args, **kwargs)
321 5ce3ce4f Sofia Papagiannaki
322 672d445a Sofia Papagiannaki
        self.fields.keyOrder = ['username', 'password']
323 672d445a Sofia Papagiannaki
        if was_limited and RECAPTCHA_ENABLED:
324 672d445a Sofia Papagiannaki
            self.fields.keyOrder.extend(['recaptcha_challenge_field',
325 5ce3ce4f Sofia Papagiannaki
                                         'recaptcha_response_field', ])
326 4f78c22c Sofia Papagiannaki
    
327 29816137 Sofia Papagiannaki
    def clean_username(self):
328 29816137 Sofia Papagiannaki
        if 'username' in self.cleaned_data:
329 29816137 Sofia Papagiannaki
            return self.cleaned_data['username'].lower()
330 29816137 Sofia Papagiannaki
    
331 672d445a Sofia Papagiannaki
    def clean_recaptcha_response_field(self):
332 672d445a Sofia Papagiannaki
        if 'recaptcha_challenge_field' in self.cleaned_data:
333 672d445a Sofia Papagiannaki
            self.validate_captcha()
334 672d445a Sofia Papagiannaki
        return self.cleaned_data['recaptcha_response_field']
335 672d445a Sofia Papagiannaki
336 672d445a Sofia Papagiannaki
    def clean_recaptcha_challenge_field(self):
337 672d445a Sofia Papagiannaki
        if 'recaptcha_response_field' in self.cleaned_data:
338 672d445a Sofia Papagiannaki
            self.validate_captcha()
339 672d445a Sofia Papagiannaki
        return self.cleaned_data['recaptcha_challenge_field']
340 672d445a Sofia Papagiannaki
341 672d445a Sofia Papagiannaki
    def validate_captcha(self):
342 672d445a Sofia Papagiannaki
        rcf = self.cleaned_data['recaptcha_challenge_field']
343 672d445a Sofia Papagiannaki
        rrf = self.cleaned_data['recaptcha_response_field']
344 672d445a Sofia Papagiannaki
        check = captcha.submit(rcf, rrf, RECAPTCHA_PRIVATE_KEY, self.ip)
345 672d445a Sofia Papagiannaki
        if not check.is_valid:
346 5ce3ce4f Sofia Papagiannaki
            raise forms.ValidationError(
347 5ce3ce4f Sofia Papagiannaki
                _('You have not entered the correct words'))
348 4f78c22c Sofia Papagiannaki
    
349 eedb3923 Sofia Papagiannaki
    def clean(self):
350 eedb3923 Sofia Papagiannaki
        super(LoginForm, self).clean()
351 21f89374 Sofia Papagiannaki
        if self.user_cache and self.user_cache.provider not in ('local', ''):
352 eedb3923 Sofia Papagiannaki
            raise forms.ValidationError(_('Local login is not the current authentication method for this account.'))
353 eedb3923 Sofia Papagiannaki
        return self.cleaned_data
354 64cd4730 Antony Chazapis
355 5ce3ce4f Sofia Papagiannaki
356 890b0eaf Sofia Papagiannaki
class ProfileForm(forms.ModelForm):
357 890b0eaf Sofia Papagiannaki
    """
358 890b0eaf Sofia Papagiannaki
    Subclass of ``ModelForm`` for permiting user to edit his/her profile.
359 a5373d5f Sofia Papagiannaki
    Most of the fields are readonly since the user is not allowed to change
360 a5373d5f Sofia Papagiannaki
    them.
361 18ffbee1 Sofia Papagiannaki

362 a5373d5f Sofia Papagiannaki
    The class defines a save method which sets ``is_verified`` to True so as the
363 a5373d5f Sofia Papagiannaki
    user during the next login will not to be redirected to profile page.
364 890b0eaf Sofia Papagiannaki
    """
365 c301698f Sofia Papagiannaki
    renew = forms.BooleanField(label='Renew token', required=False)
366 18ffbee1 Sofia Papagiannaki
367 890b0eaf Sofia Papagiannaki
    class Meta:
368 890b0eaf Sofia Papagiannaki
        model = AstakosUser
369 5ce3ce4f Sofia Papagiannaki
        fields = ('email', 'first_name', 'last_name', 'auth_token',
370 5ce3ce4f Sofia Papagiannaki
                  'auth_token_expires')
371 18ffbee1 Sofia Papagiannaki
372 64cd4730 Antony Chazapis
    def __init__(self, *args, **kwargs):
373 890b0eaf Sofia Papagiannaki
        super(ProfileForm, self).__init__(*args, **kwargs)
374 890b0eaf Sofia Papagiannaki
        instance = getattr(self, 'instance', None)
375 0a569195 Sofia Papagiannaki
        ro_fields = ('email', 'auth_token', 'auth_token_expires')
376 890b0eaf Sofia Papagiannaki
        if instance and instance.id:
377 890b0eaf Sofia Papagiannaki
            for field in ro_fields:
378 890b0eaf Sofia Papagiannaki
                self.fields[field].widget.attrs['readonly'] = True
379 18ffbee1 Sofia Papagiannaki
380 890b0eaf Sofia Papagiannaki
    def save(self, commit=True):
381 890b0eaf Sofia Papagiannaki
        user = super(ProfileForm, self).save(commit=False)
382 890b0eaf Sofia Papagiannaki
        user.is_verified = True
383 c301698f Sofia Papagiannaki
        if self.cleaned_data.get('renew'):
384 c301698f Sofia Papagiannaki
            user.renew_token()
385 890b0eaf Sofia Papagiannaki
        if commit:
386 890b0eaf Sofia Papagiannaki
            user.save()
387 890b0eaf Sofia Papagiannaki
        return user
388 64cd4730 Antony Chazapis
389 5ce3ce4f Sofia Papagiannaki
390 890b0eaf Sofia Papagiannaki
class FeedbackForm(forms.Form):
391 890b0eaf Sofia Papagiannaki
    """
392 890b0eaf Sofia Papagiannaki
    Form for writing feedback.
393 890b0eaf Sofia Papagiannaki
    """
394 0a569195 Sofia Papagiannaki
    feedback_msg = forms.CharField(widget=forms.Textarea, label=u'Message')
395 8f5a3a06 Sofia Papagiannaki
    feedback_data = forms.CharField(widget=forms.HiddenInput(), label='',
396 8f5a3a06 Sofia Papagiannaki
                                    required=False)
397 5ed6816e Sofia Papagiannaki
398 5ce3ce4f Sofia Papagiannaki
399 5ed6816e Sofia Papagiannaki
class SendInvitationForm(forms.Form):
400 5ed6816e Sofia Papagiannaki
    """
401 5ed6816e Sofia Papagiannaki
    Form for sending an invitations
402 5ed6816e Sofia Papagiannaki
    """
403 18ffbee1 Sofia Papagiannaki
404 5ce3ce4f Sofia Papagiannaki
    email = forms.EmailField(required=True, label='Email address')
405 5ce3ce4f Sofia Papagiannaki
    first_name = forms.EmailField(label='First name')
406 5ce3ce4f Sofia Papagiannaki
    last_name = forms.EmailField(label='Last name')
407 5ce3ce4f Sofia Papagiannaki
408 e2125441 Sofia Papagiannaki
409 e2125441 Sofia Papagiannaki
class ExtendedPasswordResetForm(PasswordResetForm):
410 e2125441 Sofia Papagiannaki
    """
411 e2125441 Sofia Papagiannaki
    Extends PasswordResetForm by overriding save method:
412 e2125441 Sofia Papagiannaki
    passes a custom from_email in send_mail.
413 18ffbee1 Sofia Papagiannaki

414 e2125441 Sofia Papagiannaki
    Since Django 1.3 this is useless since ``django.contrib.auth.views.reset_password``
415 e2125441 Sofia Papagiannaki
    accepts a from_email argument.
416 e2125441 Sofia Papagiannaki
    """
417 23c271b3 Sofia Papagiannaki
    def clean_email(self):
418 23c271b3 Sofia Papagiannaki
        email = super(ExtendedPasswordResetForm, self).clean_email()
419 23c271b3 Sofia Papagiannaki
        try:
420 0a569195 Sofia Papagiannaki
            user = AstakosUser.objects.get(email=email, is_active=True)
421 23c271b3 Sofia Papagiannaki
            if not user.has_usable_password():
422 5ce3ce4f Sofia Papagiannaki
                raise forms.ValidationError(
423 5ce3ce4f Sofia Papagiannaki
                    _("This account has not a usable password."))
424 aab4d540 Sofia Papagiannaki
        except AstakosUser.DoesNotExist:
425 23c271b3 Sofia Papagiannaki
            raise forms.ValidationError(_('That e-mail address doesn\'t have an associated user account. Are you sure you\'ve registered?'))
426 23c271b3 Sofia Papagiannaki
        return email
427 5ce3ce4f Sofia Papagiannaki
428 5ce3ce4f Sofia Papagiannaki
    def save(
429 5ce3ce4f Sofia Papagiannaki
        self, domain_override=None, email_template_name='registration/password_reset_email.html',
430 5ce3ce4f Sofia Papagiannaki
            use_https=False, token_generator=default_token_generator, request=None):
431 e2125441 Sofia Papagiannaki
        """
432 e2125441 Sofia Papagiannaki
        Generates a one-use only link for resetting password and sends to the user.
433 e2125441 Sofia Papagiannaki
        """
434 e2125441 Sofia Papagiannaki
        for user in self.users_cache:
435 18ffbee1 Sofia Papagiannaki
            url = reverse('django.contrib.auth.views.password_reset_confirm',
436 5ce3ce4f Sofia Papagiannaki
                          kwargs={'uidb36': int_to_base36(user.id),
437 5ce3ce4f Sofia Papagiannaki
                                  'token': token_generator.make_token(user)
438 5ce3ce4f Sofia Papagiannaki
                                  }
439 5ce3ce4f Sofia Papagiannaki
                          )
440 a53b19da Sofia Papagiannaki
            url = urljoin(BASEURL, url)
441 e2125441 Sofia Papagiannaki
            t = loader.get_template(email_template_name)
442 e2125441 Sofia Papagiannaki
            c = {
443 e2125441 Sofia Papagiannaki
                'email': user.email,
444 8f378756 Sofia Papagiannaki
                'url': url,
445 374611bc Sofia Papagiannaki
                'site_name': SITENAME,
446 e2125441 Sofia Papagiannaki
                'user': user,
447 a53b19da Sofia Papagiannaki
                'baseurl': BASEURL,
448 09122dd8 Sofia Papagiannaki
                'support': DEFAULT_CONTACT_EMAIL
449 e2125441 Sofia Papagiannaki
            }
450 1cbce16f Sofia Papagiannaki
            from_email = settings.SERVER_EMAIL
451 1fcf4a99 Kostas Papadimitriou
            send_mail(_(PASSWORD_RESET_EMAIL_SUBJECT),
452 5ce3ce4f Sofia Papagiannaki
                      t.render(Context(c)), from_email, [user.email])
453 5ce3ce4f Sofia Papagiannaki
454 270dd48d Sofia Papagiannaki
455 49790d9d Sofia Papagiannaki
class EmailChangeForm(forms.ModelForm):
456 49790d9d Sofia Papagiannaki
    class Meta:
457 49790d9d Sofia Papagiannaki
        model = EmailChange
458 49790d9d Sofia Papagiannaki
        fields = ('new_email_address',)
459 5ce3ce4f Sofia Papagiannaki
460 49790d9d Sofia Papagiannaki
    def clean_new_email_address(self):
461 49790d9d Sofia Papagiannaki
        addr = self.cleaned_data['new_email_address']
462 49790d9d Sofia Papagiannaki
        if AstakosUser.objects.filter(email__iexact=addr):
463 49790d9d Sofia Papagiannaki
            raise forms.ValidationError(_(u'This email address is already in use. Please supply a different email address.'))
464 49790d9d Sofia Papagiannaki
        return addr
465 5ce3ce4f Sofia Papagiannaki
466 49790d9d Sofia Papagiannaki
    def save(self, email_template_name, request, commit=True):
467 49790d9d Sofia Papagiannaki
        ec = super(EmailChangeForm, self).save(commit=False)
468 49790d9d Sofia Papagiannaki
        ec.user = request.user
469 5ce3ce4f Sofia Papagiannaki
        activation_key = hashlib.sha1(
470 5ce3ce4f Sofia Papagiannaki
            str(random()) + smart_str(ec.new_email_address))
471 5ce3ce4f Sofia Papagiannaki
        ec.activation_key = activation_key.hexdigest()
472 49790d9d Sofia Papagiannaki
        if commit:
473 49790d9d Sofia Papagiannaki
            ec.save()
474 49790d9d Sofia Papagiannaki
        send_change_email(ec, request, email_template_name=email_template_name)
475 49790d9d Sofia Papagiannaki
476 5ce3ce4f Sofia Papagiannaki
477 270dd48d Sofia Papagiannaki
class SignApprovalTermsForm(forms.ModelForm):
478 270dd48d Sofia Papagiannaki
    class Meta:
479 270dd48d Sofia Papagiannaki
        model = AstakosUser
480 270dd48d Sofia Papagiannaki
        fields = ("has_signed_terms",)
481 18ffbee1 Sofia Papagiannaki
482 270dd48d Sofia Papagiannaki
    def __init__(self, *args, **kwargs):
483 270dd48d Sofia Papagiannaki
        super(SignApprovalTermsForm, self).__init__(*args, **kwargs)
484 18ffbee1 Sofia Papagiannaki
485 270dd48d Sofia Papagiannaki
    def clean_has_signed_terms(self):
486 270dd48d Sofia Papagiannaki
        has_signed_terms = self.cleaned_data['has_signed_terms']
487 270dd48d Sofia Papagiannaki
        if not has_signed_terms:
488 270dd48d Sofia Papagiannaki
            raise forms.ValidationError(_('You have to agree with the terms'))
489 270dd48d Sofia Papagiannaki
        return has_signed_terms
490 8f5a3a06 Sofia Papagiannaki
491 5ce3ce4f Sofia Papagiannaki
492 8f5a3a06 Sofia Papagiannaki
class InvitationForm(forms.ModelForm):
493 8f5a3a06 Sofia Papagiannaki
    username = forms.EmailField(label=_("Email"))
494 5ce3ce4f Sofia Papagiannaki
495 18ffbee1 Sofia Papagiannaki
    def __init__(self, *args, **kwargs):
496 18ffbee1 Sofia Papagiannaki
        super(InvitationForm, self).__init__(*args, **kwargs)
497 5ce3ce4f Sofia Papagiannaki
498 8f5a3a06 Sofia Papagiannaki
    class Meta:
499 8f5a3a06 Sofia Papagiannaki
        model = Invitation
500 8f5a3a06 Sofia Papagiannaki
        fields = ('username', 'realname')
501 5ce3ce4f Sofia Papagiannaki
502 8f5a3a06 Sofia Papagiannaki
    def clean_username(self):
503 8f5a3a06 Sofia Papagiannaki
        username = self.cleaned_data['username']
504 8f5a3a06 Sofia Papagiannaki
        try:
505 5ce3ce4f Sofia Papagiannaki
            Invitation.objects.get(username=username)
506 5ce3ce4f Sofia Papagiannaki
            raise forms.ValidationError(
507 5ce3ce4f Sofia Papagiannaki
                _('There is already invitation for this email.'))
508 8f5a3a06 Sofia Papagiannaki
        except Invitation.DoesNotExist:
509 8f5a3a06 Sofia Papagiannaki
            pass
510 18ffbee1 Sofia Papagiannaki
        return username
511 1039bab1 Sofia Papagiannaki
512 5ce3ce4f Sofia Papagiannaki
513 1039bab1 Sofia Papagiannaki
class ExtendedPasswordChangeForm(PasswordChangeForm):
514 1039bab1 Sofia Papagiannaki
    """
515 1039bab1 Sofia Papagiannaki
    Extends PasswordChangeForm by enabling user
516 1039bab1 Sofia Papagiannaki
    to optionally renew also the token.
517 1039bab1 Sofia Papagiannaki
    """
518 ee210d1d Sofia Papagiannaki
    if not NEWPASSWD_INVALIDATE_TOKEN:
519 48e9f076 Sofia Papagiannaki
        renew = forms.BooleanField(label='Renew token', required=False,
520 48e9f076 Sofia Papagiannaki
                                   initial=True,
521 48e9f076 Sofia Papagiannaki
                                   help_text='Unsetting this may result in security risk.')
522 5ce3ce4f Sofia Papagiannaki
523 1039bab1 Sofia Papagiannaki
    def __init__(self, user, *args, **kwargs):
524 1039bab1 Sofia Papagiannaki
        super(ExtendedPasswordChangeForm, self).__init__(user, *args, **kwargs)
525 5ce3ce4f Sofia Papagiannaki
526 1039bab1 Sofia Papagiannaki
    def save(self, commit=True):
527 1039bab1 Sofia Papagiannaki
        user = super(ExtendedPasswordChangeForm, self).save(commit=False)
528 ee210d1d Sofia Papagiannaki
        if NEWPASSWD_INVALIDATE_TOKEN or self.cleaned_data.get('renew'):
529 1039bab1 Sofia Papagiannaki
            user.renew_token()
530 1039bab1 Sofia Papagiannaki
        if commit:
531 1039bab1 Sofia Papagiannaki
            user.save()
532 8e45d6fd Sofia Papagiannaki
        return user
533 8e45d6fd Sofia Papagiannaki
534 5ce3ce4f Sofia Papagiannaki
535 0f4fa26d Sofia Papagiannaki
class AstakosGroupCreationForm(forms.ModelForm):
536 0f4fa26d Sofia Papagiannaki
    kind = forms.ModelChoiceField(
537 0f4fa26d Sofia Papagiannaki
        queryset=GroupKind.objects.all(),
538 0f4fa26d Sofia Papagiannaki
        label="",
539 0f4fa26d Sofia Papagiannaki
        widget=forms.HiddenInput()
540 0f4fa26d Sofia Papagiannaki
    )
541 0f4fa26d Sofia Papagiannaki
    name = forms.URLField()
542 1831a0fe Olga Brani
    moderation_enabled = forms.BooleanField(
543 1831a0fe Olga Brani
        help_text="Check if you want to approve members participation manually",
544 1831a0fe Olga Brani
        required=False   
545 1831a0fe Olga Brani
    )
546 8e45d6fd Sofia Papagiannaki
    
547 0f4fa26d Sofia Papagiannaki
    class Meta:
548 0f4fa26d Sofia Papagiannaki
        model = AstakosGroup
549 5ce3ce4f Sofia Papagiannaki
550 0f4fa26d Sofia Papagiannaki
    def __init__(self, *args, **kwargs):
551 0f4fa26d Sofia Papagiannaki
        try:
552 0f4fa26d Sofia Papagiannaki
            resources = kwargs.pop('resources')
553 0f4fa26d Sofia Papagiannaki
        except KeyError:
554 0f4fa26d Sofia Papagiannaki
            resources = {}
555 0f4fa26d Sofia Papagiannaki
        super(AstakosGroupCreationForm, self).__init__(*args, **kwargs)
556 7faeaef3 Olga Brani
        self.fields.keyOrder = ['kind', 'name', 'homepage', 'desc', 'issue_date',
557 0f4fa26d Sofia Papagiannaki
                                'expiration_date', 'estimated_participants',
558 0f4fa26d Sofia Papagiannaki
                                'moderation_enabled']
559 0f4fa26d Sofia Papagiannaki
        for id, r in resources.iteritems():
560 0f4fa26d Sofia Papagiannaki
            self.fields['resource_%s' % id] = forms.IntegerField(
561 0f4fa26d Sofia Papagiannaki
                label=r,
562 0f4fa26d Sofia Papagiannaki
                required=False,
563 0f4fa26d Sofia Papagiannaki
                help_text=_('Leave it blank for no additional quota.')
564 0f4fa26d Sofia Papagiannaki
            )
565 5ce3ce4f Sofia Papagiannaki
566 0f4fa26d Sofia Papagiannaki
    def resources(self):
567 0f4fa26d Sofia Papagiannaki
        for name, value in self.cleaned_data.items():
568 0f4fa26d Sofia Papagiannaki
            prefix, delimiter, suffix = name.partition('resource_')
569 0f4fa26d Sofia Papagiannaki
            if suffix:
570 0f4fa26d Sofia Papagiannaki
                # yield only those having a value
571 0f4fa26d Sofia Papagiannaki
                if not value:
572 0f4fa26d Sofia Papagiannaki
                    continue
573 0f4fa26d Sofia Papagiannaki
                yield (suffix, value)
574 01ac12d5 Sofia Papagiannaki
575 51c57c9c Sofia Papagiannaki
class AstakosGroupUpdateForm(forms.ModelForm):
576 51c57c9c Sofia Papagiannaki
    class Meta:
577 51c57c9c Sofia Papagiannaki
        model = AstakosGroup
578 51c57c9c Sofia Papagiannaki
        fields = ('homepage', 'desc')
579 5ce3ce4f Sofia Papagiannaki
580 a4233484 Sofia Papagiannaki
class AddGroupMembersForm(forms.Form):
581 a4233484 Sofia Papagiannaki
    q = forms.CharField(max_length=800, widget=forms.Textarea, label=_('Search users'),
582 a4233484 Sofia Papagiannaki
                        help_text=_('Add comma separated user emails'),
583 a4233484 Sofia Papagiannaki
                        required=True)
584 a4233484 Sofia Papagiannaki
    
585 a4233484 Sofia Papagiannaki
    def clean(self):
586 a4233484 Sofia Papagiannaki
        q = self.cleaned_data.get('q') or ''
587 a4233484 Sofia Papagiannaki
        users = q.split(',')
588 a4233484 Sofia Papagiannaki
        users = list(u.strip() for u in users if u)
589 a4233484 Sofia Papagiannaki
        db_entries = AstakosUser.objects.filter(email__in=users)
590 a4233484 Sofia Papagiannaki
        unknown = list(set(users) - set(u.email for u in db_entries))
591 a4233484 Sofia Papagiannaki
        if unknown:
592 a4233484 Sofia Papagiannaki
            raise forms.ValidationError(
593 9e5075ef Sofia Papagiannaki
                _('Unknown users: %s' % ','.join(unknown)))
594 a4233484 Sofia Papagiannaki
        self.valid_users = db_entries
595 a4233484 Sofia Papagiannaki
        return self.cleaned_data
596 a4233484 Sofia Papagiannaki
    
597 a4233484 Sofia Papagiannaki
    def get_valid_users(self):
598 a4233484 Sofia Papagiannaki
        """Should be called after form cleaning"""
599 a4233484 Sofia Papagiannaki
        try:
600 a4233484 Sofia Papagiannaki
            return self.valid_users
601 a4233484 Sofia Papagiannaki
        except:
602 a4233484 Sofia Papagiannaki
            return ()
603 a4233484 Sofia Papagiannaki
604 a4233484 Sofia Papagiannaki
605 01ac12d5 Sofia Papagiannaki
class AstakosGroupSearchForm(forms.Form):
606 5ce3ce4f Sofia Papagiannaki
    q = forms.CharField(max_length=200, label='Search group')
607 54213d7a Sofia Papagiannaki
608 54213d7a Sofia Papagiannaki
class TimelineForm(forms.Form):
609 88305cf0 root
#    entity = forms.CharField(
610 88305cf0 root
#        widget=forms.HiddenInput(), label='')
611 88305cf0 root
    entity = forms.ModelChoiceField(
612 88305cf0 root
        queryset=AstakosUser.objects.filter(is_active = True)
613 88305cf0 root
    )
614 54213d7a Sofia Papagiannaki
    resource = forms.ModelChoiceField(
615 6e52912b Sofia Papagiannaki
        queryset=Resource.objects.all()
616 54213d7a Sofia Papagiannaki
    )
617 54213d7a Sofia Papagiannaki
    start_date = forms.DateTimeField()
618 54213d7a Sofia Papagiannaki
    end_date = forms.DateTimeField()
619 82b05401 root
    details = forms.BooleanField(required=False, label="Detailed Listing")
620 82b05401 root
    operation = forms.ChoiceField(
621 82b05401 root
                        label   = 'Charge Method',
622 82b05401 root
                        choices = ( ('',                '-------------'),
623 82b05401 root
                                    ('charge_usage',    'Charge Usage'),
624 82b05401 root
                                    ('charge_traffic',  'Charge Traffic'), )
625 82b05401 root
                )
626 6e52912b Sofia Papagiannaki
    def clean(self):
627 6e52912b Sofia Papagiannaki
        super(TimelineForm, self).clean()
628 6e52912b Sofia Papagiannaki
        d = self.cleaned_data
629 6e52912b Sofia Papagiannaki
        if 'resource' in d:
630 6e52912b Sofia Papagiannaki
            d['resource'] = str(d['resource'])
631 6e52912b Sofia Papagiannaki
        if 'start_date' in d:
632 c3f6cdf1 root
            d['start_date'] = d['start_date'].strftime("%Y-%m-%dT%H:%M:%S.%f")[:24]
633 6e52912b Sofia Papagiannaki
        if 'end_date' in d:
634 c3f6cdf1 root
            d['end_date'] = d['end_date'].strftime("%Y-%m-%dT%H:%M:%S.%f")[:24]
635 88305cf0 root
        if 'entity' in d:
636 88305cf0 root
            d['entity'] = d['entity'].email 
637 c3f6cdf1 root
        return d
638 c3f6cdf1 root
639 789bcaf9 Sofia Papagiannaki
class AstakosGroupSortForm(forms.Form):
640 789bcaf9 Sofia Papagiannaki
    sort_by = forms.ChoiceField(label='Sort by',
641 3bb604eb Sofia Papagiannaki
                                choices=(('groupname', 'Name'),
642 3bb604eb Sofia Papagiannaki
                                         ('kindname', 'Type'),
643 3bb604eb Sofia Papagiannaki
                                         ('issue_date', 'Issue Date'),
644 2be26b73 Olga Brani
                                         ('expiration_date', 'Expiration Date'),
645 2be26b73 Olga Brani
                                         ('approved_members_num', 'Participants'),
646 2be26b73 Olga Brani
                                         ('is_enabled', 'Status'),
647 04febd09 Olga Brani
                                         ('moderation_enabled', 'Moderation'),
648 04febd09 Olga Brani
                                         ('membership_status','Enrollment Status')
649 2be26b73 Olga Brani
                                         ),
650 1b3db4f0 root
                                required=False)
651 801be7a3 Sofia Papagiannaki
652 801be7a3 Sofia Papagiannaki
class MembersSortForm(forms.Form):
653 801be7a3 Sofia Papagiannaki
    sort_by = forms.ChoiceField(label='Sort by',
654 801be7a3 Sofia Papagiannaki
                                choices=(('person__email', 'User Id'),
655 801be7a3 Sofia Papagiannaki
                                         ('person__first_name', 'Name'),
656 801be7a3 Sofia Papagiannaki
                                         ('date_joined', 'Status')
657 801be7a3 Sofia Papagiannaki
                                         ),
658 1b3db4f0 root
                                required=False)
659 9eafaa32 Sofia Papagiannaki
660 9eafaa32 Sofia Papagiannaki
class PickResourceForm(forms.Form):
661 9eafaa32 Sofia Papagiannaki
    resource = forms.ModelChoiceField(
662 9eafaa32 Sofia Papagiannaki
        queryset=Resource.objects.select_related().all()
663 9eafaa32 Sofia Papagiannaki
    )
664 485c713e Sofia Papagiannaki
    resource.widget.attrs["onchange"]="this.form.submit()"
665 485c713e Sofia Papagiannaki
666 48e9f076 Sofia Papagiannaki
class ExtendedSetPasswordForm(SetPasswordForm):
667 48e9f076 Sofia Papagiannaki
    """
668 48e9f076 Sofia Papagiannaki
    Extends SetPasswordForm by enabling user
669 48e9f076 Sofia Papagiannaki
    to optionally renew also the token.
670 48e9f076 Sofia Papagiannaki
    """
671 ee210d1d Sofia Papagiannaki
    if not NEWPASSWD_INVALIDATE_TOKEN:
672 48e9f076 Sofia Papagiannaki
        renew = forms.BooleanField(label='Renew token', required=False,
673 48e9f076 Sofia Papagiannaki
                                   initial=True,
674 48e9f076 Sofia Papagiannaki
                                   help_text='Unsetting this may result in security risk.')
675 48e9f076 Sofia Papagiannaki
    
676 48e9f076 Sofia Papagiannaki
    def __init__(self, user, *args, **kwargs):
677 48e9f076 Sofia Papagiannaki
        super(ExtendedSetPasswordForm, self).__init__(user, *args, **kwargs)
678 48e9f076 Sofia Papagiannaki
    
679 48e9f076 Sofia Papagiannaki
    def save(self, commit=True):
680 48e9f076 Sofia Papagiannaki
        user = super(ExtendedSetPasswordForm, self).save(commit=False)
681 ee210d1d Sofia Papagiannaki
        if NEWPASSWD_INVALIDATE_TOKEN or self.cleaned_data.get('renew'):
682 48e9f076 Sofia Papagiannaki
            try:
683 48e9f076 Sofia Papagiannaki
                user = AstakosUser.objects.get(id=user.id)
684 48e9f076 Sofia Papagiannaki
            except AstakosUser.DoesNotExist:
685 48e9f076 Sofia Papagiannaki
                pass
686 48e9f076 Sofia Papagiannaki
            else:
687 48e9f076 Sofia Papagiannaki
                user.renew_token()
688 48e9f076 Sofia Papagiannaki
        if commit:
689 48e9f076 Sofia Papagiannaki
            user.save()
690 a5373d5f Sofia Papagiannaki
        return user