summaryrefslogtreecommitdiffstats
path: root/django_authopenid
diff options
context:
space:
mode:
Diffstat (limited to 'django_authopenid')
-rw-r--r--django_authopenid/__init__.py40
-rw-r--r--django_authopenid/admin.py9
-rw-r--r--django_authopenid/forms.py435
-rw-r--r--django_authopenid/middleware.py24
-rw-r--r--django_authopenid/mimeparse.py160
-rw-r--r--django_authopenid/models.py71
-rw-r--r--django_authopenid/urls.py27
-rw-r--r--django_authopenid/util.py145
-rw-r--r--django_authopenid/views.py787
9 files changed, 0 insertions, 1698 deletions
diff --git a/django_authopenid/__init__.py b/django_authopenid/__init__.py
deleted file mode 100644
index ff040ed7..00000000
--- a/django_authopenid/__init__.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# -*- 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.
-
-"""
-Django authentification application to *with openid using django auth contrib/.
-
-This application allow a user to connect to you website with :
- * legacy account : username/password
- * openid url
-"""
-
-__version__ = "0.9.4"
diff --git a/django_authopenid/admin.py b/django_authopenid/admin.py
deleted file mode 100644
index f64ee579..00000000
--- a/django_authopenid/admin.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# -*- coding: utf-8 -*-
-
-from django.contrib import admin
-from django_authopenid.models import UserAssociation
-
-
-class UserAssociationAdmin(admin.ModelAdmin):
- """User association admin class"""
-admin.site.register(UserAssociation, UserAssociationAdmin) \ No newline at end of file
diff --git a/django_authopenid/forms.py b/django_authopenid/forms.py
deleted file mode 100644
index 09fa76b1..00000000
--- a/django_authopenid/forms.py
+++ /dev/null
@@ -1,435 +0,0 @@
-# -*- 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
-
-import re
-
-
-# needed for some linux distributions like debian
-try:
- from openid.yadis import xri
-except ImportError:
- from yadis import xri
-
-from django_authopenid.util import clean_next
-
-__all__ = ['OpenidSigninForm', 'OpenidAuthForm', 'OpenidVerifyForm',
- 'OpenidRegisterForm', 'RegistrationForm', 'ChangepwForm',
- 'ChangeemailForm', 'EmailPasswordForm', 'DeleteForm',
- 'ChangeOpenidForm', 'ChangeEmailForm', 'ChangepwForm']
-
-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 = forms.CharField(max_length=255, widget=forms.HiddenInput(), required=False)
-
- 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']
-
- def clean_next(self):
- """ validate next """
- if 'next' in self.cleaned_data and self.cleaned_data['next'] != "":
- self.cleaned_data['next'] = clean_next(self.cleaned_data['next'])
- return self.cleaned_data['next']
-
-
-attrs_dict = { 'class': 'required login' }
-username_re = re.compile(r'^\w+$')
-RESERVED_NAMES = (u'fuck', u'shit', u'ass', u'sex', u'add',
- u'edit', u'save', u'delete', u'manage', u'update', 'remove', 'new')
-
-class OpenidAuthForm(forms.Form):
- """ legacy account signin form """
- next = forms.CharField(max_length=255, widget=forms.HiddenInput(),
- required=False)
- username = forms.CharField(max_length=30,
- widget=forms.widgets.TextInput(attrs=attrs_dict))
- password = forms.CharField(max_length=128,
- widget=forms.widgets.PasswordInput(attrs=attrs_dict))
-
- def __init__(self, data=None, files=None, auto_id='id_%s',
- prefix=None, initial=None):
- super(OpenidAuthForm, self).__init__(data, files, auto_id,
- prefix, initial)
- self.user_cache = None
-
- def clean_username(self):
- """ validate username and test if it exists."""
- if 'username' in self.cleaned_data and \
- 'openid_url' not in self.cleaned_data:
- if not username_re.search(self.cleaned_data['username']):
- raise forms.ValidationError(_("Usernames can only contain \
- letters, numbers and underscores"))
- try:
- user = User.objects.get(
- username__exact = self.cleaned_data['username']
- )
- except User.DoesNotExist:
- raise forms.ValidationError(_("This username does not exist \
- in our database. Please choose another."))
- except User.MultipleObjectsReturned:
- raise forms.ValidationError(u'There is already more than one \
- account registered with that username. Please try \
- another.')
- return self.cleaned_data['username']
-
- def clean_password(self):
- """" test if password is valid for this username """
- 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 clean_next(self):
- """ validate next url """
- if 'next' in self.cleaned_data and \
- self.cleaned_data['next'] != "":
- self.cleaned_data['next'] = clean_next(self.cleaned_data['next'])
- return self.cleaned_data['next']
-
- def get_user(self):
- """ get authenticated user """
- return self.user_cache
-
-
-class OpenidRegisterForm(forms.Form):
- """ openid signin form """
- next = forms.CharField(max_length=255, widget=forms.HiddenInput(),
- required=False)
- username = forms.CharField(max_length=30,
- widget=forms.widgets.TextInput(attrs=attrs_dict))
- email = forms.EmailField(widget=forms.TextInput(attrs=dict(attrs_dict,
- maxlength=200)), label=u'Email address')
-
- def clean_username(self):
- """ test if username is valid and exist in database """
- if 'username' in self.cleaned_data:
- if not username_re.search(self.cleaned_data['username']):
- raise forms.ValidationError(_('invalid user name'))
- if self.cleaned_data['username'] in RESERVED_NAMES:
- raise forms.ValidationError(_('sorry, this name can not be used, please try another'))
- if len(self.cleaned_data['username']) < 3:
- raise forms.ValidationError(_('username too short'))
- try:
- user = User.objects.get(
- username__exact = self.cleaned_data['username']
- )
- except User.DoesNotExist:
- return self.cleaned_data['username']
- except User.MultipleObjectsReturned:
- raise forms.ValidationError(_('this name is already in use - please try anoter'))
- raise forms.ValidationError(_('this name is already in use - please try anoter'))
-
- def clean_email(self):
- """For security reason one unique email in database"""
- if 'email' in self.cleaned_data:
- try:
- user = User.objects.get(email = 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(_("This email is already \
- registered in our database. Please choose another."))
-
-
-class OpenidVerifyForm(forms.Form):
- """ openid verify form (associate an openid with an account) """
- next = forms.CharField(max_length=255, widget = forms.HiddenInput(),
- required=False)
- username = forms.CharField(max_length=30,
- widget=forms.widgets.TextInput(attrs=attrs_dict))
- password = forms.CharField(max_length=128,
- widget=forms.widgets.PasswordInput(attrs=attrs_dict))
-
- 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_username(self):
- """ validate username """
- if 'username' in self.cleaned_data:
- if not username_re.search(self.cleaned_data['username']):
- raise forms.ValidationError(_("Usernames can only contain \
- letters, numbers and underscores"))
- try:
- user = User.objects.get(
- username__exact = self.cleaned_data['username']
- )
- except User.DoesNotExist:
- raise forms.ValidationError(_("This username don't exist. \
- Please choose another."))
- except User.MultipleObjectsReturned:
- raise forms.ValidationError(u'Somehow, that username is in \
- use for multiple accounts. Please contact us to get this \
- problem resolved.')
- return self.cleaned_data['username']
-
- 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
-
-
-attrs_dict = { 'class': 'required' }
-username_re = re.compile(r'^\w+$')
-
-class RegistrationForm(forms.Form):
- """ legacy registration form """
-
- next = forms.CharField(max_length=255, widget=forms.HiddenInput(),
- required=False)
- username = forms.CharField(max_length=30,
- widget=forms.TextInput(attrs=attrs_dict),
- label=_('choose a username'))
- email = forms.EmailField(widget=forms.TextInput(attrs=dict(attrs_dict,
- maxlength=200)), label=_('your email address'))
- password1 = forms.CharField(widget=forms.PasswordInput(attrs=attrs_dict),
- label=_('choose password'))
- password2 = forms.CharField(widget=forms.PasswordInput(attrs=attrs_dict),
- label=_('retype password'))
-
- def clean_username(self):
- """
- Validates that the username is alphanumeric and is not already
- in use.
-
- """
- if 'username' in self.cleaned_data:
- if not username_re.search(self.cleaned_data['username']):
- raise forms.ValidationError(u'Usernames can only contain \
- letters, numbers and underscores')
- try:
- user = User.objects.get(
- username__exact = self.cleaned_data['username']
- )
-
- except User.DoesNotExist:
- return self.cleaned_data['username']
- except User.MultipleObjectsReturned:
- raise forms.ValidationError(u'Somehow, that username is in \
- use for multiple accounts. Please contact us to get this \
- problem resolved.')
- raise forms.ValidationError(u'This username is already taken. \
- Please choose another.')
-
- def clean_email(self):
- """ validate if email exist in database
- :return: raise error if it exist """
- if 'email' in self.cleaned_data:
- try:
- user = User.objects.get(email = 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.')
- return self.cleaned_data['email']
-
- def clean_password2(self):
- """
- Validates that the two password inputs match.
-
- """
- if 'password1' in self.cleaned_data and \
- 'password2' in self.cleaned_data and \
- self.cleaned_data['password1'] == \
- self.cleaned_data['password2']:
- return self.cleaned_data['password2']
- raise forms.ValidationError(u'You must type the same password each \
- time')
-
-
-class ChangepwForm(forms.Form):
- """ change password form """
- oldpw = forms.CharField(widget=forms.PasswordInput(attrs=attrs_dict))
- password1 = forms.CharField(widget=forms.PasswordInput(attrs=attrs_dict))
- password2 = forms.CharField(widget=forms.PasswordInput(attrs=attrs_dict))
-
- def __init__(self, data=None, user=None, *args, **kwargs):
- if user is None:
- raise TypeError("Keyword argument 'user' must be supplied")
- super(ChangepwForm, 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']
-
- def clean_password2(self):
- """
- Validates that the two password inputs match.
- """
- if 'password1' in self.cleaned_data and \
- 'password2' in self.cleaned_data and \
- self.cleaned_data['password1'] == self.cleaned_data['password2']:
- return self.cleaned_data['password2']
- raise forms.ValidationError(_("new passwords do not match"))
-
-
-class ChangeemailForm(forms.Form):
- """ change email form """
- email = forms.EmailField(widget=forms.TextInput(attrs=dict(attrs_dict,
- maxlength=200)), label=u'Email address')
- password = forms.CharField(widget=forms.PasswordInput(attrs=attrs_dict))
-
- def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, \
- initial=None, user=None):
- if user is None:
- raise TypeError("Keyword argument 'user' must be supplied")
- super(ChangeemailForm, self).__init__(data, files, auto_id,
- prefix, initial)
- self.test_openid = False
- self.user = user
-
-
- def clean_email(self):
- """ check if email don't exist """
- if 'email' in self.cleaned_data:
- if self.user.email != self.cleaned_data['email']:
- try:
- user = User.objects.get(email = 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.')
- return self.cleaned_data['email']
-
-
- 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 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=attrs_dict))
- password = forms.CharField(widget=forms.PasswordInput(attrs=attrs_dict))
-
- 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 = forms.CharField(max_length=30,
- widget=forms.TextInput(attrs={'class': "required" }))
-
- 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']
diff --git a/django_authopenid/middleware.py b/django_authopenid/middleware.py
deleted file mode 100644
index c0572c6e..00000000
--- a/django_authopenid/middleware.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# -*- coding: utf-8 -*-
-from django_authopenid import mimeparse
-from django.http import HttpResponseRedirect
-from django.core.urlresolvers import reverse
-
-__all__ = ["OpenIDMiddleware"]
-
-class OpenIDMiddleware(object):
- """
- Populate request.openid. This comes either from cookie or from
- session, depending on the presence of OPENID_USE_SESSIONS.
- """
- def process_request(self, request):
- request.openid = request.session.get('openid', None)
-
- def process_response(self, request, response):
- if response.status_code != 200 or len(response.content) < 200:
- return response
- path = request.get_full_path()
- if path == "/" and request.META.has_key('HTTP_ACCEPT') and \
- mimeparse.best_match(['text/html', 'application/xrds+xml'],
- request.META['HTTP_ACCEPT']) == 'application/xrds+xml':
- return HttpResponseRedirect(reverse('yadis_xrdf'))
- return response \ No newline at end of file
diff --git a/django_authopenid/mimeparse.py b/django_authopenid/mimeparse.py
deleted file mode 100644
index ab02eab0..00000000
--- a/django_authopenid/mimeparse.py
+++ /dev/null
@@ -1,160 +0,0 @@
-"""MIME-Type Parser
-
-This module provides basic functions for handling mime-types. It can handle
-matching mime-types against a list of media-ranges. See section 14.1 of
-the HTTP specification [RFC 2616] for a complete explaination.
-
- http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1
-
-Contents:
- - parse_mime_type(): Parses a mime-type into it's component parts.
- - parse_media_range(): Media-ranges are mime-types with wild-cards and a 'q' quality parameter.
- - quality(): Determines the quality ('q') of a mime-type when compared against a list of media-ranges.
- - quality_parsed(): Just like quality() except the second parameter must be pre-parsed.
- - best_match(): Choose the mime-type with the highest quality ('q') from a list of candidates.
-"""
-
-__version__ = "0.1.1"
-__author__ = 'Joe Gregorio'
-__email__ = "joe@bitworking.org"
-__credits__ = ""
-
-def parse_mime_type(mime_type):
- """Carves up a mime_type and returns a tuple of the
- (type, subtype, params) where 'params' is a dictionary
- of all the parameters for the media range.
- For example, the media range 'application/xhtml;q=0.5' would
- get parsed into:
-
- ('application', 'xhtml', {'q', '0.5'})
- """
- parts = mime_type.split(";")
- params = dict([tuple([s.strip() for s in param.split("=")])\
- for param in parts[1:] ])
- (type, subtype) = parts[0].split("/")
- return (type.strip(), subtype.strip(), params)
-
-def parse_media_range(range):
- """Carves up a media range and returns a tuple of the
- (type, subtype, params) where 'params' is a dictionary
- of all the parameters for the media range.
- For example, the media range 'application/*;q=0.5' would
- get parsed into:
-
- ('application', '*', {'q', '0.5'})
-
- In addition this function also guarantees that there
- is a value for 'q' in the params dictionary, filling it
- in with a proper default if necessary.
- """
- (type, subtype, params) = parse_mime_type(range)
- if not params.has_key('q') or not params['q'] or \
- not float(params['q']) or float(params['q']) > 1\
- or float(params['q']) < 0:
- params['q'] = '1'
- return (type, subtype, params)
-
-def quality_parsed(mime_type, parsed_ranges):
- """Find the best match for a given mime_type against
- a list of media_ranges that have already been
- parsed by parse_media_range(). Returns the
- 'q' quality parameter of the best match, 0 if no
- match was found. This function bahaves the same as quality()
- except that 'parsed_ranges' must be a list of
- parsed media ranges. """
- best_fitness = -1
- best_match = ""
- best_fit_q = 0
- (target_type, target_subtype, target_params) =\
- parse_media_range(mime_type)
- for (type, subtype, params) in parsed_ranges:
- param_matches = reduce(lambda x, y: x+y, [1 for (key, value) in \
- target_params.iteritems() if key != 'q' and \
- params.has_key(key) and value == params[key]], 0)
- if (type == target_type or type == '*' or target_type == '*') and \
- (subtype == target_subtype or subtype == '*' or target_subtype == '*'):
- fitness = (type == target_type) and 100 or 0
- fitness += (subtype == target_subtype) and 10 or 0
- fitness += param_matches
- if fitness > best_fitness:
- best_fitness = fitness
- best_fit_q = params['q']
-
- return float(best_fit_q)
-
-def quality(mime_type, ranges):
- """Returns the quality 'q' of a mime_type when compared
- against the media-ranges in ranges. For example:
-
- >>> quality('text/html','text/*;q=0.3, text/html;q=0.7, text/html;level=1, text/html;level=2;q=0.4, */*;q=0.5')
- 0.7
-
- """
- parsed_ranges = [parse_media_range(r) for r in ranges.split(",")]
- return quality_parsed(mime_type, parsed_ranges)
-
-def best_match(supported, header):
- """Takes a list of supported mime-types and finds the best
- match for all the media-ranges listed in header. The value of
- header must be a string that conforms to the format of the
- HTTP Accept: header. The value of 'supported' is a list of
- mime-types.
-
- >>> best_match(['application/xbel+xml', 'text/xml'], 'text/*;q=0.5,*/*; q=0.1')
- 'text/xml'
- """
- parsed_header = [parse_media_range(r) for r in header.split(",")]
- weighted_matches = [(quality_parsed(mime_type, parsed_header), mime_type)\
- for mime_type in supported]
- weighted_matches.sort()
- return weighted_matches[-1][0] and weighted_matches[-1][1] or ''
-
-if __name__ == "__main__":
- import unittest
-
- class TestMimeParsing(unittest.TestCase):
-
- def test_parse_media_range(self):
- self.assert_(('application', 'xml', {'q': '1'}) == parse_media_range('application/xml;q=1'))
- self.assertEqual(('application', 'xml', {'q': '1'}), parse_media_range('application/xml'))
- self.assertEqual(('application', 'xml', {'q': '1'}), parse_media_range('application/xml;q='))
- self.assertEqual(('application', 'xml', {'q': '1'}), parse_media_range('application/xml ; q='))
- self.assertEqual(('application', 'xml', {'q': '1', 'b': 'other'}), parse_media_range('application/xml ; q=1;b=other'))
- self.assertEqual(('application', 'xml', {'q': '1', 'b': 'other'}), parse_media_range('application/xml ; q=2;b=other'))
-
- def test_rfc_2616_example(self):
- accept = "text/*;q=0.3, text/html;q=0.7, text/html;level=1, text/html;level=2;q=0.4, */*;q=0.5"
- self.assertEqual(1, quality("text/html;level=1", accept))
- self.assertEqual(0.7, quality("text/html", accept))
- self.assertEqual(0.3, quality("text/plain", accept))
- self.assertEqual(0.5, quality("image/jpeg", accept))
- self.assertEqual(0.4, quality("text/html;level=2", accept))
- self.assertEqual(0.7, quality("text/html;level=3", accept))
-
- def test_best_match(self):
- mime_types_supported = ['application/xbel+xml', 'application/xml']
- # direct match
- self.assertEqual(best_match(mime_types_supported, 'application/xbel+xml'), 'application/xbel+xml')
- # direct match with a q parameter
- self.assertEqual(best_match(mime_types_supported, 'application/xbel+xml; q=1'), 'application/xbel+xml')
- # direct match of our second choice with a q parameter
- self.assertEqual(best_match(mime_types_supported, 'application/xml; q=1'), 'application/xml')
- # match using a subtype wildcard
- self.assertEqual(best_match(mime_types_supported, 'application/*; q=1'), 'application/xml')
- # match using a type wildcard
- self.assertEqual(best_match(mime_types_supported, '*/*'), 'application/xml')
-
- mime_types_supported = ['application/xbel+xml', 'text/xml']
- # match using a type versus a lower weighted subtype
- self.assertEqual(best_match(mime_types_supported, 'text/*;q=0.5,*/*; q=0.1'), 'text/xml')
- # fail to match anything
- self.assertEqual(best_match(mime_types_supported, 'text/html,application/atom+xml; q=0.9'), '')
-
- def test_support_wildcards(self):
- mime_types_supported = ['image/*', 'application/xml']
- # match using a type wildcard
- self.assertEqual(best_match(mime_types_supported, 'image/png'), 'image/*')
- # match using a wildcard for both requested and supported
- self.assertEqual(best_match(mime_types_supported, 'image/*'), 'image/*')
-
- unittest.main() \ No newline at end of file
diff --git a/django_authopenid/models.py b/django_authopenid/models.py
deleted file mode 100644
index 9826c452..00000000
--- a/django_authopenid/models.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# -*- coding: utf-8 -*-
-from django.conf import settings
-from django.contrib.auth.models import User
-from django.db import models
-
-import md5, random, sys, os, time
-
-__all__ = ['Nonce', 'Association', 'UserAssociation',
- 'UserPasswordQueueManager', 'UserPasswordQueue']
-
-class Nonce(models.Model):
- """ openid nonce """
- server_url = models.CharField(max_length=255)
- timestamp = models.IntegerField()
- salt = models.CharField(max_length=40)
-
- def __unicode__(self):
- return u"Nonce: %s" % self.id
-
-
-class Association(models.Model):
- """ association openid url and lifetime """
- server_url = models.TextField(max_length=2047)
- handle = models.CharField(max_length=255)
- secret = models.TextField(max_length=255) # Stored base64 encoded
- issued = models.IntegerField()
- lifetime = models.IntegerField()
- assoc_type = models.TextField(max_length=64)
-
- def __unicode__(self):
- return u"Association: %s, %s" % (self.server_url, self.handle)
-
-class UserAssociation(models.Model):
- """
- model to manage association between openid and user
- """
- openid_url = models.CharField(blank=False, max_length=255)
- user = models.ForeignKey(User, unique=True)
-
- def __unicode__(self):
- return "Openid %s with user %s" % (self.openid_url, self.user)
-
-class UserPasswordQueueManager(models.Manager):
- """ manager for UserPasswordQueue object """
- def get_new_confirm_key(self):
- "Returns key that isn't being used."
- # The random module is seeded when this Apache child is created.
- # Use SECRET_KEY as added salt.
- while 1:
- confirm_key = md5.new("%s%s%s%s" % (
- random.randint(0, sys.maxint - 1), os.getpid(),
- time.time(), settings.SECRET_KEY)).hexdigest()
- try:
- self.get(confirm_key=confirm_key)
- except self.model.DoesNotExist:
- break
- return confirm_key
-
-
-class UserPasswordQueue(models.Model):
- """
- model for new password queue.
- """
- user = models.ForeignKey(User, unique=True)
- new_password = models.CharField(max_length=30)
- confirm_key = models.CharField(max_length=40)
-
- objects = UserPasswordQueueManager()
-
- def __unicode__(self):
- return self.user.username
diff --git a/django_authopenid/urls.py b/django_authopenid/urls.py
deleted file mode 100644
index 1ab65941..00000000
--- a/django_authopenid/urls.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# -*- coding: utf-8 -*-
-from django.conf.urls.defaults import patterns, url
-from django.utils.translation import ugettext as _
-
-urlpatterns = patterns('django_authopenid.views',
- # yadis rdf
- url(r'^yadis.xrdf$', 'xrdf', name='yadis_xrdf'),
- # manage account registration
- url(r'^%s$' % _('signin/'), 'signin', name='user_signin'),
- url(r'^%s$' % _('signout/'), 'signout', name='user_signout'),
- url(r'^%s%s$' % (_('signin/'), _('complete/')), 'complete_signin',
- name='user_complete_signin'),
- url(r'^%s$' % _('register/'), 'register', name='user_register'),
- url(r'^%s$' % _('signup/'), 'signup', name='user_signup'),
- #disable current sendpw function
- url(r'^%s$' % _('sendpw/'), 'signin', name='user_sendpw'),
- #url(r'^%s$' % _('sendpw/'), 'sendpw', name='user_sendpw'),
- #url(r'^%s%s$' % (_('password/'), _('confirm/')), 'confirmchangepw',
- # name='user_confirmchangepw'),
-
- # manage account settings
- #url(r'^$', 'account_settings', name='user_account_settings'),
- #url(r'^%s$' % _('password/'), 'changepw', name='user_changepw'),
- #url(r'^%s$' % _('email/'), 'changeemail', name='user_changeemail'),
- #url(r'^%s$' % _('openid/'), 'changeopenid', name='user_changeopenid'),
- url(r'^%s$' % _('delete/'), 'delete', name='user_delete'),
-)
diff --git a/django_authopenid/util.py b/django_authopenid/util.py
deleted file mode 100644
index 841a81c7..00000000
--- a/django_authopenid/util.py
+++ /dev/null
@@ -1,145 +0,0 @@
-# -*- coding: utf-8 -*-
-from openid.store.interface import OpenIDStore
-from openid.association import Association as OIDAssociation
-from openid.extensions import sreg
-import openid.store
-
-from django.db.models.query import Q
-from django.conf import settings
-from django.http import str_to_unicode
-
-
-# needed for some linux distributions like debian
-try:
- from openid.yadis import xri
-except:
- from yadis import xri
-
-import time, base64, md5, operator
-import urllib
-
-from models import Association, Nonce
-
-__all__ = ['OpenID', 'DjangoOpenIDStore', 'from_openid_response', 'clean_next']
-
-DEFAULT_NEXT = getattr(settings, 'OPENID_REDIRECT_NEXT', '/')
-def clean_next(next):
- if next is None:
- return DEFAULT_NEXT
- next = str_to_unicode(urllib.unquote(next), 'utf-8')
- next = next.strip()
- if next.startswith('/'):
- return next
- return DEFAULT_NEXT
-
-class OpenID:
- def __init__(self, openid_, issued, attrs=None, sreg_=None):
- self.openid = openid_
- self.issued = issued
- self.attrs = attrs or {}
- self.sreg = sreg_ or {}
- self.is_iname = (xri.identifierScheme(openid_) == 'XRI')
-
- def __repr__(self):
- return '<OpenID: %s>' % self.openid
-
- def __str__(self):
- return self.openid
-
-class DjangoOpenIDStore(OpenIDStore):
- def __init__(self):
- self.max_nonce_age = 6 * 60 * 60 # Six hours
-
- def storeAssociation(self, server_url, association):
- assoc = Association(
- server_url = server_url,
- handle = association.handle,
- secret = base64.encodestring(association.secret),
- issued = association.issued,
- lifetime = association.issued,
- assoc_type = association.assoc_type
- )
- assoc.save()
-
- def getAssociation(self, server_url, handle=None):
- assocs = []
- if handle is not None:
- assocs = Association.objects.filter(
- server_url = server_url, handle = handle
- )
- else:
- assocs = Association.objects.filter(
- server_url = server_url
- )
- if not assocs:
- return None
- associations = []
- for assoc in assocs:
- association = OIDAssociation(
- assoc.handle, base64.decodestring(assoc.secret), assoc.issued,
- assoc.lifetime, assoc.assoc_type
- )
- if association.getExpiresIn() == 0:
- self.removeAssociation(server_url, assoc.handle)
- else:
- associations.append((association.issued, association))
- if not associations:
- return None
- return associations[-1][1]
-
- def removeAssociation(self, server_url, handle):
- assocs = list(Association.objects.filter(
- server_url = server_url, handle = handle
- ))
- assocs_exist = len(assocs) > 0
- for assoc in assocs:
- assoc.delete()
- return assocs_exist
-
- def useNonce(self, server_url, timestamp, salt):
- if abs(timestamp - time.time()) > openid.store.nonce.SKEW:
- return False
-
- query = [
- Q(server_url__exact=server_url),
- Q(timestamp__exact=timestamp),
- Q(salt__exact=salt),
- ]
- try:
- ononce = Nonce.objects.get(reduce(operator.and_, query))
- except Nonce.DoesNotExist:
- ononce = Nonce(
- server_url=server_url,
- timestamp=timestamp,
- salt=salt
- )
- ononce.save()
- return True
-
- ononce.delete()
-
- return False
-
- def cleanupNonce(self):
- Nonce.objects.filter(timestamp<int(time.time()) - nonce.SKEW).delete()
-
- def cleanupAssociations(self):
- Association.objects.extra(where=['issued + lifetimeint<(%s)' % time.time()]).delete()
-
- def getAuthKey(self):
- # Use first AUTH_KEY_LEN characters of md5 hash of SECRET_KEY
- return md5.new(settings.SECRET_KEY).hexdigest()[:self.AUTH_KEY_LEN]
-
- def isDumb(self):
- return False
-
-def from_openid_response(openid_response):
- """ return openid object from response """
- issued = int(time.time())
- sreg_resp = sreg.SRegResponse.fromSuccessResponse(openid_response) \
- or []
-
- return OpenID(
- openid_response.identity_url, issued, openid_response.signed_fields,
- dict(sreg_resp)
- )
diff --git a/django_authopenid/views.py b/django_authopenid/views.py
deleted file mode 100644
index a9072c12..00000000
--- a/django_authopenid/views.py
+++ /dev/null
@@ -1,787 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2007, 2008, Benoît Chesneau
-# Copyright (c) 2007 Simon Willison, original work on django-openid
-#
-# 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.http import HttpResponseRedirect, get_host
-from django.shortcuts import render_to_response as render
-from django.template import RequestContext, loader, Context
-from django.conf import settings
-from django.contrib.auth.models import User
-from django.contrib.auth import login, logout
-from django.contrib.auth.decorators import login_required
-from django.core.urlresolvers import reverse
-from django.utils.encoding import smart_unicode
-from django.utils.html import escape
-from django.utils.translation import ugettext as _
-from django.contrib.sites.models import Site
-from django.utils.http import urlquote_plus
-from django.core.mail import send_mail
-
-from openid.consumer.consumer import Consumer, \
- SUCCESS, CANCEL, FAILURE, SETUP_NEEDED
-from openid.consumer.discover import DiscoveryFailure
-from openid.extensions import sreg
-# needed for some linux distributions like debian
-try:
- from openid.yadis import xri
-except ImportError:
- from yadis import xri
-
-import re
-import urllib
-
-
-from django_authopenid.util import OpenID, DjangoOpenIDStore, from_openid_response, clean_next
-from django_authopenid.models import UserAssociation, UserPasswordQueue
-from django_authopenid.forms import OpenidSigninForm, OpenidAuthForm, OpenidRegisterForm, \
- OpenidVerifyForm, RegistrationForm, ChangepwForm, ChangeemailForm, \
- ChangeopenidForm, DeleteForm, EmailPasswordForm
-
-def get_url_host(request):
- if request.is_secure():
- protocol = 'https'
- else:
- protocol = 'http'
- host = escape(get_host(request))
- return '%s://%s' % (protocol, host)
-
-def get_full_url(request):
- return get_url_host(request) + request.get_full_path()
-
-
-
-def ask_openid(request, openid_url, redirect_to, on_failure=None,
- sreg_request=None):
- """ basic function to ask openid and return response """
- request.encoding = 'UTF-8'
- on_failure = on_failure or signin_failure
-
- trust_root = getattr(
- settings, 'OPENID_TRUST_ROOT', get_url_host(request) + '/'
- )
- if xri.identifierScheme(openid_url) == 'XRI' and getattr(
- settings, 'OPENID_DISALLOW_INAMES', False
- ):
- msg = _("i-names are not supported")
- return on_failure(request, msg)
- consumer = Consumer(request.session, DjangoOpenIDStore())
- try:
- auth_request = consumer.begin(openid_url)
- except DiscoveryFailure:
- msg = _(u"非法OpenID地址: %s" % openid_url)
- return on_failure(request, msg)
-
- if sreg_request:
- auth_request.addExtension(sreg_request)
- redirect_url = auth_request.redirectURL(trust_root, redirect_to)
- return HttpResponseRedirect(redirect_url)
-
-def complete(request, on_success=None, on_failure=None, return_to=None):
- """ complete openid signin """
- on_success = on_success or default_on_success
- on_failure = on_failure or default_on_failure
-
- consumer = Consumer(request.session, DjangoOpenIDStore())
- # make sure params are encoded in utf8
- params = dict((k,smart_unicode(v)) for k, v in request.GET.items())
- openid_response = consumer.complete(params, return_to)
-
-
- if openid_response.status == SUCCESS:
- return on_success(request, openid_response.identity_url,
- openid_response)
- elif openid_response.status == CANCEL:
- return on_failure(request, 'The request was canceled')
- elif openid_response.status == FAILURE:
- return on_failure(request, openid_response.message)
- elif openid_response.status == SETUP_NEEDED:
- return on_failure(request, 'Setup needed')
- else:
- assert False, "Bad openid status: %s" % openid_response.status
-
-def default_on_success(request, identity_url, openid_response):
- """ default action on openid signin success """
- request.session['openid'] = from_openid_response(openid_response)
- return HttpResponseRedirect(clean_next(request.GET.get('next')))
-
-def default_on_failure(request, message):
- """ default failure action on signin """
- return render('openid_failure.html', {
- 'message': message
- })
-
-
-def not_authenticated(func):
- """ decorator that redirect user to next page if
- he is already logged."""
- def decorated(request, *args, **kwargs):
- if request.user.is_authenticated():
- next = request.GET.get("next", "/")
- return HttpResponseRedirect(next)
- return func(request, *args, **kwargs)
- return decorated
-
-@not_authenticated
-def signin(request):
- """
- signin page. It manage the legacy authentification (user/password)
- and authentification with openid.
-
- url: /signin/
-
- template : authopenid/signin.htm
- """
- request.encoding = 'UTF-8'
- on_failure = signin_failure
- next = clean_next(request.GET.get('next'))
-
- form_signin = OpenidSigninForm(initial={'next':next})
- form_auth = OpenidAuthForm(initial={'next':next})
-
- if request.POST:
-
- if 'bsignin' in request.POST.keys():
-
- form_signin = OpenidSigninForm(request.POST)
- if form_signin.is_valid():
- next = clean_next(form_signin.cleaned_data.get('next'))
- sreg_req = sreg.SRegRequest(optional=['nickname', 'email'])
- redirect_to = "%s%s?%s" % (
- get_url_host(request),
- reverse('user_complete_signin'),
- urllib.urlencode({'next':next})
- )
-
- return ask_openid(request,
- form_signin.cleaned_data['openid_url'],
- redirect_to,
- on_failure=signin_failure,
- sreg_request=sreg_req)
-
- elif 'blogin' in request.POST.keys():
- # perform normal django authentification
- form_auth = OpenidAuthForm(request.POST)
- if form_auth.is_valid():
- user_ = form_auth.get_user()
- login(request, user_)
- next = clean_next(form_auth.cleaned_data.get('next'))
- return HttpResponseRedirect(next)
-
-
- return render('authopenid/signin.html', {
- 'form1': form_auth,
- 'form2': form_signin,
- 'msg': request.GET.get('msg',''),
- 'sendpw_url': reverse('user_sendpw'),
- }, context_instance=RequestContext(request))
-
-def complete_signin(request):
- """ in case of complete signin with openid """
- return complete(request, signin_success, signin_failure,
- get_url_host(request) + reverse('user_complete_signin'))
-
-
-def signin_success(request, identity_url, openid_response):
- """
- openid signin success.
-
- If the openid is already registered, the user is redirected to
- url set par next or in settings with OPENID_REDIRECT_NEXT variable.
- If none of these urls are set user is redirectd to /.
-
- if openid isn't registered user is redirected to register page.
- """
-
- openid_ = from_openid_response(openid_response)
- request.session['openid'] = openid_
- try:
- rel = UserAssociation.objects.get(openid_url__exact = str(openid_))
- except:
- # try to register this new user
- return register(request)
- user_ = rel.user
- if user_.is_active:
- user_.backend = "django.contrib.auth.backends.ModelBackend"
- login(request, user_)
-
- next = clean_next(request.GET.get('next'))
- return HttpResponseRedirect(next)
-
-def is_association_exist(openid_url):
- """ test if an openid is already in database """
- is_exist = True
- try:
- uassoc = UserAssociation.objects.get(openid_url__exact = openid_url)
- except:
- is_exist = False
- return is_exist
-
-@not_authenticated
-def register(request):
- """
- register an openid.
-
- If user is already a member he can associate its openid with
- its account.
-
- A new account could also be created and automaticaly associated
- to the openid.
-
- url : /complete/
-
- template : authopenid/complete.html
- """
-
- is_redirect = False
- next = clean_next(request.GET.get('next'))
- openid_ = request.session.get('openid', None)
- if not openid_:
- return HttpResponseRedirect(reverse('user_signin') + next)
-
- nickname = openid_.sreg.get('nickname', '')
- email = openid_.sreg.get('email', '')
-
- form1 = OpenidRegisterForm(initial={
- 'next': next,
- 'username': nickname,
- 'email': email,
- })
- form2 = OpenidVerifyForm(initial={
- 'next': next,
- 'username': nickname,
- })
-
- if request.POST:
- just_completed = False
- if 'bnewaccount' in request.POST.keys():
- form1 = OpenidRegisterForm(request.POST)
- if form1.is_valid():
- next = clean_next(form1.cleaned_data.get('next'))
- is_redirect = True
- tmp_pwd = User.objects.make_random_password()
- user_ = User.objects.create_user(form1.cleaned_data['username'],
- form1.cleaned_data['email'], tmp_pwd)
-
- # make association with openid
- uassoc = UserAssociation(openid_url=str(openid_),
- user_id=user_.id)
- uassoc.save()
-
- # login
- user_.backend = "django.contrib.auth.backends.ModelBackend"
- login(request, user_)
- elif 'bverify' in request.POST.keys():
- form2 = OpenidVerifyForm(request.POST)
- if form2.is_valid():
- is_redirect = True
- next = clean_next(form2.cleaned_data.get('next'))
- user_ = form2.get_user()
-
- uassoc = UserAssociation(openid_url=str(openid_),
- user_id=user_.id)
- uassoc.save()
- login(request, user_)
-
- # redirect, can redirect only if forms are valid.
- if is_redirect:
- return HttpResponseRedirect(next)
-
- return render('authopenid/complete.html', {
- 'form1': form1,
- 'form2': form2,
- 'nickname': nickname,
- 'email': email
- }, context_instance=RequestContext(request))
-
-def signin_failure(request, message):
- """
- falure with openid signin. Go back to signin page.
-
- template : "authopenid/signin.html"
- """
- next = clean_next(request.GET.get('next'))
- form_signin = OpenidSigninForm(initial={'next': next})
- form_auth = OpenidAuthForm(initial={'next': next})
-
- return render('authopenid/signin.html', {
- 'msg': message,
- 'form1': form_auth,
- 'form2': form_signin,
- }, context_instance=RequestContext(request))
-
-@not_authenticated
-def signup(request):
- """
- signup page. Create a legacy account
-
- url : /signup/"
-
- templates: authopenid/signup.html, authopenid/confirm_email.txt
- """
- action_signin = reverse('user_signin')
- next = clean_next(request.GET.get('next'))
- form = RegistrationForm(initial={'next':next})
- form_signin = OpenidSigninForm(initial={'next':next})
-
- if request.POST:
- form = RegistrationForm(request.POST)
- if form.is_valid():
- next = clean_next(form.cleaned_data.get('next'))
- user_ = User.objects.create_user( form.cleaned_data['username'],
- form.cleaned_data['email'], form.cleaned_data['password1'])
-
- user_.backend = "django.contrib.auth.backends.ModelBackend"
- login(request, user_)
-
- # send email
- current_domain = Site.objects.get_current().domain
- subject = _("Welcome")
- message_template = loader.get_template(
- 'authopenid/confirm_email.txt'
- )
- message_context = Context({
- 'site_url': 'http://%s/' % current_domain,
- 'username': form.cleaned_data['username'],
- 'password': form.cleaned_data['password1']
- })
- message = message_template.render(message_context)
- send_mail(subject, message, settings.DEFAULT_FROM_EMAIL,
- [user_.email])
-
- return HttpResponseRedirect(next)
-
- return render('authopenid/signup.html', {
- 'form': form,
- 'form2': form_signin,
- }, context_instance=RequestContext(request))
-
-@login_required
-def signout(request):
- """
- signout from the website. Remove openid from session and kill it.
-
- url : /signout/"
- """
- try:
- del request.session['openid']
- except KeyError:
- pass
- next = clean_next(request.GET.get('next'))
- logout(request)
-
- return HttpResponseRedirect(next)
-
-def xrdf(request):
- url_host = get_url_host(request)
- return_to = [
- "%s%s" % (url_host, reverse('user_complete_signin'))
- ]
- return render('authopenid/yadis.xrdf', {
- 'return_to': return_to
- }, context_instance=RequestContext(request))
-
-@login_required
-def account_settings(request):
- """
- index pages to changes some basic account settings :
- - change password
- - change email
- - associate a new openid
- - delete account
-
- url : /
-
- template : authopenid/settings.html
- """
- msg = request.GET.get('msg', '')
- is_openid = True
-
- try:
- uassoc = UserAssociation.objects.get(
- user__username__exact=request.user.username
- )
- except:
- is_openid = False
-
-
- return render('authopenid/settings.html', {
- 'msg': msg,
- 'is_openid': is_openid
- }, context_instance=RequestContext(request))
-
-@login_required
-def changepw(request):
- """
- change password view.
-
- url : /changepw/
- template: authopenid/changepw.html
- """
-
- user_ = request.user
-
- if request.POST:
- form = ChangepwForm(request.POST, user=user_)
- if form.is_valid():
- user_.set_password(form.cleaned_data['password1'])
- user_.save()
- msg = _("Password changed.")
- redirect = "%s?msg=%s" % (
- reverse('user_account_settings'),
- urlquote_plus(msg))
- return HttpResponseRedirect(redirect)
- else:
- form = ChangepwForm(user=user_)
-
- return render('authopenid/changepw.html', {'form': form },
- context_instance=RequestContext(request))
-
-@login_required
-def changeemail(request):
- """
- changeemail view. It require password or openid to allow change.
-
- url: /changeemail/
-
- template : authopenid/changeemail.html
- """
- msg = request.GET.get('msg', '')
- extension_args = {}
- user_ = request.user
-
- redirect_to = get_url_host(request) + reverse('user_changeemail')
-
- if request.POST:
- form = ChangeemailForm(request.POST, user=user_)
- if form.is_valid():
- if not form.test_openid:
- user_.email = form.cleaned_data['email']
- user_.save()
- msg = _("Email changed.")
- redirect = "%s?msg=%s" % (reverse('user_account_settings'),
- urlquote_plus(msg))
- return HttpResponseRedirect(redirect)
- else:
- request.session['new_email'] = form.cleaned_data['email']
- return ask_openid(request, form.cleaned_data['password'],
- redirect_to, on_failure=emailopenid_failure)
- elif not request.POST and 'openid.mode' in request.GET:
- return complete(request, emailopenid_success,
- emailopenid_failure, redirect_to)
- else:
- form = ChangeemailForm(initial={'email': user_.email},
- user=user_)
-
- return render('authopenid/changeemail.html', {
- 'form': form,
- 'msg': msg
- }, context_instance=RequestContext(request))
-
-
-def emailopenid_success(request, identity_url, openid_response):
- openid_ = from_openid_response(openid_response)
-
- user_ = request.user
- try:
- uassoc = UserAssociation.objects.get(
- openid_url__exact=identity_url
- )
- except:
- return emailopenid_failure(request,
- _("No OpenID %s found associated in our database" % identity_url))
-
- if uassoc.user.username != request.user.username:
- return emailopenid_failure(request,
- _("The OpenID %s isn't associated to current user logged in" %
- identity_url))
-
- new_email = request.session.get('new_email', '')
- if new_email:
- user_.email = new_email
- user_.save()
- del request.session['new_email']
- msg = _("Email Changed.")
-
- redirect = "%s?msg=%s" % (reverse('user_account_settings'),
- urlquote_plus(msg))
- return HttpResponseRedirect(redirect)
-
-
-def emailopenid_failure(request, message):
- redirect_to = "%s?msg=%s" % (
- reverse('user_changeemail'), urlquote_plus(message))
- return HttpResponseRedirect(redirect_to)
-
-@login_required
-def changeopenid(request):
- """
- change openid view. Allow user to change openid
- associated to its username.
-
- url : /changeopenid/
-
- template: authopenid/changeopenid.html
- """
-
- extension_args = {}
- openid_url = ''
- has_openid = True
- msg = request.GET.get('msg', '')
-
- user_ = request.user
-
- try:
- uopenid = UserAssociation.objects.get(user=user_)
- openid_url = uopenid.openid_url
- except:
- has_openid = False
-
- redirect_to = get_url_host(request) + reverse('user_changeopenid')
- if request.POST and has_openid:
- form = ChangeopenidForm(request.POST, user=user_)
- if form.is_valid():
- return ask_openid(request, form.cleaned_data['openid_url'],
- redirect_to, on_failure=changeopenid_failure)
- elif not request.POST and has_openid:
- if 'openid.mode' in request.GET:
- return complete(request, changeopenid_success,
- changeopenid_failure, redirect_to)
-
- form = ChangeopenidForm(initial={'openid_url': openid_url }, user=user_)
- return render('authopenid/changeopenid.html', {
- 'form': form,
- 'has_openid': has_openid,
- 'msg': msg
- }, context_instance=RequestContext(request))
-
-def changeopenid_success(request, identity_url, openid_response):
- openid_ = from_openid_response(openid_response)
- is_exist = True
- try:
- uassoc = UserAssociation.objects.get(openid_url__exact=identity_url)
- except:
- is_exist = False
-
- if not is_exist:
- try:
- uassoc = UserAssociation.objects.get(
- user__username__exact=request.user.username
- )
- uassoc.openid_url = identity_url
- uassoc.save()
- except:
- uassoc = UserAssociation(user=request.user,
- openid_url=identity_url)
- uassoc.save()
- elif uassoc.user.username != request.user.username:
- return changeopenid_failure(request,
- _('This OpenID is already associated with another account.'))
-
- request.session['openids'] = []
- request.session['openids'].append(openid_)
-
- msg = _("OpenID %s is now associated with your account." % identity_url)
- redirect = "%s?msg=%s" % (
- reverse('user_account_settings'),
- urlquote_plus(msg))
- return HttpResponseRedirect(redirect)
-
-
-def changeopenid_failure(request, message):
- redirect_to = "%s?msg=%s" % (
- reverse('user_changeopenid'),
- urlquote_plus(message))
- return HttpResponseRedirect(redirect_to)
-
-@login_required
-def delete(request):
- """
- delete view. Allow user to delete its account. Password/openid are required to
- confirm it. He should also check the confirm checkbox.
-
- url : /delete
-
- template : authopenid/delete.html
- """
-
- extension_args = {}
-
- user_ = request.user
-
- redirect_to = get_url_host(request) + reverse('user_delete')
- if request.POST:
- form = DeleteForm(request.POST, user=user_)
- if form.is_valid():
- if not form.test_openid:
- user_.delete()
- return signout(request)
- else:
- return ask_openid(request, form.cleaned_data['password'],
- redirect_to, on_failure=deleteopenid_failure)
- elif not request.POST and 'openid.mode' in request.GET:
- return complete(request, deleteopenid_success, deleteopenid_failure,
- redirect_to)
-
- form = DeleteForm(user=user_)
-
- msg = request.GET.get('msg','')
- return render('authopenid/delete.html', {
- 'form': form,
- 'msg': msg,
- }, context_instance=RequestContext(request))
-
-def deleteopenid_success(request, identity_url, openid_response):
- openid_ = from_openid_response(openid_response)
-
- user_ = request.user
- try:
- uassoc = UserAssociation.objects.get(
- openid_url__exact=identity_url
- )
- except:
- return deleteopenid_failure(request,
- _("No OpenID %s found associated in our database" % identity_url))
-
- if uassoc.user.username == user_.username:
- user_.delete()
- return signout(request)
- else:
- return deleteopenid_failure(request,
- _("The OpenID %s isn't associated to current user logged in" %
- identity_url))
-
- msg = _("Account deleted.")
- redirect = "/?msg=%s" % (urlquote_plus(msg))
- return HttpResponseRedirect(redirect)
-
-
-def deleteopenid_failure(request, message):
- redirect_to = "%s?msg=%s" % (reverse('user_delete'), urlquote_plus(message))
- return HttpResponseRedirect(redirect_to)
-
-
-def sendpw(request):
- """
- send a new password to the user. It return a mail with
- a new pasword and a confirm link in. To activate the
- new password, the user should click on confirm link.
-
- url : /sendpw/
-
- templates : authopenid/sendpw_email.txt, authopenid/sendpw.html
- """
-
- msg = request.GET.get('msg','')
- if request.POST:
- form = EmailPasswordForm(request.POST)
- if form.is_valid():
- new_pw = User.objects.make_random_password()
- confirm_key = UserPasswordQueue.objects.get_new_confirm_key()
- try:
- uqueue = UserPasswordQueue.objects.get(
- user=form.user_cache
- )
- except:
- uqueue = UserPasswordQueue(
- user=form.user_cache
- )
- uqueue.new_password = new_pw
- uqueue.confirm_key = confirm_key
- uqueue.save()
- # send email
- current_domain = Site.objects.get_current().domain
- subject = _("Request for new password")
- message_template = loader.get_template(
- 'authopenid/sendpw_email.txt')
- message_context = Context({
- 'site_url': 'http://%s' % current_domain,
- 'confirm_key': confirm_key,
- 'username': form.user_cache.username,
- 'password': new_pw,
- 'url_confirm': reverse('user_confirmchangepw'),
- })
- message = message_template.render(message_context)
- send_mail(subject, message, settings.DEFAULT_FROM_EMAIL,
- [form.user_cache.email])
- msg = _("A new password has been sent to your email address.")
- else:
- form = EmailPasswordForm()
-
- return render('authopenid/sendpw.html', {
- 'form': form,
- 'msg': msg
- }, context_instance=RequestContext(request))
-
-
-def confirmchangepw(request):
- """
- view to set new password when the user click on confirm link
- in its mail. Basically it check if the confirm key exist, then
- replace old password with new password and remove confirm
- ley from the queue. Then it redirect the user to signin
- page.
-
- url : /sendpw/confirm/?key
-
- """
- confirm_key = request.GET.get('key', '')
- if not confirm_key:
- return HttpResponseRedirect('/')
-
- try:
- uqueue = UserPasswordQueue.objects.get(
- confirm_key__exact=confirm_key
- )
- except:
- msg = _("Could not change password. Confirmation key '%s'\
- is not registered." % confirm_key)
- redirect = "%s?msg=%s" % (
- reverse('user_sendpw'), urlquote_plus(msg))
- return HttpResponseRedirect(redirect)
-
- try:
- user_ = User.objects.get(id=uqueue.user.id)
- except:
- msg = _("Can not change password. User don't exist anymore \
- in our database.")
- redirect = "%s?msg=%s" % (reverse('user_sendpw'),
- urlquote_plus(msg))
- return HttpResponseRedirect(redirect)
-
- user_.set_password(uqueue.new_password)
- user_.save()
- uqueue.delete()
- msg = _("Password changed for %s. You may now sign in." %
- user_.username)
- redirect = "%s?msg=%s" % (reverse('user_signin'),
- urlquote_plus(msg))
-
- return HttpResponseRedirect(redirect)