Permalink
Browse files

Merge commit 'simonw/master' into upstream

Conflicts:
	django_openid/tests/auth_tests.py
  • Loading branch information...
2 parents b541933 + cd6d304 commit 455693a87c64f7493fc892ba1ff92245e6694fe6 @brosner committed Aug 13, 2009
View
@@ -1,15 +1,13 @@
from django.http import HttpResponseRedirect as Redirect, Http404
from django_openid import consumer, signed
+from django_openid.utils import hex_to_int, int_to_hex
from django.conf import settings
from django.contrib.auth import authenticate
from django.core.mail import send_mail
import hashlib, datetime
from urlparse import urljoin
-hex_to_int = lambda s: int(s, 16)
-int_to_hex = lambda i: hex(i).replace('0x', '').lower().replace('l', '')
-
# TODO: prevent multiple associations of same OpenID
class AuthConsumer(consumer.SessionConsumer):
@@ -31,6 +29,7 @@ class AuthConsumer(consumer.SessionConsumer):
recovery_complete_template = 'django_openid/recovery_complete.html'
recovery_email_from = None
+ recovery_email_subject = 'Recover your account'
password_logins_enabled = True
account_recovery_enabled = True
@@ -45,6 +44,8 @@ class AuthConsumer(consumer.SessionConsumer):
bad_password_message = 'Incorrect username or password'
invalid_token_message = 'Invalid token'
recovery_email_sent_message = 'Check your mail for further instructions'
+ recovery_not_found_message = 'No matching user was found'
+ recovery_multiple_found_message = 'Try entering your username instead'
r_user_not_found_message = 'That user account does not exist'
account_recovery_url = None
@@ -67,8 +68,8 @@ def show_login(self, request, extra_message=None):
)
if self.password_logins_enabled:
- response.template = self.login_plus_password_template
- response.context.update({
+ response.template_name = self.login_plus_password_template
+ response.template_context.update({
'account_recovery': self.account_recovery_enabled and (
self.account_recovery_url or (request.path + 'recover/')
),
@@ -248,7 +249,7 @@ def show_associate_done(self, request, openid):
return response
def need_authenticated_user(self, request):
- return self.show_error(self.need_authenticated_user_message)
+ return self.show_error(request, self.need_authenticated_user_message)
def do_associations(self, request):
"Interface for managing your account's associated OpenIDs"
@@ -305,7 +306,7 @@ def do_recover(self, request, extra_message = None):
users = self.lookup_users_by_email(submitted)
if users:
if len(users) > 1:
- extra_message = 'Try entering your username instead'
+ extra_message = self.recovery_multiple_found_message
user = None
else:
user = users[0]
@@ -314,6 +315,8 @@ def do_recover(self, request, extra_message = None):
return self.show_message(
request, 'E-mail sent', self.recovery_email_sent_message
)
+ else:
+ extra_message = self.recovery_not_found_message
return self.render(request, self.recover_template, {
'action': request.path,
'message': extra_message,
@@ -373,7 +376,7 @@ def do_r(self, request, token = ''):
'associate_url': urljoin(request.path, '../../associations/'),
'user': user,
})
- do_r.urlregex = '^r/([\w.]+)/$'
+ do_r.urlregex = '^r/([^/]+)/$'
def generate_recovery_code(self, user):
# Code is {hex-days}.{hex-userid}.{signature}
@@ -394,7 +397,7 @@ def send_recovery_email(self, request, user):
'code': code,
'user': user,
}).content
- send_email(
+ send_mail(
subject = self.recovery_email_subject,
message = email_body,
from_email = self.recovery_email_from or \
No changes.
@@ -0,0 +1,19 @@
+from django_openid.provider import Provider
+from django.shortcuts import render_to_response as render
+
+class AnonProvider(Provider):
+ def user_is_logged_in(self, *args):
+ return True
+
+ def user_owns_openid(self, *args):
+ return True
+
+ def user_trusts_root(self, *args):
+ return True
+
+def openid_page(request, slug):
+ return render('openid_page.html', {
+ 'slug': slug,
+ 'full_url': request.build_absolute_uri(),
+ 'server_url': request.build_absolute_uri('/server/'),
+ })
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+ "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<link rel="openid2.provider" href="{{ server_url }}">
+<title>An OpenID: {{ full_url }}</title>
+</head>
+<body>
+This is {{ full_url }}
+</body>
+</html>
@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+import sys
+sys.path.insert(0, '../../../') # parent of django_openid directory
+from django.core.management import execute_manager
+try:
+ import settings # Assumed to be in the same directory.
+except ImportError:
+ import sys
+ sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
+ sys.exit(1)
+
+if __name__ == "__main__":
+ execute_manager(settings)
@@ -0,0 +1,76 @@
+DEBUG = True
+TEMPLATE_DEBUG = DEBUG
+
+ADMINS = (
+ # ('Your Name', 'your_email@domain.com'),
+)
+
+MANAGERS = ADMINS
+
+DATABASE_ENGINE = 'sqlite3' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
+DATABASE_NAME = 'data.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://en.wikipedia.org/wiki/List_of_tz_zones_by_name
+# although not all choices may be available on all operating systems.
+# If running in a Windows environment this must be set to the same as your
+# system time zone.
+TIME_ZONE = 'Europe/London'
+
+# Language code for this installation. All choices can be found here:
+# http://www.i18nguy.com/unicode/language-identifiers.html
+LANGUAGE_CODE = 'en-gb'
+
+SITE_ID = 1
+
+# 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 = ''
+
+# URL that handles the media served from MEDIA_ROOT. Make sure to use a
+# trailing slash if there is a path component (optional in other cases).
+# Examples: "http://media.lawrence.com", "http://example.com/media/"
+MEDIA_URL = ''
+
+# 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/'
+
+# Make this unique, and don't share it with anybody.
+SECRET_KEY = '_vpc(7bu)r323l2td%)o&c&!$)8n(rh55^@#3)=h&^z6)%2w&0'
+
+# List of callables that know how to import templates from various sources.
+TEMPLATE_LOADERS = (
+ 'django.template.loaders.filesystem.load_template_source',
+ 'django.template.loaders.app_directories.load_template_source',
+# 'django.template.loaders.eggs.load_template_source',
+)
+
+MIDDLEWARE_CLASSES = (
+ 'django.middleware.common.CommonMiddleware',
+ 'django.contrib.sessions.middleware.SessionMiddleware',
+ 'django.contrib.auth.middleware.AuthenticationMiddleware',
+)
+
+ROOT_URLCONF = '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.
+)
+
+INSTALLED_APPS = (
+ 'django.contrib.sessions',
+ 'django_openid',
+ 'anon_provider',
+)
@@ -0,0 +1,9 @@
+from django.conf.urls.defaults import *
+from django.http import HttpResponseRedirect
+from anon_provider import AnonProvider, openid_page
+
+urlpatterns = patterns('',
+ (r'^$', lambda r: HttpResponseRedirect('/openid/')),
+ (r'^server/$', AnonProvider()),
+ (r'^(\w+)/$', openid_page),
+)
@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+import sys
+sys.path.insert(0, '../../../') # parent of django_openid directory
+from django.core.management import execute_manager
+try:
+ import settings # Assumed to be in the same directory.
+except ImportError:
+ import sys
+ sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
+ sys.exit(1)
+
+if __name__ == "__main__":
+ execute_manager(settings)
@@ -0,0 +1,83 @@
+# run "python -m smtpd -n -c DebuggingServer localhost:1025" to see outgoing
+# messages dumped to the terminal
+EMAIL_HOST = 'localhost'
+EMAIL_PORT = 1025
+
+DEBUG = True
+TEMPLATE_DEBUG = DEBUG
+
+ADMINS = (
+ # ('Your Name', 'your_email@domain.com'),
+)
+
+MANAGERS = ADMINS
+
+DATABASE_ENGINE = 'sqlite3' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
+DATABASE_NAME = 'data.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://en.wikipedia.org/wiki/List_of_tz_zones_by_name
+# although not all choices may be available on all operating systems.
+# If running in a Windows environment this must be set to the same as your
+# system time zone.
+TIME_ZONE = 'Europe/London'
+
+# Language code for this installation. All choices can be found here:
+# http://www.i18nguy.com/unicode/language-identifiers.html
+LANGUAGE_CODE = 'en-gb'
+
+SITE_ID = 1
+
+# 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 = ''
+
+# URL that handles the media served from MEDIA_ROOT. Make sure to use a
+# trailing slash if there is a path component (optional in other cases).
+# Examples: "http://media.lawrence.com", "http://example.com/media/"
+MEDIA_URL = ''
+
+# 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/'
+
+# Make this unique, and don't share it with anybody.
+SECRET_KEY = '_vpc(7bu)r323l2td%)o&c&!$)8n(rh55^@#3)=h&^z6)%2w&0'
+
+# List of callables that know how to import templates from various sources.
+TEMPLATE_LOADERS = (
+ 'django.template.loaders.filesystem.load_template_source',
+ 'django.template.loaders.app_directories.load_template_source',
+# 'django.template.loaders.eggs.load_template_source',
+)
+
+MIDDLEWARE_CLASSES = (
+ 'django.middleware.common.CommonMiddleware',
+ 'django.contrib.sessions.middleware.SessionMiddleware',
+ 'django.contrib.auth.middleware.AuthenticationMiddleware',
+ 'django_openid.registration.RegistrationConsumer',
+)
+
+ROOT_URLCONF = '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.
+)
+
+INSTALLED_APPS = (
+ 'django.contrib.sessions',
+ 'django.contrib.contenttypes',
+ 'django.contrib.auth',
+ 'django_openid',
+)
@@ -0,0 +1,8 @@
+from django.conf.urls.defaults import *
+from django.http import HttpResponseRedirect
+from django_openid.registration import RegistrationConsumer
+
+urlpatterns = patterns('',
+ (r'^$', lambda r: HttpResponseRedirect('/openid/')),
+ (r'^openid/(.*)', RegistrationConsumer()),
+)
@@ -0,0 +1 @@
+build
@@ -0,0 +1,58 @@
+Integrating with django.contrib.auth
+====================================
+
+The obvious next step with OpenID is to integrate it with Django's built-in concept of authentication, using the models from django.contrib.auth (in particular the User) model. The correct way of thinking about OpenID in this context is as an alternative to authenticating with a password. django_openid supports allowing users to associate 0 or more OpenIDs with a User account.
+
+Setting up auth integration
+---------------------------
+
+Auth integration is implemented using AuthConsumer, a subclass of Consumer. AuthConsumer adds the ability to associate OpenIDs with user accounts.
+
+If you want users to be able to register for new accounts on your site using their OpenID, you should use RegistrationConsumer instead. RegistrationConsumer subclasses AuthConsumer but adds a flow for registering new accounts.
+
+Here's how to set up AuthConsumer::
+
+ from django.conf.urls.defaults import *
+ from django_openid.registration import RegistrationConsumer
+
+ urlpatterns = patterns('',
+ # ...
+ (r'^openid/(.*)', RegistrationConsumer()),
+ # ...
+ )
+
+If you are using Django 1.1, you can do the following instead::
+
+ from django.conf.urls.defaults import *
+ from django_openid.registration import RegistrationConsumer
+
+ registration_consumer = Consumer()
+
+ urlpatterns = patterns('',
+ (r'^openid/', include(registration_consumer.urls)),
+ )
+
+Using named URL patterns
+------------------------
+
+Using Django 1.1 and the include pattern shown above, URLs within the registration consumer will be exposed as named URL patterns. By default, the names will follow the pattern 'openid-ACTION' - but you can change this default if you like by over-riding the urlname_pattern property of your Consumer subclass.
+
+You can also provide names to specific patterns using the following idiom (which also works in Django 1.0)::
+
+ url(r'^account/register/$', registration_consumer, {
+ 'rest_of_url': 'register/',
+ }, name = 'custom-register'),
+ url(r'^account/login/$', registration_consumer, {
+ 'rest_of_url': 'login/',
+ }, name = 'custom-login'),
+ url(r'^account/logout/$', registration_consumer, {
+ 'rest_of_url': 'logout/',
+ }, name = 'custom-logout'),
+ (r'^account/(.*?)$', registration_consumer),
+
+You can also use this idiom to apply decorators to individual paths within the Consumer::
+
+ url(r'^account/register/$', view_decorator(registration_consumer), {
+ 'rest_of_url': 'register/',
+ }, name = 'custom-register'),
+
Oops, something went wrong.

0 comments on commit 455693a

Please sign in to comment.