Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (12.5 kB)

1 aba1e498 Antony Chazapis
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2 a70dacde Kostas Papadimitriou
#
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 a70dacde Kostas Papadimitriou
#
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 a70dacde Kostas Papadimitriou
#
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 a70dacde Kostas Papadimitriou
#
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 a70dacde Kostas Papadimitriou
#
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 270dd48d Sofia Papagiannaki
from datetime import datetime
35 64cd4730 Antony Chazapis
36 64cd4730 Antony Chazapis
from django import forms
37 64cd4730 Antony Chazapis
from django.utils.translation import ugettext as _
38 e2125441 Sofia Papagiannaki
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm, PasswordResetForm
39 e2125441 Sofia Papagiannaki
from django.core.mail import send_mail
40 e2125441 Sofia Papagiannaki
from django.contrib.auth.tokens import default_token_generator
41 e2125441 Sofia Papagiannaki
from django.template import Context, loader
42 e2125441 Sofia Papagiannaki
from django.utils.http import int_to_base36
43 374611bc Sofia Papagiannaki
from django.core.urlresolvers import reverse
44 270dd48d Sofia Papagiannaki
from django.utils.functional import lazy
45 a70dacde Kostas Papadimitriou
from django.utils.safestring import mark_safe
46 5ed6816e Sofia Papagiannaki
47 0905ccd2 Sofia Papagiannaki
from astakos.im.models import AstakosUser
48 53bf2659 Sofia Papagiannaki
from astakos.im.settings import INVITATIONS_PER_LEVEL, DEFAULT_FROM_EMAIL, BASEURL, SITENAME, RECAPTCHA_PRIVATE_KEY, DEFAULT_CONTACT_EMAIL, RECAPTCHA_ENABLED
49 270dd48d Sofia Papagiannaki
from astakos.im.widgets import DummyWidget, RecaptchaWidget, ApprovalTermsWidget
50 270dd48d Sofia Papagiannaki
51 270dd48d Sofia Papagiannaki
# since Django 1.4 use django.core.urlresolvers.reverse_lazy instead
52 d8f63346 Sofia Papagiannaki
from astakos.im.util import reverse_lazy, get_latest_terms
53 64cd4730 Antony Chazapis
54 3bf924ec Sofia Papagiannaki
import logging
55 db7fecd9 Sofia Papagiannaki
import recaptcha.client.captcha as captcha
56 64cd4730 Antony Chazapis
57 e015e9e6 Sofia Papagiannaki
logger = logging.getLogger(__name__)
58 e015e9e6 Sofia Papagiannaki
59 15efc749 Sofia Papagiannaki
class LocalUserCreationForm(UserCreationForm):
60 890b0eaf Sofia Papagiannaki
    """
61 890b0eaf Sofia Papagiannaki
    Extends the built in UserCreationForm in several ways:
62 a70dacde Kostas Papadimitriou

63 8316698a Sofia Papagiannaki
    * Adds email, first_name, last_name, recaptcha_challenge_field, recaptcha_response_field field.
64 5ed6816e Sofia Papagiannaki
    * The username field isn't visible and it is assigned a generated id.
65 a70dacde Kostas Papadimitriou
    * User created is not active.
66 890b0eaf Sofia Papagiannaki
    """
67 db7fecd9 Sofia Papagiannaki
    recaptcha_challenge_field = forms.CharField(widget=DummyWidget)
68 db7fecd9 Sofia Papagiannaki
    recaptcha_response_field = forms.CharField(widget=RecaptchaWidget, label='')
69 a70dacde Kostas Papadimitriou
70 794852f2 Sofia Papagiannaki
    class Meta:
71 794852f2 Sofia Papagiannaki
        model = AstakosUser
72 270dd48d Sofia Papagiannaki
        fields = ("email", "first_name", "last_name", "has_signed_terms")
73 270dd48d Sofia Papagiannaki
        widgets = {"has_signed_terms":ApprovalTermsWidget(terms_uri=reverse_lazy('latest_terms'))}
74 a70dacde Kostas Papadimitriou
75 64cd4730 Antony Chazapis
    def __init__(self, *args, **kwargs):
