Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (38 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 c4b1a172 Kostas Papadimitriou
from astakos.im import auth_providers
71 64cd4730 Antony Chazapis
72 ae497612 Olga Brani
import astakos.im.messages as astakos_messages
73 64cd4730 Antony Chazapis
74 3bf924ec Sofia Papagiannaki
import logging
75 49790d9d Sofia Papagiannaki
import hashlib
76 db7fecd9 Sofia Papagiannaki
import recaptcha.client.captcha as captcha
77 caf70869 Sofia Papagiannaki
import re
78 64cd4730 Antony Chazapis
79 e015e9e6 Sofia Papagiannaki
logger = logging.getLogger(__name__)
80 e015e9e6 Sofia Papagiannaki
81 caf70869 Sofia Papagiannaki
DOMAIN_VALUE_REGEX = re.compile(
82 892410d3 Sofia Papagiannaki
    r'^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}$',
83 73fbaec4 Sofia Papagiannaki
    re.IGNORECASE)
84 d2633501 Kostas Papadimitriou
85 caf70869 Sofia Papagiannaki
class StoreUserMixin(object):
86 e5966bd9 Kostas Papadimitriou
87 d2633501 Kostas Papadimitriou
    @transaction.commit_on_success
88 d2633501 Kostas Papadimitriou
    def store_user(self, user, request):
89 d2633501 Kostas Papadimitriou
        user.save()
90 d2633501 Kostas Papadimitriou
        self.post_store_user(user, request)
91 d2633501 Kostas Papadimitriou
        return user
92 d2633501 Kostas Papadimitriou
93 d2633501 Kostas Papadimitriou
    def post_store_user(self, user, request):
94 d2633501 Kostas Papadimitriou
        """
95 d2633501 Kostas Papadimitriou
        Interface method for descendant backends to be able to do stuff within
96 d2633501 Kostas Papadimitriou
        the transaction enabled by store_user.
97 d2633501 Kostas Papadimitriou
        """
98 d2633501 Kostas Papadimitriou
        pass
99 d2633501 Kostas Papadimitriou
100 d2633501 Kostas Papadimitriou
101 d2633501 Kostas Papadimitriou
class LocalUserCreationForm(UserCreationForm, StoreUserMixin):
102 890b0eaf Sofia Papagiannaki
    """
103 890b0eaf Sofia Papagiannaki
    Extends the built in UserCreationForm in several ways:
104 18ffbee1 Sofia Papagiannaki

105 8316698a Sofia Papagiannaki
    * Adds email, first_name, last_name, recaptcha_challenge_field, recaptcha_response_field field.
106 5ed6816e Sofia Papagiannaki
    * The username field isn't visible and it is assigned a generated id.
107 18ffbee1 Sofia Papagiannaki
    * User created is not active.
108 890b0eaf Sofia Papagiannaki
    """
109 db7fecd9 Sofia Papagiannaki
    recaptcha_challenge_field = forms.CharField(widget=DummyWidget)
110 5ce3ce4f Sofia Papagiannaki
    recaptcha_response_field = forms.CharField(
111 5ce3ce4f Sofia Papagiannaki
        widget=RecaptchaWidget, label='')
112 18ffbee1 Sofia Papagiannaki
113 794852f2 Sofia Papagiannaki
    class Meta:
114 794852f2 Sofia Papagiannaki
        model = AstakosUser
115 5ce3ce4f Sofia Papagiannaki
        fields = ("email", "first_name", "last_name",
116 5ce3ce4f Sofia Papagiannaki
                  "has_signed_terms", "has_signed_terms")
117 18ffbee1 Sofia Papagiannaki
118 64cd4730 Antony Chazapis
    def __init__(self, *args, **kwargs):
119 64cd4730 Antony Chazapis
        """
120 890b0eaf Sofia Papagiannaki
        Changes the order of fields, and removes the username field.
121 64cd4730 Antony Chazapis
        """
122 bf0c6de5 Sofia Papagiannaki
        request = kwargs.pop('request', None)
123 672d445a Sofia Papagiannaki
        if request:
124 672d445a Sofia Papagiannaki
            self.ip = request.META.get('REMOTE_ADDR',
125 672d445a Sofia Papagiannaki
                                       request.META.get('HTTP_X_REAL_IP', None))
126 ab8bfb29 Kostas Papadimitriou
127 15efc749 Sofia Papagiannaki
        super(LocalUserCreationForm, self).__init__(*args, **kwargs)
128 890b0eaf Sofia Papagiannaki
        self.fields.keyOrder = ['email', 'first_name', 'last_name',
129 d8f63346 Sofia Papagiannaki
                                'password1', 'password2']
130 1b3398a0 Olga Brani
131 53bf2659 Sofia Papagiannaki
        if RECAPTCHA_ENABLED:
132 53bf2659 Sofia Papagiannaki
            self.fields.keyOrder.extend(['recaptcha_challenge_field',
133 5ce3ce4f Sofia Papagiannaki
                                         'recaptcha_response_field', ])
134 1b3398a0 Olga Brani
        if get_latest_terms():
135 1b3398a0 Olga Brani
            self.fields.keyOrder.append('has_signed_terms')
136 18ffbee1 Sofia Papagiannaki
137 18ffbee1 Sofia Papagiannaki
        if 'has_signed_terms' in self.fields:
138 18ffbee1 Sofia Papagiannaki
            # Overriding field label since we need to apply a link
139 18ffbee1 Sofia Papagiannaki
            # to the terms within the label
140 18ffbee1 Sofia Papagiannaki
            terms_link_html = '<a href="%s" target="_blank">%s</a>' \
141 5ce3ce4f Sofia Papagiannaki
                % (reverse('latest_terms'), _("the terms"))
142 18ffbee1 Sofia Papagiannaki
            self.fields['has_signed_terms'].label = \
143 5ce3ce4f Sofia Papagiannaki
                mark_safe("I agree with %s" % terms_link_html)
144 18ffbee1 Sofia Papagiannaki
145 af4eb974 Sofia Papagiannaki
    def clean_email(self):
146 e5966bd9 Kostas Papadimitriou
        email = self.cleaned_data['email']
147 881c856c Sofia Papagiannaki
        if not email:
148 ae497612 Olga Brani
            raise forms.ValidationError(_(astakos_messages.REQUIRED_FIELD))
149 0a569195 Sofia Papagiannaki
        if reserved_email(email):
150 ae497612 Olga Brani
            raise forms.ValidationError(_(astakos_messages.EMAIL_USED))
151 0a569195 Sofia Papagiannaki
        return email
152 18ffbee1 Sofia Papagiannaki
153 270dd48d Sofia Papagiannaki
    def clean_has_signed_terms(self):
154 270dd48d Sofia Papagiannaki
        has_signed_terms = self.cleaned_data['has_signed_terms']
155 270dd48d Sofia Papagiannaki
        if not has_signed_terms:
156 ae497612 Olga Brani
            raise forms.ValidationError(_(astakos_messages.SIGN_TERMS))
157 270dd48d Sofia Papagiannaki
        return has_signed_terms
158 18ffbee1 Sofia Papagiannaki
159 db7fecd9 Sofia Papagiannaki
    def clean_recaptcha_response_field(self):
160 db7fecd9 Sofia Papagiannaki
        if 'recaptcha_challenge_field' in self.cleaned_data:
161 db7fecd9 Sofia Papagiannaki
            self.validate_captcha()
162 db7fecd9 Sofia Papagiannaki
        return self.cleaned_data['recaptcha_response_field']
163 db7fecd9 Sofia Papagiannaki
164 db7fecd9 Sofia Papagiannaki
    def clean_recaptcha_challenge_field(self):
165 db7fecd9 Sofia Papagiannaki
        if 'recaptcha_response_field' in self.cleaned_data:
166 db7fecd9 Sofia Papagiannaki
            self.validate_captcha()
167 db7fecd9 Sofia Papagiannaki
        return self.cleaned_data['recaptcha_challenge_field']
168 db7fecd9 Sofia Papagiannaki
169 db7fecd9 Sofia Papagiannaki
    def validate_captcha(self):
170 db7fecd9 Sofia Papagiannaki
        rcf = self.cleaned_data['recaptcha_challenge_field']
171 db7fecd9 Sofia Papagiannaki
        rrf = self.cleaned_data['recaptcha_response_field']
172 db7fecd9 Sofia Papagiannaki
        check = captcha.submit(rcf, rrf, RECAPTCHA_PRIVATE_KEY, self.ip)
173 db7fecd9 Sofia Papagiannaki
        if not check.is_valid:
174 ae497612 Olga Brani
            raise forms.ValidationError(_(astakos_messages.CAPTCHA_VALIDATION_ERR))
175 18ffbee1 Sofia Papagiannaki
176 d2633501 Kostas Papadimitriou
    def post_store_user(self, user, request):
177 d2633501 Kostas Papadimitriou
        """
178 d2633501 Kostas Papadimitriou
        Interface method for descendant backends to be able to do stuff within
179 d2633501 Kostas Papadimitriou
        the transaction enabled by store_user.
180 d2633501 Kostas Papadimitriou
        """
181 d2633501 Kostas Papadimitriou
        user.add_auth_provider('local', auth_backend='astakos')
182 d2633501 Kostas Papadimitriou
        user.set_password(self.cleaned_data['password1'])
183 d2633501 Kostas Papadimitriou
184 890b0eaf Sofia Papagiannaki
    def save(self, commit=True):
185 64cd4730 Antony Chazapis
        """
186 890b0eaf Sofia Papagiannaki
        Saves the email, first_name and last_name properties, after the normal
187 890b0eaf Sofia Papagiannaki
        save behavior is complete.
188 890b0eaf Sofia Papagiannaki
        """
189 15efc749 Sofia Papagiannaki
        user = super(LocalUserCreationForm, self).save(commit=False)
190 d2633501 Kostas Papadimitriou
        user.renew_token()
191 9fb8e808 Sofia Papagiannaki
        if commit:
192 9fb8e808 Sofia Papagiannaki
            user.save()
193 aab4d540 Sofia Papagiannaki
            logger.log(LOGGING_LEVEL, 'Created user %s' % user.email)
194 890b0eaf Sofia Papagiannaki
        return user
195 64cd4730 Antony Chazapis
196 5ce3ce4f Sofia Papagiannaki
197 15efc749 Sofia Papagiannaki
class InvitedLocalUserCreationForm(LocalUserCreationForm):
198 890b0eaf Sofia Papagiannaki
    """
199 062c970c Sofia Papagiannaki
    Extends the LocalUserCreationForm: email is readonly.
200 890b0eaf Sofia Papagiannaki
    """
201 794852f2 Sofia Papagiannaki
    class Meta:
202 794852f2 Sofia Papagiannaki
        model = AstakosUser
203 270dd48d Sofia Papagiannaki
        fields = ("email", "first_name", "last_name", "has_signed_terms")
204 18ffbee1 Sofia Papagiannaki
205 64cd4730 Antony Chazapis
    def __init__(self, *args, **kwargs):
206 64cd4730 Antony Chazapis
        """
207 3bf924ec Sofia Papagiannaki
        Changes the order of fields, and removes the username field.
208 64cd4730 Antony Chazapis
        """
209 15efc749 Sofia Papagiannaki
        super(InvitedLocalUserCreationForm, self).__init__(*args, **kwargs)
210 18ffbee1 Sofia Papagiannaki
211 64cd4730 Antony Chazapis
        #set readonly form fields
212 062c970c Sofia Papagiannaki
        ro = ('email', 'username',)
213 4e30244e Sofia Papagiannaki
        for f in ro:
214 4e30244e Sofia Papagiannaki
            self.fields[f].widget.attrs['readonly'] = True
215 ab8bfb29 Kostas Papadimitriou
216 9fb8e808 Sofia Papagiannaki
    def save(self, commit=True):
217 15efc749 Sofia Papagiannaki
        user = super(InvitedLocalUserCreationForm, self).save(commit=False)
218 74836e50 Sofia Papagiannaki
        user.set_invitations_level()
219 8316698a Sofia Papagiannaki
        user.email_verified = True
220 9fb8e808 Sofia Papagiannaki
        if commit:
221 9fb8e808 Sofia Papagiannaki
            user.save()
222 9fb8e808 Sofia Papagiannaki
        return user
223 5ed6816e Sofia Papagiannaki
224 d2633501 Kostas Papadimitriou
225 d2633501 Kostas Papadimitriou
class ThirdPartyUserCreationForm(forms.ModelForm, StoreUserMixin):
226 6c8a3f7c Sofia Papagiannaki
    id = forms.CharField(
227 6c8a3f7c Sofia Papagiannaki
        widget=forms.HiddenInput(),
228 6c8a3f7c Sofia Papagiannaki
        label='',
229 6c8a3f7c Sofia Papagiannaki
        required=False
230 6c8a3f7c Sofia Papagiannaki
    )
231 ef20ea07 Sofia Papagiannaki
    third_party_identifier = forms.CharField(
232 ef20ea07 Sofia Papagiannaki
        widget=forms.HiddenInput(),
233 ef20ea07 Sofia Papagiannaki
        label=''
234 ef20ea07 Sofia Papagiannaki
    )
235 8f5a3a06 Sofia Papagiannaki
    class Meta:
236 8f5a3a06 Sofia Papagiannaki
        model = AstakosUser
237 6c8a3f7c Sofia Papagiannaki
        fields = ['id', 'email', 'third_party_identifier', 'first_name', 'last_name']
238 ab8bfb29 Kostas Papadimitriou
239 8f5a3a06 Sofia Papagiannaki
    def __init__(self, *args, **kwargs):
240 8f5a3a06 Sofia Papagiannaki
        """
241 8f5a3a06 Sofia Papagiannaki
        Changes the order of fields, and removes the username field.
242 8f5a3a06 Sofia Papagiannaki
        """
243 0a569195 Sofia Papagiannaki
        self.request = kwargs.get('request', None)
244 0a569195 Sofia Papagiannaki
        if self.request:
245 0a569195 Sofia Papagiannaki
            kwargs.pop('request')
246 2e90e3ec Kostas Papadimitriou
247 ef20ea07 Sofia Papagiannaki
        latest_terms = get_latest_terms()
248 ef20ea07 Sofia Papagiannaki
        if latest_terms:
249 ef20ea07 Sofia Papagiannaki
            self._meta.fields.append('has_signed_terms')
250 2e90e3ec Kostas Papadimitriou
251 8f5a3a06 Sofia Papagiannaki
        super(ThirdPartyUserCreationForm, self).__init__(*args, **kwargs)
252 2e90e3ec Kostas Papadimitriou
253 ef20ea07 Sofia Papagiannaki
        if latest_terms:
254 8f5a3a06 Sofia Papagiannaki
            self.fields.keyOrder.append('has_signed_terms')
255 2e90e3ec Kostas Papadimitriou
256 18ffbee1 Sofia Papagiannaki
        if 'has_signed_terms' in self.fields:
257 18ffbee1 Sofia Papagiannaki
            # Overriding field label since we need to apply a link
258 18ffbee1 Sofia Papagiannaki
            # to the terms within the label
259 18ffbee1 Sofia Papagiannaki
            terms_link_html = '<a href="%s" target="_blank">%s</a>' \
260 5ce3ce4f Sofia Papagiannaki
                % (reverse('latest_terms'), _("the terms"))
261 18ffbee1 Sofia Papagiannaki
            self.fields['has_signed_terms'].label = \
262 18ffbee1 Sofia Papagiannaki
                    mark_safe("I agree with %s" % terms_link_html)
263 2e90e3ec Kostas Papadimitriou
264 18ffbee1 Sofia Papagiannaki
    def clean_email(self):
265 e5966bd9 Kostas Papadimitriou
        email = self.cleaned_data['email']
266 18ffbee1 Sofia Papagiannaki
        if not email:
267 ae497612 Olga Brani
            raise forms.ValidationError(_(astakos_messages.REQUIRED_FIELD))
268 c630fee6 Kostas Papadimitriou
        if reserved_email(email):
269 c630fee6 Kostas Papadimitriou
            raise forms.ValidationError(_(astakos_messages.EMAIL_USED))
270 0a569195 Sofia Papagiannaki
        return email
271 ab8bfb29 Kostas Papadimitriou
272 18ffbee1 Sofia Papagiannaki
    def clean_has_signed_terms(self):
273 18ffbee1 Sofia Papagiannaki
        has_signed_terms = self.cleaned_data['has_signed_terms']
274 18ffbee1 Sofia Papagiannaki
        if not has_signed_terms:
275 ae497612 Olga Brani
            raise forms.ValidationError(_(astakos_messages.SIGN_TERMS))
276 18ffbee1 Sofia Papagiannaki
        return has_signed_terms
277 ab8bfb29 Kostas Papadimitriou
278 d2633501 Kostas Papadimitriou
    def post_store_user(self, user, request):
279 d2633501 Kostas Papadimitriou
        pending = PendingThirdPartyUser.objects.get(
280 d2633501 Kostas Papadimitriou
                                token=request.POST.get('third_party_token'),
281 d2633501 Kostas Papadimitriou
                                third_party_identifier= \
282 d2633501 Kostas Papadimitriou
            self.cleaned_data.get('third_party_identifier'))
283 d2633501 Kostas Papadimitriou
        return user.add_pending_auth_provider(pending)
284 d2633501 Kostas Papadimitriou
285 d2633501 Kostas Papadimitriou
286 8f5a3a06 Sofia Papagiannaki
    def save(self, commit=True):
287 8f5a3a06 Sofia Papagiannaki
        user = super(ThirdPartyUserCreationForm, self).save(commit=False)
288 8f5a3a06 Sofia Papagiannaki
        user.set_unusable_password()
289 d2633501 Kostas Papadimitriou
        user.renew_token()
290 8f5a3a06 Sofia Papagiannaki
        if commit:
291 8f5a3a06 Sofia Papagiannaki
            user.save()
292 aab4d540 Sofia Papagiannaki
            logger.log(LOGGING_LEVEL, 'Created user %s' % user.email)
293 8f5a3a06 Sofia Papagiannaki
        return user
294 8f5a3a06 Sofia Papagiannaki
295 5ce3ce4f Sofia Papagiannaki
296 8f5a3a06 Sofia Papagiannaki
class InvitedThirdPartyUserCreationForm(ThirdPartyUserCreationForm):
297 4e30244e Sofia Papagiannaki
    """
298 062c970c Sofia Papagiannaki
    Extends the ThirdPartyUserCreationForm: email is readonly.
299 4e30244e Sofia Papagiannaki
    """
300 8f5a3a06 Sofia Papagiannaki
    def __init__(self, *args, **kwargs):
301 4e30244e Sofia Papagiannaki
        """
302 4e30244e Sofia Papagiannaki
        Changes the order of fields, and removes the username field.
303 4e30244e Sofia Papagiannaki
        """
304 5ce3ce4f Sofia Papagiannaki
        super(
305 5ce3ce4f Sofia Papagiannaki
            InvitedThirdPartyUserCreationForm, self).__init__(*args, **kwargs)
306 4e30244e Sofia Papagiannaki
307 8f5a3a06 Sofia Papagiannaki
        #set readonly form fields
308 062c970c Sofia Papagiannaki
        ro = ('email',)
309 4e30244e Sofia Papagiannaki
        for f in ro:
310 4e30244e Sofia Papagiannaki
            self.fields[f].widget.attrs['readonly'] = True
311 ab8bfb29 Kostas Papadimitriou
312 4e30244e Sofia Papagiannaki
    def save(self, commit=True):
313 4e30244e Sofia Papagiannaki
        user = super(InvitedThirdPartyUserCreationForm, self).save(commit=False)
314 d2633501 Kostas Papadimitriou
        user.set_invitation_level()
315 4e30244e Sofia Papagiannaki
        user.email_verified = True
316 4e30244e Sofia Papagiannaki
        if commit:
317 4e30244e Sofia Papagiannaki
            user.save()
318 4e30244e Sofia Papagiannaki
        return user
319 8f5a3a06 Sofia Papagiannaki
320 5ce3ce4f Sofia Papagiannaki
321 18ffbee1 Sofia Papagiannaki
class ShibbolethUserCreationForm(ThirdPartyUserCreationForm):
322 5ce3ce4f Sofia Papagiannaki
    additional_email = forms.CharField(
323 5ce3ce4f Sofia Papagiannaki
        widget=forms.HiddenInput(), label='', required=False)
324 ab8bfb29 Kostas Papadimitriou
325 ca828a10 Sofia Papagiannaki
    def __init__(self, *args, **kwargs):
326 ca828a10 Sofia Papagiannaki
        super(ShibbolethUserCreationForm, self).__init__(*args, **kwargs)
327 ca828a10 Sofia Papagiannaki
        # copy email value to additional_mail in case user will change it
328 ca828a10 Sofia Papagiannaki
        name = 'email'
329 ca828a10 Sofia Papagiannaki
        field = self.fields[name]
330 ca828a10 Sofia Papagiannaki
        self.initial['additional_email'] = self.initial.get(name, field.initial)
331 ef20ea07 Sofia Papagiannaki
        self.initial['email'] = None
332 d2633501 Kostas Papadimitriou
333 4e30244e Sofia Papagiannaki
334 9a06d96f Olga Brani
class InvitedShibbolethUserCreationForm(ShibbolethUserCreationForm,
335 9a06d96f Olga Brani
                                        InvitedThirdPartyUserCreationForm):
336 4e30244e Sofia Papagiannaki
    pass
337 ab8bfb29 Kostas Papadimitriou
338 5ce3ce4f Sofia Papagiannaki
339 5ed6816e Sofia Papagiannaki
class LoginForm(AuthenticationForm):
340 5ed6816e Sofia Papagiannaki
    username = forms.EmailField(label=_("Email"))
341 672d445a Sofia Papagiannaki
    recaptcha_challenge_field = forms.CharField(widget=DummyWidget)
342 5ce3ce4f Sofia Papagiannaki
    recaptcha_response_field = forms.CharField(
343 5ce3ce4f Sofia Papagiannaki
        widget=RecaptchaWidget, label='')
344 ab8bfb29 Kostas Papadimitriou
345 672d445a Sofia Papagiannaki
    def __init__(self, *args, **kwargs):
346 672d445a Sofia Papagiannaki
        was_limited = kwargs.get('was_limited', False)
347 672d445a Sofia Papagiannaki
        request = kwargs.get('request', None)
348 672d445a Sofia Papagiannaki
        if request:
349 672d445a Sofia Papagiannaki
            self.ip = request.META.get('REMOTE_ADDR',
350 672d445a Sofia Papagiannaki
                                       request.META.get('HTTP_X_REAL_IP', None))
351 ab8bfb29 Kostas Papadimitriou
352 672d445a Sofia Papagiannaki
        t = ('request', 'was_limited')
353 672d445a Sofia Papagiannaki
        for elem in t:
354 672d445a Sofia Papagiannaki
            if elem in kwargs.keys():
355 672d445a Sofia Papagiannaki
                kwargs.pop(elem)
356 672d445a Sofia Papagiannaki
        super(LoginForm, self).__init__(*args, **kwargs)
357 ab8bfb29 Kostas Papadimitriou
358 672d445a Sofia Papagiannaki
        self.fields.keyOrder = ['username', 'password']
359 672d445a Sofia Papagiannaki
        if was_limited and RECAPTCHA_ENABLED:
360 672d445a Sofia Papagiannaki
            self.fields.keyOrder.extend(['recaptcha_challenge_field',
361 5ce3ce4f Sofia Papagiannaki
                                         'recaptcha_response_field', ])
362 9a06d96f Olga Brani
363 9a06d96f Olga Brani
    def clean_username(self):
364 4bdd7e3d Kostas Papadimitriou
        return self.cleaned_data['username'].lower()
365 ab8bfb29 Kostas Papadimitriou
366 672d445a Sofia Papagiannaki
    def clean_recaptcha_response_field(self):
367 672d445a Sofia Papagiannaki
        if 'recaptcha_challenge_field' in self.cleaned_data:
368 672d445a Sofia Papagiannaki
            self.validate_captcha()
369 672d445a Sofia Papagiannaki
        return self.cleaned_data['recaptcha_response_field']
370 672d445a Sofia Papagiannaki
371 672d445a Sofia Papagiannaki
    def clean_recaptcha_challenge_field(self):
372 672d445a Sofia Papagiannaki
        if 'recaptcha_response_field' in self.cleaned_data:
373 672d445a Sofia Papagiannaki
            self.validate_captcha()
374 672d445a Sofia Papagiannaki
        return self.cleaned_data['recaptcha_challenge_field']
375 672d445a Sofia Papagiannaki
376 672d445a Sofia Papagiannaki
    def validate_captcha(self):
377 672d445a Sofia Papagiannaki
        rcf = self.cleaned_data['recaptcha_challenge_field']
378 672d445a Sofia Papagiannaki
        rrf = self.cleaned_data['recaptcha_response_field']
379 672d445a Sofia Papagiannaki
        check = captcha.submit(rcf, rrf, RECAPTCHA_PRIVATE_KEY, self.ip)
380 672d445a Sofia Papagiannaki
        if not check.is_valid:
381 ae497612 Olga Brani
            raise forms.ValidationError(_(astakos_messages.CAPTCHA_VALIDATION_ERR))
382 2e90e3ec Kostas Papadimitriou
383 eedb3923 Sofia Papagiannaki
    def clean(self):
384 1f3b4b39 Sofia Papagiannaki
        """
385 1f3b4b39 Sofia Papagiannaki
        Override default behavior in order to check user's activation later
386 1f3b4b39 Sofia Papagiannaki
        """
387 c4b1a172 Kostas Papadimitriou
        username = self.cleaned_data.get('username')
388 c4b1a172 Kostas Papadimitriou
389 bea8a810 Kostas Papadimitriou
        if username:
390 bea8a810 Kostas Papadimitriou
            try:
391 bea8a810 Kostas Papadimitriou
                user = AstakosUser.objects.get_by_identifier(username)
392 bea8a810 Kostas Papadimitriou
                if not user.has_auth_provider('local'):
393 bea8a810 Kostas Papadimitriou
                    provider = auth_providers.get_provider('local')
394 bea8a810 Kostas Papadimitriou
                    raise forms.ValidationError(
395 bea8a810 Kostas Papadimitriou
                        _(provider.get_message('NOT_ACTIVE_FOR_USER')))
396 bea8a810 Kostas Papadimitriou
            except AstakosUser.DoesNotExist:
397 bea8a810 Kostas Papadimitriou
                pass
398 c4b1a172 Kostas Papadimitriou
399 1f3b4b39 Sofia Papagiannaki
        try:
400 1f3b4b39 Sofia Papagiannaki
            super(LoginForm, self).clean()
401 1f3b4b39 Sofia Papagiannaki
        except forms.ValidationError, e:
402 c4b1a172 Kostas Papadimitriou
            if self.user_cache is None:
403 c4b1a172 Kostas Papadimitriou
                raise
404 c4b1a172 Kostas Papadimitriou
            if not self.user_cache.is_active:
405 c4b1a172 Kostas Papadimitriou
                raise forms.ValidationError(self.user_cache.get_inactive_message())
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 4bdd7e3d Kostas Papadimitriou
            user = AstakosUser.objects.get(email__iexact=email)
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 34a76cdb Kostas Papadimitriou
517 49790d9d Sofia Papagiannaki
    class Meta:
518 49790d9d Sofia Papagiannaki
        model = EmailChange
519 49790d9d Sofia Papagiannaki
        fields = ('new_email_address',)
520 ab8bfb29 Kostas Papadimitriou
521 49790d9d Sofia Papagiannaki
    def clean_new_email_address(self):
522 49790d9d Sofia Papagiannaki
        addr = self.cleaned_data['new_email_address']
523 49790d9d Sofia Papagiannaki
        if AstakosUser.objects.filter(email__iexact=addr):
524 ae497612 Olga Brani
            raise forms.ValidationError(_(astakos_messages.EMAIL_USED))
525 49790d9d Sofia Papagiannaki
        return addr
526 ab8bfb29 Kostas Papadimitriou
527 49790d9d Sofia Papagiannaki
    def save(self, email_template_name, request, commit=True):
528 49790d9d Sofia Papagiannaki
        ec = super(EmailChangeForm, self).save(commit=False)
529 49790d9d Sofia Papagiannaki
        ec.user = request.user
530 5ce3ce4f Sofia Papagiannaki
        activation_key = hashlib.sha1(
531 5ce3ce4f Sofia Papagiannaki
            str(random()) + smart_str(ec.new_email_address))
532 5ce3ce4f Sofia Papagiannaki
        ec.activation_key = activation_key.hexdigest()
533 49790d9d Sofia Papagiannaki
        if commit:
534 49790d9d Sofia Papagiannaki
            ec.save()
535 49790d9d Sofia Papagiannaki
        send_change_email(ec, request, email_template_name=email_template_name)
536 49790d9d Sofia Papagiannaki
537 5ce3ce4f Sofia Papagiannaki
538 270dd48d Sofia Papagiannaki
class SignApprovalTermsForm(forms.ModelForm):
539 34a76cdb Kostas Papadimitriou
540 270dd48d Sofia Papagiannaki
    class Meta:
541 270dd48d Sofia Papagiannaki
        model = AstakosUser
542 270dd48d Sofia Papagiannaki
        fields = ("has_signed_terms",)
543 18ffbee1 Sofia Papagiannaki
544 270dd48d Sofia Papagiannaki
    def __init__(self, *args, **kwargs):
545 270dd48d Sofia Papagiannaki
        super(SignApprovalTermsForm, self).__init__(*args, **kwargs)
546 18ffbee1 Sofia Papagiannaki
547 270dd48d Sofia Papagiannaki
    def clean_has_signed_terms(self):
548 270dd48d Sofia Papagiannaki
        has_signed_terms = self.cleaned_data['has_signed_terms']
549 270dd48d Sofia Papagiannaki
        if not has_signed_terms:
550 ae497612 Olga Brani
            raise forms.ValidationError(_(astakos_messages.SIGN_TERMS))
551 270dd48d Sofia Papagiannaki
        return has_signed_terms
552 8f5a3a06 Sofia Papagiannaki
553 5ce3ce4f Sofia Papagiannaki
554 8f5a3a06 Sofia Papagiannaki
class InvitationForm(forms.ModelForm):
555 34a76cdb Kostas Papadimitriou
556 8f5a3a06 Sofia Papagiannaki
    username = forms.EmailField(label=_("Email"))
557 ab8bfb29 Kostas Papadimitriou
558 18ffbee1 Sofia Papagiannaki
    def __init__(self, *args, **kwargs):
559 18ffbee1 Sofia Papagiannaki
        super(InvitationForm, self).__init__(*args, **kwargs)
560 ab8bfb29 Kostas Papadimitriou
561 8f5a3a06 Sofia Papagiannaki
    class Meta:
562 8f5a3a06 Sofia Papagiannaki
        model = Invitation
563 8f5a3a06 Sofia Papagiannaki
        fields = ('username', 'realname')
564 ab8bfb29 Kostas Papadimitriou
565 8f5a3a06 Sofia Papagiannaki
    def clean_username(self):
566 8f5a3a06 Sofia Papagiannaki
        username = self.cleaned_data['username']
567 8f5a3a06 Sofia Papagiannaki
        try:
568 5ce3ce4f Sofia Papagiannaki
            Invitation.objects.get(username=username)
569 ae497612 Olga Brani
            raise forms.ValidationError(_(astakos_messages.INVITATION_EMAIL_EXISTS))
570 8f5a3a06 Sofia Papagiannaki
        except Invitation.DoesNotExist:
571 8f5a3a06 Sofia Papagiannaki
            pass
572 18ffbee1 Sofia Papagiannaki
        return username
573 1039bab1 Sofia Papagiannaki
574 5ce3ce4f Sofia Papagiannaki
575 1039bab1 Sofia Papagiannaki
class ExtendedPasswordChangeForm(PasswordChangeForm):
576 1039bab1 Sofia Papagiannaki
    """
577 1039bab1 Sofia Papagiannaki
    Extends PasswordChangeForm by enabling user
578 1039bab1 Sofia Papagiannaki
    to optionally renew also the token.
579 1039bab1 Sofia Papagiannaki
    """
580 ee210d1d Sofia Papagiannaki
    if not NEWPASSWD_INVALIDATE_TOKEN:
581 48e9f076 Sofia Papagiannaki
        renew = forms.BooleanField(label='Renew token', required=False,
582 48e9f076 Sofia Papagiannaki
                                   initial=True,
583 48e9f076 Sofia Papagiannaki
                                   help_text='Unsetting this may result in security risk.')
584 ab8bfb29 Kostas Papadimitriou
585 1039bab1 Sofia Papagiannaki
    def __init__(self, user, *args, **kwargs):
586 bf0c6de5 Sofia Papagiannaki
        self.session_key = kwargs.pop('session_key', None)
587 1039bab1 Sofia Papagiannaki
        super(ExtendedPasswordChangeForm, self).__init__(user, *args, **kwargs)
588 ab8bfb29 Kostas Papadimitriou
589 1039bab1 Sofia Papagiannaki
    def save(self, commit=True):
590 bf0c6de5 Sofia Papagiannaki
        try:
591 bf0c6de5 Sofia Papagiannaki
            if NEWPASSWD_INVALIDATE_TOKEN or self.cleaned_data.get('renew'):
592 bf0c6de5 Sofia Papagiannaki
                self.user.renew_token()
593 bf0c6de5 Sofia Papagiannaki
            self.user.flush_sessions(current_key=self.session_key)
594 bf0c6de5 Sofia Papagiannaki
        except AttributeError:
595 bf0c6de5 Sofia Papagiannaki
            # if user model does has not such methods
596 bf0c6de5 Sofia Papagiannaki
            pass
597 53161dd8 Sofia Papagiannaki
        return super(ExtendedPasswordChangeForm, self).save(commit=commit)
598 48e9f076 Sofia Papagiannaki
599 5ce3ce4f Sofia Papagiannaki
600 73fbaec4 Sofia Papagiannaki
# class AstakosGroupCreationForm(forms.ModelForm):
601 73fbaec4 Sofia Papagiannaki
#     kind = forms.ModelChoiceField(
602 73fbaec4 Sofia Papagiannaki
#         queryset=GroupKind.objects.all(),
603 73fbaec4 Sofia Papagiannaki
#         label="",
604 73fbaec4 Sofia Papagiannaki
#         widget=forms.HiddenInput()
605 73fbaec4 Sofia Papagiannaki
#     )
606 73fbaec4 Sofia Papagiannaki
#     name = forms.CharField(
607 73fbaec4 Sofia Papagiannaki
#         validators=[validators.RegexValidator(
608 73fbaec4 Sofia Papagiannaki
#             DOMAIN_VALUE_REGEX,
609 73fbaec4 Sofia Papagiannaki
#             _(astakos_messages.DOMAIN_VALUE_ERR), 'invalid'
610 73fbaec4 Sofia Papagiannaki
#         )],
611 73fbaec4 Sofia Papagiannaki
#         widget=forms.TextInput(attrs={'placeholder': 'myproject.mylab.ntua.gr'}),
612 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 "
613 73fbaec4 Sofia Papagiannaki
#     )
614 73fbaec4 Sofia Papagiannaki
#     homepage = forms.URLField(
615 73fbaec4 Sofia Papagiannaki
#         label= 'Homepage Url',
616 73fbaec4 Sofia Papagiannaki
#         widget=forms.TextInput(attrs={'placeholder': 'http://myproject.com'}),
617 73fbaec4 Sofia Papagiannaki
#         help_text="This should be a URL pointing at your project's site. e.g.: http://myproject.com ",
618 73fbaec4 Sofia Papagiannaki
#         required=False
619 73fbaec4 Sofia Papagiannaki
#     )
620 73fbaec4 Sofia Papagiannaki
#     desc = forms.CharField(
621 73fbaec4 Sofia Papagiannaki
#         label= 'Description',
622 73fbaec4 Sofia Papagiannaki
#         widget=forms.Textarea, 
623 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. "
624 73fbaec4 Sofia Papagiannaki
#     )
625 73fbaec4 Sofia Papagiannaki
#     issue_date = forms.DateTimeField(
626 73fbaec4 Sofia Papagiannaki
#         label= 'Start date',
627 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."
628 73fbaec4 Sofia Papagiannaki
#     )
629 73fbaec4 Sofia Papagiannaki
#     expiration_date = forms.DateTimeField(
630 73fbaec4 Sofia Papagiannaki
#         label= 'End date',
631 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.  "
632 73fbaec4 Sofia Papagiannaki
#     )
633 73fbaec4 Sofia Papagiannaki
#     moderation_enabled = forms.BooleanField(
634 73fbaec4 Sofia Papagiannaki
#         label= 'Moderated',
635 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. ",
636 73fbaec4 Sofia Papagiannaki
#         required=False,
637 73fbaec4 Sofia Papagiannaki
#         initial=True
638 73fbaec4 Sofia Papagiannaki
#     )
639 73fbaec4 Sofia Papagiannaki
#     max_participants = forms.IntegerField(
640 73fbaec4 Sofia Papagiannaki
#         label='Total number of members',
641 73fbaec4 Sofia Papagiannaki
#         required=True, min_value=1,
642 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. "
643 73fbaec4 Sofia Papagiannaki
#     )
644 73fbaec4 Sofia Papagiannaki
# 
645 73fbaec4 Sofia Papagiannaki
#     class Meta:
646 73fbaec4 Sofia Papagiannaki
#         model = AstakosGroup
647 73fbaec4 Sofia Papagiannaki
# 
648 73fbaec4 Sofia Papagiannaki
#     def __init__(self, *args, **kwargs):
649 73fbaec4 Sofia Papagiannaki
#         #update QueryDict
650 73fbaec4 Sofia Papagiannaki
#         args = list(args)
651 73fbaec4 Sofia Papagiannaki
#         qd = args.pop(0).copy()
652 73fbaec4 Sofia Papagiannaki
#         members_unlimited = qd.pop('members_unlimited', False)
653 73fbaec4 Sofia Papagiannaki
#         members_uplimit = qd.pop('members_uplimit', None)
654 73fbaec4 Sofia Papagiannaki
# 
655 73fbaec4 Sofia Papagiannaki
#         #substitue QueryDict
656 73fbaec4 Sofia Papagiannaki
#         args.insert(0, qd)
657 73fbaec4 Sofia Papagiannaki
# 
658 73fbaec4 Sofia Papagiannaki
#         super(AstakosGroupCreationForm, self).__init__(*args, **kwargs)
659 73fbaec4 Sofia Papagiannaki
#         
660 73fbaec4 Sofia Papagiannaki
#         self.fields.keyOrder = ['kind', 'name', 'homepage', 'desc',
661 73fbaec4 Sofia Papagiannaki
#                                 'issue_date', 'expiration_date',
662 73fbaec4 Sofia Papagiannaki
#                                 'moderation_enabled', 'max_participants']
663 73fbaec4 Sofia Papagiannaki
#         def add_fields((k, v)):
664 73fbaec4 Sofia Papagiannaki
#             k = k.partition('_proxy')[0]
665 73fbaec4 Sofia Papagiannaki
#             self.fields[k] = forms.IntegerField(
666 73fbaec4 Sofia Papagiannaki
#                 required=False,
667 73fbaec4 Sofia Papagiannaki
#                 widget=forms.HiddenInput(),
668 73fbaec4 Sofia Papagiannaki
#                 min_value=1
669 73fbaec4 Sofia Papagiannaki
#             )
670 73fbaec4 Sofia Papagiannaki
#         map(add_fields,
671 73fbaec4 Sofia Papagiannaki
#             ((k, v) for k,v in qd.iteritems() if k.endswith('_uplimit'))
672 73fbaec4 Sofia Papagiannaki
#         )
673 73fbaec4 Sofia Papagiannaki
# 
674 73fbaec4 Sofia Papagiannaki
#         def add_fields((k, v)):
675 73fbaec4 Sofia Papagiannaki
#             self.fields[k] = forms.BooleanField(
676 73fbaec4 Sofia Papagiannaki
#                 required=False,
677 73fbaec4 Sofia Papagiannaki
#                 #widget=forms.HiddenInput()
678 73fbaec4 Sofia Papagiannaki
#             )
679 73fbaec4 Sofia Papagiannaki
#         map(add_fields,
680 73fbaec4 Sofia Papagiannaki
#             ((k, v) for k,v in qd.iteritems() if k.startswith('is_selected_'))
681 73fbaec4 Sofia Papagiannaki
#         )
682 73fbaec4 Sofia Papagiannaki
# 
683 73fbaec4 Sofia Papagiannaki
#     def policies(self):
684 73fbaec4 Sofia Papagiannaki
#         self.clean()
685 73fbaec4 Sofia Papagiannaki
#         policies = []
686 73fbaec4 Sofia Papagiannaki
#         append = policies.append
687 73fbaec4 Sofia Papagiannaki
#         for name, uplimit in self.cleaned_data.iteritems():
688 73fbaec4 Sofia Papagiannaki
# 
689 73fbaec4 Sofia Papagiannaki
#             subs = name.split('_uplimit')
690 73fbaec4 Sofia Papagiannaki
#             if len(subs) == 2:
691 73fbaec4 Sofia Papagiannaki
#                 prefix, suffix = subs
692 73fbaec4 Sofia Papagiannaki
#                 s, sep, r = prefix.partition(RESOURCE_SEPARATOR)
693 73fbaec4 Sofia Papagiannaki
#                 resource = Resource.objects.get(service__name=s, name=r)
694 73fbaec4 Sofia Papagiannaki
# 
695 73fbaec4 Sofia Papagiannaki
#                 # keep only resource limits for selected resource groups
696 73fbaec4 Sofia Papagiannaki
#                 if self.cleaned_data.get(
697 73fbaec4 Sofia Papagiannaki
#                     'is_selected_%s' % resource.group, False
698 73fbaec4 Sofia Papagiannaki
#                 ):
699 73fbaec4 Sofia Papagiannaki
#                     append(dict(service=s, resource=r, uplimit=uplimit))
700 73fbaec4 Sofia Papagiannaki
#         return policies
701 73fbaec4 Sofia Papagiannaki
# 
702 73fbaec4 Sofia Papagiannaki
# class AstakosGroupCreationSummaryForm(forms.ModelForm):
703 73fbaec4 Sofia Papagiannaki
#     kind = forms.ModelChoiceField(
704 73fbaec4 Sofia Papagiannaki
#         queryset=GroupKind.objects.all(),
705 73fbaec4 Sofia Papagiannaki
#         label="",
706 73fbaec4 Sofia Papagiannaki
#         widget=forms.HiddenInput()
707 73fbaec4 Sofia Papagiannaki
#     )
708 73fbaec4 Sofia Papagiannaki
#     name = forms.CharField(
709 73fbaec4 Sofia Papagiannaki
#         widget=forms.TextInput(attrs={'placeholder': 'eg. foo.ece.ntua.gr'}),
710 73fbaec4 Sofia Papagiannaki
#         help_text="Name should be in the form of dns"
711 73fbaec4 Sofia Papagiannaki
#     )
712 73fbaec4 Sofia Papagiannaki
#     moderation_enabled = forms.BooleanField(
713 73fbaec4 Sofia Papagiannaki
#         help_text="Check if you want to approve members participation manually",
714 73fbaec4 Sofia Papagiannaki
#         required=False,
715 73fbaec4 Sofia Papagiannaki
#         initial=True
716 73fbaec4 Sofia Papagiannaki
#     )
717 73fbaec4 Sofia Papagiannaki
#     max_participants = forms.IntegerField(
718 73fbaec4 Sofia Papagiannaki
#         required=False, min_value=1
719 73fbaec4 Sofia Papagiannaki
#     )
720 73fbaec4 Sofia Papagiannaki
# 
721 73fbaec4 Sofia Papagiannaki
#     class Meta:
722 73fbaec4 Sofia Papagiannaki
#         model = AstakosGroup
723 73fbaec4 Sofia Papagiannaki
# 
724 73fbaec4 Sofia Papagiannaki
#     def __init__(self, *args, **kwargs):
725 73fbaec4 Sofia Papagiannaki
#         #update QueryDict
726 73fbaec4 Sofia Papagiannaki
#         args = list(args)
727 73fbaec4 Sofia Papagiannaki
#         qd = args.pop(0).copy()
728 73fbaec4 Sofia Papagiannaki
#         members_unlimited = qd.pop('members_unlimited', False)
729 73fbaec4 Sofia Papagiannaki
#         members_uplimit = qd.pop('members_uplimit', None)
730 73fbaec4 Sofia Papagiannaki
# 
731 73fbaec4 Sofia Papagiannaki
#         #substitue QueryDict
732 73fbaec4 Sofia Papagiannaki
#         args.insert(0, qd)
733 73fbaec4 Sofia Papagiannaki
# 
734 73fbaec4 Sofia Papagiannaki
#         super(AstakosGroupCreationSummaryForm, self).__init__(*args, **kwargs)
735 73fbaec4 Sofia Papagiannaki
#         self.fields.keyOrder = ['kind', 'name', 'homepage', 'desc',
736 73fbaec4 Sofia Papagiannaki
#                                 'issue_date', 'expiration_date',
737 73fbaec4 Sofia Papagiannaki
#                                 'moderation_enabled', 'max_participants']
738 73fbaec4 Sofia Papagiannaki
#         def add_fields((k, v)):
739 73fbaec4 Sofia Papagiannaki
#             self.fields[k] = forms.IntegerField(
740 73fbaec4 Sofia Papagiannaki
#                 required=False,
741 73fbaec4 Sofia Papagiannaki
#                 widget=forms.TextInput(),
742 73fbaec4 Sofia Papagiannaki
#                 min_value=1
743 73fbaec4 Sofia Papagiannaki
#             )
744 73fbaec4 Sofia Papagiannaki
#         map(add_fields,
745 73fbaec4 Sofia Papagiannaki
#             ((k, v) for k,v in qd.iteritems() if k.endswith('_uplimit'))
746 73fbaec4 Sofia Papagiannaki
#         )
747 73fbaec4 Sofia Papagiannaki
# 
748 73fbaec4 Sofia Papagiannaki
#         def add_fields((k, v)):
749 73fbaec4 Sofia Papagiannaki
#             self.fields[k] = forms.BooleanField(
750 73fbaec4 Sofia Papagiannaki
#                 required=False,
751 73fbaec4 Sofia Papagiannaki
#                 widget=forms.HiddenInput()
752 73fbaec4 Sofia Papagiannaki
#             )
753 73fbaec4 Sofia Papagiannaki
#         map(add_fields,
754 73fbaec4 Sofia Papagiannaki
#             ((k, v) for k,v in qd.iteritems() if k.startswith('is_selected_'))
755 73fbaec4 Sofia Papagiannaki
#         )
756 73fbaec4 Sofia Papagiannaki
#         for f in self.fields.values():
757 73fbaec4 Sofia Papagiannaki
#             f.widget = forms.HiddenInput()
758 73fbaec4 Sofia Papagiannaki
# 
759 73fbaec4 Sofia Papagiannaki
#     def clean(self):
760 73fbaec4 Sofia Papagiannaki
#         super(AstakosGroupCreationSummaryForm, self).clean()
761 73fbaec4 Sofia Papagiannaki
#         self.cleaned_data['policies'] = []
762 73fbaec4 Sofia Papagiannaki
#         append = self.cleaned_data['policies'].append
763 73fbaec4 Sofia Papagiannaki
#         #tbd = [f for f in self.fields if (f.startswith('is_selected_') and (not f.endswith('_proxy')))]
764 73fbaec4 Sofia Papagiannaki
#         tbd = [f for f in self.fields if f.startswith('is_selected_')]
765 73fbaec4 Sofia Papagiannaki
#         for name, uplimit in self.cleaned_data.iteritems():
766 73fbaec4 Sofia Papagiannaki
#             subs = name.split('_uplimit')
767 73fbaec4 Sofia Papagiannaki
#             if len(subs) == 2:
768 73fbaec4 Sofia Papagiannaki
#                 tbd.append(name)
769 73fbaec4 Sofia Papagiannaki
#                 prefix, suffix = subs
770 73fbaec4 Sofia Papagiannaki
#                 s, sep, r = prefix.partition(RESOURCE_SEPARATOR)
771 73fbaec4 Sofia Papagiannaki
#                 resource = Resource.objects.get(service__name=s, name=r)
772 73fbaec4 Sofia Papagiannaki
# 
773 73fbaec4 Sofia Papagiannaki
#                 # keep only resource limits for selected resource groups
774 73fbaec4 Sofia Papagiannaki
#                 if self.cleaned_data.get(
775 73fbaec4 Sofia Papagiannaki
#                     'is_selected_%s' % resource.group, False
776 73fbaec4 Sofia Papagiannaki
#                 ):
777 73fbaec4 Sofia Papagiannaki
#                     append(dict(service=s, resource=r, uplimit=uplimit))
778 73fbaec4 Sofia Papagiannaki
#         for name in tbd:
779 73fbaec4 Sofia Papagiannaki
#             self.cleaned_data.pop(name, None)
780 73fbaec4 Sofia Papagiannaki
#         return self.cleaned_data
781 73fbaec4 Sofia Papagiannaki
# 
782 73fbaec4 Sofia Papagiannaki
# class AstakosGroupUpdateForm(forms.ModelForm):
783 73fbaec4 Sofia Papagiannaki
#     class Meta:
784 73fbaec4 Sofia Papagiannaki
#         model = AstakosGroup
785 73fbaec4 Sofia Papagiannaki
#         fields = ( 'desc','homepage', 'moderation_enabled')
786 73fbaec4 Sofia Papagiannaki
# 
787 73fbaec4 Sofia Papagiannaki
# 
788 73fbaec4 Sofia Papagiannaki
# class AddGroupMembersForm(forms.Form):
789 73fbaec4 Sofia Papagiannaki
#     q = forms.CharField(
790 73fbaec4 Sofia Papagiannaki
#         max_length=800, widget=forms.Textarea, label=_('Add members'),
791 73fbaec4 Sofia Papagiannaki
#         help_text=_(astakos_messages.ADD_GROUP_MEMBERS_Q_HELP),
792 73fbaec4 Sofia Papagiannaki
#         required=True)
793 73fbaec4 Sofia Papagiannaki
# 
794 73fbaec4 Sofia Papagiannaki
#     def clean(self):
795 73fbaec4 Sofia Papagiannaki
#         q = self.cleaned_data.get('q') or ''
796 73fbaec4 Sofia Papagiannaki
#         users = q.split(',')
797 73fbaec4 Sofia Papagiannaki
#         users = list(u.strip() for u in users if u)
798 73fbaec4 Sofia Papagiannaki
#         db_entries = AstakosUser.objects.filter(email__in=users)
799 73fbaec4 Sofia Papagiannaki
#         unknown = list(set(users) - set(u.email for u in db_entries))
800 73fbaec4 Sofia Papagiannaki
#         if unknown:
801 73fbaec4 Sofia Papagiannaki
#             raise forms.ValidationError(_(astakos_messages.UNKNOWN_USERS) % ','.join(unknown))
802 73fbaec4 Sofia Papagiannaki
#         self.valid_users = db_entries
803 73fbaec4 Sofia Papagiannaki
#         return self.cleaned_data
804 73fbaec4 Sofia Papagiannaki
# 
805 73fbaec4 Sofia Papagiannaki
#     def get_valid_users(self):
806 73fbaec4 Sofia Papagiannaki
#         """Should be called after form cleaning"""
807 73fbaec4 Sofia Papagiannaki
#         try:
808 73fbaec4 Sofia Papagiannaki
#             return self.valid_users
809 73fbaec4 Sofia Papagiannaki
#         except:
810 73fbaec4 Sofia Papagiannaki
#             return ()
811 73fbaec4 Sofia Papagiannaki
# 
812 73fbaec4 Sofia Papagiannaki
# 
813 73fbaec4 Sofia Papagiannaki
# class AstakosGroupSearchForm(forms.Form):
814 73fbaec4 Sofia Papagiannaki
#     q = forms.CharField(max_length=200, label='Search project')
815 73fbaec4 Sofia Papagiannaki
# 
816 73fbaec4 Sofia Papagiannaki
# 
817 73fbaec4 Sofia Papagiannaki
# class TimelineForm(forms.Form):
818 73fbaec4 Sofia Papagiannaki
#     entity = forms.ModelChoiceField(
819 73fbaec4 Sofia Papagiannaki
#         queryset=AstakosUser.objects.filter(is_active=True)
820 73fbaec4 Sofia Papagiannaki
#     )
821 73fbaec4 Sofia Papagiannaki
#     resource = forms.ModelChoiceField(
822 73fbaec4 Sofia Papagiannaki
#         queryset=Resource.objects.all()
823 73fbaec4 Sofia Papagiannaki
#     )
824 73fbaec4 Sofia Papagiannaki
#     start_date = forms.DateTimeField()
825 73fbaec4 Sofia Papagiannaki
#     end_date = forms.DateTimeField()
826 73fbaec4 Sofia Papagiannaki
#     details = forms.BooleanField(required=False, label="Detailed Listing")
827 73fbaec4 Sofia Papagiannaki
#     operation = forms.ChoiceField(
828 73fbaec4 Sofia Papagiannaki
#         label='Charge Method',
829 73fbaec4 Sofia Papagiannaki
#         choices=(('', '-------------'),
830 73fbaec4 Sofia Papagiannaki
#                  ('charge_usage', 'Charge Usage'),
831 73fbaec4 Sofia Papagiannaki
#                  ('charge_traffic', 'Charge Traffic'), )
832 73fbaec4 Sofia Papagiannaki
#     )
833 73fbaec4 Sofia Papagiannaki
# 
834 73fbaec4 Sofia Papagiannaki
#     def clean(self):
835 73fbaec4 Sofia Papagiannaki
#         super(TimelineForm, self).clean()
836 73fbaec4 Sofia Papagiannaki
#         d = self.cleaned_data
837 73fbaec4 Sofia Papagiannaki
#         if 'resource' in d:
838 73fbaec4 Sofia Papagiannaki
#             d['resource'] = str(d['resource'])
839 73fbaec4 Sofia Papagiannaki
#         if 'start_date' in d:
840 73fbaec4 Sofia Papagiannaki
#             d['start_date'] = d['start_date'].strftime(
841 73fbaec4 Sofia Papagiannaki
#                 "%Y-%m-%dT%H:%M:%S.%f")[:24]
842 73fbaec4 Sofia Papagiannaki
#         if 'end_date' in d:
843 73fbaec4 Sofia Papagiannaki
#             d['end_date'] = d['end_date'].strftime("%Y-%m-%dT%H:%M:%S.%f")[:24]
844 73fbaec4 Sofia Papagiannaki
#         if 'entity' in d:
845 73fbaec4 Sofia Papagiannaki
#             d['entity'] = d['entity'].email
846 73fbaec4 Sofia Papagiannaki
#         return d
847 73fbaec4 Sofia Papagiannaki
# 
848 73fbaec4 Sofia Papagiannaki
# 
849 73fbaec4 Sofia Papagiannaki
# class AstakosGroupSortForm(forms.Form):
850 73fbaec4 Sofia Papagiannaki
#     sorting = forms.ChoiceField(
851 73fbaec4 Sofia Papagiannaki
#         label='Sort by',
852 73fbaec4 Sofia Papagiannaki
#         choices=(
853 73fbaec4 Sofia Papagiannaki
#             ('groupname', 'Name'),
854 73fbaec4 Sofia Papagiannaki
#             ('issue_date', 'Issue Date'),
855 73fbaec4 Sofia Papagiannaki
#             ('expiration_date', 'Expiration Date'),
856 73fbaec4 Sofia Papagiannaki
#             ('approved_members_num', 'Participants'),
857 73fbaec4 Sofia Papagiannaki
#             ('moderation_enabled', 'Moderation'),
858 73fbaec4 Sofia Papagiannaki
#             ('membership_status', 'Enrollment Status')
859 73fbaec4 Sofia Papagiannaki
#         ),
860 73fbaec4 Sofia Papagiannaki
#         required=True
861 73fbaec4 Sofia Papagiannaki
#     )
862 73fbaec4 Sofia Papagiannaki
# 
863 73fbaec4 Sofia Papagiannaki
# class MembersSortForm(forms.Form):
864 73fbaec4 Sofia Papagiannaki
#     sorting = forms.ChoiceField(
865 73fbaec4 Sofia Papagiannaki
#         label='Sort by',
866 73fbaec4 Sofia Papagiannaki
#         choices=(('person__email', 'User Id'),
867 73fbaec4 Sofia Papagiannaki
#                  ('person__first_name', 'Name'),
868 73fbaec4 Sofia Papagiannaki
#                  ('date_joined', 'Status')
869 73fbaec4 Sofia Papagiannaki
#         ),
870 73fbaec4 Sofia Papagiannaki
#         required=True
871 73fbaec4 Sofia Papagiannaki
#     )
872 73fbaec4 Sofia Papagiannaki
# 
873 73fbaec4 Sofia Papagiannaki
# class PickResourceForm(forms.Form):
874 73fbaec4 Sofia Papagiannaki
#     resource = forms.ModelChoiceField(
875 73fbaec4 Sofia Papagiannaki
#         queryset=Resource.objects.select_related().all()
876 73fbaec4 Sofia Papagiannaki
#     )
877 73fbaec4 Sofia Papagiannaki
#     resource.widget.attrs["onchange"] = "this.form.submit()"
878 9a06d96f Olga Brani
879 9a06d96f Olga Brani
880 48e9f076 Sofia Papagiannaki
class ExtendedSetPasswordForm(SetPasswordForm):
881 48e9f076 Sofia Papagiannaki
    """
882 48e9f076 Sofia Papagiannaki
    Extends SetPasswordForm by enabling user
883 48e9f076 Sofia Papagiannaki
    to optionally renew also the token.
884 48e9f076 Sofia Papagiannaki
    """
885 ee210d1d Sofia Papagiannaki
    if not NEWPASSWD_INVALIDATE_TOKEN:
886 bf0c6de5 Sofia Papagiannaki
        renew = forms.BooleanField(
887 bf0c6de5 Sofia Papagiannaki
            label='Renew token',
888 bf0c6de5 Sofia Papagiannaki
            required=False,
889 bf0c6de5 Sofia Papagiannaki
            initial=True,
890 47b77c8b Sofia Papagiannaki
            help_text='Unsetting this may result in security risk.')
891 2e90e3ec Kostas Papadimitriou
892 48e9f076 Sofia Papagiannaki
    def __init__(self, user, *args, **kwargs):
893 48e9f076 Sofia Papagiannaki
        super(ExtendedSetPasswordForm, self).__init__(user, *args, **kwargs)
894 d2633501 Kostas Papadimitriou
895 d2633501 Kostas Papadimitriou
    @transaction.commit_on_success()
896 48e9f076 Sofia Papagiannaki
    def save(self, commit=True):
897 bf0c6de5 Sofia Papagiannaki
        try:
898 bf0c6de5 Sofia Papagiannaki
            self.user = AstakosUser.objects.get(id=self.user.id)
899 bf0c6de5 Sofia Papagiannaki
            if NEWPASSWD_INVALIDATE_TOKEN or self.cleaned_data.get('renew'):
900 53161dd8 Sofia Papagiannaki
                self.user.renew_token()
901 d2633501 Kostas Papadimitriou
            #self.user.flush_sessions()
902 d2633501 Kostas Papadimitriou
            if not self.user.has_auth_provider('local'):
903 d2633501 Kostas Papadimitriou
                self.user.add_auth_provider('local', auth_backend='astakos')
904 d2633501 Kostas Papadimitriou
905 bf0c6de5 Sofia Papagiannaki
        except BaseException, e:
906 bf0c6de5 Sofia Papagiannaki
            logger.exception(e)
907 53161dd8 Sofia Papagiannaki
        return super(ExtendedSetPasswordForm, self).save(commit=commit)
908 e1a80257 Sofia Papagiannaki
909 e1a80257 Sofia Papagiannaki
910 e1a80257 Sofia Papagiannaki
class ProjectApplicationForm(forms.ModelForm):
911 e1a80257 Sofia Papagiannaki
    name = forms.CharField(
912 e1a80257 Sofia Papagiannaki
        validators=[validators.RegexValidator(
913 e1a80257 Sofia Papagiannaki
            DOMAIN_VALUE_REGEX,
914 e1a80257 Sofia Papagiannaki
            _(astakos_messages.DOMAIN_VALUE_ERR),
915 e1a80257 Sofia Papagiannaki
            'invalid'
916 e1a80257 Sofia Papagiannaki
        )],
917 e1a80257 Sofia Papagiannaki
        widget=forms.TextInput(attrs={'placeholder': 'eg. foo.ece.ntua.gr'}),
918 e1a80257 Sofia Papagiannaki
        help_text="Name should be in the form of dns"
919 e1a80257 Sofia Papagiannaki
    )
920 e1a80257 Sofia Papagiannaki
    comments = forms.CharField(widget=forms.Textarea, required=False)
921 e1a80257 Sofia Papagiannaki
    
922 e1a80257 Sofia Papagiannaki
    class Meta:
923 73fbaec4 Sofia Papagiannaki
        model = ProjectApplication
924 73fbaec4 Sofia Papagiannaki
        exclude = (
925 5200e864 Sofia Papagiannaki
            'project',
926 73fbaec4 Sofia Papagiannaki
            'resource_grants', 'id', 'applicant', 'owner',
927 73fbaec4 Sofia Papagiannaki
            'precursor_application', 'state', 'issue_date')
928 73fbaec4 Sofia Papagiannaki
929 e1a80257 Sofia Papagiannaki
    def clean(self):
930 185b2190 Sofia Papagiannaki
        userid = self.data.get('user', None)
931 e1a80257 Sofia Papagiannaki
        self.user = None
932 e1a80257 Sofia Papagiannaki
        if userid:
933 e1a80257 Sofia Papagiannaki
            try:
934 e1a80257 Sofia Papagiannaki
                self.user = AstakosUser.objects.get(id=userid)
935 e1a80257 Sofia Papagiannaki
            except AstakosUser.DoesNotExist:
936 e1a80257 Sofia Papagiannaki
                pass
937 e1a80257 Sofia Papagiannaki
        if not self.user:
938 e1a80257 Sofia Papagiannaki
            raise forms.ValidationError(_(astakos_messages.NO_APPLICANT))
939 e1a80257 Sofia Papagiannaki
        super(ProjectApplicationForm, self).clean()
940 e1a80257 Sofia Papagiannaki
        return self.cleaned_data
941 e1a80257 Sofia Papagiannaki
    
942 f3342849 Sofia Papagiannaki
    @property
943 f3342849 Sofia Papagiannaki
    def resource_policies(self):
944 e1a80257 Sofia Papagiannaki
        policies = []
945 e1a80257 Sofia Papagiannaki
        append = policies.append
946 f3342849 Sofia Papagiannaki
        for name, value in self.data.iteritems():
947 f3342849 Sofia Papagiannaki
            if not value:
948 f3342849 Sofia Papagiannaki
                continue
949 56eb807c Sofia Papagiannaki
            uplimit = value
950 56eb807c Sofia Papagiannaki
            if name.endswith('_uplimit'):
951 56eb807c Sofia Papagiannaki
                subs = name.split('_uplimit')
952 e1a80257 Sofia Papagiannaki
                prefix, suffix = subs
953 e1a80257 Sofia Papagiannaki
                s, sep, r = prefix.partition(RESOURCE_SEPARATOR)
954 e1a80257 Sofia Papagiannaki
                resource = Resource.objects.get(service__name=s, name=r)
955 e1a80257 Sofia Papagiannaki
956 e1a80257 Sofia Papagiannaki
                # keep only resource limits for selected resource groups
957 f3342849 Sofia Papagiannaki
#                 if self.data.get(
958 f3342849 Sofia Papagiannaki
#                     'is_selected_%s' % resource.group, False
959 f3342849 Sofia Papagiannaki
#                 ):
960 f3342849 Sofia Papagiannaki
                if uplimit:
961 e1a80257 Sofia Papagiannaki
                    append(dict(service=s, resource=r, uplimit=uplimit))
962 e1a80257 Sofia Papagiannaki
        return policies
963 e1a80257 Sofia Papagiannaki
964 e1a80257 Sofia Papagiannaki
    def save(self, commit=True):
965 73fbaec4 Sofia Papagiannaki
        application = super(ProjectApplicationForm, self).save(commit=False)
966 e1a80257 Sofia Papagiannaki
        applicant = self.user
967 e1a80257 Sofia Papagiannaki
        comments = self.cleaned_data.pop('comments', None)
968 23df5afa Sofia Papagiannaki
        precursor_application = self.instance
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 7592e3e2 Sofia Papagiannaki
                 ('member_leave_policy__description', 'Sort by Member Leave Policy'),
988 7592e3e2 Sofia Papagiannaki
                 ('-name', 'Sort by Name'),
989 7592e3e2 Sofia Papagiannaki
                 ('-issue_date', 'Sort by Issue date'),
990 7592e3e2 Sofia Papagiannaki
                 ('-start_date', 'Sort by Start Date'),
991 7592e3e2 Sofia Papagiannaki
                 ('-end_date', 'Sort by End Date'),
992 7592e3e2 Sofia Papagiannaki
#                  ('-approved_members_num', 'Sort by Participants'),
993 7592e3e2 Sofia Papagiannaki
                 ('-state', 'Sort by Status'),
994 7592e3e2 Sofia Papagiannaki
                 ('-member_join_policy__description', 'Sort by Member Join Policy'),
995 7592e3e2 Sofia Papagiannaki
                 ('-member_leave_policy__description', 'Sort by Member Leave Policy')
996 8327782d Sofia Papagiannaki
        ),
