diff options
author | Evgeny Fadeev <evgeny.fadeev@gmail.com> | 2010-06-12 22:51:11 -0400 |
---|---|---|
committer | Evgeny Fadeev <evgeny.fadeev@gmail.com> | 2010-06-12 22:51:11 -0400 |
commit | 3a3a11d32c72ab79ce94679aae7a549230c7104f (patch) | |
tree | 3ac36a302b85d5497b3d335238044c8f481ac0fd /forum/deps/django_authopenid/forms.py | |
parent | 8b6a10ead45bcd915f5da223de2b3fd3c30fc7b5 (diff) | |
download | askbot-3a3a11d32c72ab79ce94679aae7a549230c7104f.tar.gz askbot-3a3a11d32c72ab79ce94679aae7a549230c7104f.tar.bz2 askbot-3a3a11d32c72ab79ce94679aae7a549230c7104f.zip |
moved livesettings and django_authopenid into forum/deps
Diffstat (limited to 'forum/deps/django_authopenid/forms.py')
-rw-r--r-- | forum/deps/django_authopenid/forms.py | 322 |
1 files changed, 322 insertions, 0 deletions
diff --git a/forum/deps/django_authopenid/forms.py b/forum/deps/django_authopenid/forms.py new file mode 100644 index 00000000..dd66591e --- /dev/null +++ b/forum/deps/django_authopenid/forms.py @@ -0,0 +1,322 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2007, 2008, BenoƮt Chesneau +# +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# * notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# * notice, this list of conditions and the following disclaimer in the +# * documentation and/or other materials provided with the +# * distribution. Neither the name of the <ORGANIZATION> nor the names +# * of its contributors may be used to endorse or promote products +# * derived from this software without specific prior written +# * permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +from django import forms +from django.contrib.auth.models import User +from django.contrib.auth import authenticate +from django.utils.translation import ugettext as _ +from django.conf import settings +from forum.conf import settings as forum_settings +import types +import re +from django.utils.safestring import mark_safe +from recaptcha_django import ReCaptchaField +from forum.utils.forms import NextUrlField, UserNameField, UserEmailField, SetPasswordForm +EXTERNAL_LOGIN_APP = settings.LOAD_EXTERNAL_LOGIN_APP() + +# needed for some linux distributions like debian +try: + from openid.yadis import xri +except ImportError: + from yadis import xri + +from forum.utils.forms import clean_next +from forum.deps.django_authopenid.models import ExternalLoginData + +__all__ = ['OpenidSigninForm', 'ClassicLoginForm', 'OpenidVerifyForm', + 'OpenidRegisterForm', 'ClassicRegisterForm', 'ChangePasswordForm', + 'ChangeEmailForm', 'EmailPasswordForm', 'DeleteForm', + 'ChangeOpenidForm'] + +class OpenidSigninForm(forms.Form): + """ signin form """ + openid_url = forms.CharField(max_length=255, widget=forms.widgets.TextInput(attrs={'class': 'openid-login-input', 'size':80})) + next = NextUrlField() + + def clean_openid_url(self): + """ test if openid is accepted """ + if 'openid_url' in self.cleaned_data: + openid_url = self.cleaned_data['openid_url'] + if xri.identifierScheme(openid_url) == 'XRI' and getattr( + settings, 'OPENID_DISALLOW_INAMES', False + ): + raise forms.ValidationError(_('i-names are not supported')) + return self.cleaned_data['openid_url'] + +class ClassicLoginForm(forms.Form): + """ legacy account signin form """ + next = NextUrlField() + username = UserNameField(required=False,skip_clean=True) + password = forms.CharField(max_length=128, + widget=forms.widgets.PasswordInput(attrs={'class':'required login'}), + required=False) + + def __init__(self, data=None, files=None, auto_id='id_%s', + prefix=None, initial=None): + super(ClassicLoginForm, self).__init__(data, files, auto_id, + prefix, initial) + self.user_cache = None + + def _clean_nonempty_field(self,field): + value = None + if field in self.cleaned_data: + value = str(self.cleaned_data[field]).strip() + if value == '': + value = None + self.cleaned_data[field] = value + return value + + def clean_username(self): + return self._clean_nonempty_field('username') + + def clean_password(self): + return self._clean_nonempty_field('password') + + def clean(self): + """ + this clean function actually cleans username and password + + test if password is valid for this username + this is really the "authenticate" function + also openid_auth is not an authentication backend + since it's written in a way that does not comply with + the Django convention + """ + + error_list = [] + username = self.cleaned_data['username'] + password = self.cleaned_data['password'] + + self.user_cache = None + if username and password: + if settings.USE_EXTERNAL_LEGACY_LOGIN == True: + pw_ok = False + try: + pw_ok = EXTERNAL_LOGIN_APP.api.check_password(username,password) + except forms.ValidationError, e: + error_list.extend(e.messages) + if pw_ok: + external_user = ExternalLoginData.objects.get(external_username=username) + if external_user.user == None: + return self.cleaned_data + user = external_user.user + openid_logins = user.userassociation_set.all() + + if len(openid_logins) > 0: + msg1 = _('Account with this name already exists on the forum') + msg2 = _('can\'t have two logins to the same account yet, sorry.') + error_list.append(msg1) + error_list.append(msg2) + self._errors['__all__'] = forms.util.ErrorList(error_list) + return self.cleaned_data + else: + #synchronize password with external login + user.set_password(password) + user.save() + #this auth will always succeed + self.user_cache = authenticate(username=user.username,\ + password=password) + else: + #keep self.user_cache == None + #nothing to do, error message will be set below + pass + else: + self.user_cache = authenticate(username=username, password=password) + + if self.user_cache is None: + del self.cleaned_data['username'] + del self.cleaned_data['password'] + error_list.insert(0,(_("Please enter valid username and password " + "(both are case-sensitive)."))) + elif self.user_cache.is_active == False: + error_list.append(_("This account is inactive.")) + if len(error_list) > 0: + error_list.insert(0,_('Login failed.')) + elif password == None and username == None: + error_list.append(_('Please enter username and password')) + elif password == None: + error_list.append(_('Please enter your password')) + elif username == None: + error_list.append(_('Please enter user name')) + if len(error_list) > 0: + self._errors['__all__'] = forms.util.ErrorList(error_list) + return self.cleaned_data + + def get_user(self): + """ get authenticated user """ + return self.user_cache + + +class OpenidRegisterForm(forms.Form): + """ openid signin form """ + next = NextUrlField() + username = UserNameField() + email = UserEmailField() + +class OpenidVerifyForm(forms.Form): + """ openid verify form (associate an openid with an account) """ + next = NextUrlField() + username = UserNameField(must_exist=True) + password = forms.CharField(max_length=128, + widget=forms.widgets.PasswordInput(attrs={'class':'required login'})) + + def __init__(self, data=None, files=None, auto_id='id_%s', + prefix=None, initial=None): + super(OpenidVerifyForm, self).__init__(data, files, auto_id, + prefix, initial) + self.user_cache = None + + def clean_password(self): + """ test if password is valid for this user """ + if 'username' in self.cleaned_data and \ + 'password' in self.cleaned_data: + self.user_cache = authenticate( + username = self.cleaned_data['username'], + password = self.cleaned_data['password'] + ) + if self.user_cache is None: + raise forms.ValidationError(_("Please enter a valid \ + username and password. Note that both fields are \ + case-sensitive.")) + elif self.user_cache.is_active == False: + raise forms.ValidationError(_("This account is inactive.")) + return self.cleaned_data['password'] + + def get_user(self): + """ get authenticated user """ + return self.user_cache + +class ClassicRegisterForm(SetPasswordForm): + """ legacy registration form """ + + next = NextUrlField() + username = UserNameField() + email = UserEmailField() + #fields password1 and password2 are inherited + recaptcha = ReCaptchaField() + +class ChangePasswordForm(SetPasswordForm): + """ change password form """ + oldpw = forms.CharField(widget=forms.PasswordInput(attrs={'class':'required'}), + label=mark_safe(_('Current password'))) + + def __init__(self, data=None, user=None, *args, **kwargs): + if user is None: + raise TypeError("Keyword argument 'user' must be supplied") + super(ChangePasswordForm, self).__init__(data, *args, **kwargs) + self.user = user + + def clean_oldpw(self): + """ test old password """ + if not self.user.check_password(self.cleaned_data['oldpw']): + raise forms.ValidationError(_("Old password is incorrect. \ + Please enter the correct password.")) + return self.cleaned_data['oldpw'] + +class ChangeEmailForm(forms.Form): + """ change email form """ + email = UserEmailField(skip_clean=True) + + def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, \ + initial=None, user=None): + super(ChangeEmailForm, self).__init__(data, files, auto_id, + prefix, initial) + self.user = user + + def clean_email(self): + """ check if email don't exist """ + if 'email' in self.cleaned_data: + if forum_settings.EMAIL_UNIQUE == True: + try: + user = User.objects.get(email = self.cleaned_data['email']) + if self.user and self.user == user: + return self.cleaned_data['email'] + except User.DoesNotExist: + return self.cleaned_data['email'] + except User.MultipleObjectsReturned: + raise forms.ValidationError(u'There is already more than one \ + account registered with that e-mail address. Please try \ + another.') + raise forms.ValidationError(u'This email is already registered \ + in our database. Please choose another.') + else: + return self.cleaned_data['email'] + +class ChangeopenidForm(forms.Form): + """ change openid form """ + openid_url = forms.CharField(max_length=255, + widget=forms.TextInput(attrs={'class': "required" })) + + def __init__(self, data=None, user=None, *args, **kwargs): + if user is None: + raise TypeError("Keyword argument 'user' must be supplied") + super(ChangeopenidForm, self).__init__(data, *args, **kwargs) + self.user = user + +class DeleteForm(forms.Form): + """ confirm form to delete an account """ + confirm = forms.CharField(widget=forms.CheckboxInput(attrs={'class':'required'})) + password = forms.CharField(widget=forms.PasswordInput(attrs={'class':'required'})) + + def __init__(self, data=None, files=None, auto_id='id_%s', + prefix=None, initial=None, user=None): + super(DeleteForm, self).__init__(data, files, auto_id, prefix, initial) + self.test_openid = False + self.user = user + + def clean_password(self): + """ check if we have to test a legacy account or not """ + if 'password' in self.cleaned_data: + if not self.user.check_password(self.cleaned_data['password']): + self.test_openid = True + return self.cleaned_data['password'] + + +class EmailPasswordForm(forms.Form): + """ send new password form """ + username = UserNameField(skip_clean=True,label=mark_safe(_('Your user name (<i>required</i>)'))) + + def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, + initial=None): + super(EmailPasswordForm, self).__init__(data, files, auto_id, + prefix, initial) + self.user_cache = None + + def clean_username(self): + """ get user for this username """ + if 'username' in self.cleaned_data: + try: + self.user_cache = User.objects.get( + username = self.cleaned_data['username']) + except: + raise forms.ValidationError(_("Incorrect username.")) + return self.cleaned_data['username'] |