76 64cd4730 Antony Chazapis
        """
77 890b0eaf Sofia Papagiannaki
        Changes the order of fields, and removes the username field.
78 64cd4730 Antony Chazapis
        """
79 db7fecd9 Sofia Papagiannaki
        if 'ip' in kwargs:
80 db7fecd9 Sofia Papagiannaki
            self.ip = kwargs['ip']
81 db7fecd9 Sofia Papagiannaki
            kwargs.pop('ip')
82 15efc749 Sofia Papagiannaki
        super(LocalUserCreationForm, self).__init__(*args, **kwargs)
83 890b0eaf Sofia Papagiannaki
        self.fields.keyOrder = ['email', 'first_name', 'last_name',
84 d8f63346 Sofia Papagiannaki
                                'password1', 'password2']
85 d8f63346 Sofia Papagiannaki
        if get_latest_terms():
86 d8f63346 Sofia Papagiannaki
            self.fields.keyOrder.append('has_signed_terms')
87 53bf2659 Sofia Papagiannaki
        if RECAPTCHA_ENABLED:
88 53bf2659 Sofia Papagiannaki
            self.fields.keyOrder.extend(['recaptcha_challenge_field',
89 53bf2659 Sofia Papagiannaki
                                         'recaptcha_response_field',])
90 a70dacde Kostas Papadimitriou
91 a70dacde Kostas Papadimitriou
        if 'has_signed_terms' in self.fields:
92 a70dacde Kostas Papadimitriou
            # Overriding field label since we need to apply a link
93 a70dacde Kostas Papadimitriou
            # to the terms within the label
94 a70dacde Kostas Papadimitriou
            terms_link_html = '<a href="%s" target="_blank">%s</a>' \
95 a70dacde Kostas Papadimitriou
                    % (reverse('latest_terms'), _("the terms"))
96 a70dacde Kostas Papadimitriou
            self.fields['has_signed_terms'].label = \
97 a70dacde Kostas Papadimitriou
                    mark_safe("I agree with %s" % terms_link_html)
98 a70dacde Kostas Papadimitriou
99 af4eb974 Sofia Papagiannaki
    def clean_email(self):
100 af4eb974 Sofia Papagiannaki
        email = self.cleaned_data['email']
101 881c856c Sofia Papagiannaki
        if not email:
102 881c856c Sofia Papagiannaki
            raise forms.ValidationError(_("This field is required"))
103 af4eb974 Sofia Papagiannaki
        try:
104 af4eb974 Sofia Papagiannaki
            AstakosUser.objects.get(email = email)
105 c37263ea Sofia Papagiannaki
            raise forms.ValidationError(_("This email is already used"))
106 af4eb974 Sofia Papagiannaki
        except AstakosUser.DoesNotExist:
107 af4eb974 Sofia Papagiannaki
            return email
108 a70dacde Kostas Papadimitriou
109 270dd48d Sofia Papagiannaki
    def clean_has_signed_terms(self):
110 270dd48d Sofia Papagiannaki
        has_signed_terms = self.cleaned_data['has_signed_terms']
111 270dd48d Sofia Papagiannaki
        if not has_signed_terms:
112 270dd48d Sofia Papagiannaki
            raise forms.ValidationError(_('You have to agree with the terms'))
113 270dd48d Sofia Papagiannaki
        return has_signed_terms
114 a70dacde Kostas Papadimitriou
115 db7fecd9 Sofia Papagiannaki
    def clean_recaptcha_response_field(self):
116 db7fecd9 Sofia Papagiannaki
        if 'recaptcha_challenge_field' in self.cleaned_data:
117 db7fecd9 Sofia Papagiannaki
            self.validate_captcha()
118 db7fecd9 Sofia Papagiannaki
        return self.cleaned_data['recaptcha_response_field']
119 db7fecd9 Sofia Papagiannaki
120 db7fecd9 Sofia Papagiannaki
    def clean_recaptcha_challenge_field(self):
121 db7fecd9 Sofia Papagiannaki
        if 'recaptcha_response_field' in self.cleaned_data:
122 db7fecd9 Sofia Papagiannaki
            self.validate_captcha()