997 8327782d Sofia Papagiannaki
        required=True
998 ccab6eb5 Sofia Papagiannaki
    )
999 ccab6eb5 Sofia Papagiannaki
1000 ccab6eb5 Sofia Papagiannaki
class AddProjectMembersForm(forms.Form):
1001 ccab6eb5 Sofia Papagiannaki
    q = forms.CharField(
1002 ccab6eb5 Sofia Papagiannaki
        max_length=800, widget=forms.Textarea, label=_('Add members'),
1003 ccab6eb5 Sofia Papagiannaki
        help_text=_(astakos_messages.ADD_PROJECT_MEMBERS_Q_HELP),
1004 ccab6eb5 Sofia Papagiannaki
        required=True)
1005 ccab6eb5 Sofia Papagiannaki
1006 ccab6eb5 Sofia Papagiannaki
    def clean(self):
1007 ccab6eb5 Sofia Papagiannaki
        q = self.cleaned_data.get('q') or ''
1008 ccab6eb5 Sofia Papagiannaki
        users = q.split(',')
1009 ccab6eb5 Sofia Papagiannaki
        users = list(u.strip() for u in users if u)
1010 ccab6eb5 Sofia Papagiannaki
        db_entries = AstakosUser.objects.filter(email__in=users)
1011 ccab6eb5 Sofia Papagiannaki
        unknown = list(set(users) - set(u.email for u in db_entries))
