aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNatalia Bidart <>2015-04-24 10:41:19 -0300
committerRicardo Kirkner <ricardo.kirkner@canonical.com>2015-04-24 10:41:19 -0300
commit201c1f3a81ecd8fe3ebb3ba99d3b419fd9122f5f (patch)
tree9a25dc13517d8b37c6055402e61f6f4b2f477178
parent6f4e845e6dc74c75789d17bbdfda456a74cb9db3 (diff)
parent0f5894bc5afcc65d2c09c971b69247bc9660880d (diff)
- Migrated base code to support Django 1.4-1.8.
- General code and tests cleanup, fixed all the pep8 errors.
-rw-r--r--.bzrignore11
-rw-r--r--Makefile7
-rw-r--r--django_openid_auth/__init__.py1
-rw-r--r--django_openid_auth/admin.py56
-rw-r--r--django_openid_auth/auth.py48
-rw-r--r--django_openid_auth/exceptions.py15
-rw-r--r--django_openid_auth/forms.py16
-rw-r--r--django_openid_auth/management/commands/openid_cleanup.py2
-rw-r--r--django_openid_auth/migrations/0001_initial.py169
-rw-r--r--django_openid_auth/models.py9
-rw-r--r--django_openid_auth/signals.py2
-rw-r--r--django_openid_auth/south_migrations/0001_initial.py116
-rw-r--r--django_openid_auth/south_migrations/0002_add_perm_account_verified.py (renamed from django_openid_auth/migrations/0002_add_perm_account_verified.py)0
-rw-r--r--django_openid_auth/south_migrations/__init__.py0
-rw-r--r--django_openid_auth/store.py6
-rw-r--r--django_openid_auth/teams.py36
-rw-r--r--django_openid_auth/tests/__init__.py20
-rw-r--r--django_openid_auth/tests/helpers.py2
-rw-r--r--django_openid_auth/tests/test_admin.py54
-rw-r--r--django_openid_auth/tests/test_auth.py301
-rw-r--r--django_openid_auth/tests/test_models.py6
-rw-r--r--django_openid_auth/tests/test_settings.py49
-rw-r--r--django_openid_auth/tests/test_store.py7
-rw-r--r--django_openid_auth/tests/test_views.py1003
-rw-r--r--django_openid_auth/tests/urls.py8
-rw-r--r--django_openid_auth/urls.py7
-rw-r--r--django_openid_auth/views.py54
-rw-r--r--example_consumer/settings.py132
-rw-r--r--example_consumer/urls.py15
-rw-r--r--example_consumer/wsgi.py14
-rwxr-xr-xmanage.py (renamed from example_consumer/manage.py)2
-rw-r--r--setup.py2
-rw-r--r--tox.ini41
33 files changed, 1120 insertions, 1091 deletions
diff --git a/.bzrignore b/.bzrignore
index 963356d..c7bca8f 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -1,6 +1,5 @@
-./django
-./MANIFEST
-./build
-./dist
-./sqlite.db
-./.tox/
+MANIFEST
+build
+dist
+db.sqlite3
+.tox
diff --git a/Makefile b/Makefile
index d43e6cb..ca855c9 100644
--- a/Makefile
+++ b/Makefile
@@ -1,10 +1,9 @@
check:
- PYTHONPATH=$(shell pwd) python example_consumer/manage.py test \
- --verbosity=2 django_openid_auth
+ PYTHONPATH=$(shell pwd) python manage.py test --verbosity=2 django_openid_auth
run-example-consumer:
- PYTHONPATH=$(shell pwd) python example_consumer/manage.py syncdb
- PYTHONPATH=$(shell pwd) python example_consumer/manage.py runserver
+ PYTHONPATH=$(shell pwd) python manage.py syncdb --migrate
+ PYTHONPATH=$(shell pwd) python manage.py runserver
.PHONY: check run-example-consumer
diff --git a/django_openid_auth/__init__.py b/django_openid_auth/__init__.py
index b19fae1..ca9566c 100644
--- a/django_openid_auth/__init__.py
+++ b/django_openid_auth/__init__.py
@@ -26,4 +26,3 @@
# 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.
-
diff --git a/django_openid_auth/admin.py b/django_openid_auth/admin.py
index 23b191a..5fc1214 100644
--- a/django_openid_auth/admin.py
+++ b/django_openid_auth/admin.py
@@ -27,8 +27,15 @@
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
+from __future__ import unicode_literals
+
+from urllib import urlencode
+from urlparse import parse_qsl, urlparse
+
from django.conf import settings
from django.contrib import admin
+from django.http import HttpResponseRedirect
+from django_openid_auth import views
from django_openid_auth.models import Nonce, Association, UserOpenID
from django_openid_auth.store import DjangoOpenIDStore
@@ -69,22 +76,33 @@ class UserOpenIDAdmin(admin.ModelAdmin):
admin.site.register(UserOpenID, UserOpenIDAdmin)
-# Support for allowing openid authentication for /admin (django.contrib.admin)
-if getattr(settings, 'OPENID_USE_AS_ADMIN_LOGIN', False):
- from django.http import HttpResponseRedirect
- from django_openid_auth import views
-
- def _openid_login(self, request, error_message='', extra_context=None):
- if request.user.is_authenticated():
- if not request.user.is_staff:
- return views.default_render_failure(
- request, "User %s does not have admin access."
- % request.user.username)
- assert error_message, "Unknown Error: %s" % error_message
- else:
- # Redirect to openid login path,
- return HttpResponseRedirect(
- settings.LOGIN_URL + "?next=" + request.get_full_path())
-
- # Overide the standard admin login form.
- admin.sites.AdminSite.login = _openid_login
+# store a reference to the original admin login
+original_admin_login = admin.sites.AdminSite.login
+
+
+def _openid_login(instance, request, error_message='', extra_context=None):
+ # Support for allowing openid authentication for /admin
+ # (django.contrib.admin)
+ if not getattr(settings, 'OPENID_USE_AS_ADMIN_LOGIN', False):
+ return original_admin_login(
+ instance, request, extra_context=extra_context)
+
+ if not request.user.is_authenticated():
+ # Redirect to openid login path,
+ _, _, path, _, query, _ = urlparse(request.get_full_path())
+ qs = dict(parse_qsl(query))
+ qs.setdefault('next', path)
+ return HttpResponseRedirect(
+ settings.LOGIN_URL + "?" + urlencode(qs))
+
+ if not request.user.is_staff:
+ return views.default_render_failure(
+ request, "User %s does not have admin/staff access."
+ % request.user.username)
+
+ # No error message was supplied
+ assert error_message, "Unknown Error: %s" % error_message
+
+
+# Overide the standard admin login form.
+admin.sites.AdminSite.login = _openid_login
diff --git a/django_openid_auth/auth.py b/django_openid_auth/auth.py
index e846460..faf46b8 100644
--- a/django_openid_auth/auth.py
+++ b/django_openid_auth/auth.py
@@ -28,6 +28,8 @@
"""Glue between OpenID and django.contrib.auth."""
+from __future__ import unicode_literals
+
__metaclass__ = type
import re
@@ -93,8 +95,9 @@ class OpenIDBackend:
if getattr(settings, 'OPENID_PHYSICAL_MULTIFACTOR_REQUIRED', False):
pape_response = pape.Response.fromSuccessResponse(openid_response)
- if pape_response is None or \
- pape.AUTH_MULTI_FACTOR_PHYSICAL not in pape_response.auth_policies:
+ key = pape.AUTH_MULTI_FACTOR_PHYSICAL
+ if (pape_response is None or
+ key not in pape_response.auth_policies):
raise MissingPhysicalMultiFactor()
teams_response = teams.TeamsResponse.fromSuccessResponse(
@@ -165,7 +168,7 @@ class OpenIDBackend:
if len(split_names) == 2:
first_name, last_name = split_names
else:
- first_name = u''
+ first_name = ''
last_name = fullname
verification_scheme_map = getattr(
@@ -194,12 +197,13 @@ class OpenIDBackend:
if nickname is None or nickname == '':
raise MissingUsernameViolation()
- # If we don't have a nickname, and we're not being strict, use a default
+ # If we don't have a nickname, and we're not being strict, use a
+ # default
nickname = nickname or 'openiduser'
# See if we already have this nickname assigned to a username
try:
- user = User.objects.get(username__exact=nickname)
+ User.objects.get(username__exact=nickname)
except User.DoesNotExist:
# No conflict, we can use this nickname
return nickname
@@ -231,7 +235,6 @@ class OpenIDBackend:
# No user associated with this identity_url
pass
-
if getattr(settings, 'OPENID_STRICT_USERNAMES', False):
if User.objects.filter(username__exact=nickname).count() > 0:
raise DuplicateUsernameViolation(
@@ -248,7 +251,7 @@ class OpenIDBackend:
if i > 1:
username += str(i)
try:
- user = User.objects.get(username__exact=username)
+ User.objects.get(username__exact=username)
except User.DoesNotExist:
break
i += 1
@@ -266,12 +269,12 @@ class OpenIDBackend:
"An attribute required for logging in was not "
"returned ({0}).".format(required_attr))
- nickname = self._get_preferred_username(details['nickname'],
- details['email'])
+ nickname = self._get_preferred_username(
+ details['nickname'], details['email'])
email = details['email'] or ''
- username = self._get_available_username(nickname,
- openid_response.identity_url)
+ username = self._get_available_username(
+ nickname, openid_response.identity_url)
user = User.objects.create_user(username, email, password=None)
self.associate_openid(user, openid_response)
@@ -328,13 +331,16 @@ class OpenIDBackend:
user.save()
def get_teams_mapping(self):
- teams_mapping_auto = getattr(settings, 'OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO', False)
- teams_mapping_auto_blacklist = getattr(settings, 'OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO_BLACKLIST', [])
+ teams_mapping_auto = getattr(
+ settings, 'OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO', False)
+ teams_mapping_auto_blacklist = getattr(
+ settings, 'OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO_BLACKLIST', [])
teams_mapping = getattr(settings, 'OPENID_LAUNCHPAD_TEAMS_MAPPING', {})
if teams_mapping_auto:
- #ignore teams_mapping. use all django-groups
+ # ignore teams_mapping. use all django-groups
teams_mapping = dict()
- all_groups = Group.objects.exclude(name__in=teams_mapping_auto_blacklist)
+ all_groups = Group.objects.exclude(
+ name__in=teams_mapping_auto_blacklist)
for group in all_groups:
teams_mapping[group.name] = group.name
return teams_mapping
@@ -344,12 +350,12 @@ class OpenIDBackend:
if len(teams_mapping) == 0:
return
- current_groups = set(user.groups.filter(
- name__in=teams_mapping.values()))
- desired_groups = set(Group.objects.filter(
- name__in=[teams_mapping[lp_team]
- for lp_team in teams_response.is_member
- if lp_team in teams_mapping]))
+ mapping = [
+ teams_mapping[lp_team] for lp_team in teams_response.is_member
+ if lp_team in teams_mapping]
+ current_groups = set(
+ user.groups.filter(name__in=teams_mapping.values()))
+ desired_groups = set(Group.objects.filter(name__in=mapping))
for group in current_groups - desired_groups:
user.groups.remove(group)
for group in desired_groups - current_groups:
diff --git a/django_openid_auth/exceptions.py b/django_openid_auth/exceptions.py
index 60da2dd..23eb560 100644
--- a/django_openid_auth/exceptions.py
+++ b/django_openid_auth/exceptions.py
@@ -28,20 +28,27 @@
"""Exception classes thrown by OpenID Authentication and Validation."""
+from __future__ import unicode_literals
+
+
class DjangoOpenIDException(Exception):
pass
+
class RequiredAttributeNotReturned(DjangoOpenIDException):
pass
+
class IdentityAlreadyClaimed(DjangoOpenIDException):
def __init__(self, message=None):
if message is None:
- self.message = "Another user already exists for your selected OpenID"
+ self.message = (
+ "Another user already exists for your selected OpenID")
else:
self.message = message
+
class DuplicateUsernameViolation(DjangoOpenIDException):
def __init__(self, message=None):
@@ -50,6 +57,7 @@ class DuplicateUsernameViolation(DjangoOpenIDException):
else:
self.message = message
+
class MissingUsernameViolation(DjangoOpenIDException):
def __init__(self, message=None):
@@ -58,11 +66,12 @@ class MissingUsernameViolation(DjangoOpenIDException):
else:
self.message = message
+
class MissingPhysicalMultiFactor(DjangoOpenIDException):
def __init__(self, message=None):
if message is None:
- self.message = "Login requires physical multi-factor authentication."
+ self.message = (
+ "Login requires physical multi-factor authentication.")
else:
self.message = message
-
diff --git a/django_openid_auth/forms.py b/django_openid_auth/forms.py
index 7a2538f..88bbc50 100644
--- a/django_openid_auth/forms.py
+++ b/django_openid_auth/forms.py
@@ -27,6 +27,8 @@
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
+from __future__ import unicode_literals
+
from django import forms
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import UserChangeForm
@@ -49,6 +51,7 @@ def teams_new_unicode(self):
return "%s -> %s" % (name, ", ".join(group_teams))
else:
return name
+
Group.unicode_before_teams = Group.__unicode__
Group.__unicode__ = teams_new_unicode
@@ -64,9 +67,11 @@ class UserChangeFormWithTeamRestriction(UserChangeForm):
user_groups = self.instance.groups.all()
for group in data:
if group.name in known_teams and group not in user_groups:
- raise forms.ValidationError("""The group %s is mapped to an
- external team. You cannot assign it manually.""" % group.name)
+ raise forms.ValidationError(
+ "The group %s is mapped to an external team. "
+ "You cannot assign it manually." % group.name)
return data
+
UserAdmin.form = UserChangeFormWithTeamRestriction
@@ -78,10 +83,7 @@ class OpenIDLoginForm(forms.Form):
def clean_openid_identifier(self):
if 'openid_identifier' in self.cleaned_data:
openid_identifier = self.cleaned_data['openid_identifier']
- if xri.identifierScheme(openid_identifier) == 'XRI' and getattr(
- settings, 'OPENID_DISALLOW_INAMES', False
- ):
+ if (xri.identifierScheme(openid_identifier) == 'XRI' and
+ getattr(settings, 'OPENID_DISALLOW_INAMES', False)):
raise forms.ValidationError(_('i-names are not supported'))
return self.cleaned_data['openid_identifier']
-
-
diff --git a/django_openid_auth/management/commands/openid_cleanup.py b/django_openid_auth/management/commands/openid_cleanup.py
index a5d3304..c2f779f 100644
--- a/django_openid_auth/management/commands/openid_cleanup.py
+++ b/django_openid_auth/management/commands/openid_cleanup.py
@@ -26,6 +26,8 @@
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
+from __future__ import unicode_literals
+
from django.core.management.base import NoArgsCommand
from django_openid_auth.store import DjangoOpenIDStore
diff --git a/django_openid_auth/migrations/0001_initial.py b/django_openid_auth/migrations/0001_initial.py
index f2035f3..c8bb23c 100644
--- a/django_openid_auth/migrations/0001_initial.py
+++ b/django_openid_auth/migrations/0001_initial.py
@@ -1,116 +1,55 @@
# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
- def forwards(self, orm):
- # Adding model 'Nonce'
- db.create_table(u'django_openid_auth_nonce', (
- (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
- ('server_url', self.gf('django.db.models.fields.CharField')(max_length=2047)),
- ('timestamp', self.gf('django.db.models.fields.IntegerField')()),
- ('salt', self.gf('django.db.models.fields.CharField')(max_length=40)),
- ))
- db.send_create_signal(u'django_openid_auth', ['Nonce'])
-
- # Adding model 'Association'
- db.create_table(u'django_openid_auth_association', (
- (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
- ('server_url', self.gf('django.db.models.fields.TextField')(max_length=2047)),
- ('handle', self.gf('django.db.models.fields.CharField')(max_length=255)),
- ('secret', self.gf('django.db.models.fields.TextField')(max_length=255)),
- ('issued', self.gf('django.db.models.fields.IntegerField')()),
- ('lifetime', self.gf('django.db.models.fields.IntegerField')()),
- ('assoc_type', self.gf('django.db.models.fields.TextField')(max_length=64)),
- ))
- db.send_create_signal(u'django_openid_auth', ['Association'])
-
- # Adding model 'UserOpenID'
- db.create_table(u'django_openid_auth_useropenid', (
- (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
- ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
- ('claimed_id', self.gf('django.db.models.fields.TextField')(unique=True, max_length=2047)),
- ('display_id', self.gf('django.db.models.fields.TextField')(max_length=2047)),
- ))
- db.send_create_signal(u'django_openid_auth', ['UserOpenID'])
-
-
- def backwards(self, orm):
- # Deleting model 'Nonce'
- db.delete_table(u'django_openid_auth_nonce')
-
- # Deleting model 'Association'
- db.delete_table(u'django_openid_auth_association')
-
- # Deleting model 'UserOpenID'
- db.delete_table(u'django_openid_auth_useropenid')
-
-
- models = {
- u'auth.group': {
- 'Meta': {'object_name': 'Group'},
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
- 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
- },
- u'auth.permission': {
- 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
- 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
- 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
- },
- u'auth.user': {
- 'Meta': {'object_name': 'User'},
- 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
- 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
- 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
- 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
- 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
- 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
- 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
- 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
- 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
- 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
- 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
- },
- u'contenttypes.contenttype': {
- 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
- 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
- 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
- },
- u'django_openid_auth.association': {
- 'Meta': {'object_name': 'Association'},
- 'assoc_type': ('django.db.models.fields.TextField', [], {'max_length': '64'}),
- 'handle': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'issued': ('django.db.models.fields.IntegerField', [], {}),
- 'lifetime': ('django.db.models.fields.IntegerField', [], {}),
- 'secret': ('django.db.models.fields.TextField', [], {'max_length': '255'}),
- 'server_url': ('django.db.models.fields.TextField', [], {'max_length': '2047'})
- },
- u'django_openid_auth.nonce': {
- 'Meta': {'object_name': 'Nonce'},
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'salt': ('django.db.models.fields.CharField', [], {'max_length': '40'}),
- 'server_url': ('django.db.models.fields.CharField', [], {'max_length': '2047'}),
- 'timestamp': ('django.db.models.fields.IntegerField', [], {})
- },
- u'django_openid_auth.useropenid': {
- 'Meta': {'object_name': 'UserOpenID'},
- 'claimed_id': ('django.db.models.fields.TextField', [], {'unique': 'True', 'max_length': '2047'}),
- 'display_id': ('django.db.models.fields.TextField', [], {'max_length': '2047'}),
- u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
- 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"})
- }
- }
-
- complete_apps = ['django_openid_auth'] \ No newline at end of file
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+from django.conf import settings
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Association',
+ fields=[
+ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+ ('server_url', models.TextField(max_length=2047)),
+ ('handle', models.CharField(max_length=255)),
+ ('secret', models.TextField(max_length=255)),
+ ('issued', models.IntegerField()),
+ ('lifetime', models.IntegerField()),
+ ('assoc_type', models.TextField(max_length=64)),
+ ],
+ options={
+ },
+ bases=(models.Model,),
+ ),
+ migrations.CreateModel(
+ name='Nonce',
+ fields=[
+ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+ ('server_url', models.CharField(max_length=2047)),
+ ('timestamp', models.IntegerField()),
+ ('salt', models.CharField(max_length=40)),
+ ],
+ options={
+ },
+ bases=(models.Model,),
+ ),
+ migrations.CreateModel(
+ name='UserOpenID',
+ fields=[
+ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+ ('claimed_id', models.TextField(unique=True, max_length=2047)),
+ ('display_id', models.TextField(max_length=2047)),
+ ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
+ ],
+ options={
+ 'permissions': (('account_verified', 'The OpenID has been verified'),),
+ },
+ bases=(models.Model,),
+ ),
+ ]
diff --git a/django_openid_auth/models.py b/django_openid_auth/models.py
index 1e82668..083d8bc 100644
--- a/django_openid_auth/models.py
+++ b/django_openid_auth/models.py
@@ -27,11 +27,10 @@
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
-from django.contrib.auth.models import (
- Permission,
- User,
-)
+from __future__ import unicode_literals
+
from django.db import models
+from django.contrib.auth.models import Permission, User
class Nonce(models.Model):
@@ -46,7 +45,7 @@ class Nonce(models.Model):
class Association(models.Model):
server_url = models.TextField(max_length=2047)
handle = models.CharField(max_length=255)
- secret = models.TextField(max_length=255) # Stored base64 encoded
+ secret = models.TextField(max_length=255) # Stored base64 encoded
issued = models.IntegerField()
lifetime = models.IntegerField()
assoc_type = models.TextField(max_length=64)
diff --git a/django_openid_auth/signals.py b/django_openid_auth/signals.py
index 6f3a74b..e3b3d1d 100644
--- a/django_openid_auth/signals.py
+++ b/django_openid_auth/signals.py
@@ -27,6 +27,8 @@
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
+from __future__ import unicode_literals
+
import django.dispatch
diff --git a/django_openid_auth/south_migrations/0001_initial.py b/django_openid_auth/south_migrations/0001_initial.py
new file mode 100644
index 0000000..f2035f3
--- /dev/null
+++ b/django_openid_auth/south_migrations/0001_initial.py
@@ -0,0 +1,116 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+ # Adding model 'Nonce'
+ db.create_table(u'django_openid_auth_nonce', (
+ (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('server_url', self.gf('django.db.models.fields.CharField')(max_length=2047)),
+ ('timestamp', self.gf('django.db.models.fields.IntegerField')()),
+ ('salt', self.gf('django.db.models.fields.CharField')(max_length=40)),
+ ))
+ db.send_create_signal(u'django_openid_auth', ['Nonce'])
+
+ # Adding model 'Association'
+ db.create_table(u'django_openid_auth_association', (
+ (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('server_url', self.gf('django.db.models.fields.TextField')(max_length=2047)),
+ ('handle', self.gf('django.db.models.fields.CharField')(max_length=255)),
+ ('secret', self.gf('django.db.models.fields.TextField')(max_length=255)),
+ ('issued', self.gf('django.db.models.fields.IntegerField')()),
+ ('lifetime', self.gf('django.db.models.fields.IntegerField')()),
+ ('assoc_type', self.gf('django.db.models.fields.TextField')(max_length=64)),
+ ))
+ db.send_create_signal(u'django_openid_auth', ['Association'])
+
+ # Adding model 'UserOpenID'
+ db.create_table(u'django_openid_auth_useropenid', (
+ (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
+ ('claimed_id', self.gf('django.db.models.fields.TextField')(unique=True, max_length=2047)),
+ ('display_id', self.gf('django.db.models.fields.TextField')(max_length=2047)),
+ ))
+ db.send_create_signal(u'django_openid_auth', ['UserOpenID'])
+
+
+ def backwards(self, orm):
+ # Deleting model 'Nonce'
+ db.delete_table(u'django_openid_auth_nonce')
+
+ # Deleting model 'Association'
+ db.delete_table(u'django_openid_auth_association')
+
+ # Deleting model 'UserOpenID'
+ db.delete_table(u'django_openid_auth_useropenid')
+
+
+ models = {
+ u'auth.group': {
+ 'Meta': {'object_name': 'Group'},
+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+ 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+ },
+ u'auth.permission': {
+ 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
+ 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+ },
+ u'auth.user': {
+ 'Meta': {'object_name': 'User'},
+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+ 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+ },
+ u'contenttypes.contenttype': {
+ 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+ 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+ },
+ u'django_openid_auth.association': {
+ 'Meta': {'object_name': 'Association'},
+ 'assoc_type': ('django.db.models.fields.TextField', [], {'max_length': '64'}),
+ 'handle': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'issued': ('django.db.models.fields.IntegerField', [], {}),
+ 'lifetime': ('django.db.models.fields.IntegerField', [], {}),
+ 'secret': ('django.db.models.fields.TextField', [], {'max_length': '255'}),
+ 'server_url': ('django.db.models.fields.TextField', [], {'max_length': '2047'})
+ },
+ u'django_openid_auth.nonce': {
+ 'Meta': {'object_name': 'Nonce'},
+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'salt': ('django.db.models.fields.CharField', [], {'max_length': '40'}),
+ 'server_url': ('django.db.models.fields.CharField', [], {'max_length': '2047'}),
+ 'timestamp': ('django.db.models.fields.IntegerField', [], {})
+ },
+ u'django_openid_auth.useropenid': {
+ 'Meta': {'object_name': 'UserOpenID'},
+ 'claimed_id': ('django.db.models.fields.TextField', [], {'unique': 'True', 'max_length': '2047'}),
+ 'display_id': ('django.db.models.fields.TextField', [], {'max_length': '2047'}),
+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"})
+ }
+ }
+
+ complete_apps = ['django_openid_auth'] \ No newline at end of file
diff --git a/django_openid_auth/migrations/0002_add_perm_account_verified.py b/django_openid_auth/south_migrations/0002_add_perm_account_verified.py
index 335794f..335794f 100644
--- a/django_openid_auth/migrations/0002_add_perm_account_verified.py
+++ b/django_openid_auth/south_migrations/0002_add_perm_account_verified.py
diff --git a/django_openid_auth/south_migrations/__init__.py b/django_openid_auth/south_migrations/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/django_openid_auth/south_migrations/__init__.py
diff --git a/django_openid_auth/store.py b/django_openid_auth/store.py
index b804c6f..3c1c3e8 100644
--- a/django_openid_auth/store.py
+++ b/django_openid_auth/store.py
@@ -27,6 +27,8 @@
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
+from __future__ import unicode_literals
+
import base64
import time
@@ -38,8 +40,10 @@ from django_openid_auth.models import Association, Nonce
class DjangoOpenIDStore(OpenIDStore):
+
def __init__(self):
- self.max_nonce_age = 6 * 60 * 60 # Six hours
+ super(DjangoOpenIDStore, self).__init__()
+ self.max_nonce_age = 6 * 60 * 60 # Six hours
def storeAssociation(self, server_url, association):
try:
diff --git a/django_openid_auth/teams.py b/django_openid_auth/teams.py
index a11a4f1..ed84fe3 100644
--- a/django_openid_auth/teams.py
+++ b/django_openid_auth/teams.py
@@ -64,31 +64,30 @@ will be provided:
@since: 2.1.1
"""
-from openid.message import registerNamespaceAlias, \
- NamespaceAliasRegistrationError
-from openid.extension import Extension
-from openid import oidutil
+from __future__ import unicode_literals
-try:
- basestring #pylint:disable-msg=W0104
-except NameError:
- # For Python 2.2
- basestring = (str, unicode) #pylint:disable-msg=W0622
+from openid import oidutil
+from openid.extension import Extension
+from openid.message import (
+ registerNamespaceAlias,
+ NamespaceAliasRegistrationError,
+)
__all__ = [
'TeamsRequest',
'TeamsResponse',
'ns_uri',
'supportsTeams',
- ]
+]
ns_uri = 'http://ns.launchpad.net/2007/openid-teams'
try:
registerNamespaceAlias(ns_uri, 'lp')
except NamespaceAliasRegistrationError, e:
- oidutil.log('registerNamespaceAlias(%r, %r) failed: %s' % (ns_uri,
- 'lp', str(e),))
+ oidutil.log(
+ 'registerNamespaceAlias(%r, %r) failed: %s' % (ns_uri, 'lp', str(e)))
+
def supportsTeams(endpoint):
"""Does the given endpoint advertise support for Launchpad Teams?
@@ -101,6 +100,7 @@ def supportsTeams(endpoint):
"""
return endpoint.usesExtension(ns_uri)
+
class TeamsNamespaceError(ValueError):
"""The Launchpad teams namespace was not found and could not
be created using the expected name (there's another extension
@@ -115,6 +115,7 @@ class TeamsNamespaceError(ValueError):
the message that is being processed.
"""
+
def getTeamsNS(message):
"""Extract the Launchpad teams namespace URI from the given
OpenID message.
@@ -145,7 +146,8 @@ def getTeamsNS(message):
# we know that ns_uri defined, because it's defined in the
# else clause of the loop as well, so disable the warning
- return ns_uri #pylint:disable-msg=W0631
+ return ns_uri
+
class TeamsRequest(Extension):
"""An object to hold the state of a Launchpad teams request.
@@ -154,7 +156,8 @@ class TeamsRequest(Extension):
names that the RP is interested in.
@type required: [str]
- @group Consumer: requestField, requestTeams, getExtensionArgs, addToOpenIDRequest
+ @group Consumer: requestField, requestTeams, getExtensionArgs,
+ addToOpenIDRequest
@group Server: fromOpenIDRequest, parseExtensionArgs
"""
@@ -308,6 +311,7 @@ class TeamsRequest(Extension):
return args
+
class TeamsResponse(Extension):
"""Represents the data returned in a Launchpad teams response
inside of an OpenID C{id_res} response. This object will be
@@ -394,7 +398,6 @@ class TeamsResponse(Extension):
if "is_member" in args:
is_member_str = args["is_member"]
self.is_member = is_member_str.split(',')
- #self.is_member = args["is_member"]
return self
@@ -406,6 +409,5 @@ class TeamsResponse(Extension):
@see: openid.extension
"""
- ns_args = {'is_member': ','.join(self.is_member),}
+ ns_args = {'is_member': ','.join(self.is_member)}
return ns_args
-
diff --git a/django_openid_auth/tests/__init__.py b/django_openid_auth/tests/__init__.py
index 70bcb36..771817e 100644
--- a/django_openid_auth/tests/__init__.py
+++ b/django_openid_auth/tests/__init__.py
@@ -26,18 +26,8 @@
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
-import unittest
-from test_views import *
-from test_settings import *
-from test_store import *
-from test_auth import *
-from test_admin import *
-
-
-def suite():
- suite = unittest.TestSuite()
- for name in ['test_auth', 'test_models', 'test_settings', 'test_store',
- 'test_views', 'test_admin']:
- mod = __import__('%s.%s' % (__name__, name), {}, {}, ['suite'])
- suite.addTest(mod.suite())
- return suite
+from .test_views import * # flake8: noqa
+from .test_settings import *
+from .test_store import *
+from .test_auth import *
+from .test_admin import *
diff --git a/django_openid_auth/tests/helpers.py b/django_openid_auth/tests/helpers.py
index b663c5b..f8fb0ae 100644
--- a/django_openid_auth/tests/helpers.py
+++ b/django_openid_auth/tests/helpers.py
@@ -1,3 +1,5 @@
+from __future__ import unicode_literals
+
from django.test.utils import override_settings
diff --git a/django_openid_auth/tests/test_admin.py b/django_openid_auth/tests/test_admin.py
index f233854..a659a31 100644
--- a/django_openid_auth/tests/test_admin.py
+++ b/django_openid_auth/tests/test_admin.py
@@ -25,35 +25,19 @@
# 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.
-"""
-Tests for the django_openid_auth Admin login form replacement.
-"""
-import unittest
+"""Tests for the django_openid_auth Admin login form replacement."""
-from django.conf import settings
-from django.contrib.auth.models import User, AnonymousUser
+from __future__ import unicode_literals
-settings.OPENID_USE_AS_ADMIN_LOGIN = True
+from django.conf import settings
+from django.contrib.auth.models import User
from django.test import TestCase
+from django.test.utils import override_settings
-def create_user(is_staff=False, authenticated=True):
- """
- Create and return a user, either the AnonymousUser or a normal Django user,
- setting the is_staff attribute if appropriate.
- """
- if not authenticated:
- return AnonymousUser()
- else:
- user = User(
- username=u'testing', email='testing@example.com',
- is_staff=is_staff)
- user.set_password(u'test')
- user.save()
-
-
+@override_settings(OPENID_USE_AS_ADMIN_LOGIN=True)
class SiteAdminTests(TestCase):
"""
TestCase for accessing /admin/ when the django_openid_auth form replacement
@@ -65,23 +49,21 @@ class SiteAdminTests(TestCase):
If the request has an authenticated user, who is not flagged as a
staff member, then they get a failure response.
"""
- create_user()
- self.client.login(username='testing', password='test')
- response = self.client.get('/admin/')
- self.assertTrue('User testing does not have admin access.' in
- response.content, 'Missing error message in response')
+ User.objects.create_user(
+ username='testing', email='testing@example.com', password='test')
+ assert self.client.login(username='testing', password='test')
+ response = self.client.get('/admin/', follow=True)
+ self.assertContains(
+ response,
+ 'User testing does not have admin/staff access.', status_code=403)
def test_admin_site_with_openid_login_non_authenticated_user(self):
"""
Unauthenticated users accessing the admin page should be directed to
the OpenID login url.
"""
- response = self.client.get('/admin/')
- self.assertEqual(302, response.status_code)
- self.assertEqual('http://testserver' + getattr(settings, 'LOGIN_URL',
- '/openid/login') + '?next=/admin/',
- response['Location'])
-
-
-def suite():
- return unittest.TestLoader().loadTestsFromName(__name__)
+ response = self.client.get('/admin/', follow=True)
+ self.assertRedirects(
+ response,
+ getattr(settings, 'LOGIN_URL', '/openid/login') +
+ '?next=%2Fadmin%2F')
diff --git a/django_openid_auth/tests/test_auth.py b/django_openid_auth/tests/test_auth.py
index ef70a7d..b37bedd 100644
--- a/django_openid_auth/tests/test_auth.py
+++ b/django_openid_auth/tests/test_auth.py
@@ -26,80 +26,41 @@
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
-import unittest
-
-from django.conf import settings
-from django.contrib.auth.models import (
- Group,
- Permission,
- User,
-)
+from __future__ import unicode_literals
+
+from django.contrib.auth.models import Group, Permission, User
from django.test import TestCase
+from django.test.utils import override_settings
-from django_openid_auth.auth import OpenIDBackend
-from django_openid_auth.models import UserOpenID
-from django_openid_auth.teams import ns_uri as TEAMS_NS
-from django_openid_auth.tests.helpers import override_session_serializer
from openid.consumer.consumer import SuccessResponse
from openid.consumer.discover import OpenIDServiceEndpoint
from openid.message import Message, OPENID2_NS
+from django_openid_auth.auth import OpenIDBackend
+from django_openid_auth.models import UserOpenID
+from django_openid_auth.teams import ns_uri as TEAMS_NS
+from django_openid_auth.tests.helpers import override_session_serializer
SREG_NS = "http://openid.net/sreg/1.0"
AX_NS = "http://openid.net/srv/ax/1.0"
@override_session_serializer
+@override_settings(
+ OPENID_USE_EMAIL_FOR_USERNAME=False,
+ OPENID_LAUNCHPAD_TEAMS_REQUIRED=[],
+ OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO=False,
+ OPENID_EMAIL_WHITELIST_REGEXP_LIST=[])
class OpenIDBackendTests(TestCase):
def setUp(self):
super(OpenIDBackendTests, self).setUp()
self.backend = OpenIDBackend()
- self.old_openid_use_email_for_username = getattr(settings,
- 'OPENID_USE_EMAIL_FOR_USERNAME', False)
- self.old_openid_launchpad_teams_required = getattr(settings,
- 'OPENID_LAUNCHPAD_TEAMS_REQUIRED', [])
- self.old_openid_launchpad_teams_mapping_auto = getattr(settings,
- 'OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO', False)
- self.old_openid_email_whitelist_regexp_list = getattr(settings,
- 'OPENID_EMAIL_WHITELIST_REGEXP_LIST', [])
-
- def tearDown(self):
- settings.OPENID_USE_EMAIL_FOR_USERNAME = \
- self.old_openid_use_email_for_username
- settings.OPENID_LAUNCHPAD_TEAMS_REQUIRED = (
- self.old_openid_launchpad_teams_required)
- settings.OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO = (
- self.old_openid_launchpad_teams_mapping_auto)
- settings.OPENID_EMAIL_WHITELIST_REGEXP_LIST = (
- self.old_openid_email_whitelist_regexp_list)
-
- def test_extract_user_details_sreg(self):
- expected = {
- 'nickname': 'someuser',
- 'first_name': 'Some',
- 'last_name': 'User',
- 'email': 'foo@example.com',
- 'account_verified': False,
- }
- data = {
- 'nickname': expected['nickname'],
- 'fullname': "%s %s" % (expected['first_name'],
- expected['last_name']),
- 'email': expected['email'],
- }
- response = self.make_response_sreg(**data)
-
- details = self.backend._extract_user_details(response)
- self.assertEqual(details, expected)
- def make_fake_openid_endpoint(self, claimed_id=None):
+ def make_openid_response(self, sreg_args=None, teams_args=None):
endpoint = OpenIDServiceEndpoint()
- endpoint.claimed_id = claimed_id
- return endpoint
+ endpoint.claimed_id = 'some-id'
- def make_openid_response(self, sreg_args=None, teams_args=None):
- endpoint = self.make_fake_openid_endpoint(claimed_id='some-id')
message = Message(OPENID2_NS)
if sreg_args is not None:
for key, value in sreg_args.items():
@@ -111,11 +72,8 @@ class OpenIDBackendTests(TestCase):
endpoint, message, signed_fields=message.toPostArgs().keys())
return response
- def make_response_sreg(self, **kwargs):
- response = self.make_openid_response(sreg_args=kwargs)
- return response
-
- def make_response_ax(self, schema="http://axschema.org/",
+ def make_response_ax(
+ self, schema="http://axschema.org/",
fullname="Some User", nickname="someuser", email="foo@example.com",
first=None, last=None, verified=False):
endpoint = OpenIDServiceEndpoint()
@@ -142,9 +100,69 @@ class OpenIDBackendTests(TestCase):
return SuccessResponse(
endpoint, message, signed_fields=message.toPostArgs().keys())
+ def make_user_openid(self, user=None,
+ claimed_id='http://example.com/existing_identity',
+ display_id='http://example.com/existing_identity'):
+ if user is None:
+ user = User.objects.create_user(
+ username='someuser', email='someuser@example.com',
+ password='12345678')
+
+ user_openid, created = UserOpenID.objects.get_or_create(
+ user=user, claimed_id=claimed_id, display_id=display_id)
+ return user_openid
+
+ def assert_account_verified(self, user, initially_verified, verified):
+ # set user's verification status
+ permission = Permission.objects.get(codename='account_verified')
+ if initially_verified:
+ user.user_permissions.add(permission)
+ else:
+ user.user_permissions.remove(permission)
+
+ user = User.objects.get(pk=user.pk)
+ has_perm = user.has_perm('django_openid_auth.account_verified')
+ assert has_perm == initially_verified
+
+ if hasattr(user, '_perm_cache'):
+ del user._perm_cache
+
+ # get a response including verification status
+ response = self.make_response_ax()
+ data = dict(first_name=u"Some56789012345678901234567890123",
+ last_name=u"User56789012345678901234567890123",
+ email=u"someotheruser@example.com",
+ account_verified=verified)
+ self.backend.update_user_details(user, data, response)
+
+ # refresh object from the database
+ user = User.objects.get(pk=user.pk)
+ # check the verification status
+ self.assertEqual(
+ user.has_perm('django_openid_auth.account_verified'), verified)
+
+ def test_extract_user_details_sreg(self):
+ expected = {
+ 'nickname': 'someuser',
+ 'first_name': 'Some',
+ 'last_name': 'User',
+ 'email': 'foo@example.com',
+ 'account_verified': False,
+ }
+ data = {
+ 'nickname': expected['nickname'],
+ 'fullname': "%s %s" % (expected['first_name'],
+ expected['last_name']),
+ 'email': expected['email'],
+ }
+ response = self.make_openid_response(sreg_args=data)
+
+ details = self.backend._extract_user_details(response)
+ self.assertEqual(details, expected)
+
def test_extract_user_details_ax(self):
- response = self.make_response_ax(fullname="Some User",
- nickname="someuser", email="foo@example.com")
+ response = self.make_response_ax(
+ fullname="Some User", nickname="someuser", email="foo@example.com")
data = self.backend._extract_user_details(response)
@@ -183,13 +201,14 @@ class OpenIDBackendTests(TestCase):
def test_update_user_details_long_names(self):
response = self.make_response_ax()
- user = User.objects.create_user('someuser', 'someuser@example.com',
- password=None)
+ user = User.objects.create_user(
+ 'someuser', 'someuser@example.com', password=None)
user_openid, created = UserOpenID.objects.get_or_create(
user=user,
claimed_id='http://example.com/existing_identity',
display_id='http://example.com/existing_identity')
- data = dict(first_name=u"Some56789012345678901234567890123",
+ data = dict(
+ first_name=u"Some56789012345678901234567890123",
last_name=u"User56789012345678901234567890123",
email=u"someotheruser@example.com", account_verified=False)
@@ -198,58 +217,25 @@ class OpenIDBackendTests(TestCase):
self.assertEqual("Some56789012345678901234567890", user.first_name)
self.assertEqual("User56789012345678901234567890", user.last_name)
- def make_user(self, username='someuser', email='someuser@example.com',
- password=None):
- user = User.objects.create_user(username, email, password=password)
- return user
-
- def make_user_openid(self, user=None,
- claimed_id='http://example.com/existing_identity',
- display_id='http://example.com/existing_identity'):
- if user is None:
- user = self.make_user()
- user_openid, created = UserOpenID.objects.get_or_create(
- user=user, claimed_id=claimed_id, display_id=display_id)
- return user_openid
-
- def _test_account_verified(self, user, initially_verified, expected):
- # set user's verification status
- permission = Permission.objects.get(codename='account_verified')
- if initially_verified:
- user.user_permissions.add(permission)
- else:
- user.user_permissions.remove(permission)
+ def test_update_user_perms_initially_verified_then_verified(self):
+ self.assert_account_verified(
+ self.make_user_openid().user,
+ initially_verified=True, verified=True)
- if hasattr(user, '_perm_cache'):
- del user._perm_cache
+ def test_update_user_perms_initially_verified_then_unverified(self):
+ self.assert_account_verified(
+ self.make_user_openid().user,
+ initially_verified=True, verified=False)
- # get a response including verification status
- response = self.make_response_ax()
- data = dict(first_name=u"Some56789012345678901234567890123",
- last_name=u"User56789012345678901234567890123",
- email=u"someotheruser@example.com",
- account_verified=expected)
- self.backend.update_user_details(user, data, response)
-
- # refresh object from the database
- user = User.objects.get(pk=user.pk)
- # check the verification status
- self.assertEqual(user.has_perm('django_openid_auth.account_verified'),
- expected)
-
- def test_update_user_perms_unverified(self):
- user_openid = self.make_user_openid()
-
- for initially_verified in (False, True):
- self._test_account_verified(
- user_openid.user, initially_verified, expected=False)
-
- def test_update_user_perms_verified(self):
- user_openid = self.make_user_openid()
+ def test_update_user_perms_initially_not_verified_then_verified(self):
+ self.assert_account_verified(
+ self.make_user_openid().user,
+ initially_verified=False, verified=True)
- for initially_verified in (False, True):
- self._test_account_verified(
- user_openid.user, initially_verified, expected=True)
+ def test_update_user_perms_initially_not_verified_then_unverified(self):
+ self.assert_account_verified(
+ self.make_user_openid().user,
+ initially_verified=False, verified=False)
def test_extract_user_details_name_with_trailing_space(self):
response = self.make_response_ax(fullname="SomeUser ")
@@ -267,32 +253,35 @@ class OpenIDBackendTests(TestCase):
self.assertEqual("Some", data['first_name'])
self.assertEqual("User", data['last_name'])
+ @override_settings(OPENID_USE_EMAIL_FOR_USERNAME=True)
def test_preferred_username_email_munging(self):
- settings.OPENID_USE_EMAIL_FOR_USERNAME = True
for nick, email, expected in [
- ('nickcomesfirst', 'foo@example.com', 'nickcomesfirst'),
- ('', 'foo@example.com', 'fooexamplecom'),
- ('noemail', '', 'noemail'),
- ('', '@%.-', 'openiduser'),
- ('', '', 'openiduser'),
- (None, None, 'openiduser')]:
- self.assertEqual(expected,
+ ('nickcomesfirst', 'foo@example.com', 'nickcomesfirst'),
+ ('', 'foo@example.com', 'fooexamplecom'),
+ ('noemail', '', 'noemail'),
+ ('', '@%.-', 'openiduser'),
+ ('', '', 'openiduser'),
+ (None, None, 'openiduser')]:
+ self.assertEqual(
+ expected,
self.backend._get_preferred_username(nick, email))
def test_preferred_username_no_email_munging(self):
for nick, email, expected in [
- ('nickcomesfirst', 'foo@example.com', 'nickcomesfirst'),
- ('', 'foo@example.com', 'openiduser'),
- ('noemail', '', 'noemail'),
- ('', '@%.-', 'openiduser'),
- ('', '', 'openiduser'),
- (None, None, 'openiduser')]:
- self.assertEqual(expected,
+ ('nickcomesfirst', 'foo@example.com', 'nickcomesfirst'),
+ ('', 'foo@example.com', 'openiduser'),
+ ('noemail', '', 'noemail'),
+ ('', '@%.-', 'openiduser'),
+ ('', '', 'openiduser'),
+ (None, None, 'openiduser')]:
+ self.assertEqual(
+ expected,
self.backend._get_preferred_username(nick, email))
+ @override_settings(
+ OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO=True,
+ OPENID_LAUNCHPAD_TEAMS_REQUIRED=['team'])
def test_authenticate_when_not_member_of_teams_required(self):
- settings.OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO = True
- settings.OPENID_LAUNCHPAD_TEAMS_REQUIRED = ['team']
Group.objects.create(name='team')
response = self.make_openid_response(
@@ -302,9 +291,10 @@ class OpenIDBackendTests(TestCase):
self.assertIsNone(user)
+ @override_settings(
+ OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO=True,
+ OPENID_LAUNCHPAD_TEAMS_REQUIRED=['team'])
def test_authenticate_when_no_group_mapping_to_required_team(self):
- settings.OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO = True
- settings.OPENID_LAUNCHPAD_TEAMS_REQUIRED = ['team']
assert Group.objects.filter(name='team').count() == 0
response = self.make_openid_response(
@@ -314,9 +304,10 @@ class OpenIDBackendTests(TestCase):
self.assertIsNone(user)
+ @override_settings(
+ OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO=True,
+ OPENID_LAUNCHPAD_TEAMS_REQUIRED=['team'])
def test_authenticate_when_member_of_teams_required(self):
- settings.OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO = True
- settings.OPENID_LAUNCHPAD_TEAMS_REQUIRED = ['team']
Group.objects.create(name='team')
response = self.make_openid_response(
@@ -326,9 +317,8 @@ class OpenIDBackendTests(TestCase):
self.assertIsNotNone(user)
+ @override_settings(OPENID_LAUNCHPAD_TEAMS_REQUIRED=[])
def test_authenticate_when_no_teams_required(self):
- settings.OPENID_LAUNCHPAD_TEAMS_REQUIRED = []
-
response = self.make_openid_response(
sreg_args=dict(nickname='someuser'),
teams_args=dict(is_member='team'))
@@ -336,9 +326,10 @@ class OpenIDBackendTests(TestCase):
self.assertIsNotNone(user)
+ @override_settings(
+ OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO=True,
+ OPENID_LAUNCHPAD_TEAMS_REQUIRED=['team1', 'team2'])
def test_authenticate_when_member_of_at_least_one_team(self):
- settings.OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO = True
- settings.OPENID_LAUNCHPAD_TEAMS_REQUIRED = ['team1', 'team2']
Group.objects.create(name='team1')
response = self.make_openid_response(
@@ -348,12 +339,12 @@ class OpenIDBackendTests(TestCase):
self.assertIsNotNone(user)
- def test_authenticate_when_not_in_required_team_but_email_whitelisted(self):
- settings.OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO = True
- settings.OPENID_LAUNCHPAD_TEAMS_REQUIRED = ['team']
- settings.OPENID_EMAIL_WHITELIST_REGEXP_LIST = [
- 'foo(\+[^@]*)?@foo.com',
- ]
+ @override_settings(
+ OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO=True,
+ OPENID_LAUNCHPAD_TEAMS_REQUIRED=['team'],
+ OPENID_EMAIL_WHITELIST_REGEXP_LIST=['foo(\+[^@]*)?@foo.com'])
+ def test_authenticate_when_not_in_required_team_but_email_whitelisted(
+ self):
assert Group.objects.filter(name='team').count() == 0
response = self.make_openid_response(
@@ -370,12 +361,11 @@ class OpenIDBackendTests(TestCase):
self.assertIsNotNone(user)
+ @override_settings(
+ OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO=True,
+ OPENID_LAUNCHPAD_TEAMS_REQUIRED=['team'],
+ OPENID_EMAIL_WHITELIST_REGEXP_LIST=['foo@foo.com', 'bar@foo.com'])
def test_authenticate_whitelisted_email_multiple_patterns(self):
- settings.OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO = True
- settings.OPENID_LAUNCHPAD_TEAMS_REQUIRED = ['team']
- settings.OPENID_EMAIL_WHITELIST_REGEXP_LIST = [
- 'foo@foo.com', 'bar@foo.com',
- ]
assert Group.objects.filter(name='team').count() == 0
response = self.make_openid_response(
@@ -385,12 +375,11 @@ class OpenIDBackendTests(TestCase):
self.assertIsNotNone(user)
+ @override_settings(
+ OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO=True,
+ OPENID_LAUNCHPAD_TEAMS_REQUIRED=['team'],
+ OPENID_EMAIL_WHITELIST_REGEXP_LIST=['foo@foo.com'])
def test_authenticate_whitelisted_email_not_match(self):
- settings.OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO = True
- settings.OPENID_LAUNCHPAD_TEAMS_REQUIRED = ['team']
- settings.OPENID_EMAIL_WHITELIST_REGEXP_LIST = [
- 'foo@foo.com',
- ]
assert Group.objects.filter(name='team').count() == 0
response = self.make_openid_response(
@@ -399,7 +388,3 @@ class OpenIDBackendTests(TestCase):
user = self.backend.authenticate(openid_response=response)
self.assertIsNone(user)
-
-
-def suite():
- return unittest.TestLoader().loadTestsFromName(__name__)
diff --git a/django_openid_auth/tests/test_models.py b/django_openid_auth/tests/test_models.py
index 28fb1de..d9a48c8 100644
--- a/django_openid_auth/tests/test_models.py
+++ b/django_openid_auth/tests/test_models.py
@@ -26,7 +26,7 @@
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
-import unittest
+from __future__ import unicode_literals
from django.contrib.auth.models import User
from django.test import TestCase
@@ -72,7 +72,3 @@ class UserOpenIDModelTestCase(TestCase):
self.assertFalse(
User.objects.get(username='someuser').has_perm(
'django_openid_auth.account_verified'))
-
-
-def suite():
- return unittest.TestLoader().loadTestsFromName(__name__)
diff --git a/django_openid_auth/tests/test_settings.py b/django_openid_auth/tests/test_settings.py
index 5704ffa..d98eff8 100644
--- a/django_openid_auth/tests/test_settings.py
+++ b/django_openid_auth/tests/test_settings.py
@@ -1,4 +1,34 @@
-from unittest import skipIf, TestLoader
+# django-openid-auth - OpenID integration for django.contrib.auth
+#
+# Copyright (C) 2013 Canonical Ltd.
+#
+# 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.
+#
+# 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 __future__ import unicode_literals
+
+from unittest import skipIf
from django import VERSION
from django.conf import settings
@@ -16,20 +46,9 @@ class SessionSerializerTest(TestCase):
[0] https://bit.ly/1myzetd
[1] https://github.com/openid/python-openid/issues/17
"""
- @skipIf(VERSION >= (1, 6, 0), "Old versions used the pickle serializer.")
- def test_not_using_json_session_serializer(self):
- # We use getattr because this setting did not exist in Django
- # 1.4 (pickle serialization was hard coded)
- serializer = getattr(settings, 'SESSION_SERIALIZER', '')
- self.assertNotEqual(
- serializer, 'django.contrib.sessions.serializers.JSONSerializer')
- @skipIf(VERSION < (1, 6, 0), "Newer versions use JSON by default.")
- def test_using_json_session_serializer(self):
+ @skipIf(VERSION < (1, 5), "Django 1.4 does not provide SESSION_SERIALIZER")
+ def test_using_pickle_session_serializer(self):
serializer = getattr(settings, 'SESSION_SERIALIZER', '')
self.assertEqual(
- serializer, 'django.contrib.sessions.serializers.JSONSerializer')
-
-
-def suite():
- return TestLoader().loadTestsFromName(__name__)
+ serializer, 'django.contrib.sessions.serializers.PickleSerializer')
diff --git a/django_openid_auth/tests/test_store.py b/django_openid_auth/tests/test_store.py
index 7b2af93..e5e1451 100644
--- a/django_openid_auth/tests/test_store.py
+++ b/django_openid_auth/tests/test_store.py
@@ -26,8 +26,9 @@
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
+from __future__ import unicode_literals
+
import time
-import unittest
from django.test import TestCase
from openid.association import Association as OIDAssociation
@@ -187,7 +188,3 @@ class OpenIDStoreTests(TestCase):
# The second (non-expired) association is left behind.
self.assertNotEqual(self.store.getAssociation('server-url', 'handle2'),
None)
-
-
-def suite():
- return unittest.TestLoader().loadTestsFromName(__name__)
diff --git a/django_openid_auth/tests/test_views.py b/django_openid_auth/tests/test_views.py
index 2660be8..835ddd5 100644
--- a/django_openid_auth/tests/test_views.py
+++ b/django_openid_auth/tests/test_views.py
@@ -27,14 +27,19 @@
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
+from __future__ import unicode_literals
+
import cgi
-import unittest
-from urllib import quote_plus
+
+from urlparse import parse_qs
from django.conf import settings
from django.contrib.auth.models import User, Group, Permission
+from django.core.urlresolvers import reverse
from django.http import HttpRequest, HttpResponse
from django.test import TestCase
+from django.test.utils import override_settings
+from mock import patch
from openid.consumer.consumer import Consumer, SuccessResponse
from openid.consumer.discover import OpenIDServiceEndpoint
from openid.extensions import ax, sreg, pape
@@ -67,6 +72,7 @@ ET = importElementTree()
class StubOpenIDProvider(HTTPFetcher):
def __init__(self, base_url):
+ super(StubOpenIDProvider, self).__init__()
self.store = MemoryStore()
self.identity_url = base_url + 'identity'
self.localid_url = base_url + 'localid'
@@ -136,7 +142,9 @@ class StubOpenIDProvider(HTTPFetcher):
class DummyDjangoRequest(object):
+
def __init__(self, request_path):
+ super(DummyDjangoRequest, self).__init__()
self.request_path = request_path
self.META = {
'HTTP_HOST': "localhost",
@@ -164,8 +172,23 @@ class DummyDjangoRequest(object):
@override_session_serializer
+@override_settings(
+ OPENID_CREATE_USERS=False,
+ OPENID_STRICT_USERNAMES=False,
+ OPENID_UPDATE_DETAILS_FROM_SREG=False,
+ OPENID_SSO_SERVER_URL=None,
+ OPENID_LAUNCHPAD_TEAMS_MAPPING={},
+ OPENID_USE_AS_ADMIN_LOGIN=False,
+ OPENID_FOLLOW_RENAMES=False,
+ OPENID_PHYSICAL_MULTIFACTOR_REQUIRED=False,
+ OPENID_SREG_REQUIRED_FIELDS=[],
+ OPENID_USE_EMAIL_FOR_USERNAME=False,
+ OPENID_VALID_VERIFICATION_SCHEMES={},
+)
class RelyingPartyTests(TestCase):
+
urls = 'django_openid_auth.tests.urls'
+ login_url = reverse('openid-login')
def setUp(self):
super(RelyingPartyTests, self).setUp()
@@ -178,70 +201,16 @@ class RelyingPartyTests(TestCase):
self.consumer = make_consumer(self.req)
self.server = Server(DjangoOpenIDStore(), op_endpoint=server_url)
setDefaultFetcher(self.provider, wrap_exceptions=False)
+ self.addCleanup(setDefaultFetcher, None)
- self.old_login_redirect_url = getattr(
- settings, 'LOGIN_REDIRECT_URL', '/accounts/profile/')
- self.old_create_users = getattr(
- settings, 'OPENID_CREATE_USERS', False)
- self.old_strict_usernames = getattr(
- settings, 'OPENID_STRICT_USERNAMES', False)
- self.old_update_details = getattr(
- settings, 'OPENID_UPDATE_DETAILS_FROM_SREG', False)
- self.old_sso_server_url = getattr(
- settings, 'OPENID_SSO_SERVER_URL', None)
- self.old_teams_map = getattr(
- settings, 'OPENID_LAUNCHPAD_TEAMS_MAPPING', {})
- self.old_use_as_admin_login = getattr(
- settings, 'OPENID_USE_AS_ADMIN_LOGIN', False)
- self.old_follow_renames = getattr(
- settings, 'OPENID_FOLLOW_RENAMES', False)
- self.old_physical_multifactor = getattr(
- settings, 'OPENID_PHYSICAL_MULTIFACTOR_REQUIRED', False)
- self.old_login_render_failure = getattr(
- settings, 'OPENID_RENDER_FAILURE', None)
- self.old_openid_use_email_for_username = getattr(
- settings,
- 'OPENID_USE_EMAIL_FOR_USERNAME', False)
- self.old_required_fields = getattr(
- settings, 'OPENID_SREG_REQUIRED_FIELDS', [])
- self.old_valid_verification_schemes = getattr(
- settings, 'OPENID_VALID_VERIFICATION_SCHEMES', {})
-
- self.old_consumer_complete = Consumer.complete
-
- settings.OPENID_CREATE_USERS = False
- settings.OPENID_STRICT_USERNAMES = False
- settings.OPENID_UPDATE_DETAILS_FROM_SREG = False
- settings.OPENID_SSO_SERVER_URL = None
- settings.OPENID_LAUNCHPAD_TEAMS_MAPPING = {}
- settings.OPENID_USE_AS_ADMIN_LOGIN = False
- settings.OPENID_FOLLOW_RENAMES = False
- settings.OPENID_PHYSICAL_MULTIFACTOR_REQUIRED = False
- settings.OPENID_SREG_REQUIRED_FIELDS = []
- settings.OPENID_USE_EMAIL_FOR_USERNAME = False
- settings.OPENID_VALID_VERIFICATION_SCHEMES = {}
-
- def tearDown(self):
- settings.LOGIN_REDIRECT_URL = self.old_login_redirect_url
- settings.OPENID_CREATE_USERS = self.old_create_users
- settings.OPENID_STRICT_USERNAMES = self.old_strict_usernames
- settings.OPENID_UPDATE_DETAILS_FROM_SREG = self.old_update_details
- settings.OPENID_SSO_SERVER_URL = self.old_sso_server_url
- settings.OPENID_LAUNCHPAD_TEAMS_MAPPING = self.old_teams_map
- settings.OPENID_USE_AS_ADMIN_LOGIN = self.old_use_as_admin_login
- settings.OPENID_FOLLOW_RENAMES = self.old_follow_renames
- settings.OPENID_PHYSICAL_MULTIFACTOR_REQUIRED = (
- self.old_physical_multifactor)
- settings.OPENID_RENDER_FAILURE = self.old_login_render_failure
- Consumer.complete = self.old_consumer_complete
- settings.OPENID_SREG_REQUIRED_FIELDS = self.old_required_fields
- settings.OPENID_USE_EMAIL_FOR_USERNAME = (
- self.old_openid_use_email_for_username)
- settings.OPENID_VALID_VERIFICATION_SCHEMES = (
- self.old_valid_verification_schemes)
-
- setDefaultFetcher(None)
- super(RelyingPartyTests, self).tearDown()
+ self.openid_req_no_next = {
+ 'openid_identifier': 'http://example.com/identity'}
+ self.openid_req = {
+ 'openid_identifier': 'http://example.com/identity',
+ 'next': '/getuser/'}
+ self.openid_resp = {
+ 'nickname': 'testuser', 'fullname': 'Openid User',
+ 'email': 'test@example.com'}
def complete(self, openid_response):
"""Complete an OpenID authentication request."""
@@ -249,36 +218,33 @@ class RelyingPartyTests(TestCase):
# here. For simplicity, force generation of a redirect.
openid_response.whichEncoding = lambda: ENCODE_URL
webresponse = self.provider.server.encodeResponse(openid_response)
- self.assertEquals(webresponse.code, 302)
+ self.assertEqual(webresponse.code, 302)
redirect_to = webresponse.headers['location']
self.assertTrue(redirect_to.startswith(
'http://testserver/openid/complete/'))
return self.client.get(
- '/openid/complete/',
+ reverse('openid-complete'),
dict(cgi.parse_qsl(redirect_to.split('?', 1)[1])))
def test_login(self):
user = User.objects.create_user('someuser', 'someone@example.com')
- useropenid = UserOpenID(
+ UserOpenID.objects.create(
user=user,
claimed_id='http://example.com/identity',
display_id='http://example.com/identity')
- useropenid.save()
# The login form is displayed:
- response = self.client.get('/openid/login/')
+ response = self.client.get(self.login_url)
self.assertTemplateUsed(response, 'openid/login.html')
# Posting in an identity URL begins the authentication request:
- response = self.client.post('/openid/login/',
- {'openid_identifier': 'http://example.com/identity',
- 'next': '/getuser/'})
+ response = self.client.post(self.login_url, self.openid_req)
self.assertContains(response, 'OpenID transaction in progress')
openid_request = self.provider.parseFormPost(response.content)
- self.assertEquals(openid_request.mode, 'checkid_setup')
+ self.assertEqual(openid_request.mode, 'checkid_setup')
self.assertTrue(openid_request.return_to.startswith(
- 'http://testserver/openid/complete/'))
+ 'http://testserver/openid/complete/'))
# Complete the request. The user is redirected to the next URL.
openid_response = openid_request.answer(True)
@@ -287,59 +253,59 @@ class RelyingPartyTests(TestCase):
# And they are now logged in:
response = self.client.get('/getuser/')
- self.assertEquals(response.content, 'someuser')
+ self.assertEqual(response.content, 'someuser')
def test_login_with_nonascii_return_to(self):
"""Ensure non-ascii characters can be used for the 'next' arg."""
- response = self.client.post('/openid/login/',
+ response = self.client.post(
+ self.login_url,
{'openid_identifier': 'http://example.com/identity',
- 'next': u'/files/ñandú.jpg'.encode('utf-8')})
+ 'next': '/files/ñandú.jpg'.encode('utf-8')})
self.assertContains(response, 'OpenID transaction in progress')
def test_login_no_next(self):
"""Logins with no next parameter redirect to LOGIN_REDIRECT_URL."""
user = User.objects.create_user('someuser', 'someone@example.com')
- useropenid = UserOpenID(
+ UserOpenID.objects.create(
user=user,
claimed_id='http://example.com/identity',
display_id='http://example.com/identity')
- useropenid.save()
- settings.LOGIN_REDIRECT_URL = '/getuser/'
- response = self.client.post('/openid/login/',
- {'openid_identifier': 'http://example.com/identity'})
+ response = self.client.post(self.login_url, self.openid_req_no_next)
+
self.assertContains(response, 'OpenID transaction in progress')
openid_request = self.provider.parseFormPost(response.content)
- self.assertEquals(openid_request.mode, 'checkid_setup')
+ self.assertEqual(openid_request.mode, 'checkid_setup')
self.assertTrue(openid_request.return_to.startswith(
- 'http://testserver/openid/complete/'))
+ 'http://testserver/openid/complete/'))
# Complete the request. The user is redirected to the next URL.
openid_response = openid_request.answer(True)
- response = self.complete(openid_response)
- self.assertRedirects(
- response, 'http://testserver' + settings.LOGIN_REDIRECT_URL)
+ with self.settings(LOGIN_REDIRECT_URL='/getuser/'):
+ response = self.complete(openid_response)
+ self.assertRedirects(response, 'http://testserver/getuser/')
def test_login_sso(self):
- settings.OPENID_SSO_SERVER_URL = 'http://example.com/identity'
user = User.objects.create_user('someuser', 'someone@example.com')
- useropenid = UserOpenID(
+ UserOpenID.objects.create(
user=user,
claimed_id='http://example.com/identity',
display_id='http://example.com/identity')
- useropenid.save()
# Requesting the login form immediately begins an
# authentication request.
- response = self.client.get('/openid/login/', {'next': '/getuser/'})
- self.assertEquals(response.status_code, 200)
+ with self.settings(
+ OPENID_SSO_SERVER_URL='http://example.com/identity'):
+ response = self.client.get(self.login_url, {'next': '/getuser/'})
+
+ self.assertEqual(response.status_code, 200)
self.assertContains(response, 'OpenID transaction in progress')
openid_request = self.provider.parseFormPost(response.content)
- self.assertEquals(openid_request.mode, 'checkid_setup')
+ self.assertEqual(openid_request.mode, 'checkid_setup')
self.assertTrue(openid_request.return_to.startswith(
- 'http://testserver/openid/complete/'))
+ 'http://testserver/openid/complete/'))
# Complete the request. The user is redirected to the next URL.
openid_response = openid_request.answer(True)
@@ -348,17 +314,14 @@ class RelyingPartyTests(TestCase):
# And they are now logged in:
response = self.client.get('/getuser/')
- self.assertEquals(response.content, 'someuser')
+ self.assertEqual(response.content, 'someuser')
def test_login_create_users(self):
- settings.OPENID_CREATE_USERS = True
# Create a user with the same name as we'll pass back via sreg.
User.objects.create_user('someuser', 'someone@example.com')
# Posting in an identity URL begins the authentication request:
- response = self.client.post('/openid/login/',
- {'openid_identifier': 'http://example.com/identity',
- 'next': '/getuser/'})
+ response = self.client.post(self.login_url, self.openid_req)
self.assertContains(response, 'OpenID transaction in progress')
# Complete the request, passing back some simple registration
@@ -370,19 +333,20 @@ class RelyingPartyTests(TestCase):
sreg_request, {'nickname': 'someuser', 'fullname': 'Some User',
'email': 'foo@example.com'})
openid_response.addExtension(sreg_response)
- response = self.complete(openid_response)
+ with self.settings(OPENID_CREATE_USERS=True):
+ response = self.complete(openid_response)
self.assertRedirects(response, 'http://testserver/getuser/')
# And they are now logged in as a new user (they haven't taken
# over the existing "someuser" user).
response = self.client.get('/getuser/')
- self.assertEquals(response.content, 'someuser2')
+ self.assertEqual(response.content, 'someuser2')
# Check the details of the new user.
user = User.objects.get(username='someuser2')
- self.assertEquals(user.first_name, 'Some')
- self.assertEquals(user.last_name, 'User')
- self.assertEquals(user.email, 'foo@example.com')
+ self.assertEqual(user.first_name, 'Some')
+ self.assertEqual(user.last_name, 'User')
+ self.assertEqual(user.email, 'foo@example.com')
def _do_user_login(self, req_data, resp_data, use_sreg=True,
use_pape=None):
@@ -395,7 +359,7 @@ class RelyingPartyTests(TestCase):
def _get_login_request(self, req_data):
# Posting in an identity URL begins the authentication request:
- response = self.client.post('/openid/login/', req_data)
+ response = self.client.post(self.login_url, req_data)
self.assertContains(response, 'OpenID transaction in progress')
# Complete the request, passing back some simple registration
@@ -413,27 +377,17 @@ class RelyingPartyTests(TestCase):
sreg_request, resp_data)
openid_response.addExtension(sreg_response)
if use_pape is not None:
- policies = [
- use_pape
- ]
+ policies = [use_pape]
pape_response = pape.Response(auth_policies=policies)
openid_response.addExtension(pape_response)
return openid_response
- def parse_query_string(self, query_str):
- query_items = map(tuple,
- [item.split('=') for item in query_str.split('&')])
- query = dict(query_items)
- return query
-
+ @override_settings(OPENID_PHYSICAL_MULTIFACTOR_REQUIRED=True)
def test_login_physical_multifactor_request(self):
- settings.OPENID_PHYSICAL_MULTIFACTOR_REQUIRED = True
preferred_auth = pape.AUTH_MULTI_FACTOR_PHYSICAL
self.provider.type_uris.append(pape.ns_uri)
- openid_req = {'openid_identifier': 'http://example.com/identity',
- 'next': '/getuser/'}
- response = self.client.post('/openid/login/', openid_req)
+ response = self.client.post(self.login_url, self.openid_req)
openid_request = self.provider.parseFormPost(response.content)
request_auth = openid_request.message.getArg(
@@ -442,85 +396,82 @@ class RelyingPartyTests(TestCase):
)
self.assertEqual(request_auth, preferred_auth)
+ @override_settings(OPENID_PHYSICAL_MULTIFACTOR_REQUIRED=True)
def test_login_physical_multifactor_response(self):
- settings.OPENID_PHYSICAL_MULTIFACTOR_REQUIRED = True
preferred_auth = pape.AUTH_MULTI_FACTOR_PHYSICAL
self.provider.type_uris.append(pape.ns_uri)
def mock_complete(this, request_args, return_to):
- request = {'openid.mode': 'checkid_setup',
- 'openid.trust_root': 'http://localhost/',
- 'openid.return_to': 'http://localhost/',
- 'openid.identity': IDENTIFIER_SELECT,
- 'openid.ns.pape' : pape.ns_uri,
- 'openid.pape.auth_policies': request_args.get('openid.pape.auth_policies', pape.AUTH_NONE),
+ request = {
+ 'openid.mode': 'checkid_setup',
+ 'openid.trust_root': 'http://localhost/',
+ 'openid.return_to': 'http://localhost/',
+ 'openid.identity': IDENTIFIER_SELECT,
+ 'openid.ns.pape': pape.ns_uri,
+ 'openid.pape.auth_policies': request_args.get(
+ 'openid.pape.auth_policies', pape.AUTH_NONE),
}
openid_server = self.provider.server
orequest = openid_server.decodeRequest(request)
response = SuccessResponse(
self.endpoint, orequest.message,
- signed_fields=['openid.pape.auth_policies',])
+ signed_fields=['openid.pape.auth_policies'])
return response
- Consumer.complete = mock_complete
+
+ patch.object(Consumer, 'complete', mock_complete)
user = User.objects.create_user('testuser', 'test@example.com')
- useropenid = UserOpenID(
+ UserOpenID.objects.create(
user=user,
claimed_id='http://example.com/identity',
display_id='http://example.com/identity')
- useropenid.save()
-
- openid_req = {'openid_identifier': 'http://example.com/identity',
- 'next': '/getuser/'}
- openid_resp = {'nickname': 'testuser', 'fullname': 'Openid User',
- 'email': 'test@example.com'}
- response = self._do_user_login(openid_req, openid_resp, use_pape=pape.AUTH_MULTI_FACTOR_PHYSICAL)
+ response = self._do_user_login(
+ self.openid_req, self.openid_resp,
+ use_pape=pape.AUTH_MULTI_FACTOR_PHYSICAL)
- query = self.parse_query_string(response.request['QUERY_STRING'])
+ query = parse_qs(response.request['QUERY_STRING'])
self.assertTrue('openid.pape.auth_policies' in query)
- self.assertEqual(query['openid.pape.auth_policies'],
- quote_plus(preferred_auth))
+ self.assertEqual(
+ query['openid.pape.auth_policies'], [preferred_auth])
response = self.client.get('/getuser/')
self.assertEqual(response.content, 'testuser')
-
+ @override_settings(OPENID_PHYSICAL_MULTIFACTOR_REQUIRED=True)
def test_login_physical_multifactor_not_provided(self):
- settings.OPENID_PHYSICAL_MULTIFACTOR_REQUIRED = True
preferred_auth = pape.AUTH_MULTI_FACTOR_PHYSICAL
self.provider.type_uris.append(pape.ns_uri)
def mock_complete(this, request_args, return_to):
- request = {'openid.mode': 'checkid_setup',
- 'openid.trust_root': 'http://localhost/',
- 'openid.return_to': 'http://localhost/',
- 'openid.identity': IDENTIFIER_SELECT,
- 'openid.ns.pape' : pape.ns_uri,
- 'openid.pape.auth_policies': request_args.get('openid.pape.auth_policies', pape.AUTH_NONE),
+ request = {
+ 'openid.mode': 'checkid_setup',
+ 'openid.trust_root': 'http://localhost/',
+ 'openid.return_to': 'http://localhost/',
+ 'openid.identity': IDENTIFIER_SELECT,
+ 'openid.ns.pape': pape.ns_uri,
+ 'openid.pape.auth_policies': request_args.get(
+ 'openid.pape.auth_policies', pape.AUTH_NONE),
}
openid_server = self.provider.server
orequest = openid_server.decodeRequest(request)
response = SuccessResponse(
self.endpoint, orequest.message,
- signed_fields=['openid.pape.auth_policies',])
+ signed_fields=['openid.pape.auth_policies'])
return response
- Consumer.complete = mock_complete
+
+ patch.object(Consumer, 'complete', mock_complete)
user = User.objects.create_user('testuser', 'test@example.com')
- useropenid = UserOpenID(
+ UserOpenID.objects.create(
user=user,
claimed_id='http://example.com/identity',
display_id='http://example.com/identity')
- useropenid.save()
- openid_req = {'openid_identifier': 'http://example.com/identity',
- 'next': '/getuser/'}
- openid_resp = {'nickname': 'testuser', 'fullname': 'Openid User',
- 'email': 'test@example.com'}
-
- openid_request = self._get_login_request(openid_req)
- openid_response = self._get_login_response(openid_request, openid_req, openid_resp, use_pape=pape.AUTH_NONE)
+ openid_request = self._get_login_request(self.openid_req)
+ openid_response = self._get_login_response(
+ openid_request, self.openid_req, self.openid_resp,
+ use_pape=pape.AUTH_NONE)
response_auth = openid_request.message.getArg(
'http://specs.openid.net/extensions/pape/1.0',
@@ -529,12 +480,16 @@ class RelyingPartyTests(TestCase):
self.assertNotEqual(response_auth, preferred_auth)
response = self.complete(openid_response)
- self.assertEquals(403, response.status_code)
- self.assertContains(response, '<h1>OpenID failed</h1>', status_code=403)
- self.assertContains(response, '<p>Login requires physical multi-factor authentication.</p>', status_code=403)
+ self.assertEqual(403, response.status_code)
+ self.assertContains(
+ response, '<h1>OpenID failed</h1>', status_code=403)
+ self.assertContains(
+ response,
+ '<p>Login requires physical multi-factor authentication.</p>',
+ status_code=403)
+ @override_settings(OPENID_PHYSICAL_MULTIFACTOR_REQUIRED=True)
def test_login_physical_multifactor_not_provided_override(self):
- settings.OPENID_PHYSICAL_MULTIFACTOR_REQUIRED = True
preferred_auth = pape.AUTH_MULTI_FACTOR_PHYSICAL
self.provider.type_uris.append(pape.ns_uri)
@@ -542,40 +497,39 @@ class RelyingPartyTests(TestCase):
def mock_login_failure_handler(request, message, status=403,
template_name=None,
exception=None):
- self.assertTrue(isinstance(exception, MissingPhysicalMultiFactor))
- return HttpResponse('Test Failure Override', status=200)
- settings.OPENID_RENDER_FAILURE = mock_login_failure_handler
+ self.assertIsInstance(exception, MissingPhysicalMultiFactor)
+ return HttpResponse('Test Failure Override', status=200)
def mock_complete(this, request_args, return_to):
- request = {'openid.mode': 'checkid_setup',
- 'openid.trust_root': 'http://localhost/',
- 'openid.return_to': 'http://localhost/',
- 'openid.identity': IDENTIFIER_SELECT,
- 'openid.ns.pape' : pape.ns_uri,
- 'openid.pape.auth_policies': request_args.get('openid.pape.auth_policies', pape.AUTH_NONE),
+ pape_policy = request_args.get(
+ 'openid.pape.auth_policies', pape.AUTH_NONE)
+ request = {
+ 'openid.mode': 'checkid_setup',
+ 'openid.trust_root': 'http://localhost/',
+ 'openid.return_to': 'http://localhost/',
+ 'openid.identity': IDENTIFIER_SELECT,
+ 'openid.ns.pape': pape.ns_uri,
+ 'openid.pape.auth_policies': pape_policy,
}
openid_server = self.provider.server
orequest = openid_server.decodeRequest(request)
response = SuccessResponse(
self.endpoint, orequest.message,
- signed_fields=['openid.pape.auth_policies',])
+ signed_fields=['openid.pape.auth_policies'])
return response
- Consumer.complete = mock_complete
+
+ patch.object(Consumer, 'complete', mock_complete)
user = User.objects.create_user('testuser', 'test@example.com')
- useropenid = UserOpenID(
+ UserOpenID.objects.create(
user=user,
claimed_id='http://example.com/identity',
display_id='http://example.com/identity')
- useropenid.save()
-
- openid_req = {'openid_identifier': 'http://example.com/identity',
- 'next': '/getuser/'}
- openid_resp = {'nickname': 'testuser', 'fullname': 'Openid User',
- 'email': 'test@example.com'}
- openid_request = self._get_login_request(openid_req)
- openid_response = self._get_login_response(openid_request, openid_req, openid_resp, use_pape=pape.AUTH_NONE)
+ openid_request = self._get_login_request(self.openid_req)
+ openid_response = self._get_login_response(
+ openid_request, self.openid_req, self.openid_resp,
+ use_pape=pape.AUTH_NONE)
response_auth = openid_request.message.getArg(
'http://specs.openid.net/extensions/pape/1.0',
@@ -583,193 +537,174 @@ class RelyingPartyTests(TestCase):
)
self.assertNotEqual(response_auth, preferred_auth)
- # Status code should be 200, since we over-rode the login_failure handler
- response = self.complete(openid_response)
- self.assertEquals(200, response.status_code)
+ # Status code should be 200, since we over-rode the login_failure
+ with self.settings(OPENID_RENDER_FAILURE=mock_login_failure_handler):
+ response = self.complete(openid_response)
+ self.assertEqual(200, response.status_code)
self.assertContains(response, 'Test Failure Override')
def test_login_without_nickname(self):
- settings.OPENID_CREATE_USERS = True
-
- openid_req = {'openid_identifier': 'http://example.com/identity',
- 'next': '/getuser/'}
- openid_resp = {'nickname': '', 'fullname': 'Openid User',
- 'email': 'foo@example.com'}
- self._do_user_login(openid_req, openid_resp)
- response = self.client.get('/getuser/')
+ self.openid_resp = {
+ 'nickname': '', 'fullname': 'Openid User',
+ 'email': 'foo@example.com'}
+ with self.settings(OPENID_CREATE_USERS=True):
+ self._do_user_login(self.openid_req, self.openid_resp)
+ response = self.client.get('/getuser/')
# username defaults to 'openiduser'
- self.assertEquals(response.content, 'openiduser')
+ self.assertEqual(response.content, 'openiduser')
# The user's full name and email have been updated.
user = User.objects.get(username=response.content)
- self.assertEquals(user.first_name, 'Openid')
- self.assertEquals(user.last_name, 'User')
- self.assertEquals(user.email, 'foo@example.com')
+ self.assertEqual(user.first_name, 'Openid')
+ self.assertEqual(user.last_name, 'User')
+ self.assertEqual(user.email, 'foo@example.com')
def test_login_without_nickname_with_email_suggestion(self):
- settings.OPENID_CREATE_USERS = True
- settings.OPENID_USE_EMAIL_FOR_USERNAME = True
-
- openid_req = {'openid_identifier': 'http://example.com/identity',
- 'next': '/getuser/'}
- openid_resp = {'nickname': '', 'fullname': 'Openid User',
- 'email': 'foo@example.com'}
- self._do_user_login(openid_req, openid_resp)
- response = self.client.get('/getuser/')
+ self.openid_resp = {
+ 'nickname': '', 'fullname': 'Openid User',
+ 'email': 'foo@example.com'}
+ with self.settings(
+ OPENID_CREATE_USERS=True, OPENID_USE_EMAIL_FOR_USERNAME=True):
+ self._do_user_login(self.openid_req, self.openid_resp)
+ response = self.client.get('/getuser/')
# username defaults to a munged version of the email
- self.assertEquals(response.content, 'fooexamplecom')
+ self.assertEqual(response.content, 'fooexamplecom')
def test_login_duplicate_username_numbering(self):
- settings.OPENID_FOLLOW_RENAMES = False
- settings.OPENID_CREATE_USERS = True
- settings.OPENID_UPDATE_DETAILS_FROM_SREG = True
# Setup existing user who's name we're going to conflict with
- user = User.objects.create_user('testuser', 'someone@example.com')
+ User.objects.create_user('testuser', 'someone@example.com')
# identity url is for 'renameuser'
- openid_req = {'openid_identifier': 'http://example.com/identity',
- 'next': '/getuser/'}
- # but returned username is for 'testuser', which already exists for another identity
- openid_resp = {'nickname': 'testuser', 'fullname': 'Test User',
- 'email': 'test@example.com'}
- self._do_user_login(openid_req, openid_resp)
- response = self.client.get('/getuser/')
+ # but returned username is for 'testuser', which already exists for
+ # another identity
+ with self.settings(
+ OPENID_FOLLOW_RENAMES=False, OPENID_CREATE_USERS=True,
+ OPENID_UPDATE_DETAILS_FROM_SREG=True):
+ self._do_user_login(self.openid_req, self.openid_resp)
+ response = self.client.get('/getuser/')
# Since this username is already taken by someone else, we go through
# the process of adding +i to it, and get testuser2.
- self.assertEquals(response.content, 'testuser2')
+ self.assertEqual(response.content, 'testuser2')
def test_login_duplicate_username_numbering_with_conflicts(self):
- settings.OPENID_FOLLOW_RENAMES = False
- settings.OPENID_CREATE_USERS = True
- settings.OPENID_UPDATE_DETAILS_FROM_SREG = True
# Setup existing user who's name we're going to conflict with
- user = User.objects.create_user('testuser', 'someone@example.com')
- user = User.objects.create_user('testuser3', 'someone@example.com')
+ User.objects.create_user('testuser', 'someone@example.com')
+ User.objects.create_user('testuser3', 'someone@example.com')
# identity url is for 'renameuser'
- openid_req = {'openid_identifier': 'http://example.com/identity',
- 'next': '/getuser/'}
- # but returned username is for 'testuser', which already exists for another identity
- openid_resp = {'nickname': 'testuser', 'fullname': 'Test User',
- 'email': 'test@example.com'}
- self._do_user_login(openid_req, openid_resp)
- response = self.client.get('/getuser/')
+ # but returned username is for 'testuser', which already exists for
+ # another identity
+ with self.settings(
+ OPENID_FOLLOW_RENAMES=False, OPENID_CREATE_USERS=True,
+ OPENID_UPDATE_DETAILS_FROM_SREG=True):
+ self._do_user_login(self.openid_req, self.openid_resp)
+ response = self.client.get('/getuser/')
# Since this username is already taken by someone else, we go through
# the process of adding +i to it starting with the count of users with
# username starting with 'testuser', of which there are 2. i should
# start at 3, which already exists, so it should skip to 4.
- self.assertEquals(response.content, 'testuser4')
+ self.assertEqual(response.content, 'testuser4')
def test_login_duplicate_username_numbering_with_holes(self):
- settings.OPENID_FOLLOW_RENAMES = False
- settings.OPENID_CREATE_USERS = True
- settings.OPENID_UPDATE_DETAILS_FROM_SREG = True
# Setup existing user who's name we're going to conflict with
- user = User.objects.create_user('testuser', 'someone@example.com')
- user = User.objects.create_user('testuser1', 'someone@example.com')
- user = User.objects.create_user('testuser6', 'someone@example.com')
- user = User.objects.create_user('testuser7', 'someone@example.com')
- user = User.objects.create_user('testuser8', 'someone@example.com')
+ User.objects.create_user('testuser', 'someone@example.com')
+ User.objects.create_user('testuser1', 'someone@example.com')
+ User.objects.create_user('testuser6', 'someone@example.com')
+ User.objects.create_user('testuser7', 'someone@example.com')
+ User.objects.create_user('testuser8', 'someone@example.com')
# identity url is for 'renameuser'
- openid_req = {'openid_identifier': 'http://example.com/identity',
- 'next': '/getuser/'}
- # but returned username is for 'testuser', which already exists for another identity
- openid_resp = {'nickname': 'testuser', 'fullname': 'Test User',
- 'email': 'test@example.com'}
- self._do_user_login(openid_req, openid_resp)
- response = self.client.get('/getuser/')
+ # but returned username is for 'testuser', which already exists for
+ # another identity
+ with self.settings(
+ OPENID_FOLLOW_RENAMES=False, OPENID_CREATE_USERS=True,
+ OPENID_UPDATE_DETAILS_FROM_SREG=True):
+ self._do_user_login(self.openid_req, self.openid_resp)
+ response = self.client.get('/getuser/')
# Since this username is already taken by someone else, we go through
# the process of adding +i to it starting with the count of users with
# username starting with 'testuser', of which there are 5. i should
# start at 6, and increment until it reaches 9.
- self.assertEquals(response.content, 'testuser9')
+ self.assertEqual(response.content, 'testuser9')
- def test_login_duplicate_username_numbering_with_nonsequential_matches(self):
- settings.OPENID_FOLLOW_RENAMES = False
- settings.OPENID_CREATE_USERS = True
- settings.OPENID_UPDATE_DETAILS_FROM_SREG = True
+ def test_login_duplicate_username_numbering_with_nonsequential_matches(
+ self):
# Setup existing user who's name we're going to conflict with
- user = User.objects.create_user('testuser', 'someone@example.com')
- user = User.objects.create_user('testuserfoo', 'someone@example.com')
+ User.objects.create_user('testuser', 'someone@example.com')
+ User.objects.create_user('testuserfoo', 'someone@example.com')
# identity url is for 'renameuser'
- openid_req = {'openid_identifier': 'http://example.com/identity',
- 'next': '/getuser/'}
- # but returned username is for 'testuser', which already exists for another identity
- openid_resp = {'nickname': 'testuser', 'fullname': 'Test User',
- 'email': 'test@example.com'}
- self._do_user_login(openid_req, openid_resp)
- response = self.client.get('/getuser/')
+ # but returned username is for 'testuser', which already exists for
+ # another identity
+ with self.settings(
+ OPENID_FOLLOW_RENAMES=False, OPENID_CREATE_USERS=True,
+ OPENID_UPDATE_DETAILS_FROM_SREG=True):
+ self._do_user_login(self.openid_req, self.openid_resp)
+ response = self.client.get('/getuser/')
# Since this username is already taken by someone else, we go through
# the process of adding +i to it starting with the count of users with
# username starting with 'testuser', of which there are 2. i should
# start at 3, which will be available.
- self.assertEquals(response.content, 'testuser3')
+ self.assertEqual(response.content, 'testuser3')
def test_login_follow_rename(self):
- settings.OPENID_FOLLOW_RENAMES = True
- settings.OPENID_UPDATE_DETAILS_FROM_SREG = True
user = User.objects.create_user('testuser', 'someone@example.com')
- useropenid = UserOpenID(
+ UserOpenID.objects.create(
user=user,
claimed_id='http://example.com/identity',
display_id='http://example.com/identity')
- useropenid.save()
- openid_req = {'openid_identifier': 'http://example.com/identity',
- 'next': '/getuser/'}
- openid_resp = {'nickname': 'someuser', 'fullname': 'Some User',
- 'email': 'foo@example.com'}
- self._do_user_login(openid_req, openid_resp)
- response = self.client.get('/getuser/')
+ self.openid_resp = {
+ 'nickname': 'someuser', 'fullname': 'Some User',
+ 'email': 'foo@example.com'}
+ with self.settings(
+ OPENID_FOLLOW_RENAMES=True,
+ OPENID_UPDATE_DETAILS_FROM_SREG=True):
+ self._do_user_login(self.openid_req, self.openid_resp)
+ response = self.client.get('/getuser/')
# If OPENID_FOLLOW_RENAMES, they are logged in as
# someuser (the passed in nickname has changed the username)
- self.assertEquals(response.content, 'someuser')
+ self.assertEqual(response.content, 'someuser')
# The user's full name and email have been updated.
user = User.objects.get(username=response.content)
- self.assertEquals(user.first_name, 'Some')
- self.assertEquals(user.last_name, 'User')
- self.assertEquals(user.email, 'foo@example.com')
+ self.assertEqual(user.first_name, 'Some')
+ self.assertEqual(user.last_name, 'User')
+ self.assertEqual(user.email, 'foo@example.com')
def test_login_follow_rename_without_nickname_change(self):
- settings.OPENID_FOLLOW_RENAMES = True
- settings.OPENID_UPDATE_DETAILS_FROM_SREG = True
- settings.OPENID_STRICT_USERNAMES = True
user = User.objects.create_user('testuser', 'someone@example.com')
- useropenid = UserOpenID(
+ UserOpenID.objects.create(
user=user,
claimed_id='http://example.com/identity',
display_id='http://example.com/identity')
- useropenid.save()
- openid_req = {'openid_identifier': 'http://example.com/identity',
- 'next': '/getuser/'}
- openid_resp = {'nickname': 'testuser', 'fullname': 'Some User',
- 'email': 'foo@example.com'}
- self._do_user_login(openid_req, openid_resp)
- response = self.client.get('/getuser/')
+ self.openid_resp = {
+ 'nickname': 'testuser', 'fullname': 'Some User',
+ 'email': 'foo@example.com'}
+ with self.settings(
+ OPENID_FOLLOW_RENAMES=True, OPENID_STRICT_USERNAMES=True,
+ OPENID_UPDATE_DETAILS_FROM_SREG=True):
+ self._do_user_login(self.openid_req, self.openid_resp)
+ response = self.client.get('/getuser/')
# Username should not have changed
- self.assertEquals(response.content, 'testuser')
+ self.assertEqual(response.content, 'testuser')
# The user's full name and email have been updated.
user = User.objects.get(username=response.content)
- self.assertEquals(user.first_name, 'Some')
- self.assertEquals(user.last_name, 'User')
- self.assertEquals(user.email, 'foo@example.com')
+ self.assertEqual(user.first_name, 'Some')
+ self.assertEqual(user.last_name, 'User')
+ self.assertEqual(user.email, 'foo@example.com')
def test_login_follow_rename_conflict(self):
- settings.OPENID_FOLLOW_RENAMES = True
- settings.OPENID_UPDATE_DETAILS_FROM_SREG = True
# Setup existing user who's name we're going to switch to
user = User.objects.create_user('testuser', 'someone@example.com')
UserOpenID.objects.get_or_create(
@@ -778,35 +713,37 @@ class RelyingPartyTests(TestCase):
display_id='http://example.com/existing_identity')
# Setup user who is going to try to change username to 'testuser'
- renamed_user = User.objects.create_user('renameuser', 'someone@example.com')
+ renamed_user = User.objects.create_user(
+ 'renameuser', 'someone@example.com')
UserOpenID.objects.get_or_create(
user=renamed_user,
claimed_id='http://example.com/identity',
display_id='http://example.com/identity')
# identity url is for 'renameuser'
- openid_req = {'openid_identifier': 'http://example.com/identity',
- 'next': '/getuser/'}
- # but returned username is for 'testuser', which already exists for another identity
- openid_resp = {'nickname': 'testuser', 'fullname': 'Rename User',
- 'email': 'rename@example.com'}
- self._do_user_login(openid_req, openid_resp)
- response = self.client.get('/getuser/')
+ # but returned username is for 'testuser', which already exists for
+ # another identity
+ self.openid_resp = {
+ 'nickname': 'testuser', 'fullname': 'Rename User',
+ 'email': 'rename@example.com'}
+ with self.settings(
+ OPENID_FOLLOW_RENAMES=True,
+ OPENID_UPDATE_DETAILS_FROM_SREG=True):
+ self._do_user_login(self.openid_req, self.openid_resp)
+ response = self.client.get('/getuser/')
# If OPENID_FOLLOW_RENAMES, attempt to change username to 'testuser'
- # but since that username is already taken by someone else, we go through
- # the process of adding +i to it, and get testuser2.
- self.assertEquals(response.content, 'testuser2')
+ # but since that username is already taken by someone else, we go
+ # through the process of adding +i to it, and get testuser2.
+ self.assertEqual(response.content, 'testuser2')
# The user's full name and email have been updated.
user = User.objects.get(username=response.content)
- self.assertEquals(user.first_name, 'Rename')
- self.assertEquals(user.last_name, 'User')
- self.assertEquals(user.email, 'rename@example.com')
+ self.assertEqual(user.first_name, 'Rename')
+ self.assertEqual(user.last_name, 'User')
+ self.assertEqual(user.email, 'rename@example.com')
def test_login_follow_rename_false_onlyonce(self):
- settings.OPENID_FOLLOW_RENAMES = True
- settings.OPENID_UPDATE_DETAILS_FROM_SREG = True
# Setup existing user who's name we're going to switch to
user = User.objects.create_user('testuser', 'someone@example.com')
UserOpenID.objects.get_or_create(
@@ -815,38 +752,40 @@ class RelyingPartyTests(TestCase):
display_id='http://example.com/existing_identity')
# Setup user who is going to try to change username to 'testuser'
- renamed_user = User.objects.create_user('testuser2000eight', 'someone@example.com')
+ renamed_user = User.objects.create_user(
+ 'testuser2000eight', 'someone@example.com')
UserOpenID.objects.get_or_create(
user=renamed_user,
claimed_id='http://example.com/identity',
display_id='http://example.com/identity')
# identity url is for 'testuser2000eight'
- openid_req = {'openid_identifier': 'http://example.com/identity',
- 'next': '/getuser/'}
- # but returned username is for 'testuser', which already exists for another identity
- openid_resp = {'nickname': 'testuser2', 'fullname': 'Rename User',
- 'email': 'rename@example.com'}
- self._do_user_login(openid_req, openid_resp)
- response = self.client.get('/getuser/')
+ # but returned username is for 'testuser', which already exists for
+ # another identity
+ self.openid_resp = {
+ 'nickname': 'testuser2', 'fullname': 'Rename User',
+ 'email': 'rename@example.com'}
+ with self.settings(
+ OPENID_FOLLOW_RENAMES=True,
+ OPENID_UPDATE_DETAILS_FROM_SREG=True):
+ self._do_user_login(self.openid_req, self.openid_resp)
+ response = self.client.get('/getuser/')
# If OPENID_FOLLOW_RENAMES, attempt to change username to 'testuser'
- # but since that username is already taken by someone else, we go through
- # the process of adding +i to it. Even though it looks like the username
- # follows the nickname+i scheme, it has non-numbers in the suffix, so
- # it's not an auto-generated one. The regular process of renaming to
- # 'testuser' has a conflict, so we get +2 at the end.
- self.assertEquals(response.content, 'testuser2')
+ # but since that username is already taken by someone else, we go
+ # through the process of adding +i to it. Even though it looks like
+ # the username follows the nickname+i scheme, it has non-numbers in the
+ # suffix, so it's not an auto-generated one. The regular process of
+ # renaming to 'testuser' has a conflict, so we get +2 at the end.
+ self.assertEqual(response.content, 'testuser2')
# The user's full name and email have been updated.
user = User.objects.get(username=response.content)
- self.assertEquals(user.first_name, 'Rename')
- self.assertEquals(user.last_name, 'User')
- self.assertEquals(user.email, 'rename@example.com')
+ self.assertEqual(user.first_name, 'Rename')
+ self.assertEqual(user.last_name, 'User')
+ self.assertEqual(user.email, 'rename@example.com')
def test_login_follow_rename_conflict_onlyonce(self):
- settings.OPENID_FOLLOW_RENAMES = True
- settings.OPENID_UPDATE_DETAILS_FROM_SREG = True
# Setup existing user who's name we're going to switch to
user = User.objects.create_user('testuser', 'someone@example.com')
UserOpenID.objects.get_or_create(
@@ -855,36 +794,38 @@ class RelyingPartyTests(TestCase):
display_id='http://example.com/existing_identity')
# Setup user who is going to try to change username to 'testuser'
- renamed_user = User.objects.create_user('testuser2000', 'someone@example.com')
+ renamed_user = User.objects.create_user(
+ 'testuser2000', 'someone@example.com')
UserOpenID.objects.get_or_create(
user=renamed_user,
claimed_id='http://example.com/identity',
display_id='http://example.com/identity')
# identity url is for 'testuser2000'
- openid_req = {'openid_identifier': 'http://example.com/identity',
- 'next': '/getuser/'}
- # but returned username is for 'testuser', which already exists for another identity
- openid_resp = {'nickname': 'testuser', 'fullname': 'Rename User',
- 'email': 'rename@example.com'}
- self._do_user_login(openid_req, openid_resp)
- response = self.client.get('/getuser/')
+ # but returned username is for 'testuser', which already exists for
+ # another identity
+ self.openid_resp = {
+ 'nickname': 'testuser', 'fullname': 'Rename User',
+ 'email': 'rename@example.com'}
+ with self.settings(
+ OPENID_FOLLOW_RENAMES=True,
+ OPENID_UPDATE_DETAILS_FROM_SREG=True):
+ self._do_user_login(self.openid_req, self.openid_resp)
+ response = self.client.get('/getuser/')
# If OPENID_FOLLOW_RENAMES, attempt to change username to 'testuser'
- # but since that username is already taken by someone else, we go through
- # the process of adding +i to it. Since the user for this identity url
- # already has a name matching that pattern, check if first.
- self.assertEquals(response.content, 'testuser2000')
+ # but since that username is already taken by someone else, we go
+ # through the process of adding +i to it. Since the user for this
+ # identity url already has a name matching that pattern, check if first
+ self.assertEqual(response.content, 'testuser2000')
# The user's full name and email have been updated.
user = User.objects.get(username=response.content)
- self.assertEquals(user.first_name, 'Rename')
- self.assertEquals(user.last_name, 'User')
- self.assertEquals(user.email, 'rename@example.com')
+ self.assertEqual(user.first_name, 'Rename')
+ self.assertEqual(user.last_name, 'User')
+ self.assertEqual(user.email, 'rename@example.com')
def test_login_follow_rename_false_conflict(self):
- settings.OPENID_FOLLOW_RENAMES = True
- settings.OPENID_UPDATE_DETAILS_FROM_SREG = True
# Setup existing user who's username matches the name+i pattern
user = User.objects.create_user('testuser2', 'someone@example.com')
UserOpenID.objects.get_or_create(
@@ -893,34 +834,33 @@ class RelyingPartyTests(TestCase):
display_id='http://example.com/identity')
# identity url is for 'testuser2'
- openid_req = {'openid_identifier': 'http://example.com/identity',
- 'next': '/getuser/'}
# but returned username is for 'testuser', which looks like we've done
# a username+1 for them already, but 'testuser' isn't actually taken
- openid_resp = {'nickname': 'testuser', 'fullname': 'Same User',
- 'email': 'same@example.com'}
- self._do_user_login(openid_req, openid_resp)
- response = self.client.get('/getuser/')
+ self.openid_resp = {
+ 'nickname': 'testuser', 'fullname': 'Same User',
+ 'email': 'same@example.com'}
+ with self.settings(
+ OPENID_FOLLOW_RENAMES=True,
+ OPENID_UPDATE_DETAILS_FROM_SREG=True):
+ self._do_user_login(self.openid_req, self.openid_resp)
+ response = self.client.get('/getuser/')
# If OPENID_FOLLOW_RENAMES, username should be changed to 'testuser'
# because it wasn't currently taken
- self.assertEquals(response.content, 'testuser')
+ self.assertEqual(response.content, 'testuser')
# The user's full name and email have been updated.
user = User.objects.get(username=response.content)
- self.assertEquals(user.first_name, 'Same')
- self.assertEquals(user.last_name, 'User')
- self.assertEquals(user.email, 'same@example.com')
+ self.assertEqual(user.first_name, 'Same')
+ self.assertEqual(user.last_name, 'User')
+ self.assertEqual(user.email, 'same@example.com')
+ @override_settings(
+ OPENID_CREATE_USERS=True, OPENID_STRICT_USERNAMES=True,
+ OPENID_SREG_REQUIRED_FIELDS=[])
def test_strict_username_no_nickname(self):
- settings.OPENID_CREATE_USERS = True
- settings.OPENID_STRICT_USERNAMES = True
- settings.OPENID_SREG_REQUIRED_FIELDS = []
-
# Posting in an identity URL begins the authentication request:
- response = self.client.post('/openid/login/',
- {'openid_identifier': 'http://example.com/identity',
- 'next': '/getuser/'})
+ response = self.client.post(self.login_url, self.openid_req)
self.assertContains(response, 'OpenID transaction in progress')
# Complete the request, passing back some simple registration
@@ -929,35 +869,36 @@ class RelyingPartyTests(TestCase):
sreg_request = sreg.SRegRequest.fromOpenIDRequest(openid_request)
openid_response = openid_request.answer(True)
sreg_response = sreg.SRegResponse.extractResponse(
- sreg_request, {'nickname': '', # No nickname
+ sreg_request, {'nickname': '', # No nickname
'fullname': 'Some User',
'email': 'foo@example.com'})
openid_response.addExtension(sreg_response)
response = self.complete(openid_response)
# Status code should be 403: Forbidden
- self.assertEquals(403, response.status_code)
- self.assertContains(response, '<h1>OpenID failed</h1>', status_code=403)
- self.assertContains(response, "An attribute required for logging in was not returned "
- "(nickname)", status_code=403)
+ self.assertEqual(403, response.status_code)
+ self.assertContains(
+ response, '<h1>OpenID failed</h1>', status_code=403)
+ self.assertContains(
+ response,
+ "An attribute required for logging in was not returned (nickname)",
+ status_code=403)
+ @override_settings(
+ OPENID_CREATE_USERS=True, OPENID_STRICT_USERNAMES=True,
+ OPENID_SREG_REQUIRED_FIELDS=[])
def test_strict_username_no_nickname_override(self):
- settings.OPENID_CREATE_USERS = True
- settings.OPENID_STRICT_USERNAMES = True
- settings.OPENID_SREG_REQUIRED_FIELDS = []
-
# Override the login_failure handler
def mock_login_failure_handler(request, message, status=403,
template_name=None,
exception=None):
- self.assertTrue(isinstance(exception, (RequiredAttributeNotReturned, MissingUsernameViolation)))
- return HttpResponse('Test Failure Override', status=200)
- settings.OPENID_RENDER_FAILURE = mock_login_failure_handler
+ self.assertIsInstance(
+ exception,
+ (RequiredAttributeNotReturned, MissingUsernameViolation))
+ return HttpResponse('Test Failure Override', status=200)
# Posting in an identity URL begins the authentication request:
- response = self.client.post('/openid/login/',
- {'openid_identifier': 'http://example.com/identity',
- 'next': '/getuser/'})
+ response = self.client.post(self.login_url, self.openid_req)
self.assertContains(response, 'OpenID transaction in progress')
# Complete the request, passing back some simple registration
@@ -966,31 +907,27 @@ class RelyingPartyTests(TestCase):
sreg_request = sreg.SRegRequest.fromOpenIDRequest(openid_request)
openid_response = openid_request.answer(True)
sreg_response = sreg.SRegResponse.extractResponse(
- sreg_request, {'nickname': '', # No nickname
+ sreg_request, {'nickname': '', # No nickname
'fullname': 'Some User',
'email': 'foo@example.com'})
openid_response.addExtension(sreg_response)
- response = self.complete(openid_response)
+ with self.settings(OPENID_RENDER_FAILURE=mock_login_failure_handler):
+ response = self.complete(openid_response)
- # Status code should be 200, since we over-rode the login_failure handler
- self.assertEquals(200, response.status_code)
+ # Status code should be 200, since we over-rode the login_failure
+ self.assertEqual(200, response.status_code)
self.assertContains(response, 'Test Failure Override')
def test_strict_username_duplicate_user(self):
- settings.OPENID_CREATE_USERS = True
- settings.OPENID_STRICT_USERNAMES = True
# Create a user with the same name as we'll pass back via sreg.
user = User.objects.create_user('someuser', 'someone@example.com')
- useropenid = UserOpenID(
+ UserOpenID.objects.create(
user=user,
claimed_id='http://example.com/different_identity',
display_id='http://example.com/different_identity')
- useropenid.save()
# Posting in an identity URL begins the authentication request:
- response = self.client.post('/openid/login/',
- {'openid_identifier': 'http://example.com/identity',
- 'next': '/getuser/'})
+ response = self.client.post(self.login_url, self.openid_req)
self.assertContains(response, 'OpenID transaction in progress')
# Complete the request, passing back some simple registration
@@ -1002,40 +939,37 @@ class RelyingPartyTests(TestCase):
sreg_request, {'nickname': 'someuser', 'fullname': 'Some User',
'email': 'foo@example.com'})
openid_response.addExtension(sreg_response)
- response = self.complete(openid_response)
+ with self.settings(
+ OPENID_CREATE_USERS=True, OPENID_STRICT_USERNAMES=True):
+ response = self.complete(openid_response)
# Status code should be 403: Forbidden
- self.assertEquals(403, response.status_code)
- self.assertContains(response, '<h1>OpenID failed</h1>', status_code=403)
- self.assertContains(response,
+ self.assertEqual(403, response.status_code)
+ self.assertContains(
+ response, '<h1>OpenID failed</h1>', status_code=403)
+ self.assertContains(
+ response,
"The username (someuser) with which you tried to log in is "
"already in use for a different account.",
status_code=403)
def test_strict_username_duplicate_user_override(self):
- settings.OPENID_CREATE_USERS = True
- settings.OPENID_STRICT_USERNAMES = True
-
# Override the login_failure handler
def mock_login_failure_handler(request, message, status=403,
template_name=None,
exception=None):
- self.assertTrue(isinstance(exception, DuplicateUsernameViolation))
- return HttpResponse('Test Failure Override', status=200)
- settings.OPENID_RENDER_FAILURE = mock_login_failure_handler
+ self.assertIsInstance(exception, DuplicateUsernameViolation)
+ return HttpResponse('Test Failure Override', status=200)
# Create a user with the same name as we'll pass back via sreg.
user = User.objects.create_user('someuser', 'someone@example.com')
- useropenid = UserOpenID(
+ UserOpenID.objects.create(
user=user,
claimed_id='http://example.com/different_identity',
display_id='http://example.com/different_identity')
- useropenid.save()
# Posting in an identity URL begins the authentication request:
- response = self.client.post('/openid/login/',
- {'openid_identifier': 'http://example.com/identity',
- 'next': '/getuser/'})
+ response = self.client.post(self.login_url, self.openid_req)
self.assertContains(response, 'OpenID transaction in progress')
# Complete the request, passing back some simple registration
@@ -1047,21 +981,18 @@ class RelyingPartyTests(TestCase):
sreg_request, {'nickname': 'someuser', 'fullname': 'Some User',
'email': 'foo@example.com'})
openid_response.addExtension(sreg_response)
- response = self.complete(openid_response)
+ with self.settings(
+ OPENID_RENDER_FAILURE=mock_login_failure_handler,
+ OPENID_CREATE_USERS=True, OPENID_STRICT_USERNAMES=True):
+ response = self.complete(openid_response)
- # Status code should be 200, since we over-rode the login_failure handler
- self.assertEquals(200, response.status_code)
+ # Status code should be 200, since we over-rode the login_failure
+ self.assertEqual(200, response.status_code)
self.assertContains(response, 'Test Failure Override')
def test_login_requires_sreg_required_fields(self):
- # If any required attributes are not included in the response,
- # we fail with a forbidden.
- settings.OPENID_CREATE_USERS = True
- settings.OPENID_SREG_REQUIRED_FIELDS = ('email', 'language')
# Posting in an identity URL begins the authentication request:
- response = self.client.post('/openid/login/',
- {'openid_identifier': 'http://example.com/identity',
- 'next': '/getuser/'})
+ response = self.client.post(self.login_url, self.openid_req)
self.assertContains(response, 'OpenID transaction in progress')
# Complete the request, passing back some simple registration
@@ -1074,52 +1005,52 @@ class RelyingPartyTests(TestCase):
'fullname': 'Some User',
'email': 'foo@example.com'})
openid_response.addExtension(sreg_response)
- response = self.complete(openid_response)
+ # If any required attributes are not included in the response,
+ # we fail with a forbidden.
+ with self.settings(
+ OPENID_CREATE_USERS=True,
+ OPENID_SREG_REQUIRED_FIELDS=('email', 'language')):
+ response = self.complete(openid_response)
# Status code should be 403: Forbidden as we didn't include
# a required field - language.
- self.assertContains(response,
- "An attribute required for logging in was not returned "
- "(language)", status_code=403)
+ self.assertContains(
+ response,
+ "An attribute required for logging in was not returned (language)",
+ status_code=403)
def test_login_update_details(self):
- settings.OPENID_UPDATE_DETAILS_FROM_SREG = True
user = User.objects.create_user('testuser', 'someone@example.com')
- useropenid = UserOpenID(
+ UserOpenID.objects.create(
user=user,
claimed_id='http://example.com/identity',
display_id='http://example.com/identity')
- useropenid.save()
- openid_req = {'openid_identifier': 'http://example.com/identity',
- 'next': '/getuser/'}
- openid_resp = {'nickname': 'testuser', 'fullname': 'Some User',
- 'email': 'foo@example.com'}
- self._do_user_login(openid_req, openid_resp)
- response = self.client.get('/getuser/')
+ self.openid_resp = {
+ 'nickname': 'testuser', 'fullname': 'Some User',
+ 'email': 'foo@example.com'}
+ with self.settings(OPENID_UPDATE_DETAILS_FROM_SREG=True):
+ self._do_user_login(self.openid_req, self.openid_resp)
+ response = self.client.get('/getuser/')
- self.assertEquals(response.content, 'testuser')
+ self.assertEqual(response.content, 'testuser')
# The user's full name and email have been updated.
user = User.objects.get(username=response.content)
- self.assertEquals(user.first_name, 'Some')
- self.assertEquals(user.last_name, 'User')
- self.assertEquals(user.email, 'foo@example.com')
+ self.assertEqual(user.first_name, 'Some')
+ self.assertEqual(user.last_name, 'User')
+ self.assertEqual(user.email, 'foo@example.com')
def test_login_uses_sreg_extra_fields(self):
- # The configurable sreg attributes are used in the request.
- settings.OPENID_SREG_EXTRA_FIELDS = ('language',)
user = User.objects.create_user('testuser', 'someone@example.com')
- useropenid = UserOpenID(
+ UserOpenID.objects.create(
user=user,
claimed_id='http://example.com/identity',
display_id='http://example.com/identity')
- useropenid.save()
# Posting in an identity URL begins the authentication request:
- response = self.client.post('/openid/login/',
- {'openid_identifier': 'http://example.com/identity',
- 'next': '/getuser/'})
+ with self.settings(OPENID_SREG_EXTRA_FIELDS=('language',)):
+ response = self.client.post(self.login_url, self.openid_req)
openid_request = self.provider.parseFormPost(response.content)
sreg_request = sreg.SRegRequest.fromOpenIDRequest(openid_request)
@@ -1128,18 +1059,15 @@ class RelyingPartyTests(TestCase):
def test_login_uses_sreg_required_fields(self):
# The configurable sreg attributes are used in the request.
- settings.OPENID_SREG_REQUIRED_FIELDS = ('email', 'language')
user = User.objects.create_user('testuser', 'someone@example.com')
- useropenid = UserOpenID(
+ UserOpenID.objects.create(
user=user,
claimed_id='http://example.com/identity',
display_id='http://example.com/identity')
- useropenid.save()
# Posting in an identity URL begins the authentication request:
- response = self.client.post('/openid/login/',
- {'openid_identifier': 'http://example.com/identity',
- 'next': '/getuser/'})
+ with self.settings(OPENID_SREG_REQUIRED_FIELDS=('email', 'language')):
+ response = self.client.post(self.login_url, self.openid_req)
openid_request = self.provider.parseFormPost(response.content)
sreg_request = sreg.SRegRequest.fromOpenIDRequest(openid_request)
@@ -1149,20 +1077,16 @@ class RelyingPartyTests(TestCase):
def check_login_attribute_exchange(self, validation_type, is_verified,
request_account_verified=True):
- settings.OPENID_UPDATE_DETAILS_FROM_SREG = True
user = User.objects.create_user('testuser', 'someone@example.com')
- useropenid = UserOpenID(
+ UserOpenID.objects.create(
user=user,
claimed_id='http://example.com/identity',
display_id='http://example.com/identity')
- useropenid.save()
# Configure the provider to advertise attribute exchange
# protocol and start the authentication process:
self.provider.type_uris.append('http://openid.net/srv/ax/1.0')
- response = self.client.post('/openid/login/',
- {'openid_identifier': 'http://example.com/identity',
- 'next': '/getuser/'})
+ response = self.client.post(self.login_url, self.openid_req)
self.assertContains(response, 'OpenID transaction in progress')
# The resulting OpenID request uses the Attribute Exchange
@@ -1173,28 +1097,20 @@ class RelyingPartyTests(TestCase):
self.assertEqual(sreg_request.optional, [])
fetch_request = ax.FetchRequest.fromOpenIDRequest(openid_request)
- self.assertTrue(fetch_request.has_key(
- 'http://axschema.org/contact/email'))
- self.assertTrue(fetch_request.has_key(
- 'http://axschema.org/namePerson'))
- self.assertTrue(fetch_request.has_key(
- 'http://axschema.org/namePerson/first'))
- self.assertTrue(fetch_request.has_key(
- 'http://axschema.org/namePerson/last'))
- self.assertTrue(fetch_request.has_key(
- 'http://axschema.org/namePerson/friendly'))
+ self.assertIn('http://axschema.org/contact/email', fetch_request)
+ self.assertIn('http://axschema.org/namePerson', fetch_request)
+ self.assertIn('http://axschema.org/namePerson/first', fetch_request)
+ self.assertIn('http://axschema.org/namePerson/last', fetch_request)
+ self.assertIn('http://axschema.org/namePerson/friendly', fetch_request)
# myOpenID compatibilty attributes:
- self.assertTrue(fetch_request.has_key(
- 'http://schema.openid.net/contact/email'))
- self.assertTrue(fetch_request.has_key(
- 'http://schema.openid.net/namePerson'))
- self.assertTrue(fetch_request.has_key(
- 'http://schema.openid.net/namePerson/friendly'))
+ self.assertIn('http://schema.openid.net/contact/email', fetch_request)
+ self.assertIn('http://schema.openid.net/namePerson', fetch_request)
+ self.assertIn(
+ 'http://schema.openid.net/namePerson/friendly', fetch_request)
+
# Account verification:
- self.assertEqual(
- fetch_request.has_key(
- 'http://ns.login.ubuntu.com/2013/validation/account'),
- request_account_verified)
+ validation = 'http://ns.login.ubuntu.com/2013/validation/account'
+ self.assertEqual(validation in fetch_request, request_account_verified)
# Build up a response including AX data.
openid_response = openid_request.answer(True)
@@ -1212,36 +1128,40 @@ class RelyingPartyTests(TestCase):
'http://ns.login.ubuntu.com/2013/validation/account',
validation_type)
openid_response.addExtension(fetch_response)
- response = self.complete(openid_response)
+ with self.settings(OPENID_UPDATE_DETAILS_FROM_SREG=True):
+ response = self.complete(openid_response)
self.assertRedirects(response, 'http://testserver/getuser/')
# And they are now logged in as testuser (the passed in
# nickname has not caused the username to change), because
- # settings.OPENID_FOLLOW_RENAMES is False.
+ assert not settings.OPENID_FOLLOW_RENAMES, (
+ 'OPENID_FOLLOW_RENAMES must be False')
response = self.client.get('/getuser/')
- self.assertEquals(response.content, 'testuser')
+ self.assertEqual(response.content, 'testuser')
# The user's full name and email have been updated.
user = User.objects.get(username='testuser')
- self.assertEquals(user.first_name, 'Firstname')
- self.assertEquals(user.last_name, 'Lastname')
- self.assertEquals(user.email, 'foo@example.com')
+ self.assertEqual(user.first_name, 'Firstname')
+ self.assertEqual(user.last_name, 'Lastname')
+ self.assertEqual(user.email, 'foo@example.com')
# So have the user's permissions
self.assertEqual(
user.has_perm('django_openid_auth.account_verified'), is_verified)
def test_login_attribute_exchange_with_verification(self):
- settings.OPENID_VALID_VERIFICATION_SCHEMES = {
+ schemes = {
self.provider.endpoint_url: ('token_via_email',),
}
- self.check_login_attribute_exchange('token_via_email',
- is_verified=True)
+ with self.settings(OPENID_VALID_VERIFICATION_SCHEMES=schemes):
+ self.check_login_attribute_exchange('token_via_email',
+ is_verified=True)
def test_login_attribute_exchange_without_verification(self):
- settings.OPENID_VALID_VERIFICATION_SCHEMES = {
+ schemes = {
self.provider.endpoint_url: ('token_via_email',),
}
- self.check_login_attribute_exchange(None, is_verified=False)
+ with self.settings(OPENID_VALID_VERIFICATION_SCHEMES=schemes):
+ self.check_login_attribute_exchange(None, is_verified=False)
def test_login_attribute_exchange_without_account_verified(self):
# don't request account_verified attribute in AX request (as there are
@@ -1252,32 +1172,32 @@ class RelyingPartyTests(TestCase):
request_account_verified=False)
def test_login_attribute_exchange_unrecognised_verification(self):
- settings.OPENID_VALID_VERIFICATION_SCHEMES = {
+ schemes = {
self.provider.endpoint_url: ('token_via_email',),
}
- self.check_login_attribute_exchange('unrecognised_scheme',
- is_verified=False)
+ with self.settings(OPENID_VALID_VERIFICATION_SCHEMES=schemes):
+ self.check_login_attribute_exchange('unrecognised_scheme',
+ is_verified=False)
def test_login_attribute_exchange_different_default_verification(self):
- settings.OPENID_VALID_VERIFICATION_SCHEMES = {
+ schemes = {
None: ('token_via_email', 'sms'),
'http://otherprovider/': ('unrecognised_scheme',),
}
- self.check_login_attribute_exchange('unrecognised_scheme',
- is_verified=False)
+ with self.settings(OPENID_VALID_VERIFICATION_SCHEMES=schemes):
+ self.check_login_attribute_exchange('unrecognised_scheme',
+ is_verified=False)
def test_login_attribute_exchange_matched_default_verification(self):
- settings.OPENID_VALID_VERIFICATION_SCHEMES = {
+ schemes = {
None: ('token_via_email',),
'http://otherprovider/': ('unrecognised_scheme',),
}
- self.check_login_attribute_exchange('token_via_email',
- is_verified=True)
+ with self.settings(OPENID_VALID_VERIFICATION_SCHEMES=schemes):
+ self.check_login_attribute_exchange('token_via_email',
+ is_verified=True)
def test_login_teams(self):
- settings.OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO = False
- settings.OPENID_LAUNCHPAD_TEAMS_MAPPING = {'teamname': 'groupname',
- 'otherteam': 'othergroup'}
user = User.objects.create_user('testuser', 'someone@example.com')
group = Group(name='groupname')
group.save()
@@ -1291,16 +1211,13 @@ class RelyingPartyTests(TestCase):
Permission.objects.get(codename='add_useropenid'))
user.groups.add(ogroup)
user.save()
- useropenid = UserOpenID(
+ UserOpenID.objects.create(
user=user,
claimed_id='http://example.com/identity',
display_id='http://example.com/identity')
- useropenid.save()
# Posting in an identity URL begins the authentication request:
- response = self.client.post('/openid/login/',
- {'openid_identifier': 'http://example.com/identity',
- 'next': '/getuser/'})
+ response = self.client.post(self.login_url, self.openid_req)
self.assertContains(response, 'OpenID transaction in progress')
# Complete the request
@@ -1310,23 +1227,23 @@ class RelyingPartyTests(TestCase):
teams_response = teams.TeamsResponse.extractResponse(
teams_request, 'teamname,some-other-team')
openid_response.addExtension(teams_response)
- response = self.complete(openid_response)
+ mapping = {'teamname': 'groupname', 'otherteam': 'othergroup'}
+ with self.settings(
+ OPENID_LAUNCHPAD_TEAMS_MAPPING=mapping,
+ OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO=False):
+ response = self.complete(openid_response)
self.assertRedirects(response, 'http://testserver/getuser/')
# And they are now logged in as testuser
response = self.client.get('/getuser/')
- self.assertEquals(response.content, 'testuser')
+ self.assertEqual(response.content, 'testuser')
# The user's groups have been updated.
- user = User.objects.get(username='testuser')
- self.assertTrue(group in user.groups.all())
- self.assertTrue(ogroup not in user.groups.all())
+ User.objects.get(username='testuser')
+ self.assertIn(group, user.groups.all())
+ self.assertNotIn(ogroup, user.groups.all())
def test_login_teams_automapping(self):
- settings.OPENID_LAUNCHPAD_TEAMS_MAPPING = {'teamname': 'groupname',
- 'otherteam': 'othergroup'}
- settings.OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO = True
- settings.OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO_BLACKLIST = ['django-group1', 'django-group2']
user = User.objects.create_user('testuser', 'someone@example.com')
group1 = Group(name='django-group1')
group1.save()
@@ -1335,26 +1252,29 @@ class RelyingPartyTests(TestCase):
group3 = Group(name='django-group3')
group3.save()
user.save()
- useropenid = UserOpenID(
+ UserOpenID.objects.create(
user=user,
claimed_id='http://example.com/identity',
display_id='http://example.com/identity')
- useropenid.save()
# Posting in an identity URL begins the authentication request:
- response = self.client.post('/openid/login/',
- {'openid_identifier': 'http://example.com/identity',
- 'next': '/getuser/'})
+ response = self.client.post(self.login_url, self.openid_req)
self.assertContains(response, 'OpenID transaction in progress')
# Complete the request
- openid_request = self.provider.parseFormPost(response.content)
- openid_response = openid_request.answer(True)
- teams_request = teams.TeamsRequest.fromOpenIDRequest(openid_request)
-
- self.assertEqual(group1 in user.groups.all(), False)
- self.assertEqual(group2 in user.groups.all(), False)
- self.assertTrue(group3 not in user.groups.all())
+ mapping = {'teamname': 'groupname', 'otherteam': 'othergroup'}
+ blacklist = ['django-group1', 'django-group2']
+ with self.settings(
+ OPENID_LAUNCHPAD_TEAMS_MAPPING=mapping,
+ OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO=True,
+ OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO_BLACKLIST=blacklist):
+ openid_request = self.provider.parseFormPost(response.content)
+ openid_request.answer(True)
+ teams.TeamsRequest.fromOpenIDRequest(openid_request)
+
+ self.assertNotIn(group1, user.groups.all())
+ self.assertNotIn(group2, user.groups.all())
+ self.assertNotIn(group3, user.groups.all())
def test_login_teams_staff_not_defined(self):
assert getattr(settings, 'OPENID_LAUNCHPAD_STAFF_TEAMS', None) is None
@@ -1363,39 +1283,42 @@ class RelyingPartyTests(TestCase):
user.save()
self.assertTrue(user.is_staff)
- user = self.get_openid_authed_user_with_teams(user, 'teamname,some-other-team')
+ user = self.get_openid_authed_user_with_teams(
+ user, 'teamname,some-other-team')
self.assertTrue(user.is_staff)
def test_login_teams_staff_assignment(self):
- settings.OPENID_LAUNCHPAD_STAFF_TEAMS = ('teamname',)
user = User.objects.create_user('testuser', 'someone@example.com')
user.is_staff = False
user.save()
self.assertFalse(user.is_staff)
- user = self.get_openid_authed_user_with_teams(user, 'teamname,some-other-team')
+ with self.settings(
+ OPENID_LAUNCHPAD_STAFF_TEAMS=('teamname',)):
+ user = self.get_openid_authed_user_with_teams(
+ user, 'teamname,some-other-team')
self.assertTrue(user.is_staff)
def test_login_teams_staff_unassignment(self):
- settings.OPENID_LAUNCHPAD_STAFF_TEAMS = ('different-teamname',)
user = User.objects.create_user('testuser', 'someone@example.com')
user.is_staff = True
user.save()
self.assertTrue(user.is_staff)
- user = self.get_openid_authed_user_with_teams(user, 'teamname,some-other-team')
+ with self.settings(
+ OPENID_LAUNCHPAD_STAFF_TEAMS=('different-teamname',)):
+ user = self.get_openid_authed_user_with_teams(
+ user, 'teamname,some-other-team')
self.assertFalse(user.is_staff)
def get_openid_authed_user_with_teams(self, user, teams_str):
- useropenid = UserOpenID(
+ UserOpenID.objects.create(
user=user,
claimed_id='http://example.com/identity',
display_id='http://example.com/identity')
- useropenid.save()
# Posting in an identity URL begins the authentication request:
- response = self.client.post('/openid/login/',
- {'openid_identifier': 'http://example.com/identity'})
+ response = self.client.post(self.login_url, self.openid_req_no_next)
# Complete the request
openid_request = self.provider.parseFormPost(response.content)
@@ -1411,23 +1334,24 @@ class RelyingPartyTests(TestCase):
# An oauth_login_complete signal is emitted including the
# request and sreg_response.
user = User.objects.create_user('someuser', 'someone@example.com')
- useropenid = UserOpenID(
+ UserOpenID.objects.create(
user=user,
claimed_id='http://example.com/identity',
display_id='http://example.com/identity')
- useropenid.save()
- response = self.client.post('/openid/login/',
- {'openid_identifier': 'http://example.com/identity'})
+
+ response = self.client.post(self.login_url, self.openid_req_no_next)
openid_request = self.provider.parseFormPost(response.content)
openid_response = openid_request.answer(True)
# Use a closure to test whether the signal handler was called.
self.signal_handler_called = False
+
def login_callback(sender, **kwargs):
- self.assertTrue(isinstance(
- kwargs.get('request', None), HttpRequest))
- self.assertTrue(isinstance(
- kwargs.get('openid_response', None), SuccessResponse))
+ self.assertIsInstance(
+ kwargs.get('request', None), HttpRequest)
+ self.assertIsInstance(
+ kwargs.get('openid_response', None), SuccessResponse)
self.signal_handler_called = True
+
openid_login_complete.connect(login_callback)
response = self.complete(openid_response)
@@ -1438,9 +1362,11 @@ class RelyingPartyTests(TestCase):
@override_session_serializer
class HelperFunctionsTest(TestCase):
+
+ domains = ["example.com", "example.org"]
+
+ @override_settings(ALLOWED_EXTERNAL_OPENID_REDIRECT_DOMAINS=domains)
def test_sanitise_redirect_url(self):
- settings.ALLOWED_EXTERNAL_OPENID_REDIRECT_DOMAINS = [
- "example.com", "example.org"]
# list of URLs and whether they should be passed or not
urls = [
("http://example.com", True),
@@ -1462,6 +1388,3 @@ class HelperFunctionsTest(TestCase):
self.assertEqual(url, sanitised)
else:
self.assertEqual(settings.LOGIN_REDIRECT_URL, sanitised)
-
-def suite():
- return unittest.TestLoader().loadTestsFromName(__name__)
diff --git a/django_openid_auth/tests/urls.py b/django_openid_auth/tests/urls.py
index 04ae954..d30e01d 100644
--- a/django_openid_auth/tests/urls.py
+++ b/django_openid_auth/tests/urls.py
@@ -26,14 +26,18 @@
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
+from __future__ import unicode_literals
+
+from django.conf.urls import patterns, include
from django.http import HttpResponse
-from django.conf.urls import *
def get_user(request):
return HttpResponse(request.user.username)
-urlpatterns = patterns('',
+
+urlpatterns = patterns(
+ '',
(r'^getuser/$', get_user),
(r'^openid/', include('django_openid_auth.urls')),
)
diff --git a/django_openid_auth/urls.py b/django_openid_auth/urls.py
index 629383a..c984671 100644
--- a/django_openid_auth/urls.py
+++ b/django_openid_auth/urls.py
@@ -27,9 +27,12 @@
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
-from django.conf.urls import *
+from __future__ import unicode_literals
-urlpatterns = patterns('django_openid_auth.views',
+from django.conf.urls import patterns, url
+
+urlpatterns = patterns(
+ 'django_openid_auth.views',
url(r'^login/$', 'login_begin', name='openid-login'),
url(r'^complete/$', 'login_complete', name='openid-complete'),
url(r'^logo.gif$', 'logo', name='openid-logo'),
diff --git a/django_openid_auth/views.py b/django_openid_auth/views.py
index 50d74e8..dc9c248 100644
--- a/django_openid_auth/views.py
+++ b/django_openid_auth/views.py
@@ -27,6 +27,8 @@
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
+from __future__ import unicode_literals
+
import re
import urllib
from urlparse import urlsplit
@@ -62,6 +64,7 @@ from django_openid_auth.exceptions import (
next_url_re = re.compile('^/[-\w/]+$')
+
def is_valid_next_url(next):
# When we allow this:
# /openid/?next=/welcome/
@@ -78,8 +81,8 @@ def sanitise_redirect_url(redirect_to):
is_valid = False
elif '//' in redirect_to:
# Allow the redirect URL to be external if it's a permitted domain
- allowed_domains = getattr(settings,
- "ALLOWED_EXTERNAL_OPENID_REDIRECT_DOMAINS", [])
+ allowed_domains = getattr(
+ settings, "ALLOWED_EXTERNAL_OPENID_REDIRECT_DOMAINS", [])
s, netloc, p, q, f = urlsplit(redirect_to)
# allow it if netloc is blank or if the domain is allowed
if netloc:
@@ -113,11 +116,13 @@ def render_openid_request(request, openid_request, return_to, trust_root=None):
if openid_request.shouldSendRedirect():
redirect_url = openid_request.redirectURL(
trust_root, return_to)
- return HttpResponseRedirect(redirect_url)
+ response = HttpResponseRedirect(redirect_url)
else:
form_html = openid_request.htmlMarkup(
trust_root, return_to, form_tag_attrs={'id': 'openid_message'})
- return HttpResponse(form_html, content_type='text/html;charset=UTF-8')
+ response = HttpResponse(
+ form_html, content_type='text/html;charset=UTF-8')
+ return response
def default_render_failure(request, message, status=403,
@@ -133,7 +138,7 @@ def default_render_failure(request, message, status=403,
def parse_openid_response(request):
"""Parse an OpenID response from a Django request."""
# Short cut if there is no request parameters.
- #if len(request.REQUEST) == 0:
+ # if len(request.REQUEST) == 0:
# return None
current_url = request.build_absolute_uri()
@@ -164,15 +169,15 @@ def login_begin(request, template_name='openid/login.html',
# Invalid or no form data:
if openid_url is None:
- return render_to_response(template_name, {
- 'form': login_form,
- redirect_field_name: redirect_to
- }, context_instance=RequestContext(request))
+ context = {'form': login_form, redirect_field_name: redirect_to}
+ return render_to_response(
+ template_name, context,
+ context_instance=RequestContext(request))
consumer = make_consumer(request)
try:
openid_request = consumer.begin(openid_url)
- except DiscoveryFailure, exc:
+ except DiscoveryFailure as exc:
return render_failure(
request, "OpenID discovery error: %s" % (str(exc),), status=500,
exception=exc)
@@ -222,11 +227,11 @@ def login_begin(request, template_name='openid/login.html',
sreg_optional_fields.extend(
getattr(settings, 'OPENID_SREG_EXTRA_FIELDS', []))
sreg_optional_fields = [
- field for field in sreg_optional_fields if (
- not field in sreg_required_fields)]
+ field for field in sreg_optional_fields
+ if field not in sreg_required_fields]
openid_request.addExtension(
sreg.SRegRequest(optional=sreg_optional_fields,
- required=sreg_required_fields))
+ required=sreg_required_fields))
if getattr(settings, 'OPENID_PHYSICAL_MULTIFACTOR_REQUIRED', False):
preferred_auth = [
@@ -236,13 +241,16 @@ def login_begin(request, template_name='openid/login.html',
openid_request.addExtension(pape_request)
# Request team info
- teams_mapping_auto = getattr(settings, 'OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO', False)
- teams_mapping_auto_blacklist = getattr(settings, 'OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO_BLACKLIST', [])
+ teams_mapping_auto = getattr(
+ settings, 'OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO', False)
+ teams_mapping_auto_blacklist = getattr(
+ settings, 'OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO_BLACKLIST', [])
launchpad_teams = getattr(settings, 'OPENID_LAUNCHPAD_TEAMS_MAPPING', {})
if teams_mapping_auto:
- #ignore launchpad teams. use all django-groups
+ # ignore launchpad teams. use all django-groups
launchpad_teams = dict()
- all_groups = Group.objects.exclude(name__in=teams_mapping_auto_blacklist)
+ all_groups = Group.objects.exclude(
+ name__in=teams_mapping_auto_blacklist)
for group in all_groups:
launchpad_teams[group.name] = group.name
@@ -270,9 +278,9 @@ def login_begin(request, template_name='openid/login.html',
def login_complete(request, redirect_field_name=REDIRECT_FIELD_NAME,
render_failure=None):
redirect_to = request.REQUEST.get(redirect_field_name, '')
- render_failure = render_failure or \
- getattr(settings, 'OPENID_RENDER_FAILURE', None) or \
- default_render_failure
+ render_failure = (
+ render_failure or getattr(settings, 'OPENID_RENDER_FAILURE', None) or
+ default_render_failure)
openid_response = parse_openid_response(request)
if not openid_response:
@@ -288,10 +296,12 @@ def login_complete(request, redirect_field_name=REDIRECT_FIELD_NAME,
if user is not None:
if user.is_active:
auth_login(request, user)
- response = HttpResponseRedirect(sanitise_redirect_url(redirect_to))
+ response = HttpResponseRedirect(
+ sanitise_redirect_url(redirect_to))
# Notify any listeners that we successfully logged in.
- openid_login_complete.send(sender=UserOpenID, request=request,
+ openid_login_complete.send(
+ sender=UserOpenID, request=request,
openid_response=openid_response)
return response
diff --git a/example_consumer/settings.py b/example_consumer/settings.py
index af1fc3b..bd5e5cb 100644
--- a/example_consumer/settings.py
+++ b/example_consumer/settings.py
@@ -27,91 +27,44 @@
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
-# Django settings for example project.
-import django
-django_version = django.get_version()
-DEBUG = True
-TEMPLATE_DEBUG = DEBUG
+"""
+Django settings for example_consumer project.
-ADMINS = (
- # ('Your Name', 'your_email@domain.com'),
-)
+For more information on this file, see
+https://docs.djangoproject.com/en/1.7/topics/settings/
-MANAGERS = ADMINS
+For the full list of settings and their values, see
+https://docs.djangoproject.com/en/1.7/ref/settings/
+"""
-if django_version >= "1.2":
- csrf_middleware = 'django.middleware.csrf.CsrfViewMiddleware'
- DATABASES = {
- 'default': {
- 'ENGINE': 'django.db.backends.sqlite3',
- 'NAME': 'sqlite.db',
- }
- }
- TEMPLATE_LOADERS = (
- 'django.template.loaders.filesystem.Loader',
- 'django.template.loaders.app_directories.Loader',
- )
-else:
- csrf_middleware = 'django.contrib.csrf.middleware.CsrfViewMiddleware'
- TEMPLATE_LOADERS = (
- 'django.template.loaders.filesystem.load_template_source',
- 'django.template.loaders.app_directories.load_template_source',
- )
- DATABASE_ENGINE = 'sqlite3' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'.
- DATABASE_NAME = 'sqlite.db' # Or path to database file if using sqlite3.
- DATABASE_USER = '' # Not used with sqlite3.
- DATABASE_PASSWORD = '' # Not used with sqlite3.
- DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3.
- DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3.
-
-# Local time zone for this installation. Choices can be found here:
-# http://www.postgresql.org/docs/8.1/static/datetime-keywords.html#DATETIME-TIMEZONE-SET-TABLE
-# although not all variations may be possible on all operating systems.
-# If running in a Windows environment this must be set to the same as your
-# system time zone.
-TIME_ZONE = 'America/Chicago'
-
-# Language code for this installation. All choices can be found here:
-# http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes
-# http://blogs.law.harvard.edu/tech/stories/storyReader$15
-LANGUAGE_CODE = 'en-us'
+# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
+import os
+import django
-SITE_ID = 1
+BASE_DIR = os.path.dirname(os.path.dirname(__file__))
-# If you set this to False, Django will make some optimizations so as not
-# to load the internationalization machinery.
-USE_I18N = True
-# Absolute path to the directory that holds media.
-# Example: "/home/media/media.lawrence.com/"
-MEDIA_ROOT = ''
+# Quick-start development settings - unsuitable for production
+# See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/
+
+# SECURITY WARNING: keep the secret key used in production secret!
+SECRET_KEY = '34958734985734985734985798437'
-# URL that handles the media served from MEDIA_ROOT.
-# Example: "http://media.lawrence.com"
-MEDIA_URL = ''
+# SECURITY WARNING: don't run with debug turned on in production!
+DEBUG = True
-# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
-# trailing slash.
-# Examples: "http://foo.com/media/", "/media/".
-ADMIN_MEDIA_PREFIX = '/media/'
+TEMPLATE_DEBUG = True
-# Make this unique, and don't share it with anybody.
-SECRET_KEY = '34958734985734985734985798437'
+ALLOWED_HOSTS = []
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
- csrf_middleware,
+ 'django.middleware.csrf.CsrfViewMiddleware',
)
-ROOT_URLCONF = 'example_consumer.urls'
-
-TEMPLATE_DIRS = (
- # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
- # Always use forward slashes, even on Windows.
- # Don't forget to use absolute paths, not relative paths.
-)
+# Application definition
INSTALLED_APPS = (
'django.contrib.auth',
@@ -119,9 +72,46 @@ INSTALLED_APPS = (
'django.contrib.sessions',
'django.contrib.admin',
'django_openid_auth',
- 'south',
)
+if django.VERSION < (1, 7):
+ INSTALLED_APPS += ('south',)
+
+ROOT_URLCONF = 'example_consumer.urls'
+
+WSGI_APPLICATION = 'example_consumer.wsgi.application'
+
+# Database
+# https://docs.djangoproject.com/en/1.7/ref/settings/#databases
+
+DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.sqlite3',
+ 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
+ }
+}
+
+# Internationalization
+# https://docs.djangoproject.com/en/1.7/topics/i18n/
+
+LANGUAGE_CODE = 'en-us'
+
+TIME_ZONE = 'UTC'
+
+USE_I18N = True
+
+USE_TZ = True
+
+# Static files (CSS, JavaScript, Images)
+# https://docs.djangoproject.com/en/1.7/howto/static-files/
+
+STATIC_URL = '/static/'
+
+# the library python-openid does not support a json session serializer
+# <openid.yadis.manager.YadisServiceManager> is not JSON serializable
+# https://github.com/openid/python-openid/issues/17
+SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'
+
AUTHENTICATION_BACKENDS = (
'django_openid_auth.auth.OpenIDBackend',
'django.contrib.auth.backends.ModelBackend',
@@ -144,7 +134,7 @@ OPENID_VALID_VERIFICATION_SCHEMES = {
# If set, always use this as the identity URL rather than asking the
# user. This only makes sense if it is a server URL.
-OPENID_SSO_SERVER_URL = 'https://login.launchpad.net/'
+OPENID_SSO_SERVER_URL = 'https://login.ubuntu.com/'
# Tell django.contrib.auth to use the OpenID signin URLs.
LOGIN_URL = '/openid/login/'
diff --git a/example_consumer/urls.py b/example_consumer/urls.py
index 4a9013c..40cb233 100644
--- a/example_consumer/urls.py
+++ b/example_consumer/urls.py
@@ -27,7 +27,7 @@
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
-from django.conf.urls import *
+from django.conf.urls import patterns, include, url
from django.contrib import admin
import views
@@ -35,11 +35,12 @@ import views
admin.autodiscover()
-urlpatterns = patterns('',
- (r'^$', views.index),
- (r'^openid/', include('django_openid_auth.urls')),
- (r'^logout/$', 'django.contrib.auth.views.logout'),
- (r'^private/$', views.require_authentication),
+urlpatterns = patterns(
+ '',
+ url(r'^$', views.index),
+ url(r'^openid/', include('django_openid_auth.urls')),
+ url(r'^logout/$', 'django.contrib.auth.views.logout'),
+ url(r'^private/$', views.require_authentication),
- (r'^admin/', include(admin.site.urls)),
+ url(r'^admin/', include(admin.site.urls)),
)
diff --git a/example_consumer/wsgi.py b/example_consumer/wsgi.py
new file mode 100644
index 0000000..ef48754
--- /dev/null
+++ b/example_consumer/wsgi.py
@@ -0,0 +1,14 @@
+"""
+WSGI config for demo project.
+
+It exposes the WSGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/1.7/howto/deployment/wsgi/
+"""
+
+import os
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "demo.settings")
+
+from django.core.wsgi import get_wsgi_application
+application = get_wsgi_application()
diff --git a/example_consumer/manage.py b/manage.py
index f9726f9..153bbe7 100755
--- a/example_consumer/manage.py
+++ b/manage.py
@@ -3,7 +3,7 @@ import os
import sys
if __name__ == "__main__":
- os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
+ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "example_consumer.settings")
from django.core.management import execute_from_command_line
diff --git a/setup.py b/setup.py
index a4669f7..089390c 100644
--- a/setup.py
+++ b/setup.py
@@ -43,7 +43,7 @@ from distutils.core import setup
description, long_description = __doc__.split('\n\n', 1)
-VERSION = '0.5'
+VERSION = '0.6'
setup(
name='django-openid-auth',
diff --git a/tox.ini b/tox.ini
index 28b8703..f6c4518 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,25 +1,42 @@
[tox]
envlist =
- py2.7-django1.4, py2.7-django1.5, py2.7-django1.6
+ py2.7-django1.4, py2.7-django1.5, py2.7-django1.6, py2.7-django1.7, py2.7-django1.8
[testenv]
-commands = make check
+commands = python manage.py test django_openid_auth
+deps=
+ mock
+ python-openid
-# Python 2.7
[testenv:py2.7-django1.4]
basepython = python2.7
-deps = django >= 1.4, < 1.5
- python-openid
- south
+deps =
+ django >= 1.4, < 1.5
+ {[testenv]deps}
+ south==1.0
[testenv:py2.7-django1.5]
basepython = python2.7
-deps = django >= 1.5, < 1.6
- python-openid
- south
+deps =
+ django >= 1.5, < 1.6
+ {[testenv]deps}
+ south==1.0
[testenv:py2.7-django1.6]
basepython = python2.7
-deps = django >= 1.6, < 1.7
- python-openid
- south
+deps =
+ django >= 1.6, < 1.7
+ {[testenv]deps}
+ south==1.0
+
+[testenv:py2.7-django1.7]
+basepython = python2.7
+deps =
+ django >= 1.7, < 1.8
+ {[testenv]deps}
+
+[testenv:py2.7-django1.8]
+basepython = python2.7
+deps =
+ django >= 1.8, < 1.9
+ {[testenv]deps}