123 db7fecd9 Sofia Papagiannaki
        return self.cleaned_data['recaptcha_challenge_field']
124 db7fecd9 Sofia Papagiannaki
125 db7fecd9 Sofia Papagiannaki
    def validate_captcha(self):
126 db7fecd9 Sofia Papagiannaki
        rcf = self.cleaned_data['recaptcha_challenge_field']
127 db7fecd9 Sofia Papagiannaki
        rrf = self.cleaned_data['recaptcha_response_field']
128 db7fecd9 Sofia Papagiannaki
        check = captcha.submit(rcf, rrf, RECAPTCHA_PRIVATE_KEY, self.ip)
129 db7fecd9 Sofia Papagiannaki
        if not check.is_valid:
130 db7fecd9 Sofia Papagiannaki
            raise forms.ValidationError(_('You have not entered the correct words'))
131 a70dacde Kostas Papadimitriou
132 890b0eaf Sofia Papagiannaki
    def save(self, commit=True):
133 64cd4730 Antony Chazapis
        """
134 890b0eaf Sofia Papagiannaki
        Saves the email, first_name and last_name properties, after the normal
135 890b0eaf Sofia Papagiannaki
        save behavior is complete.
136 890b0eaf Sofia Papagiannaki
        """
137 15efc749 Sofia Papagiannaki
        user = super(LocalUserCreationForm, self).save(commit=False)
138 3bf924ec Sofia Papagiannaki
        user.renew_token()
139 270dd48d Sofia Papagiannaki
        user.date_signed_terms = datetime.now()
140 9fb8e808 Sofia Papagiannaki
        if commit:
141 9fb8e808 Sofia Papagiannaki
            user.save()
142 e015e9e6 Sofia Papagiannaki
        logger.info('Created user %s', user)
143 890b0eaf Sofia Papagiannaki
        return user
144 64cd4730 Antony Chazapis
145 15efc749 Sofia Papagiannaki
class InvitedLocalUserCreationForm(LocalUserCreationForm):
146 890b0eaf Sofia Papagiannaki
    """
147 15efc749 Sofia Papagiannaki
    Extends the LocalUserCreationForm: adds an inviter readonly field.
148 890b0eaf Sofia Papagiannaki
    """
149 a70dacde Kostas Papadimitriou
150 3bf924ec Sofia Papagiannaki
    inviter = forms.CharField(widget=forms.TextInput(), label=_('Inviter Real Name'))
151 a70dacde Kostas Papadimitriou
152 794852f2 Sofia Papagiannaki
    class Meta:
153 794852f2 Sofia Papagiannaki
        model = AstakosUser
154 270dd48d Sofia Papagiannaki
        fields = ("email", "first_name", "last_name", "has_signed_terms")
155 270dd48d Sofia Papagiannaki
        widgets = {"has_signed_terms":ApprovalTermsWidget(terms_uri=reverse_lazy('latest_terms'))}
156 a70dacde Kostas Papadimitriou
157 64cd4730 Antony Chazapis
    def __init__(self, *args, **kwargs):
158 64cd4730 Antony Chazapis
        """
159 3bf924ec Sofia Papagiannaki
        Changes the order of fields, and removes the username field.
160 64cd4730 Antony Chazapis
        """
161 15efc749 Sofia Papagiannaki
        super(InvitedLocalUserCreationForm, self).__init__(*args, **kwargs)
162 a70dacde Kostas Papadimitriou
163 64cd4730 Antony Chazapis
        #set readonly form fields
164 64cd4730 Antony Chazapis
        self.fields['inviter'].widget.attrs['readonly'] = True
165 794852f2 Sofia Papagiannaki
        self.fields['email'].widget.attrs['readonly'] = True
166 794852f2 Sofia Papagiannaki
        self.fields['username'].widget.attrs['readonly'] = True
167 a70dacde Kostas Papadimitriou
168 9fb8e808 Sofia Papagiannaki
    def save(self, commit=True):
169 15efc749 Sofia Papagiannaki
        user = super(InvitedLocalUserCreationForm, self).save(commit=False)
170 881c856c Sofia Papagiannaki
        level = user.invitation.inviter.level + 1