1012 ccab6eb5 Sofia Papagiannaki
        if unknown:
1013 ccab6eb5 Sofia Papagiannaki
            raise forms.ValidationError(_(astakos_messages.UNKNOWN_USERS) % ','.join(unknown))
1014 ccab6eb5 Sofia Papagiannaki
        self.valid_users = db_entries
1015 ccab6eb5 Sofia Papagiannaki
        return self.cleaned_data
1016 ccab6eb5 Sofia Papagiannaki
1017 ccab6eb5 Sofia Papagiannaki
    def get_valid_users(self):
1018 ccab6eb5 Sofia Papagiannaki
        """Should be called after form cleaning"""
1019 ccab6eb5 Sofia Papagiannaki
        try:
1020 ccab6eb5 Sofia Papagiannaki
            return self.valid_users
1021 ccab6eb5 Sofia Papagiannaki
        except:
1022 bfe23b13 Sofia Papagiannaki
            return ()
1023 bfe23b13 Sofia Papagiannaki
1024 bfe23b13 Sofia Papagiannaki
class ProjectMembersSortForm(forms.Form):
1025 bfe23b13 Sofia Papagiannaki
    sorting = forms.ChoiceField(
1026 bfe23b13 Sofia Papagiannaki
        label='Sort by',
1027 bfe23b13 Sofia Papagiannaki
        choices=(('person__email', 'User Id'),
1028 bfe23b13 Sofia Papagiannaki
                 ('person__first_name', 'Name'),
1029 bfe23b13 Sofia Papagiannaki
                 ('acceptance_date', 'Acceptance date')
1030 bfe23b13 Sofia Papagiannaki
        ),
1031 bfe23b13 Sofia Papagiannaki
        required=True
1032 bfe23b13 Sofia Papagiannaki
    )
1033 bfe23b13 Sofia Papagiannaki
1034 6dadd24a Sofia Papagiannaki
class ProjectSearchForm(forms.Form):
1035 47b77c8b Sofia Papagiannaki
    q = forms.CharField(max_length=200, label='Search project')