Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / forms.py @ 73fbaec4

History | View | Annotate | Download (37.7 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 caf70869 Sofia Papagiannaki
from random import random
35 64cd4730 Antony Chazapis
36 64cd4730 Antony Chazapis
from django import forms
37 64cd4730 Antony Chazapis
from django.utils.translation import ugettext as _
38 e1a80257 Sofia Papagiannaki
from django.contrib.auth.forms import (
39 e1a80257 Sofia Papagiannaki
    UserCreationForm, AuthenticationForm,
40 e1a80257 Sofia Papagiannaki
    PasswordResetForm, PasswordChangeForm,
41 73fbaec4 Sofia Papagiannaki
    SetPasswordForm)
42 e2125441 Sofia Papagiannaki
from django.core.mail import send_mail
43 e2125441 Sofia Papagiannaki
from django.contrib.auth.tokens import default_token_generator
44 e2125441 Sofia Papagiannaki
from django.template import Context, loader
45 e2125441 Sofia Papagiannaki
from django.utils.http import int_to_base36
46 374611bc Sofia Papagiannaki
from django.core.urlresolvers import reverse
47 18ffbee1 Sofia Papagiannaki
from django.utils.safestring import mark_safe
48 49790d9d Sofia Papagiannaki
from django.utils.encoding import smart_str
49 1cbce16f Sofia Papagiannaki
from django.conf import settings
50 678b2236 Sofia Papagiannaki
from django.forms.models import fields_for_model
51 d2633501 Kostas Papadimitriou
from django.db import transaction
52 caf70869 Sofia Papagiannaki
from django.utils.encoding import smart_unicode
53 caf70869 Sofia Papagiannaki
from django.core import validators
54 e1a80257 Sofia Papagiannaki
from django.contrib.auth.models import AnonymousUser
55 5ed6816e Sofia Papagiannaki
56 678b2236 Sofia Papagiannaki
from astakos.im.models import (
57 73fbaec4 Sofia Papagiannaki
    AstakosUser, EmailChange, Invitation,
58 73fbaec4 Sofia Papagiannaki
#     AstakosGroup, GroupKind,
59 e1a80257 Sofia Papagiannaki
    Resource, PendingThirdPartyUser, get_latest_terms, RESOURCE_SEPARATOR,
60 73fbaec4 Sofia Papagiannaki
    ProjectApplication)
61 c0b26605 Sofia Papagiannaki
from astakos.im.settings import (
62 c0b26605 Sofia Papagiannaki
    INVITATIONS_PER_LEVEL, BASEURL, SITENAME, RECAPTCHA_PRIVATE_KEY,
63 c0b26605 Sofia Papagiannaki
    RECAPTCHA_ENABLED, DEFAULT_CONTACT_EMAIL, LOGGING_LEVEL,
64 2e90e3ec Kostas Papadimitriou
    PASSWORD_RESET_EMAIL_SUBJECT, NEWPASSWD_INVALIDATE_TOKEN,
65 73fbaec4 Sofia Papagiannaki
    MODERATION_ENABLED)
66 45f8d9ff Sofia Papagiannaki
from astakos.im.widgets import DummyWidget, RecaptchaWidget
67 73fbaec4 Sofia Papagiannaki
from astakos.im.functions import send_change_email, submit_application
68 270dd48d Sofia Papagiannaki
69 aab4d540 Sofia Papagiannaki
from astakos.im.util import reserved_email, get_query
70 64cd4730 Antony Chazapis
71 ae497612 Olga Brani
import astakos.im.messages as astakos_messages
72 64cd4730 Antony Chazapis
73 3bf924ec Sofia Papagiannaki
import logging
74 49790d9d Sofia Papagiannaki
import hashlib
75 db7fecd9 Sofia Papagiannaki
import recaptcha.client.captcha as captcha
76 caf70869 Sofia Papagiannaki
import re
77 64cd4730 Antony Chazapis
78 e015e9e6 Sofia Papagiannaki
logger = logging.getLogger(__name__)
79 e015e9e6 Sofia Papagiannaki
80 caf70869 Sofia Papagiannaki
DOMAIN_VALUE_REGEX = re.compile(
81 caf70869 Sofia Papagiannaki
    r'^(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.){0,126}(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?))$',
82 73fbaec4 Sofia Papagiannaki
    re.IGNORECASE)
83 d2633501 Kostas Papadimitriou
84 caf70869 Sofia Papagiannaki
class StoreUserMixin(object):
85 d2633501 Kostas Papadimitriou
    @transaction.commit_on_success
86 d2633501 Kostas Papadimitriou
    def store_user(self, user, request):
87 d2633501 Kostas Papadimitriou
        user.save()
88 d2633501 Kostas Papadimitriou
        self.post_store_user(user, request)
89 d2633501 Kostas Papadimitriou
        return user
90 d2633501 Kostas Papadimitriou
91 d2633501 Kostas Papadimitriou
    def post_store_user(self, user, request):
92 d2633501 Kostas Papadimitriou
        """
93 d2633501 Kostas Papadimitriou
        Interface method for descendant backends to be able to do stuff within
94 d2633501 Kostas Papadimitriou
        the transaction enabled by store_user.
95 d2633501 Kostas Papadimitriou
        """
96 d2633501 Kostas Papadimitriou
        pass
97 d2633501 Kostas Papadimitriou
98 d2633501 Kostas Papadimitriou
99 d2633501 Kostas Papadimitriou
class LocalUserCreationForm(UserCreationForm, StoreUserMixin):
100 890b0eaf Sofia Papagiannaki
    """
101 890b0eaf Sofia Papagiannaki
    Extends the built in UserCreationForm in several ways:
102 18ffbee1 Sofia Papagiannaki

103 8316698a Sofia Papagiannaki
    * Adds email, first_name, last_name, recaptcha_challenge_field, recaptcha_response_field field.
104 5ed6816e Sofia Papagiannaki
    * The username field isn't visible and it is assigned a generated id.
105 18ffbee1 Sofia Papagiannaki
    * User created is not active.
106 890b0eaf Sofia Papagiannaki
    """
107 db7fecd9 Sofia Papagiannaki
    recaptcha_challenge_field = forms.CharField(widget=DummyWidget)
108 5ce3ce4f Sofia Papagiannaki
    recaptcha_response_field = forms.CharField(
109 5ce3ce4f Sofia Papagiannaki
        widget=RecaptchaWidget, label='')
110 18ffbee1 Sofia Papagiannaki
111 794852f2 Sofia Papagiannaki
    class Meta:
112 794852f2 Sofia Papagiannaki
        model = AstakosUser
113 5ce3ce4f Sofia Papagiannaki
        fields = ("email", "first_name", "last_name",
114 5ce3ce4f Sofia Papagiannaki
                  "has_signed_terms", "has_signed_terms")
115 18ffbee1 Sofia Papagiannaki
116 64cd4730 Antony Chazapis
    def __init__(self, *args, **kwargs):
117 64cd4730 Antony Chazapis
        """
118 890b0eaf Sofia Papagiannaki
        Changes the order of fields, and removes the username field.
119 64cd4730 Antony Chazapis
        """
120 bf0c6de5 Sofia Papagiannaki
        request = kwargs.pop('request', None)
121 672d445a Sofia Papagiannaki
        if request:
122 672d445a Sofia Papagiannaki
            self.ip = request.META.get('REMOTE_ADDR',
123 672d445a Sofia Papagiannaki
                                       request.META.get('HTTP_X_REAL_IP', None))
124 ab8bfb29 Kostas Papadimitriou
125 15efc749 Sofia Papagiannaki
        super(LocalUserCreationForm, self).__init__(*args, **kwargs)
126 890b0eaf Sofia Papagiannaki
        self.fields.keyOrder = ['email', 'first_name', 'last_name',
127 d8f63346 Sofia Papagiannaki
                                'password1', 'password2']
128 1b3398a0 Olga Brani
129 53bf2659 Sofia Papagiannaki
        if RECAPTCHA_ENABLED:
130 53bf2659 Sofia Papagiannaki
            self.fields.keyOrder.extend(['recaptcha_challenge_field',
131 5ce3ce4f Sofia Papagiannaki
                                         'recaptcha_response_field', ])
132 1b3398a0 Olga Brani
        if get_latest_terms():
133 1b3398a0 Olga Brani
            self.fields.keyOrder.append('has_signed_terms')
134 18ffbee1 Sofia Papagiannaki
135 18ffbee1 Sofia Papagiannaki
        if 'has_signed_terms' in self.fields:
136 18ffbee1 Sofia Papagiannaki
            # Overriding field label since we need to apply a link
137 18ffbee1 Sofia Papagiannaki
            # to the terms within the label
138 18ffbee1 Sofia Papagiannaki
            terms_link_html = '<a href="%s" target="_blank">%s</a>' \
139 5ce3ce4f Sofia Papagiannaki
                % (reverse('latest_terms'), _("the terms"))
140 18ffbee1 Sofia Papagiannaki
            self.fields['has_signed_terms'].label = \
141 5ce3ce4f Sofia Papagiannaki
                mark_safe("I agree with %s" % terms_link_html)
142 18ffbee1 Sofia Papagiannaki
143 af4eb974 Sofia Papagiannaki
    def clean_email(self):
144 d2633501 Kostas Papadimitriou
        email = self.cleaned_data['email'].lower()
145 881c856c Sofia Papagiannaki
        if not email:
146 ae497612 Olga Brani
            raise forms.ValidationError(_(astakos_messages.REQUIRED_FIELD))
147 0a569195 Sofia Papagiannaki
        if reserved_email(email):
148 ae497612 Olga Brani
            raise forms.ValidationError(_(astakos_messages.EMAIL_USED))
149 0a569195 Sofia Papagiannaki
        return email
150 18ffbee1 Sofia Papagiannaki
151 270dd48d Sofia Papagiannaki
    def clean_has_signed_terms(self):
152 270dd48d Sofia Papagiannaki
        has_signed_terms = self.cleaned_data['has_signed_terms']
153 270dd48d Sofia Papagiannaki
        if not has_signed_terms:
154 ae497612 Olga Brani
            raise forms.ValidationError(_(astakos_messages.SIGN_TERMS))
155 270dd48d Sofia Papagiannaki
        return has_signed_terms
156 18ffbee1 Sofia Papagiannaki
157 db7fecd9 Sofia Papagiannaki
    def clean_recaptcha_response_field(self):
158 db7fecd9 Sofia Papagiannaki
        if 'recaptcha_challenge_field' in self.cleaned_data:
159 db7fecd9 Sofia Papagiannaki
            self.validate_captcha()
160 db7fecd9 Sofia Papagiannaki
        return self.cleaned_data['recaptcha_response_field']
161 db7fecd9 Sofia Papagiannaki
162 db7fecd9 Sofia Papagiannaki
    def clean_recaptcha_challenge_field(self):
163 db7fecd9 Sofia Papagiannaki
        if 'recaptcha_response_field' in self.cleaned_data:
164 db7fecd9 Sofia Papagiannaki
            self.validate_captcha()
165 db7fecd9 Sofia Papagiannaki
        return self.cleaned_data['recaptcha_challenge_field']
166 db7fecd9 Sofia Papagiannaki
167 db7fecd9 Sofia Papagiannaki
    def validate_captcha(self):
168 db7fecd9 Sofia Papagiannaki
        rcf = self.cleaned_data['recaptcha_challenge_field']
169 db7fecd9 Sofia Papagiannaki
        rrf = self.cleaned_data['recaptcha_response_field']
170 db7fecd9 Sofia Papagiannaki
        check = captcha.submit(rcf, rrf, RECAPTCHA_PRIVATE_KEY, self.ip)
171 db7fecd9 Sofia Papagiannaki
        if not check.is_valid:
172 ae497612 Olga Brani
            raise forms.ValidationError(_(astakos_messages.CAPTCHA_VALIDATION_ERR))
173 18ffbee1 Sofia Papagiannaki
174 d2633501 Kostas Papadimitriou
    def post_store_user(self, user, request):
175 d2633501 Kostas Papadimitriou
        """
176 d2633501 Kostas Papadimitriou
        Interface method for descendant backends to be able to do stuff within
177 d2633501 Kostas Papadimitriou
        the transaction enabled by store_user.
178 d2633501 Kostas Papadimitriou
        """
179 d2633501 Kostas Papadimitriou
        user.add_auth_provider('local', auth_backend='astakos')
180 d2633501 Kostas Papadimitriou
        user.set_password(self.cleaned_data['password1'])
181 d2633501 Kostas Papadimitriou
182 890b0eaf Sofia Papagiannaki
    def save(self, commit=True):
183 64cd4730 Antony Chazapis
        """
184 890b0eaf Sofia Papagiannaki
        Saves the email, first_name and last_name properties, after the normal
185 890b0eaf Sofia Papagiannaki
        save behavior is complete.
186 890b0eaf Sofia Papagiannaki
        """
187 15efc749 Sofia Papagiannaki
        user = super(LocalUserCreationForm, self).save(commit=False)
188 d2633501 Kostas Papadimitriou
        user.renew_token()
189 9fb8e808 Sofia Papagiannaki
        if commit:
190 9fb8e808 Sofia Papagiannaki
            user.save()
191 aab4d540 Sofia Papagiannaki
            logger.log(LOGGING_LEVEL, 'Created user %s' % user.email)
192 890b0eaf Sofia Papagiannaki
        return user
193 64cd4730 Antony Chazapis
194 5ce3ce4f Sofia Papagiannaki
195 15efc749 Sofia Papagiannaki
class InvitedLocalUserCreationForm(LocalUserCreationForm):
196 890b0eaf Sofia Papagiannaki
    """
197 062c970c Sofia Papagiannaki
    Extends the LocalUserCreationForm: email is readonly.
198 890b0eaf Sofia Papagiannaki
    """
199 794852f2 Sofia Papagiannaki
    class Meta:
200 794852f2 Sofia Papagiannaki
        model = AstakosUser
201 270dd48d Sofia Papagiannaki
        fields = ("email", "first_name", "last_name", "has_signed_terms")
202 18ffbee1 Sofia Papagiannaki
203 64cd4730 Antony Chazapis
    def __init__(self, *args, **kwargs):
204 64cd4730 Antony Chazapis
        """
205 3bf924ec Sofia Papagiannaki
        Changes the order of fields, and removes the username field.
206 64cd4730 Antony Chazapis
        """
207 15efc749 Sofia Papagiannaki
        super(InvitedLocalUserCreationForm, self).__init__(*args, **kwargs)
208 18ffbee1 Sofia Papagiannaki
209 64cd4730 Antony Chazapis
        #set readonly form fields
210 062c970c Sofia Papagiannaki
        ro = ('email', 'username',)
211 4e30244e Sofia Papagiannaki
        for f in ro:
212 4e30244e Sofia Papagiannaki
            self.fields[f].widget.attrs['readonly'] = True
213 ab8bfb29 Kostas Papadimitriou
214 9fb8e808 Sofia Papagiannaki
    def save(self, commit=True):
215 15efc749 Sofia Papagiannaki
        user = super(InvitedLocalUserCreationForm, self).save(commit=False)
216 74836e50 Sofia Papagiannaki
        user.set_invitations_level()
217 8316698a Sofia Papagiannaki
        user.email_verified = True
218 9fb8e808 Sofia Papagiannaki
        if commit:
219 9fb8e808 Sofia Papagiannaki
            user.save()
220 9fb8e808 Sofia Papagiannaki
        return user
221 5ed6816e Sofia Papagiannaki
222 d2633501 Kostas Papadimitriou
223 d2633501 Kostas Papadimitriou
class ThirdPartyUserCreationForm(forms.ModelForm, StoreUserMixin):
224 6c8a3f7c Sofia Papagiannaki
    id = forms.CharField(
225 6c8a3f7c Sofia Papagiannaki
        widget=forms.HiddenInput(),
226 6c8a3f7c Sofia Papagiannaki
        label='',
227 6c8a3f7c Sofia Papagiannaki
        required=False
228 6c8a3f7c Sofia Papagiannaki
    )
229 ef20ea07 Sofia Papagiannaki
    third_party_identifier = forms.CharField(
230 ef20ea07 Sofia Papagiannaki
        widget=forms.HiddenInput(),
231 ef20ea07 Sofia Papagiannaki
        label=''
232 ef20ea07 Sofia Papagiannaki
    )
233 8f5a3a06 Sofia Papagiannaki
    class Meta:
234 8f5a3a06 Sofia Papagiannaki
        model = AstakosUser
235 6c8a3f7c Sofia Papagiannaki
        fields = ['id', 'email', 'third_party_identifier', 'first_name', 'last_name']
236 ab8bfb29 Kostas Papadimitriou
237 8f5a3a06 Sofia Papagiannaki
    def __init__(self, *args, **kwargs):
238 8f5a3a06 Sofia Papagiannaki
        """
239 8f5a3a06 Sofia Papagiannaki
        Changes the order of fields, and removes the username field.
240 8f5a3a06 Sofia Papagiannaki
        """
241 0a569195 Sofia Papagiannaki
        self.request = kwargs.get('request', None)
242 0a569195 Sofia Papagiannaki
        if self.request:
243 0a569195 Sofia Papagiannaki
            kwargs.pop('request')
244 2e90e3ec Kostas Papadimitriou
245 ef20ea07 Sofia Papagiannaki
        latest_terms = get_latest_terms()
246 ef20ea07 Sofia Papagiannaki
        if latest_terms:
247 ef20ea07 Sofia Papagiannaki
            self._meta.fields.append('has_signed_terms')
248 2e90e3ec Kostas Papadimitriou
249 8f5a3a06 Sofia Papagiannaki
        super(ThirdPartyUserCreationForm, self).__init__(*args, **kwargs)
250 2e90e3ec Kostas Papadimitriou
251 ef20ea07 Sofia Papagiannaki
        if latest_terms:
252 8f5a3a06 Sofia Papagiannaki
            self.fields.keyOrder.append('has_signed_terms')
253 2e90e3ec Kostas Papadimitriou
254 18ffbee1 Sofia Papagiannaki
        if 'has_signed_terms' in self.fields:
255 18ffbee1 Sofia Papagiannaki
            # Overriding field label since we need to apply a link
256 18ffbee1 Sofia Papagiannaki
            # to the terms within the label
257 18ffbee1 Sofia Papagiannaki
            terms_link_html = '<a href="%s" target="_blank">%s</a>' \
258 5ce3ce4f Sofia Papagiannaki
                % (reverse('latest_terms'), _("the terms"))
259 18ffbee1 Sofia Papagiannaki
            self.fields['has_signed_terms'].label = \
260 18ffbee1 Sofia Papagiannaki
                    mark_safe("I agree with %s" % terms_link_html)
261 2e90e3ec Kostas Papadimitriou
262 18ffbee1 Sofia Papagiannaki
    def clean_email(self):
263 d2633501 Kostas Papadimitriou
        email = self.cleaned_data['email'].lower()
264 18ffbee1 Sofia Papagiannaki
        if not email:
265 ae497612 Olga Brani
            raise forms.ValidationError(_(astakos_messages.REQUIRED_FIELD))
266 0a569195 Sofia Papagiannaki
        return email
267 ab8bfb29 Kostas Papadimitriou
268 18ffbee1 Sofia Papagiannaki
    def clean_has_signed_terms(self):
269 18ffbee1 Sofia Papagiannaki
        has_signed_terms = self.cleaned_data['has_signed_terms']
270 18ffbee1 Sofia Papagiannaki
        if not has_signed_terms:
271 ae497612 Olga Brani
            raise forms.ValidationError(_(astakos_messages.SIGN_TERMS))
272 18ffbee1 Sofia Papagiannaki
        return has_signed_terms
273 ab8bfb29 Kostas Papadimitriou
274 d2633501 Kostas Papadimitriou
    def post_store_user(self, user, request):
275 d2633501 Kostas Papadimitriou
        pending = PendingThirdPartyUser.objects.get(
276 d2633501 Kostas Papadimitriou
                                token=request.POST.get('third_party_token'),
277 d2633501 Kostas Papadimitriou
                                third_party_identifier= \
278 d2633501 Kostas Papadimitriou
            self.cleaned_data.get('third_party_identifier'))
279 d2633501 Kostas Papadimitriou
        return user.add_pending_auth_provider(pending)
280 d2633501 Kostas Papadimitriou
281 d2633501 Kostas Papadimitriou
282 8f5a3a06 Sofia Papagiannaki
    def save(self, commit=True):
283 8f5a3a06 Sofia Papagiannaki
        user = super(ThirdPartyUserCreationForm, self).save(commit=False)
284 8f5a3a06 Sofia Papagiannaki
        user.set_unusable_password()
285 d2633501 Kostas Papadimitriou
        user.renew_token()
286 8f5a3a06 Sofia Papagiannaki
        if commit:
287 8f5a3a06 Sofia Papagiannaki
            user.save()
288 aab4d540 Sofia Papagiannaki
            logger.log(LOGGING_LEVEL, 'Created user %s' % user.email)
289 8f5a3a06 Sofia Papagiannaki
        return user
290 8f5a3a06 Sofia Papagiannaki
291 5ce3ce4f Sofia Papagiannaki
292 8f5a3a06 Sofia Papagiannaki
class InvitedThirdPartyUserCreationForm(ThirdPartyUserCreationForm):
293 4e30244e Sofia Papagiannaki
    """
294 062c970c Sofia Papagiannaki
    Extends the ThirdPartyUserCreationForm: email is readonly.
295 4e30244e Sofia Papagiannaki
    """
296 8f5a3a06 Sofia Papagiannaki
    def __init__(self, *args, **kwargs):
297 4e30244e Sofia Papagiannaki
        """
298 4e30244e Sofia Papagiannaki
        Changes the order of fields, and removes the username field.
299 4e30244e Sofia Papagiannaki
        """
300 5ce3ce4f Sofia Papagiannaki
        super(
301 5ce3ce4f Sofia Papagiannaki
            InvitedThirdPartyUserCreationForm, self).__init__(*args, **kwargs)
302 4e30244e Sofia Papagiannaki
303 8f5a3a06 Sofia Papagiannaki
        #set readonly form fields
304 062c970c Sofia Papagiannaki
        ro = ('email',)
305 4e30244e Sofia Papagiannaki
        for f in ro:
306 4e30244e Sofia Papagiannaki
            self.fields[f].widget.attrs['readonly'] = True
307 ab8bfb29 Kostas Papadimitriou
308 4e30244e Sofia Papagiannaki
    def save(self, commit=True):
309 4e30244e Sofia Papagiannaki
        user = super(InvitedThirdPartyUserCreationForm, self).save(commit=False)
310 d2633501 Kostas Papadimitriou
        user.set_invitation_level()
311 4e30244e Sofia Papagiannaki
        user.email_verified = True
312 4e30244e Sofia Papagiannaki
        if commit:
313 4e30244e Sofia Papagiannaki
            user.save()
314 4e30244e Sofia Papagiannaki
        return user
315 8f5a3a06 Sofia Papagiannaki
316 5ce3ce4f Sofia Papagiannaki
317 18ffbee1 Sofia Papagiannaki
class ShibbolethUserCreationForm(ThirdPartyUserCreationForm):
318 5ce3ce4f Sofia Papagiannaki
    additional_email = forms.CharField(
319 5ce3ce4f Sofia Papagiannaki
        widget=forms.HiddenInput(), label='', required=False)
320 ab8bfb29 Kostas Papadimitriou
321 ca828a10 Sofia Papagiannaki
    def __init__(self, *args, **kwargs):
322 ca828a10 Sofia Papagiannaki
        super(ShibbolethUserCreationForm, self).__init__(*args, **kwargs)
323 ca828a10 Sofia Papagiannaki
        # copy email value to additional_mail in case user will change it
324 ca828a10 Sofia Papagiannaki
        name = 'email'
325 ca828a10 Sofia Papagiannaki
        field = self.fields[name]
326 ca828a10 Sofia Papagiannaki
        self.initial['additional_email'] = self.initial.get(name, field.initial)
327 ef20ea07 Sofia Papagiannaki
        self.initial['email'] = None
328 d2633501 Kostas Papadimitriou
329 18ffbee1 Sofia Papagiannaki
    def clean_email(self):
330 d2633501 Kostas Papadimitriou
        email = self.cleaned_data['email'].lower()
331 6c8a3f7c Sofia Papagiannaki
        if self.instance:
332 6c8a3f7c Sofia Papagiannaki
            if self.instance.email == email:
333 6c8a3f7c Sofia Papagiannaki
                raise forms.ValidationError(_("This is your current email."))
334 789a5951 Sofia Papagiannaki
        for user in AstakosUser.objects.filter(email__iexact=email):
335 0a569195 Sofia Papagiannaki
            if user.provider == 'shibboleth':
336 ef20ea07 Sofia Papagiannaki
                raise forms.ValidationError(_(
337 6c8a3f7c Sofia Papagiannaki
                        "This email is already associated with another \
338 6c8a3f7c Sofia Papagiannaki
                         shibboleth account."
339 ef20ea07 Sofia Papagiannaki
                    )
340 ef20ea07 Sofia Papagiannaki
                )
341 ef20ea07 Sofia Papagiannaki
            else:
342 ef20ea07 Sofia Papagiannaki
                raise forms.ValidationError(_("This email is already used"))
343 ab8f7956 Sofia Papagiannaki
        super(ShibbolethUserCreationForm, self).clean_email()
344 0a569195 Sofia Papagiannaki
        return email
345 d2633501 Kostas Papadimitriou
346 4e30244e Sofia Papagiannaki
347 9a06d96f Olga Brani
class InvitedShibbolethUserCreationForm(ShibbolethUserCreationForm,
348 9a06d96f Olga Brani
                                        InvitedThirdPartyUserCreationForm):
349 4e30244e Sofia Papagiannaki
    pass
350 ab8bfb29 Kostas Papadimitriou
351 5ce3ce4f Sofia Papagiannaki
352 5ed6816e Sofia Papagiannaki
class LoginForm(AuthenticationForm):
353 5ed6816e Sofia Papagiannaki
    username = forms.EmailField(label=_("Email"))
354 672d445a Sofia Papagiannaki
    recaptcha_challenge_field = forms.CharField(widget=DummyWidget)
355 5ce3ce4f Sofia Papagiannaki
    recaptcha_response_field = forms.CharField(
356 5ce3ce4f Sofia Papagiannaki
        widget=RecaptchaWidget, label='')
357 ab8bfb29 Kostas Papadimitriou
358 672d445a Sofia Papagiannaki
    def __init__(self, *args, **kwargs):
359 672d445a Sofia Papagiannaki
        was_limited = kwargs.get('was_limited', False)
360 672d445a Sofia Papagiannaki
        request = kwargs.get('request', None)
361 672d445a Sofia Papagiannaki
        if request:
362 672d445a Sofia Papagiannaki
            self.ip = request.META.get('REMOTE_ADDR',
363 672d445a Sofia Papagiannaki
                                       request.META.get('HTTP_X_REAL_IP', None))
364 ab8bfb29 Kostas Papadimitriou
365 672d445a Sofia Papagiannaki
        t = ('request', 'was_limited')
366 672d445a Sofia Papagiannaki
        for elem in t:
367 672d445a Sofia Papagiannaki
            if elem in kwargs.keys():
368 672d445a Sofia Papagiannaki
                kwargs.pop(elem)
369 672d445a Sofia Papagiannaki
        super(LoginForm, self).__init__(*args, **kwargs)
370 ab8bfb29 Kostas Papadimitriou
371 672d445a Sofia Papagiannaki
        self.fields.keyOrder = ['username', 'password']
372 672d445a Sofia Papagiannaki
        if was_limited and RECAPTCHA_ENABLED:
373 672d445a Sofia Papagiannaki
            self.fields.keyOrder.extend(['recaptcha_challenge_field',
374 5ce3ce4f Sofia Papagiannaki
                                         'recaptcha_response_field', ])
375 9a06d96f Olga Brani
376 9a06d96f Olga Brani
    def clean_username(self):
377 9a06d96f Olga Brani
        if 'username' in self.cleaned_data:
378 9a06d96f Olga Brani
            return self.cleaned_data['username'].lower()
379 ab8bfb29 Kostas Papadimitriou
380 672d445a Sofia Papagiannaki
    def clean_recaptcha_response_field(self):
381 672d445a Sofia Papagiannaki
        if 'recaptcha_challenge_field' in self.cleaned_data:
382 672d445a Sofia Papagiannaki
            self.validate_captcha()
383 672d445a Sofia Papagiannaki
        return self.cleaned_data['recaptcha_response_field']
384 672d445a Sofia Papagiannaki
385 672d445a Sofia Papagiannaki
    def clean_recaptcha_challenge_field(self):
386 672d445a Sofia Papagiannaki
        if 'recaptcha_response_field' in self.cleaned_data:
387 672d445a Sofia Papagiannaki
            self.validate_captcha()
388 672d445a Sofia Papagiannaki
        return self.cleaned_data['recaptcha_challenge_field']
389 672d445a Sofia Papagiannaki
390 672d445a Sofia Papagiannaki
    def validate_captcha(self):
391 672d445a Sofia Papagiannaki
        rcf = self.cleaned_data['recaptcha_challenge_field']
392 672d445a Sofia Papagiannaki
        rrf = self.cleaned_data['recaptcha_response_field']
393 672d445a Sofia Papagiannaki
        check = captcha.submit(rcf, rrf, RECAPTCHA_PRIVATE_KEY, self.ip)
394 672d445a Sofia Papagiannaki
        if not check.is_valid:
395 ae497612 Olga Brani
            raise forms.ValidationError(_(astakos_messages.CAPTCHA_VALIDATION_ERR))
396 2e90e3ec Kostas Papadimitriou
397 eedb3923 Sofia Papagiannaki
    def clean(self):
398 1f3b4b39 Sofia Papagiannaki
        """
399 1f3b4b39 Sofia Papagiannaki
        Override default behavior in order to check user's activation later
400 1f3b4b39 Sofia Papagiannaki
        """
401 1f3b4b39 Sofia Papagiannaki
        try:
402 1f3b4b39 Sofia Papagiannaki
            super(LoginForm, self).clean()
403 1f3b4b39 Sofia Papagiannaki
        except forms.ValidationError, e:
404 2b5a3efa root
#            if self.user_cache is None:
405 2b5a3efa root
#                raise
406 1f3b4b39 Sofia Papagiannaki
            if self.request:
407 1f3b4b39 Sofia Papagiannaki
                if not self.request.session.test_cookie_worked():
408 1f3b4b39 Sofia Papagiannaki
                    raise
409 eedb3923 Sofia Papagiannaki
        return self.cleaned_data
410 64cd4730 Antony Chazapis
411 5ce3ce4f Sofia Papagiannaki
412 890b0eaf Sofia Papagiannaki
class ProfileForm(forms.ModelForm):
413 890b0eaf Sofia Papagiannaki
    """
414 890b0eaf Sofia Papagiannaki
    Subclass of ``ModelForm`` for permiting user to edit his/her profile.
415 9a06d96f Olga Brani
    Most of the fields are readonly since the user is not allowed to change
416 9a06d96f Olga Brani
    them.
417 18ffbee1 Sofia Papagiannaki

418 9a06d96f Olga Brani
    The class defines a save method which sets ``is_verified`` to True so as the
419 9a06d96f Olga Brani
    user during the next login will not to be redirected to profile page.
420 890b0eaf Sofia Papagiannaki
    """
421 c301698f Sofia Papagiannaki
    renew = forms.BooleanField(label='Renew token', required=False)
422 18ffbee1 Sofia Papagiannaki
423 890b0eaf Sofia Papagiannaki
    class Meta:
424 890b0eaf Sofia Papagiannaki
        model = AstakosUser
425 5ce3ce4f Sofia Papagiannaki
        fields = ('email', 'first_name', 'last_name', 'auth_token',
426 5ce3ce4f Sofia Papagiannaki
                  'auth_token_expires')
427 18ffbee1 Sofia Papagiannaki
428 64cd4730 Antony Chazapis
    def __init__(self, *args, **kwargs):
429 bf0c6de5 Sofia Papagiannaki
        self.session_key = kwargs.pop('session_key', None)
430 890b0eaf Sofia Papagiannaki
        super(ProfileForm, self).__init__(*args, **kwargs)
431 890b0eaf Sofia Papagiannaki
        instance = getattr(self, 'instance', None)
432 0a569195 Sofia Papagiannaki
        ro_fields = ('email', 'auth_token', 'auth_token_expires')
433 890b0eaf Sofia Papagiannaki
        if instance and instance.id:
434 890b0eaf Sofia Papagiannaki
            for field in ro_fields:
435 890b0eaf Sofia Papagiannaki
                self.fields[field].widget.attrs['readonly'] = True
436 18ffbee1 Sofia Papagiannaki
437 890b0eaf Sofia Papagiannaki
    def save(self, commit=True):
438 890b0eaf Sofia Papagiannaki
        user = super(ProfileForm, self).save(commit=False)
439 890b0eaf Sofia Papagiannaki
        user.is_verified = True
440 c301698f Sofia Papagiannaki
        if self.cleaned_data.get('renew'):
441 bf0c6de5 Sofia Papagiannaki
            user.renew_token(
442 bf0c6de5 Sofia Papagiannaki
                flush_sessions=True,
443 bf0c6de5 Sofia Papagiannaki
                current_key=self.session_key
444 bf0c6de5 Sofia Papagiannaki
            )
445 890b0eaf Sofia Papagiannaki
        if commit:
446 890b0eaf Sofia Papagiannaki
            user.save()
447 890b0eaf Sofia Papagiannaki
        return user
448 64cd4730 Antony Chazapis
449 5ce3ce4f Sofia Papagiannaki
450 890b0eaf Sofia Papagiannaki
class FeedbackForm(forms.Form):
451 890b0eaf Sofia Papagiannaki
    """
452 890b0eaf Sofia Papagiannaki
    Form for writing feedback.
453 890b0eaf Sofia Papagiannaki
    """
454 0a569195 Sofia Papagiannaki
    feedback_msg = forms.CharField(widget=forms.Textarea, label=u'Message')
455 8f5a3a06 Sofia Papagiannaki
    feedback_data = forms.CharField(widget=forms.HiddenInput(), label='',
456 8f5a3a06 Sofia Papagiannaki
                                    required=False)
457 5ed6816e Sofia Papagiannaki
458 5ce3ce4f Sofia Papagiannaki
459 5ed6816e Sofia Papagiannaki
class SendInvitationForm(forms.Form):
460 5ed6816e Sofia Papagiannaki
    """
461 5ed6816e Sofia Papagiannaki
    Form for sending an invitations
462 5ed6816e Sofia Papagiannaki
    """
463 18ffbee1 Sofia Papagiannaki
464 5ce3ce4f Sofia Papagiannaki
    email = forms.EmailField(required=True, label='Email address')
465 5ce3ce4f Sofia Papagiannaki
    first_name = forms.EmailField(label='First name')
466 5ce3ce4f Sofia Papagiannaki
    last_name = forms.EmailField(label='Last name')
467 5ce3ce4f Sofia Papagiannaki
468 e2125441 Sofia Papagiannaki
469 e2125441 Sofia Papagiannaki
class ExtendedPasswordResetForm(PasswordResetForm):
470 e2125441 Sofia Papagiannaki
    """
471 e2125441 Sofia Papagiannaki
    Extends PasswordResetForm by overriding save method:
472 e2125441 Sofia Papagiannaki
    passes a custom from_email in send_mail.
473 18ffbee1 Sofia Papagiannaki

474 e2125441 Sofia Papagiannaki
    Since Django 1.3 this is useless since ``django.contrib.auth.views.reset_password``
475 e2125441 Sofia Papagiannaki
    accepts a from_email argument.
476 e2125441 Sofia Papagiannaki
    """
477 23c271b3 Sofia Papagiannaki
    def clean_email(self):
478 23c271b3 Sofia Papagiannaki
        email = super(ExtendedPasswordResetForm, self).clean_email()
479 23c271b3 Sofia Papagiannaki
        try:
480 789a5951 Sofia Papagiannaki
            user = AstakosUser.objects.get(email__iexact=email, is_active=True)
481 23c271b3 Sofia Papagiannaki
            if not user.has_usable_password():
482 ae497612 Olga Brani
                raise forms.ValidationError(_(astakos_messages.UNUSABLE_PASSWORD))
483 d2633501 Kostas Papadimitriou
484 d2633501 Kostas Papadimitriou
            if not user.can_change_password():
485 d2633501 Kostas Papadimitriou
                raise forms.ValidationError(_('Password change for this account'
486 d2633501 Kostas Papadimitriou
                                              ' is not supported.'))
487 d2633501 Kostas Papadimitriou
488 23c271b3 Sofia Papagiannaki
        except AstakosUser.DoesNotExist, e:
489 ae497612 Olga Brani
            raise forms.ValidationError(_(astakos_messages.EMAIL_UNKNOWN))
490 23c271b3 Sofia Papagiannaki
        return email
491 ab8bfb29 Kostas Papadimitriou
492 5ce3ce4f Sofia Papagiannaki
    def save(
493 5ce3ce4f Sofia Papagiannaki
        self, domain_override=None, email_template_name='registration/password_reset_email.html',
494 5ce3ce4f Sofia Papagiannaki
            use_https=False, token_generator=default_token_generator, request=None):
495 e2125441 Sofia Papagiannaki
        """
496 e2125441 Sofia Papagiannaki
        Generates a one-use only link for resetting password and sends to the user.
497 e2125441 Sofia Papagiannaki
        """
498 e2125441 Sofia Papagiannaki
        for user in self.users_cache:
499 d2633501 Kostas Papadimitriou
            url = user.astakosuser.get_password_reset_url(token_generator)
500 a53b19da Sofia Papagiannaki
            url = urljoin(BASEURL, url)
501 e2125441 Sofia Papagiannaki
            t = loader.get_template(email_template_name)
502 e2125441 Sofia Papagiannaki
            c = {
503 e2125441 Sofia Papagiannaki
                'email': user.email,
504 8f378756 Sofia Papagiannaki
                'url': url,
505 374611bc Sofia Papagiannaki
                'site_name': SITENAME,
506 e2125441 Sofia Papagiannaki
                'user': user,
507 a53b19da Sofia Papagiannaki
                'baseurl': BASEURL,
508 09122dd8 Sofia Papagiannaki
                'support': DEFAULT_CONTACT_EMAIL
509 e2125441 Sofia Papagiannaki
            }
510 1cbce16f Sofia Papagiannaki
            from_email = settings.SERVER_EMAIL
511 1fcf4a99 Kostas Papadimitriou
            send_mail(_(PASSWORD_RESET_EMAIL_SUBJECT),
512 5ce3ce4f Sofia Papagiannaki
                      t.render(Context(c)), from_email, [user.email])
513 5ce3ce4f Sofia Papagiannaki
514 270dd48d Sofia Papagiannaki
515 49790d9d Sofia Papagiannaki
class EmailChangeForm(forms.ModelForm):
516 49790d9d Sofia Papagiannaki
    class Meta:
517 49790d9d Sofia Papagiannaki
        model = EmailChange
518 49790d9d Sofia Papagiannaki
        fields = ('new_email_address',)
519 ab8bfb29 Kostas Papadimitriou
520 49790d9d Sofia Papagiannaki
    def clean_new_email_address(self):
521 49790d9d Sofia Papagiannaki
        addr = self.cleaned_data['new_email_address']
522 49790d9d Sofia Papagiannaki
        if AstakosUser.objects.filter(email__iexact=addr):
523 ae497612 Olga Brani
            raise forms.ValidationError(_(astakos_messages.EMAIL_USED))
524 49790d9d Sofia Papagiannaki
        return addr
525 ab8bfb29 Kostas Papadimitriou
526 49790d9d Sofia Papagiannaki
    def save(self, email_template_name, request, commit=True):
527 49790d9d Sofia Papagiannaki
        ec = super(EmailChangeForm, self).save(commit=False)
528 49790d9d Sofia Papagiannaki
        ec.user = request.user
529 5ce3ce4f Sofia Papagiannaki
        activation_key = hashlib.sha1(
530 5ce3ce4f Sofia Papagiannaki
            str(random()) + smart_str(ec.new_email_address))
531 5ce3ce4f Sofia Papagiannaki
        ec.activation_key = activation_key.hexdigest()
532 49790d9d Sofia Papagiannaki
        if commit:
533 49790d9d Sofia Papagiannaki
            ec.save()
534 49790d9d Sofia Papagiannaki
        send_change_email(ec, request, email_template_name=email_template_name)
535 49790d9d Sofia Papagiannaki
536 5ce3ce4f Sofia Papagiannaki
537 270dd48d Sofia Papagiannaki
class SignApprovalTermsForm(forms.ModelForm):
538 270dd48d Sofia Papagiannaki
    class Meta:
539 270dd48d Sofia Papagiannaki
        model = AstakosUser
540 270dd48d Sofia Papagiannaki
        fields = ("has_signed_terms",)
541 18ffbee1 Sofia Papagiannaki
542 270dd48d Sofia Papagiannaki
    def __init__(self, *args, **kwargs):
543 270dd48d Sofia Papagiannaki
        super(SignApprovalTermsForm, self).__init__(*args, **kwargs)
544 18ffbee1 Sofia Papagiannaki
545 270dd48d Sofia Papagiannaki
    def clean_has_signed_terms(self):
546 270dd48d Sofia Papagiannaki
        has_signed_terms = self.cleaned_data['has_signed_terms']
547 270dd48d Sofia Papagiannaki
        if not has_signed_terms:
548 ae497612 Olga Brani
            raise forms.ValidationError(_(astakos_messages.SIGN_TERMS))
549 270dd48d Sofia Papagiannaki
        return has_signed_terms
550 8f5a3a06 Sofia Papagiannaki
551 5ce3ce4f Sofia Papagiannaki
552 8f5a3a06 Sofia Papagiannaki
class InvitationForm(forms.ModelForm):
553 8f5a3a06 Sofia Papagiannaki
    username = forms.EmailField(label=_("Email"))
554 ab8bfb29 Kostas Papadimitriou
555 18ffbee1 Sofia Papagiannaki
    def __init__(self, *args, **kwargs):
556 18ffbee1 Sofia Papagiannaki
        super(InvitationForm, self).__init__(*args, **kwargs)
557 ab8bfb29 Kostas Papadimitriou
558 8f5a3a06 Sofia Papagiannaki
    class Meta:
559 8f5a3a06 Sofia Papagiannaki
        model = Invitation
560 8f5a3a06 Sofia Papagiannaki
        fields = ('username', 'realname')
561 ab8bfb29 Kostas Papadimitriou
562 8f5a3a06 Sofia Papagiannaki
    def clean_username(self):
563 8f5a3a06 Sofia Papagiannaki
        username = self.cleaned_data['username']
564 8f5a3a06 Sofia Papagiannaki
        try:
565 5ce3ce4f Sofia Papagiannaki
            Invitation.objects.get(username=username)
566 ae497612 Olga Brani
            raise forms.ValidationError(_(astakos_messages.INVITATION_EMAIL_EXISTS))
567 8f5a3a06 Sofia Papagiannaki
        except Invitation.DoesNotExist:
568 8f5a3a06 Sofia Papagiannaki
            pass
569 18ffbee1 Sofia Papagiannaki
        return username
570 1039bab1 Sofia Papagiannaki
571 5ce3ce4f Sofia Papagiannaki
572 1039bab1 Sofia Papagiannaki
class ExtendedPasswordChangeForm(PasswordChangeForm):
573 1039bab1 Sofia Papagiannaki
    """
574 1039bab1 Sofia Papagiannaki
    Extends PasswordChangeForm by enabling user
575 1039bab1 Sofia Papagiannaki
    to optionally renew also the token.
576 1039bab1 Sofia Papagiannaki
    """
577 ee210d1d Sofia Papagiannaki
    if not NEWPASSWD_INVALIDATE_TOKEN:
578 48e9f076 Sofia Papagiannaki
        renew = forms.BooleanField(label='Renew token', required=False,
579 48e9f076 Sofia Papagiannaki
                                   initial=True,
580 48e9f076 Sofia Papagiannaki
                                   help_text='Unsetting this may result in security risk.')
581 ab8bfb29 Kostas Papadimitriou
582 1039bab1 Sofia Papagiannaki
    def __init__(self, user, *args, **kwargs):
583 bf0c6de5 Sofia Papagiannaki
        self.session_key = kwargs.pop('session_key', None)
584 1039bab1 Sofia Papagiannaki
        super(ExtendedPasswordChangeForm, self).__init__(user, *args, **kwargs)
585 ab8bfb29 Kostas Papadimitriou
586 1039bab1 Sofia Papagiannaki
    def save(self, commit=True):
587 bf0c6de5 Sofia Papagiannaki
        try:
588 bf0c6de5 Sofia Papagiannaki
            if NEWPASSWD_INVALIDATE_TOKEN or self.cleaned_data.get('renew'):
589 bf0c6de5 Sofia Papagiannaki
                self.user.renew_token()
590 bf0c6de5 Sofia Papagiannaki
            self.user.flush_sessions(current_key=self.session_key)
591 bf0c6de5 Sofia Papagiannaki
        except AttributeError:
592 bf0c6de5 Sofia Papagiannaki
            # if user model does has not such methods
593 bf0c6de5 Sofia Papagiannaki
            pass
594 53161dd8 Sofia Papagiannaki
        return super(ExtendedPasswordChangeForm, self).save(commit=commit)
595 48e9f076 Sofia Papagiannaki
596 5ce3ce4f Sofia Papagiannaki
597 73fbaec4 Sofia Papagiannaki
# class AstakosGroupCreationForm(forms.ModelForm):
598 73fbaec4 Sofia Papagiannaki
#     kind = forms.ModelChoiceField(
599 73fbaec4 Sofia Papagiannaki
#         queryset=GroupKind.objects.all(),
600 73fbaec4 Sofia Papagiannaki
#         label="",
601 73fbaec4 Sofia Papagiannaki
#         widget=forms.HiddenInput()
602 73fbaec4 Sofia Papagiannaki
#     )
603 73fbaec4 Sofia Papagiannaki
#     name = forms.CharField(
604 73fbaec4 Sofia Papagiannaki
#         validators=[validators.RegexValidator(
605 73fbaec4 Sofia Papagiannaki
#             DOMAIN_VALUE_REGEX,
606 73fbaec4 Sofia Papagiannaki
#             _(astakos_messages.DOMAIN_VALUE_ERR), 'invalid'
607 73fbaec4 Sofia Papagiannaki
#         )],
608 73fbaec4 Sofia Papagiannaki
#         widget=forms.TextInput(attrs={'placeholder': 'myproject.mylab.ntua.gr'}),
609 73fbaec4 Sofia Papagiannaki
#         help_text=" The Project's name should be in a domain format. The domain shouldn't neccessarily exist in the real world but is helpful to imply a structure. e.g.: myproject.mylab.ntua.gr or myservice.myteam.myorganization "
610 73fbaec4 Sofia Papagiannaki
#     )
611 73fbaec4 Sofia Papagiannaki
#     homepage = forms.URLField(
612 73fbaec4 Sofia Papagiannaki
#         label= 'Homepage Url',
613 73fbaec4 Sofia Papagiannaki
#         widget=forms.TextInput(attrs={'placeholder': 'http://myproject.com'}),
614 73fbaec4 Sofia Papagiannaki
#         help_text="This should be a URL pointing at your project's site. e.g.: http://myproject.com ",
615 73fbaec4 Sofia Papagiannaki
#         required=False
616 73fbaec4 Sofia Papagiannaki
#     )
617 73fbaec4 Sofia Papagiannaki
#     desc = forms.CharField(
618 73fbaec4 Sofia Papagiannaki
#         label= 'Description',
619 73fbaec4 Sofia Papagiannaki
#         widget=forms.Textarea, 
620 73fbaec4 Sofia Papagiannaki
#         help_text= "Please provide a short but descriptive abstract of your Project, so that anyone searching can quickly understand what this Project is about. "
621 73fbaec4 Sofia Papagiannaki
#     )
622 73fbaec4 Sofia Papagiannaki
#     issue_date = forms.DateTimeField(
623 73fbaec4 Sofia Papagiannaki
#         label= 'Start date',
624 73fbaec4 Sofia Papagiannaki
#         help_text= "Here you specify the date you want your Project to start granting its resources. Its members will get the resources coming from this Project on this exact date."
625 73fbaec4 Sofia Papagiannaki
#     )
626 73fbaec4 Sofia Papagiannaki
#     expiration_date = forms.DateTimeField(
627 73fbaec4 Sofia Papagiannaki
#         label= 'End date',
628 73fbaec4 Sofia Papagiannaki
#         help_text= "Here you specify the date you want your Project to cease. This means that after this date all members will no longer be able to allocate resources from this Project.  "
629 73fbaec4 Sofia Papagiannaki
#     )
630 73fbaec4 Sofia Papagiannaki
#     moderation_enabled = forms.BooleanField(
631 73fbaec4 Sofia Papagiannaki
#         label= 'Moderated',
632 73fbaec4 Sofia Papagiannaki
#         help_text="Select this to approve each member manually, before they become a part of your Project (default). Be sure you know what you are doing, if you uncheck this option. ",
633 73fbaec4 Sofia Papagiannaki
#         required=False,
634 73fbaec4 Sofia Papagiannaki
#         initial=True
635 73fbaec4 Sofia Papagiannaki
#     )
636 73fbaec4 Sofia Papagiannaki
#     max_participants = forms.IntegerField(
637 73fbaec4 Sofia Papagiannaki
#         label='Total number of members',
638 73fbaec4 Sofia Papagiannaki
#         required=True, min_value=1,
639 73fbaec4 Sofia Papagiannaki
#         help_text="Here you specify the number of members this Project is going to have. This means that this number of people will be granted the resources you will specify in the next step. This can be '1' if you are the only one wanting to get resources. "
640 73fbaec4 Sofia Papagiannaki
#     )
641 73fbaec4 Sofia Papagiannaki
# 
642 73fbaec4 Sofia Papagiannaki
#     class Meta:
643 73fbaec4 Sofia Papagiannaki
#         model = AstakosGroup
644 73fbaec4 Sofia Papagiannaki
# 
645 73fbaec4 Sofia Papagiannaki
#     def __init__(self, *args, **kwargs):
646 73fbaec4 Sofia Papagiannaki
#         #update QueryDict
647 73fbaec4 Sofia Papagiannaki
#         args = list(args)
648 73fbaec4 Sofia Papagiannaki
#         qd = args.pop(0).copy()
649 73fbaec4 Sofia Papagiannaki
#         members_unlimited = qd.pop('members_unlimited', False)
650 73fbaec4 Sofia Papagiannaki
#         members_uplimit = qd.pop('members_uplimit', None)
651 73fbaec4 Sofia Papagiannaki
# 
652 73fbaec4 Sofia Papagiannaki
#         #substitue QueryDict
653 73fbaec4 Sofia Papagiannaki
#         args.insert(0, qd)
654 73fbaec4 Sofia Papagiannaki
# 
655 73fbaec4 Sofia Papagiannaki
#         super(AstakosGroupCreationForm, self).__init__(*args, **kwargs)
656 73fbaec4 Sofia Papagiannaki
#         
657 73fbaec4 Sofia Papagiannaki
#         self.fields.keyOrder = ['kind', 'name', 'homepage', 'desc',
658 73fbaec4 Sofia Papagiannaki
#                                 'issue_date', 'expiration_date',
659 73fbaec4 Sofia Papagiannaki
#                                 'moderation_enabled', 'max_participants']
660 73fbaec4 Sofia Papagiannaki
#         def add_fields((k, v)):
661 73fbaec4 Sofia Papagiannaki
#             k = k.partition('_proxy')[0]
662 73fbaec4 Sofia Papagiannaki
#             self.fields[k] = forms.IntegerField(
663 73fbaec4 Sofia Papagiannaki
#                 required=False,
664 73fbaec4 Sofia Papagiannaki
#                 widget=forms.HiddenInput(),
665 73fbaec4 Sofia Papagiannaki
#                 min_value=1
666 73fbaec4 Sofia Papagiannaki
#             )
667 73fbaec4 Sofia Papagiannaki
#         map(add_fields,
668 73fbaec4 Sofia Papagiannaki
#             ((k, v) for k,v in qd.iteritems() if k.endswith('_uplimit'))
669 73fbaec4 Sofia Papagiannaki
#         )
670 73fbaec4 Sofia Papagiannaki
# 
671 73fbaec4 Sofia Papagiannaki
#         def add_fields((k, v)):
672 73fbaec4 Sofia Papagiannaki
#             self.fields[k] = forms.BooleanField(
673 73fbaec4 Sofia Papagiannaki
#                 required=False,
674 73fbaec4 Sofia Papagiannaki
#                 #widget=forms.HiddenInput()
675 73fbaec4 Sofia Papagiannaki
#             )
676 73fbaec4 Sofia Papagiannaki
#         map(add_fields,
677 73fbaec4 Sofia Papagiannaki
#             ((k, v) for k,v in qd.iteritems() if k.startswith('is_selected_'))
678 73fbaec4 Sofia Papagiannaki
#         )
679 73fbaec4 Sofia Papagiannaki
# 
680 73fbaec4 Sofia Papagiannaki
#     def policies(self):
681 73fbaec4 Sofia Papagiannaki
#         self.clean()
682 73fbaec4 Sofia Papagiannaki
#         policies = []
683 73fbaec4 Sofia Papagiannaki
#         append = policies.append
684 73fbaec4 Sofia Papagiannaki
#         for name, uplimit in self.cleaned_data.iteritems():
685 73fbaec4 Sofia Papagiannaki
# 
686 73fbaec4 Sofia Papagiannaki
#             subs = name.split('_uplimit')
687 73fbaec4 Sofia Papagiannaki
#             if len(subs) == 2:
688 73fbaec4 Sofia Papagiannaki
#                 prefix, suffix = subs
689 73fbaec4 Sofia Papagiannaki
#                 s, sep, r = prefix.partition(RESOURCE_SEPARATOR)
690 73fbaec4 Sofia Papagiannaki
#                 resource = Resource.objects.get(service__name=s, name=r)
691 73fbaec4 Sofia Papagiannaki
# 
692 73fbaec4 Sofia Papagiannaki
#                 # keep only resource limits for selected resource groups
693 73fbaec4 Sofia Papagiannaki
#                 if self.cleaned_data.get(
694 73fbaec4 Sofia Papagiannaki
#                     'is_selected_%s' % resource.group, False
695 73fbaec4 Sofia Papagiannaki
#                 ):
696 73fbaec4 Sofia Papagiannaki
#                     append(dict(service=s, resource=r, uplimit=uplimit))
697 73fbaec4 Sofia Papagiannaki
#         return policies
698 73fbaec4 Sofia Papagiannaki
# 
699 73fbaec4 Sofia Papagiannaki
# class AstakosGroupCreationSummaryForm(forms.ModelForm):
700 73fbaec4 Sofia Papagiannaki
#     kind = forms.ModelChoiceField(
701 73fbaec4 Sofia Papagiannaki
#         queryset=GroupKind.objects.all(),
702 73fbaec4 Sofia Papagiannaki
#         label="",
703 73fbaec4 Sofia Papagiannaki
#         widget=forms.HiddenInput()
704 73fbaec4 Sofia Papagiannaki
#     )
705 73fbaec4 Sofia Papagiannaki
#     name = forms.CharField(
706 73fbaec4 Sofia Papagiannaki
#         widget=forms.TextInput(attrs={'placeholder': 'eg. foo.ece.ntua.gr'}),
707 73fbaec4 Sofia Papagiannaki
#         help_text="Name should be in the form of dns"
708 73fbaec4 Sofia Papagiannaki
#     )
709 73fbaec4 Sofia Papagiannaki
#     moderation_enabled = forms.BooleanField(
710 73fbaec4 Sofia Papagiannaki
#         help_text="Check if you want to approve members participation manually",
711 73fbaec4 Sofia Papagiannaki
#         required=False,
712 73fbaec4 Sofia Papagiannaki
#         initial=True
713 73fbaec4 Sofia Papagiannaki
#     )
714 73fbaec4 Sofia Papagiannaki
#     max_participants = forms.IntegerField(
715 73fbaec4 Sofia Papagiannaki
#         required=False, min_value=1
716 73fbaec4 Sofia Papagiannaki
#     )
717 73fbaec4 Sofia Papagiannaki
# 
718 73fbaec4 Sofia Papagiannaki
#     class Meta:
719 73fbaec4 Sofia Papagiannaki
#         model = AstakosGroup
720 73fbaec4 Sofia Papagiannaki
# 
721 73fbaec4 Sofia Papagiannaki
#     def __init__(self, *args, **kwargs):
722 73fbaec4 Sofia Papagiannaki
#         #update QueryDict
723 73fbaec4 Sofia Papagiannaki
#         args = list(args)
724 73fbaec4 Sofia Papagiannaki
#         qd = args.pop(0).copy()
725 73fbaec4 Sofia Papagiannaki
#         members_unlimited = qd.pop('members_unlimited', False)
726 73fbaec4 Sofia Papagiannaki
#         members_uplimit = qd.pop('members_uplimit', None)
727 73fbaec4 Sofia Papagiannaki
# 
728 73fbaec4 Sofia Papagiannaki
#         #substitue QueryDict
729 73fbaec4 Sofia Papagiannaki
#         args.insert(0, qd)
730 73fbaec4 Sofia Papagiannaki
# 
731 73fbaec4 Sofia Papagiannaki
#         super(AstakosGroupCreationSummaryForm, self).__init__(*args, **kwargs)
732 73fbaec4 Sofia Papagiannaki
#         self.fields.keyOrder = ['kind', 'name', 'homepage', 'desc',
733 73fbaec4 Sofia Papagiannaki
#                                 'issue_date', 'expiration_date',
734 73fbaec4 Sofia Papagiannaki
#                                 'moderation_enabled', 'max_participants']
735 73fbaec4 Sofia Papagiannaki
#         def add_fields((k, v)):
736 73fbaec4 Sofia Papagiannaki
#             self.fields[k] = forms.IntegerField(
737 73fbaec4 Sofia Papagiannaki
#                 required=False,
738 73fbaec4 Sofia Papagiannaki
#                 widget=forms.TextInput(),
739 73fbaec4 Sofia Papagiannaki
#                 min_value=1
740 73fbaec4 Sofia Papagiannaki
#             )
741 73fbaec4 Sofia Papagiannaki
#         map(add_fields,
742 73fbaec4 Sofia Papagiannaki
#             ((k, v) for k,v in qd.iteritems() if k.endswith('_uplimit'))
743 73fbaec4 Sofia Papagiannaki
#         )
744 73fbaec4 Sofia Papagiannaki
# 
745 73fbaec4 Sofia Papagiannaki
#         def add_fields((k, v)):
746 73fbaec4 Sofia Papagiannaki
#             self.fields[k] = forms.BooleanField(
747 73fbaec4 Sofia Papagiannaki
#                 required=False,
748 73fbaec4 Sofia Papagiannaki
#                 widget=forms.HiddenInput()
749 73fbaec4 Sofia Papagiannaki
#             )
750 73fbaec4 Sofia Papagiannaki
#         map(add_fields,
751 73fbaec4 Sofia Papagiannaki
#             ((k, v) for k,v in qd.iteritems() if k.startswith('is_selected_'))
752 73fbaec4 Sofia Papagiannaki
#         )
753 73fbaec4 Sofia Papagiannaki
#         for f in self.fields.values():
754 73fbaec4 Sofia Papagiannaki
#             f.widget = forms.HiddenInput()
755 73fbaec4 Sofia Papagiannaki
# 
756 73fbaec4 Sofia Papagiannaki
#     def clean(self):
757 73fbaec4 Sofia Papagiannaki
#         super(AstakosGroupCreationSummaryForm, self).clean()
758 73fbaec4 Sofia Papagiannaki
#         self.cleaned_data['policies'] = []
759 73fbaec4 Sofia Papagiannaki
#         append = self.cleaned_data['policies'].append
760 73fbaec4 Sofia Papagiannaki
#         #tbd = [f for f in self.fields if (f.startswith('is_selected_') and (not f.endswith('_proxy')))]
761 73fbaec4 Sofia Papagiannaki
#         tbd = [f for f in self.fields if f.startswith('is_selected_')]
762 73fbaec4 Sofia Papagiannaki
#         for name, uplimit in self.cleaned_data.iteritems():
763 73fbaec4 Sofia Papagiannaki
#             subs = name.split('_uplimit')
764 73fbaec4 Sofia Papagiannaki
#             if len(subs) == 2:
765 73fbaec4 Sofia Papagiannaki
#                 tbd.append(name)
766 73fbaec4 Sofia Papagiannaki
#                 prefix, suffix = subs
767 73fbaec4 Sofia Papagiannaki
#                 s, sep, r = prefix.partition(RESOURCE_SEPARATOR)
768 73fbaec4 Sofia Papagiannaki
#                 resource = Resource.objects.get(service__name=s, name=r)
769 73fbaec4 Sofia Papagiannaki
# 
770 73fbaec4 Sofia Papagiannaki
#                 # keep only resource limits for selected resource groups
771 73fbaec4 Sofia Papagiannaki
#                 if self.cleaned_data.get(
772 73fbaec4 Sofia Papagiannaki
#                     'is_selected_%s' % resource.group, False
773 73fbaec4 Sofia Papagiannaki
#                 ):
774 73fbaec4 Sofia Papagiannaki
#                     append(dict(service=s, resource=r, uplimit=uplimit))
775 73fbaec4 Sofia Papagiannaki
#         for name in tbd:
776 73fbaec4 Sofia Papagiannaki
#             self.cleaned_data.pop(name, None)
777 73fbaec4 Sofia Papagiannaki
#         return self.cleaned_data
778 73fbaec4 Sofia Papagiannaki
# 
779 73fbaec4 Sofia Papagiannaki
# class AstakosGroupUpdateForm(forms.ModelForm):
780 73fbaec4 Sofia Papagiannaki
#     class Meta:
781 73fbaec4 Sofia Papagiannaki
#         model = AstakosGroup
782 73fbaec4 Sofia Papagiannaki
#         fields = ( 'desc','homepage', 'moderation_enabled')
783 73fbaec4 Sofia Papagiannaki
# 
784 73fbaec4 Sofia Papagiannaki
# 
785 73fbaec4 Sofia Papagiannaki
# class AddGroupMembersForm(forms.Form):
786 73fbaec4 Sofia Papagiannaki
#     q = forms.CharField(
787 73fbaec4 Sofia Papagiannaki
#         max_length=800, widget=forms.Textarea, label=_('Add members'),
788 73fbaec4 Sofia Papagiannaki
#         help_text=_(astakos_messages.ADD_GROUP_MEMBERS_Q_HELP),
789 73fbaec4 Sofia Papagiannaki
#         required=True)
790 73fbaec4 Sofia Papagiannaki
# 
791 73fbaec4 Sofia Papagiannaki
#     def clean(self):
792 73fbaec4 Sofia Papagiannaki
#         q = self.cleaned_data.get('q') or ''
793 73fbaec4 Sofia Papagiannaki
#         users = q.split(',')
794 73fbaec4 Sofia Papagiannaki
#         users = list(u.strip() for u in users if u)
795 73fbaec4 Sofia Papagiannaki
#         db_entries = AstakosUser.objects.filter(email__in=users)
796 73fbaec4 Sofia Papagiannaki
#         unknown = list(set(users) - set(u.email for u in db_entries))
797 73fbaec4 Sofia Papagiannaki
#         if unknown:
798 73fbaec4 Sofia Papagiannaki
#             raise forms.ValidationError(_(astakos_messages.UNKNOWN_USERS) % ','.join(unknown))
799 73fbaec4 Sofia Papagiannaki
#         self.valid_users = db_entries
800 73fbaec4 Sofia Papagiannaki
#         return self.cleaned_data
801 73fbaec4 Sofia Papagiannaki
# 
802 73fbaec4 Sofia Papagiannaki
#     def get_valid_users(self):
803 73fbaec4 Sofia Papagiannaki
#         """Should be called after form cleaning"""
804 73fbaec4 Sofia Papagiannaki
#         try:
805 73fbaec4 Sofia Papagiannaki
#             return self.valid_users
806 73fbaec4 Sofia Papagiannaki
#         except:
807 73fbaec4 Sofia Papagiannaki
#             return ()
808 73fbaec4 Sofia Papagiannaki
# 
809 73fbaec4 Sofia Papagiannaki
# 
810 73fbaec4 Sofia Papagiannaki
# class AstakosGroupSearchForm(forms.Form):
811 73fbaec4 Sofia Papagiannaki
#     q = forms.CharField(max_length=200, label='Search project')
812 73fbaec4 Sofia Papagiannaki
# 
813 73fbaec4 Sofia Papagiannaki
# 
814 73fbaec4 Sofia Papagiannaki
# class TimelineForm(forms.Form):
815 73fbaec4 Sofia Papagiannaki
#     entity = forms.ModelChoiceField(
816 73fbaec4 Sofia Papagiannaki
#         queryset=AstakosUser.objects.filter(is_active=True)
817 73fbaec4 Sofia Papagiannaki
#     )
818 73fbaec4 Sofia Papagiannaki
#     resource = forms.ModelChoiceField(
819 73fbaec4 Sofia Papagiannaki
#         queryset=Resource.objects.all()
820 73fbaec4 Sofia Papagiannaki
#     )
821 73fbaec4 Sofia Papagiannaki
#     start_date = forms.DateTimeField()
822 73fbaec4 Sofia Papagiannaki
#     end_date = forms.DateTimeField()
823 73fbaec4 Sofia Papagiannaki
#     details = forms.BooleanField(required=False, label="Detailed Listing")
824 73fbaec4 Sofia Papagiannaki
#     operation = forms.ChoiceField(
825 73fbaec4 Sofia Papagiannaki
#         label='Charge Method',
826 73fbaec4 Sofia Papagiannaki
#         choices=(('', '-------------'),
827 73fbaec4 Sofia Papagiannaki
#                  ('charge_usage', 'Charge Usage'),
828 73fbaec4 Sofia Papagiannaki
#                  ('charge_traffic', 'Charge Traffic'), )
829 73fbaec4 Sofia Papagiannaki
#     )
830 73fbaec4 Sofia Papagiannaki
# 
831 73fbaec4 Sofia Papagiannaki
#     def clean(self):
832 73fbaec4 Sofia Papagiannaki
#         super(TimelineForm, self).clean()
833 73fbaec4 Sofia Papagiannaki
#         d = self.cleaned_data
834 73fbaec4 Sofia Papagiannaki
#         if 'resource' in d:
835 73fbaec4 Sofia Papagiannaki
#             d['resource'] = str(d['resource'])
836 73fbaec4 Sofia Papagiannaki
#         if 'start_date' in d:
837 73fbaec4 Sofia Papagiannaki
#             d['start_date'] = d['start_date'].strftime(
838 73fbaec4 Sofia Papagiannaki
#                 "%Y-%m-%dT%H:%M:%S.%f")[:24]
839 73fbaec4 Sofia Papagiannaki
#         if 'end_date' in d:
840 73fbaec4 Sofia Papagiannaki
#             d['end_date'] = d['end_date'].strftime("%Y-%m-%dT%H:%M:%S.%f")[:24]
841 73fbaec4 Sofia Papagiannaki
#         if 'entity' in d:
842 73fbaec4 Sofia Papagiannaki
#             d['entity'] = d['entity'].email
843 73fbaec4 Sofia Papagiannaki
#         return d
844 73fbaec4 Sofia Papagiannaki
# 
845 73fbaec4 Sofia Papagiannaki
# 
846 73fbaec4 Sofia Papagiannaki
# class AstakosGroupSortForm(forms.Form):
847 73fbaec4 Sofia Papagiannaki
#     sorting = forms.ChoiceField(
848 73fbaec4 Sofia Papagiannaki
#         label='Sort by',
849 73fbaec4 Sofia Papagiannaki
#         choices=(
850 73fbaec4 Sofia Papagiannaki
#             ('groupname', 'Name'),
851 73fbaec4 Sofia Papagiannaki
#             ('issue_date', 'Issue Date'),
852 73fbaec4 Sofia Papagiannaki
#             ('expiration_date', 'Expiration Date'),
853 73fbaec4 Sofia Papagiannaki
#             ('approved_members_num', 'Participants'),
854 73fbaec4 Sofia Papagiannaki
#             ('moderation_enabled', 'Moderation'),
855 73fbaec4 Sofia Papagiannaki
#             ('membership_status', 'Enrollment Status')
856 73fbaec4 Sofia Papagiannaki
#         ),
857 73fbaec4 Sofia Papagiannaki
#         required=True
858 73fbaec4 Sofia Papagiannaki
#     )
859 73fbaec4 Sofia Papagiannaki
# 
860 73fbaec4 Sofia Papagiannaki
# class MembersSortForm(forms.Form):
861 73fbaec4 Sofia Papagiannaki
#     sorting = forms.ChoiceField(
862 73fbaec4 Sofia Papagiannaki
#         label='Sort by',
863 73fbaec4 Sofia Papagiannaki
#         choices=(('person__email', 'User Id'),
864 73fbaec4 Sofia Papagiannaki
#                  ('person__first_name', 'Name'),
865 73fbaec4 Sofia Papagiannaki
#                  ('date_joined', 'Status')
866 73fbaec4 Sofia Papagiannaki
#         ),
867 73fbaec4 Sofia Papagiannaki
#         required=True
868 73fbaec4 Sofia Papagiannaki
#     )
869 73fbaec4 Sofia Papagiannaki
# 
870 73fbaec4 Sofia Papagiannaki
# class PickResourceForm(forms.Form):
871 73fbaec4 Sofia Papagiannaki
#     resource = forms.ModelChoiceField(
872 73fbaec4 Sofia Papagiannaki
#         queryset=Resource.objects.select_related().all()
873 73fbaec4 Sofia Papagiannaki
#     )
874 73fbaec4 Sofia Papagiannaki
#     resource.widget.attrs["onchange"] = "this.form.submit()"
875 9a06d96f Olga Brani
876 9a06d96f Olga Brani
877 48e9f076 Sofia Papagiannaki
class ExtendedSetPasswordForm(SetPasswordForm):
878 48e9f076 Sofia Papagiannaki
    """
879 48e9f076 Sofia Papagiannaki
    Extends SetPasswordForm by enabling user
880 48e9f076 Sofia Papagiannaki
    to optionally renew also the token.
881 48e9f076 Sofia Papagiannaki
    """
882 ee210d1d Sofia Papagiannaki
    if not NEWPASSWD_INVALIDATE_TOKEN:
883 bf0c6de5 Sofia Papagiannaki
        renew = forms.BooleanField(
884 bf0c6de5 Sofia Papagiannaki
            label='Renew token',
885 bf0c6de5 Sofia Papagiannaki
            required=False,
886 bf0c6de5 Sofia Papagiannaki
            initial=True,
887 bf0c6de5 Sofia Papagiannaki
            help_text='Unsetting this may result in security risk.'
888 bf0c6de5 Sofia Papagiannaki
        )
889 2e90e3ec Kostas Papadimitriou
890 48e9f076 Sofia Papagiannaki
    def __init__(self, user, *args, **kwargs):
891 48e9f076 Sofia Papagiannaki
        super(ExtendedSetPasswordForm, self).__init__(user, *args, **kwargs)
892 d2633501 Kostas Papadimitriou
893 d2633501 Kostas Papadimitriou
    @transaction.commit_on_success()
894 48e9f076 Sofia Papagiannaki
    def save(self, commit=True):
895 bf0c6de5 Sofia Papagiannaki
        try:
896 bf0c6de5 Sofia Papagiannaki
            self.user = AstakosUser.objects.get(id=self.user.id)
897 bf0c6de5 Sofia Papagiannaki
            if NEWPASSWD_INVALIDATE_TOKEN or self.cleaned_data.get('renew'):
898 53161dd8 Sofia Papagiannaki
                self.user.renew_token()
899 d2633501 Kostas Papadimitriou
            #self.user.flush_sessions()
900 d2633501 Kostas Papadimitriou
            if not self.user.has_auth_provider('local'):
901 d2633501 Kostas Papadimitriou
                self.user.add_auth_provider('local', auth_backend='astakos')
902 d2633501 Kostas Papadimitriou
903 bf0c6de5 Sofia Papagiannaki
        except BaseException, e:
904 bf0c6de5 Sofia Papagiannaki
            logger.exception(e)
905 53161dd8 Sofia Papagiannaki
        return super(ExtendedSetPasswordForm, self).save(commit=commit)
906 e1a80257 Sofia Papagiannaki
907 e1a80257 Sofia Papagiannaki
908 e1a80257 Sofia Papagiannaki
class ProjectApplicationForm(forms.ModelForm):
909 e1a80257 Sofia Papagiannaki
    name = forms.CharField(
910 e1a80257 Sofia Papagiannaki
        validators=[validators.RegexValidator(
911 e1a80257 Sofia Papagiannaki
            DOMAIN_VALUE_REGEX,
912 e1a80257 Sofia Papagiannaki
            _(astakos_messages.DOMAIN_VALUE_ERR),
913 e1a80257 Sofia Papagiannaki
            'invalid'
914 e1a80257 Sofia Papagiannaki
        )],
915 e1a80257 Sofia Papagiannaki
        widget=forms.TextInput(attrs={'placeholder': 'eg. foo.ece.ntua.gr'}),
916 e1a80257 Sofia Papagiannaki
        help_text="Name should be in the form of dns"
917 e1a80257 Sofia Papagiannaki
    )
918 e1a80257 Sofia Papagiannaki
    comments = forms.CharField(widget=forms.Textarea, required=False)
919 e1a80257 Sofia Papagiannaki
    
920 e1a80257 Sofia Papagiannaki
    class Meta:
921 73fbaec4 Sofia Papagiannaki
        model = ProjectApplication
922 73fbaec4 Sofia Papagiannaki
        exclude = (
923 73fbaec4 Sofia Papagiannaki
            'resource_grants', 'id', 'applicant', 'owner',
924 73fbaec4 Sofia Papagiannaki
            'precursor_application', 'state', 'issue_date')
925 73fbaec4 Sofia Papagiannaki
926 e1a80257 Sofia Papagiannaki
    def clean(self):
927 185b2190 Sofia Papagiannaki
        userid = self.data.get('user', None)
928 e1a80257 Sofia Papagiannaki
        self.user = None
929 e1a80257 Sofia Papagiannaki
        if userid:
930 e1a80257 Sofia Papagiannaki
            try:
931 e1a80257 Sofia Papagiannaki
                self.user = AstakosUser.objects.get(id=userid)
932 e1a80257 Sofia Papagiannaki
            except AstakosUser.DoesNotExist:
933 e1a80257 Sofia Papagiannaki
                pass
934 e1a80257 Sofia Papagiannaki
        if not self.user:
935 e1a80257 Sofia Papagiannaki
            raise forms.ValidationError(_(astakos_messages.NO_APPLICANT))
936 e1a80257 Sofia Papagiannaki
        super(ProjectApplicationForm, self).clean()
937 e1a80257 Sofia Papagiannaki
        return self.cleaned_data
938 e1a80257 Sofia Papagiannaki
    
939 f3342849 Sofia Papagiannaki
    @property
940 f3342849 Sofia Papagiannaki
    def resource_policies(self):
941 e1a80257 Sofia Papagiannaki
        policies = []
942 e1a80257 Sofia Papagiannaki
        append = policies.append
943 f3342849 Sofia Papagiannaki
        for name, value in self.data.iteritems():
944 f3342849 Sofia Papagiannaki
            if not value:
945 f3342849 Sofia Papagiannaki
                continue
946 56eb807c Sofia Papagiannaki
            uplimit = value
947 56eb807c Sofia Papagiannaki
            if name.endswith('_uplimit'):
948 56eb807c Sofia Papagiannaki
                subs = name.split('_uplimit')
949 e1a80257 Sofia Papagiannaki
                prefix, suffix = subs
950 e1a80257 Sofia Papagiannaki
                s, sep, r = prefix.partition(RESOURCE_SEPARATOR)
951 e1a80257 Sofia Papagiannaki
                resource = Resource.objects.get(service__name=s, name=r)
952 e1a80257 Sofia Papagiannaki
953 e1a80257 Sofia Papagiannaki
                # keep only resource limits for selected resource groups
954 f3342849 Sofia Papagiannaki
#                 if self.data.get(
955 f3342849 Sofia Papagiannaki
#                     'is_selected_%s' % resource.group, False
956 f3342849 Sofia Papagiannaki
#                 ):
957 f3342849 Sofia Papagiannaki
                if uplimit:
958 e1a80257 Sofia Papagiannaki
                    append(dict(service=s, resource=r, uplimit=uplimit))
959 e1a80257 Sofia Papagiannaki
        return policies
960 e1a80257 Sofia Papagiannaki
961 e1a80257 Sofia Papagiannaki
    def save(self, commit=True):
962 73fbaec4 Sofia Papagiannaki
        application = super(ProjectApplicationForm, self).save(commit=False)
963 e1a80257 Sofia Papagiannaki
        applicant = self.user
964 e1a80257 Sofia Papagiannaki
        comments = self.cleaned_data.pop('comments', None)
965 e1a80257 Sofia Papagiannaki
        try:
966 73fbaec4 Sofia Papagiannaki
            precursor_application = self.instance.precursor_application
967 e1a80257 Sofia Papagiannaki
        except:
968 e1a80257 Sofia Papagiannaki
            precursor_application = None
969 73fbaec4 Sofia Papagiannaki
        return submit_application(
970 73fbaec4 Sofia Papagiannaki
            application,
971 ccab6eb5 Sofia Papagiannaki
            self.resource_policies,
972 e1a80257 Sofia Papagiannaki
            applicant,
973 e1a80257 Sofia Papagiannaki
            comments,
974 30a6c330 Sofia Papagiannaki
            precursor_application
975 e1a80257 Sofia Papagiannaki
        )
976 8327782d Sofia Papagiannaki
977 8327782d Sofia Papagiannaki
class ProjectSortForm(forms.Form):
978 8327782d Sofia Papagiannaki
    sorting = forms.ChoiceField(
979 8327782d Sofia Papagiannaki
        label='Sort by',
980 73fbaec4 Sofia Papagiannaki
        choices=(('name', 'Sort by Name'),
981 8327782d Sofia Papagiannaki
                 ('issue_date', 'Sort by Issue date'),
982 73fbaec4 Sofia Papagiannaki
                 ('start_date', 'Sort by Start Date'),
983 73fbaec4 Sofia Papagiannaki
                 ('end_date', 'Sort by End Date'),
984 8327782d Sofia Papagiannaki
#                  ('approved_members_num', 'Sort by Participants'),
985 d6a162d3 Sofia Papagiannaki
                 ('state', 'Sort by Status'),
986 73fbaec4 Sofia Papagiannaki
                 ('member_join_policy__description', 'Sort by Member Join Policy'),
987 73fbaec4 Sofia Papagiannaki
                 ('member_leave_policy__description', 'Sort by Member Leave Policy')
988 8327782d Sofia Papagiannaki
        ),
989 8327782d Sofia Papagiannaki
        required=True
990 ccab6eb5 Sofia Papagiannaki
    )
991 ccab6eb5 Sofia Papagiannaki
992 ccab6eb5 Sofia Papagiannaki
class AddProjectMembersForm(forms.Form):
993 ccab6eb5 Sofia Papagiannaki
    q = forms.CharField(
994 ccab6eb5 Sofia Papagiannaki
        max_length=800, widget=forms.Textarea, label=_('Add members'),
995 ccab6eb5 Sofia Papagiannaki
        help_text=_(astakos_messages.ADD_PROJECT_MEMBERS_Q_HELP),
996 ccab6eb5 Sofia Papagiannaki
        required=True)
997 ccab6eb5 Sofia Papagiannaki
998 ccab6eb5 Sofia Papagiannaki
    def clean(self):
999 ccab6eb5 Sofia Papagiannaki
        q = self.cleaned_data.get('q') or ''
1000 ccab6eb5 Sofia Papagiannaki
        users = q.split(',')
1001 ccab6eb5 Sofia Papagiannaki
        users = list(u.strip() for u in users if u)
1002 ccab6eb5 Sofia Papagiannaki
        db_entries = AstakosUser.objects.filter(email__in=users)
1003 ccab6eb5 Sofia Papagiannaki
        unknown = list(set(users) - set(u.email for u in db_entries))
1004 ccab6eb5 Sofia Papagiannaki
        if unknown:
1005 ccab6eb5 Sofia Papagiannaki
            raise forms.ValidationError(_(astakos_messages.UNKNOWN_USERS) % ','.join(unknown))
1006 ccab6eb5 Sofia Papagiannaki
        self.valid_users = db_entries
1007 ccab6eb5 Sofia Papagiannaki
        return self.cleaned_data
1008 ccab6eb5 Sofia Papagiannaki
1009 ccab6eb5 Sofia Papagiannaki
    def get_valid_users(self):
1010 ccab6eb5 Sofia Papagiannaki
        """Should be called after form cleaning"""
1011 ccab6eb5 Sofia Papagiannaki
        try:
1012 ccab6eb5 Sofia Papagiannaki
            return self.valid_users
1013 ccab6eb5 Sofia Papagiannaki
        except:
1014 bfe23b13 Sofia Papagiannaki
            return ()
1015 bfe23b13 Sofia Papagiannaki
1016 bfe23b13 Sofia Papagiannaki
class ProjectMembersSortForm(forms.Form):
1017 bfe23b13 Sofia Papagiannaki
    sorting = forms.ChoiceField(
1018 bfe23b13 Sofia Papagiannaki
        label='Sort by',
1019 bfe23b13 Sofia Papagiannaki
        choices=(('person__email', 'User Id'),
1020 bfe23b13 Sofia Papagiannaki
                 ('person__first_name', 'Name'),
1021 bfe23b13 Sofia Papagiannaki
                 ('acceptance_date', 'Acceptance date')
1022 bfe23b13 Sofia Papagiannaki
        ),
1023 bfe23b13 Sofia Papagiannaki
        required=True
1024 bfe23b13 Sofia Papagiannaki
    )
1025 bfe23b13 Sofia Papagiannaki
1026 6dadd24a Sofia Papagiannaki
class ProjectSearchForm(forms.Form):
1027 bfe23b13 Sofia Papagiannaki
    q = forms.CharField(max_length=200, label='Search project')