171 881c856c Sofia Papagiannaki
        user.level = level
172 8316698a Sofia Papagiannaki
        user.invitations = INVITATIONS_PER_LEVEL.get(level, 0)
173 8316698a Sofia Papagiannaki
        user.email_verified = True
174 9fb8e808 Sofia Papagiannaki
        if commit:
175 9fb8e808 Sofia Papagiannaki
            user.save()
176 9fb8e808 Sofia Papagiannaki
        return user
177 5ed6816e Sofia Papagiannaki
178 5ed6816e Sofia Papagiannaki
class LoginForm(AuthenticationForm):
179 5ed6816e Sofia Papagiannaki
    username = forms.EmailField(label=_("Email"))
180 64cd4730 Antony Chazapis
181 890b0eaf Sofia Papagiannaki
class ProfileForm(forms.ModelForm):
182 890b0eaf Sofia Papagiannaki
    """
183 890b0eaf Sofia Papagiannaki
    Subclass of ``ModelForm`` for permiting user to edit his/her profile.
184 890b0eaf Sofia Papagiannaki
    Most of the fields are readonly since the user is not allowed to change them.
185 a70dacde Kostas Papadimitriou

186 890b0eaf Sofia Papagiannaki
    The class defines a save method which sets ``is_verified`` to True so as the user
187 890b0eaf Sofia Papagiannaki
    during the next login will not to be redirected to profile page.
188 890b0eaf Sofia Papagiannaki
    """
189 c301698f Sofia Papagiannaki
    renew = forms.BooleanField(label='Renew token', required=False)
190 a70dacde Kostas Papadimitriou
191 890b0eaf Sofia Papagiannaki
    class Meta:
192 890b0eaf Sofia Papagiannaki
        model = AstakosUser
193 a196eb7e Sofia Papagiannaki
        fields = ('email', 'first_name', 'last_name', 'auth_token', 'auth_token_expires')
194 a70dacde Kostas Papadimitriou
195 64cd4730 Antony Chazapis
    def __init__(self, *args, **kwargs):
196 890b0eaf Sofia Papagiannaki
        super(ProfileForm, self).__init__(*args, **kwargs)
197 890b0eaf Sofia Papagiannaki
        instance = getattr(self, 'instance', None)
198 a196eb7e Sofia Papagiannaki
        ro_fields = ('auth_token', 'auth_token_expires', 'email')
199 890b0eaf Sofia Papagiannaki
        if instance and instance.id:
200 890b0eaf Sofia Papagiannaki
            for field in ro_fields:
201 890b0eaf Sofia Papagiannaki
                self.fields[field].widget.attrs['readonly'] = True
202 a70dacde Kostas Papadimitriou
203 890b0eaf Sofia Papagiannaki
    def save(self, commit=True):
204 890b0eaf Sofia Papagiannaki
        user = super(ProfileForm, self).save(commit=False)
205 890b0eaf Sofia Papagiannaki
        user.is_verified = True
206 c301698f Sofia Papagiannaki
        if self.cleaned_data.get('renew'):
207 c301698f Sofia Papagiannaki
            user.renew_token()
208 890b0eaf Sofia Papagiannaki
        if commit:
209 890b0eaf Sofia Papagiannaki
            user.save()
210 890b0eaf Sofia Papagiannaki
        return user
211 64cd4730 Antony Chazapis
212 15efc749 Sofia Papagiannaki
class ThirdPartyUserCreationForm(ProfileForm):
213 15efc749 Sofia Papagiannaki
    class Meta:
214 15efc749 Sofia Papagiannaki
        model = AstakosUser
215 15efc749 Sofia Papagiannaki
        fields = ('email', 'last_name', 'first_name', 'affiliation', 'provider', 'third_party_identifier')
216 a70dacde Kostas Papadimitriou
217 15efc749 Sofia Papagiannaki
    def __init__(self, *args, **kwargs):
218 db7fecd9 Sofia Papagiannaki
        if 'ip' in kwargs:
219 db7fecd9 Sofia Papagiannaki
            self.ip = kwargs['ip']
