summaryrefslogtreecommitdiffstats
path: root/django_authopenid
diff options
context:
space:
mode:
authorEvgeny Fadeev <evgeny.fadeev@gmail.com>2010-06-12 22:51:11 -0400
committerEvgeny Fadeev <evgeny.fadeev@gmail.com>2010-06-12 22:51:11 -0400
commit3a3a11d32c72ab79ce94679aae7a549230c7104f (patch)
tree3ac36a302b85d5497b3d335238044c8f481ac0fd /django_authopenid
parent8b6a10ead45bcd915f5da223de2b3fd3c30fc7b5 (diff)
downloadaskbot-3a3a11d32c72ab79ce94679aae7a549230c7104f.tar.gz
askbot-3a3a11d32c72ab79ce94679aae7a549230c7104f.tar.bz2
askbot-3a3a11d32c72ab79ce94679aae7a549230c7104f.zip
moved livesettings and django_authopenid into forum/deps
Diffstat (limited to 'django_authopenid')
-rw-r--r--django_authopenid/README5
-rw-r--r--django_authopenid/__init__.py40
-rw-r--r--django_authopenid/admin.py9
-rw-r--r--django_authopenid/forms.py322
-rw-r--r--django_authopenid/middleware.py28
-rw-r--r--django_authopenid/mimeparse.py160
-rw-r--r--django_authopenid/models.py80
-rw-r--r--django_authopenid/urls.py62
-rw-r--r--django_authopenid/util.py135
-rw-r--r--django_authopenid/views.py1192
10 files changed, 0 insertions, 2033 deletions
diff --git a/django_authopenid/README b/django_authopenid/README
deleted file mode 100644
index 67c33d60..00000000
--- a/django_authopenid/README
+++ /dev/null
@@ -1,5 +0,0 @@
-this is a forked version of django-authopenid module
-specifically for askbot forum project.
-
-most likely it is not useful for anything else and
-in fact will be phased out in askbot as well
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 2fd3fd7f..00000000
--- a/django_authopenid/forms.py
+++ /dev/null
@@ -1,322 +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
-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 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']
diff --git a/django_authopenid/middleware.py b/django_authopenid/middleware.py
deleted file mode 100644
index 2be8da90..00000000
--- a/django_authopenid/middleware.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# -*- coding: utf-8 -*-
-from django_authopenid import mimeparse
-from django.http import HttpResponseRedirect
-from django.core.urlresolvers import reverse
-from django.conf import settings
-import logging
-
-__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)
- logging.debug('openid in session is: %s' % str(request.openid))
-
- 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':
- logging.debug('redirecting to yadis_xrdf:%s' % reverse('yadis_xrdf'))
- return HttpResponseRedirect(reverse('yadis_xrdf'))
- return response
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 a12c2fec..00000000
--- a/django_authopenid/models.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# -*- coding: utf-8 -*-
-from django.conf import settings
-from django.contrib.auth.models import User
-from django.db import models
-
-import hashlib, 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 = hashlib.md5("%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
-
-class ExternalLoginData(models.Model):
- """this class was added by Evgeny to associate
- external authentication user with django user
- probably it just does not belong here... (EF)
- """
- external_username = models.CharField(max_length=40, unique=True, null=False)
- external_session_data = models.TextField()
- user = models.ForeignKey(User, null=True)
diff --git a/django_authopenid/urls.py b/django_authopenid/urls.py
deleted file mode 100644
index 65afc45a..00000000
--- a/django_authopenid/urls.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# -*- coding: utf-8 -*-
-from django.conf.urls.defaults import patterns, url
-from django.utils.translation import ugettext as _
-from django.conf import settings
-
-#print 'stuff to import %s' % settings.EXTERNAL_LOGIN_APP.__name__ + '.views'
-#try:
-# settings.EXTERNAL_LOGIN_APP = __import__('mediawiki.views')
-#print 'stuff to import %s' % settings.EXTERNAL_LOGIN_APP.__name__ + '.views'
-#try:
-# print 'imported fine'
-# print settings.EXTERNAL_LOGIN_APP.__dict__.keys()
-#except:
-# print 'dammit!'
-#from mediawiki.views import signup_view
-#settings.EXTERNAL_LOGIN_APP.views.signup_view()
-
-#print settings.EXTERNAL_LOGIN_APP.__dict__.keys()
-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%s$' % (_('signin/'),_('newquestion/')), 'signin', kwargs = {'newquestion':True}, name='user_signin_new_question'),
- url(r'^%s%s$' % (_('signin/'),_('newanswer/')), 'signin', kwargs = {'newanswer':True}, name='user_signin_new_answer'),
- 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/'), '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%s$' % (_('email/'),_('validate/')), 'changeemail', name='user_validateemail',kwargs = {'action':'validate'}),
- url(r'^%s%s$' % (_('email/'), _('change/')), 'changeemail', name='user_changeemail'),
- url(r'^%s%s$' % (_('email/'), _('sendkey/')), 'send_email_key', name='send_email_key'),
- url(r'^%s%s(?P<id>\d+)/(?P<key>[\dabcdef]{32})/$' % (_('email/'), _('verify/')), 'verifyemail', name='user_verifyemail'),
- url(r'^%s$' % _('openid/'), 'changeopenid', name='user_changeopenid'),
- url(r'^%s$' % _('delete/'), 'delete', name='user_delete'),
-)
-
-#todo move these out of this file completely
-if settings.USE_EXTERNAL_LEGACY_LOGIN:
- from forum.forms import NotARobotForm
- EXTERNAL_LOGIN_APP = settings.LOAD_EXTERNAL_LOGIN_APP()
- urlpatterns += patterns('',
- url('^%s$' % _('external-login/forgot-password/'),\
- 'django_authopenid.views.external_legacy_login_info', \
- name='user_external_legacy_login_issues'),
- url('^%s$' % _('external-login/signup/'), \
- EXTERNAL_LOGIN_APP.views.signup,\
- name='user_external_legacy_login_signup'),
-# url('^%s$' % _('external-login/signup/'), \
-# EXTERNAL_LOGIN_APP.forms.RegisterFormWizard( \
-# [EXTERNAL_LOGIN_APP.forms.RegisterForm, \
-# NotARobotForm]),\
-# name='user_external_legacy_login_signup'),
- )
diff --git a/django_authopenid/util.py b/django_authopenid/util.py
deleted file mode 100644
index cd2c2e2c..00000000
--- a/django_authopenid/util.py
+++ /dev/null
@@ -1,135 +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.core.urlresolvers import reverse
-
-# needed for some linux distributions like debian
-try:
- from openid.yadis import xri
-except:
- from yadis import xri
-
-import time, base64, hashlib, operator, logging
-from forum.utils.forms import clean_next, get_next_url
-
-from models import Association, Nonce
-
-__all__ = ['OpenID', 'DjangoOpenIDStore', 'from_openid_response', 'clean_next']
-
-class OpenID:
- def __init__(self, openid_, issued, attrs=None, sreg_=None):
- logging.debug('init janrain openid object')
- 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 hashlib.md5(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 cce4beb5..00000000
--- a/django_authopenid/views.py
+++ /dev/null
@@ -1,1192 +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, Http404, \
- HttpResponseServerError
-from django.shortcuts import render_to_response
-from django.template import RequestContext, loader, Context
-from django.conf import settings
-from forum.conf import settings as forum_settings
-from django.contrib.auth.models import User
-from django.contrib.auth.decorators import login_required
-from django.contrib.auth import authenticate
-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.utils.http import urlquote_plus
-from django.utils.safestring import mark_safe
-from django.core.mail import send_mail
-from django.views.defaults import server_error
-
-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 forum.forms import SimpleEmailSubscribeForm
-from django_authopenid.util import OpenID, DjangoOpenIDStore, from_openid_response
-from django_authopenid.models import UserAssociation, UserPasswordQueue, ExternalLoginData
-from django_authopenid.forms import OpenidSigninForm, ClassicLoginForm, OpenidRegisterForm, \
- OpenidVerifyForm, ClassicRegisterForm, ChangePasswordForm, ChangeEmailForm, \
- ChangeopenidForm, DeleteForm, EmailPasswordForm
-import logging
-from forum.utils.forms import get_next_url
-
-EXTERNAL_LOGIN_APP = settings.LOAD_EXTERNAL_LOGIN_APP()
-
-#todo: decouple from forum
-def login(request,user):
- from django.contrib.auth import login as _login
- from forum.models import signals
-
- if settings.USE_EXTERNAL_LEGACY_LOGIN == True:
- EXTERNAL_LOGIN_APP.api.login(request,user)
-
- #1) get old session key
- session_key = request.session.session_key
- #2) get old search state
- search_state = None
- if 'search_state' in request.session:
- search_state = request.session['search_state']
-
- #3) login and get new session key
- _login(request,user)
- #4) transfer search_state to new session if found
- if search_state:
- search_state.set_logged_in()
- request.session['search_state'] = search_state
- #5) send signal with old session key as argument
- logging.debug('logged in user %s with session key %s' % (user.username, session_key))
- #todo: move to auth app
- signals.user_logged_in.send(user=user,session_key=session_key,sender=None)
-
-#todo: uncouple this from forum
-def logout(request):
- from django.contrib.auth import logout as _logout#for login I've added wrapper below - called login
- if 'search_state' in request.session:
- request.session['search_state'].set_logged_out()
- request.session.modified = True
- _logout(request)
- if settings.USE_EXTERNAL_LEGACY_LOGIN == True:
- EXTERNAL_LOGIN_APP.api.logout(request)
-
-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")
- logging.debug('openid failed becaise 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 %(openid_url)s is invalid" % {'openid_url':openid_url})
- logging.debug(msg)
- return on_failure(request, msg)
-
- logging.debug('openid seemed to work')
- if sreg_request:
- logging.debug('adding sreg_request - wtf it is?')
- auth_request.addExtension(sreg_request)
- redirect_url = auth_request.redirectURL(trust_root, redirect_to)
- logging.debug('redirecting to %s' % redirect_url)
- 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
-
- logging.debug('in django_authopenid.complete')
-
- 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:
- logging.debug('SUCCESS')
- return on_success(request, openid_response.identity_url,
- openid_response)
- elif openid_response.status == CANCEL:
- logging.debug('CANCEL')
- return on_failure(request, 'The request was canceled')
- elif openid_response.status == FAILURE:
- logging.debug('FAILURE')
- return on_failure(request, openid_response.message)
- elif openid_response.status == SETUP_NEEDED:
- logging.debug('SETUP NEEDED')
- return on_failure(request, 'Setup needed')
- else:
- logging.debug('BAD OPENID STATUS')
- assert False, "Bad openid status: %s" % openid_response.status
-
-def default_on_success(request, identity_url, openid_response):
- """ default action on openid signin success """
- logging.debug('')
- request.session['openid'] = from_openid_response(openid_response)
- logging.debug('performing default action on openid success %s' % get_next_url(request))
- return HttpResponseRedirect(get_next_url(request))
-
-def default_on_failure(request, message):
- """ default failure action on signin """
- logging.debug('default openid failure action')
- return render_to_response('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():
- return HttpResponseRedirect(get_next_url(request))
- return func(request, *args, **kwargs)
- return decorated
-
-@not_authenticated
-def signin(request,newquestion=False,newanswer=False):
- """
- signin page. It manages the legacy authentification (user/password)
- and openid authentification
-
- url: /signin/
-
- template : authopenid/signin.htm
- """
- logging.debug('in signin view')
- request.encoding = 'UTF-8'
- on_failure = signin_failure
- email_feeds_form = SimpleEmailSubscribeForm()
- next = get_next_url(request)
- form_signin = OpenidSigninForm(initial={'next':next})
- form_auth = ClassicLoginForm(initial={'next':next})
-
- if request.method == 'POST':
- #'blogin' - password login
- if 'blogin' in request.POST.keys():
- logging.debug('processing classic login form submission')
- form_auth = ClassicLoginForm(request.POST)
- if form_auth.is_valid():
- #have login and password and need to login through external website
- if settings.USE_EXTERNAL_LEGACY_LOGIN == True:
- username = form_auth.cleaned_data['username']
- password = form_auth.cleaned_data['password']
- next = form_auth.cleaned_data['next']
- if form_auth.get_user() == None:
- #need to create internal user
-
- #1) save login and password temporarily in session
- request.session['external_username'] = username
- request.session['external_password'] = password
-
- #2) try to extract user email and nickname from external service
- email = EXTERNAL_LOGIN_APP.api.get_email(username,password)
- screen_name = EXTERNAL_LOGIN_APP.api.get_screen_name(username,password)
-
- #3) see if username clashes with some existing user
- #if so, we have to prompt the user to pick a different name
- username_taken = User.is_username_taken(screen_name)
-
- email_feeds_form = SimpleEmailSubscribeForm()
- form_data = {'username':screen_name,'email':email,'next':next}
- form = OpenidRegisterForm(initial=form_data)
- template_data = {'form1':form,'username':screen_name,\
- 'email_feeds_form':email_feeds_form,\
- 'provider':mark_safe(settings.EXTERNAL_LEGACY_LOGIN_PROVIDER_NAME),\
- 'login_type':'legacy',\
- 'gravatar_faq_url':reverse('faq') + '#gravatar',\
- 'external_login_name_is_taken':username_taken}
- return render_to_response('authopenid/complete.html',template_data,\
- context_instance=RequestContext(request))
- else:
- #user existed, external password is ok
- user = form_auth.get_user()
- login(request,user)
- response = HttpResponseRedirect(get_next_url(request))
- EXTERNAL_LOGIN_APP.api.set_login_cookies(response,user)
- return response
- else:
- #regular password authentication
- user = form_auth.get_user()
- login(request, user)
- return HttpResponseRedirect(get_next_url(request))
-
- elif 'bnewaccount' in request.POST.keys():
- logging.debug('processing classic (login/password) create account form submission')
- #register externally logged in password user with a new local account
- if settings.USE_EXTERNAL_LEGACY_LOGIN == True:
- form = OpenidRegisterForm(request.POST)
- email_feeds_form = SimpleEmailSubscribeForm(request.POST)
- form1_is_valid = form.is_valid()
- form2_is_valid = email_feeds_form.is_valid()
- if form1_is_valid and form2_is_valid:
- #create the user
- username = form.cleaned_data['username']
- password = request.session.get('external_password',None)
- email = form.cleaned_data['email']
- if password and username:
- User.objects.create_user(username,email,password)
- user = authenticate(username=username,password=password)
- EXTERNAL_LOGIN_APP.api.connect_local_user_to_external_user(user,username,password)
- external_username = request.session['external_username']
- eld = ExternalLoginData.objects.get(external_username=external_username)
- eld.user = user
- eld.save()
- login(request,user)
- email_feeds_form.save(user)
- del request.session['external_username']
- del request.session['external_password']
- response = HttpResponseRedirect(reverse('index'))
- EXTERNAL_LOGIN_APP.api.set_login_cookies(response, user)
- return response
- else:
- if password:
- del request.session['external_username']
- if username:
- del request.session['external_password']
- return HttpResponseServerError()
- else:
- username = request.POST.get('username',None)
- provider = mark_safe(settings.EXTERNAL_LEGACY_LOGIN_PROVIDER_NAME)
- username_taken = User.is_username_taken(username)
- data = {'login_type':'legacy','form1':form,'username':username,\
- 'email_feeds_form':email_feeds_form,'provider':provider,\
- 'gravatar_faq_url':reverse('faq') + '#gravatar',\
- 'external_login_name_is_taken':username_taken}
- return render_to_response('authopenid/complete.html',data,
- context_instance=RequestContext(request))
- else:
- raise Http404
-
- elif 'bsignin' in request.POST.keys() or 'openid_username' in request.POST.keys():
- logging.debug('processing signin with openid submission')
- form_signin = OpenidSigninForm(request.POST)
- if form_signin.is_valid():
- logging.debug('OpenidSigninForm is valid')
- next = form_signin.cleaned_data['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)
- else:
- logging.debug('OpenidSigninForm is NOT valid! -> redisplay login view')
-
- #if request is GET
- if request.method == 'GET':
- logging.debug('request method was GET')
- question = None
- if newquestion == True:
- from forum.models import AnonymousQuestion as AQ
- session_key = request.session.session_key
- logging.debug('retrieving anonymously posted question associated with session %s' % session_key)
- qlist = AQ.objects.filter(session_key=session_key).order_by('-added_at')
- if len(qlist) > 0:
- question = qlist[0]
- answer = None
- if newanswer == True:
- from forum.models import AnonymousAnswer as AA
- session_key = request.session.session_key
- logging.debug('retrieving posted answer associated with session %s' % session_key)
- alist = AA.objects.filter(session_key=session_key).order_by('-added_at')
- if len(alist) > 0:
- answer = alist[0]
-
- logging.debug('showing signin view')
- return render_to_response('authopenid/signin.html', {
- 'question':question,
- 'answer':answer,
- 'form1': form_auth,
- 'form2': form_signin,
- 'msg': request.GET.get('msg',''),
- 'sendpw_url': reverse('user_sendpw'),
- 'fb_api_key': forum_settings.FB_API_KEY,
- }, context_instance=RequestContext(request))
-
-def complete_signin(request):
- """ in case of complete signin with openid """
- logging.debug('')#blank log just for the trace
- 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.
- """
-
- logging.debug('')
- openid_ = from_openid_response(openid_response) #create janrain OpenID object
- request.session['openid'] = openid_
- try:
- logging.debug('trying to get user associated with this openid...')
- rel = UserAssociation.objects.get(openid_url__exact = str(openid_))
- logging.debug('success')
- except:
- logging.debug('failed --> try to register brand new user')
- # try to register this new user
- return register(request)
- user_ = rel.user
- if user_.is_active:
- user_.backend = "django.contrib.auth.backends.ModelBackend"
- logging.debug('user is active --> attached django auth ModelBackend --> calling login')
- login(request, user_)
- logging.debug('success')
- else:
- logging.debug('user is inactive, do not log them in')
- logging.debug('redirecting to %s' % get_next_url(request))
- return HttpResponseRedirect(get_next_url(request))
-
-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
- logging.debug(str(is_exist))
- 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
- """
-
- logging.debug('')
- openid_ = request.session.get('openid', None)
- next = get_next_url(request)
- if not openid_:
- logging.debug('oops, no openid in session --> go back to signin')
- return HttpResponseRedirect(reverse('user_signin') + '?next=%s' % 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,
- })
- email_feeds_form = SimpleEmailSubscribeForm()
-
- user_ = None
- is_redirect = False
- logging.debug('request method is %s' % request.method)
- if request.method == 'POST':
- if 'bnewaccount' in request.POST.keys():
- logging.debug('trying to create new account associated with openid')
- form1 = OpenidRegisterForm(request.POST)
- email_feeds_form = SimpleEmailSubscribeForm(request.POST)
- if not form1.is_valid():
- logging.debug('OpenidRegisterForm is INVALID')
- elif not email_feeds_form.is_valid():
- logging.debug('SimpleEmailSubscribeForm is INVALID')
- else:
- logging.debug('OpenidRegisterForm and SimpleEmailSubscribeForm are valid')
- next = form1.cleaned_data['next']
- is_redirect = True
- logging.debug('creatng new django user %s ...' % form1.cleaned_data['username'])
- tmp_pwd = User.objects.make_random_password()
- user_ = User.objects.create_user(form1.cleaned_data['username'],
- form1.cleaned_data['email'], tmp_pwd)
-
- user_.set_unusable_password()
- # make association with openid
- logging.debug('creating new openid user association %s <--> %s' \
- % (user_.username, str(openid_)))
- uassoc = UserAssociation(openid_url=str(openid_), user_id=user_.id)
- uassoc.save()
-
- # login
- user_.backend = "django.contrib.auth.backends.ModelBackend"
- logging.debug('logging the user in')
- login(request, user_)
- logging.debug('saving email feed settings')
- email_feeds_form.save(user_)
- elif 'bverify' in request.POST.keys():
- logging.debug('processing OpenidVerify form')
- form2 = OpenidVerifyForm(request.POST)
- if form2.is_valid():
- logging.debug('form is valid')
- is_redirect = True
- next = form2.cleaned_data['next']
- user_ = form2.get_user()
- logging.debug('creating new openid user association %s <--> %s' \
- % (user_.username, str(openid_)))
- uassoc = UserAssociation(openid_url=str(openid_),
- user_id=user_.id)
- uassoc.save()
- logging.debug('logging the user in')
- login(request, user_)
-
- #check if we need to post a question that was added anonymously
- #this needs to be a function call becase this is also done
- #if user just logged in and did not need to create the new account
-
- if user_ != None:
- if forum_settings.EMAIL_VALIDATION == True:
- logging.debug('sending email validation')
- send_new_email_key(user_,nomessage=True)
- output = validation_email_sent(request)
- set_email_validation_message(user_) #message set after generating view
- return output
- if user_.is_authenticated():
- logging.debug('success, send user to main page')
- return HttpResponseRedirect(reverse('index'))
- else:
- logging.debug('have really strange error')
- raise Exception('openid login failed')#should not ever get here
-
- openid_str = str(openid_)
- bits = openid_str.split('/')
- base_url = bits[2] #assume this is base url
- url_bits = base_url.split('.')
- provider_name = url_bits[-2].lower()
-
- providers = {'yahoo':'<font color="purple">Yahoo!</font>',
- 'flickr':'<font color="#0063dc">flick</font><font color="#ff0084">r</font>&trade;',
- 'google':'Google&trade;',
- 'aol':'<font color="#31658e">AOL</font>',
- 'myopenid':'MyOpenID',
- }
- if provider_name not in providers:
- provider_logo = provider_name
- logging.error('openid provider named "%s" has no pretty customized logo' % provider_name)
- else:
- provider_logo = providers[provider_name]
-
- logging.debug('printing authopenid/complete.html output')
- return render_to_response('authopenid/complete.html', {
- 'form1': form1,
- 'form2': form2,
- 'email_feeds_form': email_feeds_form,
- 'provider':mark_safe(provider_logo),
- 'username': nickname,
- 'email': email,
- 'login_type':'openid',
- 'gravatar_faq_url':reverse('faq') + '#gravatar',
- }, context_instance=RequestContext(request))
-
-def signin_failure(request, message):
- """
- falure with openid signin. Go back to signin page.
-
- template : "authopenid/signin.html"
- """
- logging.debug('')
- next = get_next_url(request)
- form_signin = OpenidSigninForm(initial={'next': next})
- form_auth = ClassicLoginForm(initial={'next': next})
-
- return render_to_response('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
- """
- logging.debug('')
- if settings.USE_EXTERNAL_LEGACY_LOGIN == True:
- logging.debug('handling external legacy login registration')
- return HttpResponseRedirect(reverse('user_external_legacy_login_signup'))
- next = get_next_url(request)
- logging.debug('request method was %s' % request.method)
- if request.method == 'POST':
- form = ClassicRegisterForm(request.POST)
- email_feeds_form = SimpleEmailSubscribeForm(request.POST)
-
- #validation outside if to remember form values
- logging.debug('validating classic register form')
- form1_is_valid = form.is_valid()
- logging.debug('classic register form validated')
- form2_is_valid = email_feeds_form.is_valid()
- logging.debug('email feeds form validated')
- if form1_is_valid and form2_is_valid:
- logging.debug('both forms are valid')
- next = form.cleaned_data['next']
- username = form.cleaned_data['username']
- password = form.cleaned_data['password1']
- email = form.cleaned_data['email']
-
- user_ = User.objects.create_user( username,email,password )
- logging.debug('new user %s created' % username)
- if settings.USE_EXTERNAL_LEGACY_LOGIN == True:
- EXTERNAL_LOGIN_APP.api.create_user(username,email,password)
-
- user_.backend = "django.contrib.auth.backends.ModelBackend"
- login(request, user_)
- logging.debug('new user logged in')
- email_feeds_form.save(user_)
- logging.debug('email feeds form saved')
-
- # send email
- subject = _("Welcome email subject line")
- message_template = loader.get_template(
- 'authopenid/confirm_email.txt'
- )
- message_context = Context({
- 'signup_url': forum_settings.APP_URL + reverse('user_signin'),
- 'username': username,
- 'password': password,
- })
- message = message_template.render(message_context)
- send_mail(subject, message, settings.DEFAULT_FROM_EMAIL,
- [user_.email])
- logging.debug('new user with login and password created, confirmation email sent!')
- return HttpResponseRedirect(next)
- else:
- logging.debug('create classic account forms were invalid')
- else:
- form = ClassicRegisterForm(initial={'next':next})
- email_feeds_form = SimpleEmailSubscribeForm()
- logging.debug('printing legacy signup form')
- return render_to_response('authopenid/signup.html', {
- 'form': form,
- 'email_feeds_form': email_feeds_form
- }, context_instance=RequestContext(request))
- #what if request is not posted?
-
-@login_required
-def signout(request):
- """
- signout from the website. Remove openid from session and kill it.
-
- url : /signout/"
- """
- logging.debug('')
- try:
- logging.debug('deleting openid session var')
- del request.session['openid']
- except KeyError:
- logging.debug('failed')
- pass
- logout(request)
- logging.debug('user logged out')
- return HttpResponseRedirect(get_next_url(request))
-
-def xrdf(request):
- url_host = get_url_host(request)
- logging.debug('what does this do??')
- return_to = [
- "%s%s" % (url_host, reverse('user_complete_signin'))
- ]
- return render_to_response('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
- """
- logging.debug('')
- 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_to_response('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
- """
- logging.debug('')
- user_ = request.user
-
- if user_.has_usable_password():
- if settings.USE_EXTERNAL_LEGACY_LOGIN == True:
- return HttpResponseRedirect(reverse('user_external_legacy_login_issues'))
- else:
- raise Http404
-
- if request.POST:
- form = ChangePasswordForm(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 = ChangePasswordForm(user=user_)
-
- return render_to_response('authopenid/changepw.html', {'form': form },
- context_instance=RequestContext(request))
-
-def find_email_validation_messages(user):
- msg_text = _('your email needs to be validated see %(details_url)s') \
- % {'details_url':reverse('faq') + '#validate'}
- return user.message_set.filter(message__exact=msg_text)
-
-def set_email_validation_message(user):
- messages = find_email_validation_messages(user)
- msg_text = _('your email needs to be validated see %(details_url)s') \
- % {'details_url':reverse('faq') + '#validate'}
- if len(messages) == 0:
- user.message_set.create(message=msg_text)
-
-def clear_email_validation_message(user):
- messages = find_email_validation_messages(user)
- messages.delete()
-
-def set_new_email(user, new_email, nomessage=False):
- if new_email != user.email:
- user.email = new_email
- user.email_isvalid = False
- user.save()
- if forum_settings.EMAIL_VALIDATION == True:
- send_new_email_key(user,nomessage=nomessage)
-
-def _send_email_key(user):
- """private function. sends email containing validation key
- to user's email address
- """
- subject = _("Email verification subject line")
- message_template = loader.get_template('authopenid/email_validation.txt')
- import settings
- message_context = Context({
- 'validation_link': forum_settings.APP_URL + reverse('user_verifyemail', kwargs={'id':user.id,'key':user.email_key})
- })
- message = message_template.render(message_context)
- send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, [user.email])
-
-def send_new_email_key(user,nomessage=False):
- import random
- random.seed()
- user.email_key = '%032x' % random.getrandbits(128)
- user.save()
- _send_email_key(user)
- if nomessage==False:
- set_email_validation_message(user)
-
-@login_required
-def send_email_key(request):
- """
- url = /email/sendkey/
-
- view that is shown right after sending email key
- email sending is called internally
-
- raises 404 if email validation is off
- if current email is valid shows 'key_not_sent' view of
- authopenid/changeemail.html template
- """
-
- if forum_settings.EMAIL_VALIDATION == True:
- if request.user.email_isvalid:
- return render_to_response('authopenid/changeemail.html',
- { 'email': request.user.email,
- 'action_type': 'key_not_sent',
- 'change_link': reverse('user_changeemail')},
- context_instance=RequestContext(request)
- )
- else:
- send_new_email_key(request.user)
- return validation_email_sent(request)
- else:
- raise Http404
-
-
-#internal server view used as return value by other views
-def validation_email_sent(request):
- logging.debug('')
- return render_to_response('authopenid/changeemail.html',
- { 'email': request.user.email,
- 'change_email_url': reverse('user_changeemail'),
- 'action_type': 'validate', },
- context_instance=RequestContext(request))
-
-def verifyemail(request,id=None,key=None):
- """
- view that is shown when user clicks email validation link
- url = /email/verify/{{user.id}}/{{user.email_key}}/
- """
- logging.debug('')
- if forum.settings.EMAIL_VALIDATION == True:
- user = User.objects.get(id=id)
- if user:
- if user.email_key == key:
- user.email_isvalid = True
- clear_email_validation_message(user)
- user.save()
- return render_to_response('authopenid/changeemail.html', {
- 'action_type': 'validation_complete',
- }, context_instance=RequestContext(request))
- else:
- logging.error('hmm, no user found for email validation message - foul play?')
- raise Http404
-
-@login_required
-def changeemail(request, action='change'):
- """
- changeemail view. requires openid with request type GET
-
- url: /email/*
-
- template : authopenid/changeemail.html
- """
- logging.debug('')
- msg = request.GET.get('msg', None)
- extension_args = {}
- user_ = request.user
-
- if request.POST:
- if 'cancel' in request.POST:
- msg = _('your email was not changed')
- request.user.message_set.create(message=msg)
- return HttpResponseRedirect(get_next_url(request))
- form = ChangeEmailForm(request.POST, user=user_)
- if form.is_valid():
- new_email = form.cleaned_data['email']
- if new_email != user_.email:
- if forum_settings.EMAIL_VALIDATION == True:
- action = 'validate'
- else:
- action = 'done_novalidate'
- set_new_email(user_, new_email,nomessage=True)
- else:
- action = 'keep'
-
- elif not request.POST and 'openid.mode' in request.GET:
- redirect_to = get_url_host(request) + reverse('user_changeemail')
- return complete(request, emailopenid_success,
- emailopenid_failure, redirect_to)
- else:
- form = ChangeEmailForm(initial={'email': user_.email},
- user=user_)
-
- output = render_to_response('authopenid/changeemail.html', {
- 'form': form,
- 'email': user_.email,
- 'action_type': action,
- 'gravatar_faq_url': reverse('faq') + '#gravatar',
- 'change_email_url': reverse('user_changeemail'),
- 'msg': msg
- }, context_instance=RequestContext(request))
-
- if action == 'validate':
- set_email_validation_message(user_)
-
- return output
-
-def emailopenid_success(request, identity_url, openid_response):
- logging.debug('')
- 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):
- logging.debug('')
- 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
- """
- logging.error('change openid view - never tested it yet!!!')
-
- 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_to_response('authopenid/changeopenid.html', {
- 'form': form,
- 'has_openid': has_openid,
- 'msg': msg
- }, context_instance=RequestContext(request))
-
-def changeopenid_success(request, identity_url, openid_response):
- logging.error('never tested this worflow')
- 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):
- logging.error('never tested this workflow')
- 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
- """
- logging.error('deleting account - never tested this')
-
- 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_to_response('authopenid/delete.html', {
- 'form': form,
- 'msg': msg,
- }, context_instance=RequestContext(request))
-
-def deleteopenid_success(request, identity_url, openid_response):
- logging.error('never tested this')
- 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 = reverse('index') + u"/?msg=%s" % (urlquote_plus(msg))
- return HttpResponseRedirect(redirect)
-
-
-def deleteopenid_failure(request, message):
- logging.error('never tested this')
- redirect_to = "%s?msg=%s" % (reverse('user_delete'), urlquote_plus(message))
- return HttpResponseRedirect(redirect_to)
-
-def external_legacy_login_info(request):
- logging.debug('maybe this view does not belong in this library')
- feedback_url = reverse('feedback')
- return render_to_response('authopenid/external_legacy_login_info.html',
- {'feedback_url':feedback_url},
- context_instance=RequestContext(request))
-
-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
- """
- logging.debug('')
- if settings.USE_EXTERNAL_LEGACY_LOGIN == True:
- logging.debug('delegating to view dealing with external password recovery')
- return HttpResponseRedirect(reverse('user_external_legacy_login_issues'))
-
- msg = request.GET.get('msg','')
- logging.debug('request method is %s' % request.method)
- if request.method == 'POST':
- form = EmailPasswordForm(request.POST)
- if form.is_valid():
- logging.debug('EmailPasswordForm 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
- subject = _("Request for new password")
- message_template = loader.get_template(
- 'authopenid/sendpw_email.txt')
- key_link = forum_settings.APP_URL + reverse('user_confirmchangepw') + '?key=' + confirm_key
- logging.debug('emailing new password for %s' % form.user_cache.username)
- message_context = Context({
- 'site_url': forum_settings.APP_URL + reverse('index'),
- 'key_link': key_link,
- 'username': form.user_cache.username,
- 'password': new_pw,
- })
- message = message_template.render(message_context)
- send_mail(subject, message, settings.DEFAULT_FROM_EMAIL,
- [form.user_cache.email])
- msg = _("A new password and the activation link were sent to your email address.")
- else:
- form = EmailPasswordForm()
-
- logging.debug('showing reset password form')
- return render_to_response('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
-
- """
- logging.debug('')
- confirm_key = request.GET.get('key', '')
- if not confirm_key:
- logging.error('someone called confirm password without a key!')
- return HttpResponseRedirect(reverse('index'))
-
- try:
- uqueue = UserPasswordQueue.objects.get(
- confirm_key__exact=confirm_key
- )
- except:
- msg = _("Could not change password. Confirmation key '%s'\
- is not registered." % confirm_key)
- logging.error(msg)
- 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.")
- logging.error(msg)
- 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)
- logging.debug(msg)
- redirect = "%s?msg=%s" % (reverse('user_signin'),
- urlquote_plus(msg))
-
- return HttpResponseRedirect(redirect)