220 db7fecd9 Sofia Papagiannaki
            kwargs.pop('ip')
221 15efc749 Sofia Papagiannaki
        super(ThirdPartyUserCreationForm, self).__init__(*args, **kwargs)
222 15efc749 Sofia Papagiannaki
        self.fields.keyOrder = ['email']
223 a70dacde Kostas Papadimitriou
224 15efc749 Sofia Papagiannaki
    def clean_email(self):
225 15efc749 Sofia Papagiannaki
        email = self.cleaned_data['email']
226 15efc749 Sofia Papagiannaki
        if not email:
227 15efc749 Sofia Papagiannaki
            raise forms.ValidationError(_("This field is required"))
228 15efc749 Sofia Papagiannaki
        try:
229 15efc749 Sofia Papagiannaki
            user = AstakosUser.objects.get(email = email)
230 c37263ea Sofia Papagiannaki
            raise forms.ValidationError(_("This email is already used"))
231 15efc749 Sofia Papagiannaki
        except AstakosUser.DoesNotExist:
232 15efc749 Sofia Papagiannaki
            return email
233 a70dacde Kostas Papadimitriou
234 15efc749 Sofia Papagiannaki
    def save(self, commit=True):
235 15efc749 Sofia Papagiannaki
        user = super(ThirdPartyUserCreationForm, self).save(commit=False)
236 15efc749 Sofia Papagiannaki
        user.verified = False
237 15efc749 Sofia Papagiannaki
        user.renew_token()
238 15efc749 Sofia Papagiannaki
        if commit:
239 15efc749 Sofia Papagiannaki
            user.save()
240 e015e9e6 Sofia Papagiannaki
        logger.info('Created user %s', user)
241 15efc749 Sofia Papagiannaki
        return user
242 15efc749 Sofia Papagiannaki
243 15efc749 Sofia Papagiannaki
class InvitedThirdPartyUserCreationForm(ThirdPartyUserCreationForm):
244 15efc749 Sofia Papagiannaki
    def __init__(self, *args, **kwargs):
245 15efc749 Sofia Papagiannaki
        super(InvitedThirdPartyUserCreationForm, self).__init__(*args, **kwargs)
246 15efc749 Sofia Papagiannaki
        #set readonly form fields
247 15efc749 Sofia Papagiannaki
        self.fields['email'].widget.attrs['readonly'] = True
248 64cd4730 Antony Chazapis
249 890b0eaf Sofia Papagiannaki
class FeedbackForm(forms.Form):
250 890b0eaf Sofia Papagiannaki
    """
251 890b0eaf Sofia Papagiannaki
    Form for writing feedback.
252 890b0eaf Sofia Papagiannaki
    """
253 890b0eaf Sofia Papagiannaki
    feedback_msg = forms.CharField(widget=forms.Textarea(),
254 890b0eaf Sofia Papagiannaki
                                label=u'Message', required=False)
255 92defad4 Sofia Papagiannaki
    feedback_data = forms.CharField(widget=forms.HiddenInput(),
256 92defad4 Sofia Papagiannaki
                                label='', required=False)
257 5ed6816e Sofia Papagiannaki
258 5ed6816e Sofia Papagiannaki
class SendInvitationForm(forms.Form):
259 5ed6816e Sofia Papagiannaki
    """
260 5ed6816e Sofia Papagiannaki
    Form for sending an invitations
261 5ed6816e Sofia Papagiannaki
    """
262 a70dacde Kostas Papadimitriou
263 5ed6816e Sofia Papagiannaki
    email = forms.EmailField(required = True, label = 'Email address')
264 5ed6816e Sofia Papagiannaki
    first_name = forms.EmailField(label = 'First name')
265 5ed6816e Sofia Papagiannaki
    last_name = forms.EmailField(label = 'Last name')
266 e2125441 Sofia Papagiannaki
267 e2125441 Sofia Papagiannaki
class ExtendedPasswordResetForm(PasswordResetForm):
268 e2125441 Sofia Papagiannaki
    """
269 e2125441 Sofia Papagiannaki
    Extends PasswordResetForm by overriding save method:
270 e2125441 Sofia Papagiannaki
    passes a custom from_email in send_mail.
271 a70dacde Kostas Papadimitriou

272 e2125441 Sofia Papagiannaki
    Since Django 1.3 this is useless since ``django.contrib.auth.views.reset_password``
273 e2125441 Sofia Papagiannaki
    accepts a from_email argument.
274 e2125441 Sofia Papagiannaki
    """
275 e2125441 Sofia Papagiannaki
    def save(self, domain_override=None, email_template_name='registration/password_reset_email.html',
276 e2125441 Sofia Papagiannaki
             use_https=False, token_generator=default_token_generator, request=None):
277 e2125441 Sofia Papagiannaki
        """
278 e2125441 Sofia Papagiannaki
        Generates a one-use only link for resetting password and sends to the user.
279 e2125441 Sofia Papagiannaki
        """
280 e2125441 Sofia Papagiannaki
        for user in self.users_cache:
281 8f378756 Sofia Papagiannaki
            url = urljoin(BASEURL,
282 8f378756 Sofia Papagiannaki
                          '/im/local/reset/confirm/%s-%s' %(int_to_base36(user.id),
283 8f378756 Sofia Papagiannaki
                                                            token_generator.make_token(user)))
284 e2125441 Sofia Papagiannaki
            t = loader.get_template(email_template_name)
285 e2125441 Sofia Papagiannaki
            c = {
286 e2125441 Sofia Papagiannaki
                'email': user.email,
287 8f378756 Sofia Papagiannaki
                'url': url,
288 374611bc Sofia Papagiannaki
                'site_name': SITENAME,
289 e2125441 Sofia Papagiannaki
                'user': user,
290 09122dd8 Sofia Papagiannaki
                'baseurl': BASEURL,
291 09122dd8 Sofia Papagiannaki
                'support': DEFAULT_CONTACT_EMAIL
292 e2125441 Sofia Papagiannaki
            }
293 d552ecb7 Antony Chazapis
            from_email = DEFAULT_FROM_EMAIL
294 4abc7b29 Sofia Papagiannaki
            send_mail(_("Password reset on %s alpha2 testing") % SITENAME,
295 e2125441 Sofia Papagiannaki
                t.render(Context(c)), from_email, [user.email])
296 270dd48d Sofia Papagiannaki
297 270dd48d Sofia Papagiannaki
class SignApprovalTermsForm(forms.ModelForm):
298 270dd48d Sofia Papagiannaki
    class Meta:
299 270dd48d Sofia Papagiannaki
        model = AstakosUser
300 270dd48d Sofia Papagiannaki
        fields = ("has_signed_terms",)
301 a70dacde Kostas Papadimitriou
302 270dd48d Sofia Papagiannaki
    def __init__(self, *args, **kwargs):
303 270dd48d Sofia Papagiannaki
        super(SignApprovalTermsForm, self).__init__(*args, **kwargs)
304 a70dacde Kostas Papadimitriou
305 270dd48d Sofia Papagiannaki
    def clean_has_signed_terms(self):
306 270dd48d Sofia Papagiannaki
        has_signed_terms = self.cleaned_data['has_signed_terms']
307 270dd48d Sofia Papagiannaki
        if not has_signed_terms:
308 270dd48d Sofia Papagiannaki
            raise forms.ValidationError(_('You have to agree with the terms'))
309 270dd48d Sofia Papagiannaki
        return has_signed_terms
310 a70dacde Kostas Papadimitriou
311 270dd48d Sofia Papagiannaki
    def save(self, commit=True):
312 270dd48d Sofia Papagiannaki
        """
313 270dd48d Sofia Papagiannaki
        Saves the , after the normal
314 270dd48d Sofia Papagiannaki
        save behavior is complete.
315 270dd48d Sofia Papagiannaki
        """
316 270dd48d Sofia Papagiannaki
        user = super(SignApprovalTermsForm, self).save(commit=False)
317 270dd48d Sofia Papagiannaki
        user.date_signed_terms = datetime.now()
318 270dd48d Sofia Papagiannaki
        if commit:
319 270dd48d Sofia Papagiannaki
            user.save()
320 a70dacde Kostas Papadimitriou
        return user