3
Utility code for the Django example consumer and server.
6
from django.db import connection
7
from django.template.context import RequestContext
8
from django.template import loader
9
from django import http
10
from django.core.exceptions import ImproperlyConfigured
12
from django.conf import settings
14
from openid.store.filestore import FileOpenIDStore
15
from openid.store import sqlstore
17
def getOpenIDStore(filestore_path, table_prefix):
19
Returns an OpenID association store object based on the database
20
engine chosen for this Django application.
22
* If no database engine is chosen, a filesystem-based store will
23
be used whose path is filestore_path.
25
* If a database engine is chosen, a store object for that database
26
type will be returned.
28
* If the chosen engine is not supported by the OpenID library,
29
raise ImproperlyConfigured.
31
* If a database store is used, this will create the tables
32
necessary to use it. The table names will be prefixed with
33
table_prefix. DO NOT use the same table prefix for both an
34
OpenID consumer and an OpenID server in the same database.
36
The result of this function should be passed to the Consumer
37
constructor as the store parameter.
39
if not settings.DATABASE_ENGINE:
40
return FileOpenIDStore(filestore_path)
42
# Possible side-effect: create a database connection if one isn't
46
# Create table names to specify for SQL-backed stores.
48
'settings_table': table_prefix + 'openid_settings',
49
'associations_table': table_prefix + 'openid_associations',
50
'nonces_table': table_prefix + 'openid_nonces',
54
'postgresql': sqlstore.PostgreSQLStore,
55
'mysql': sqlstore.MySQLStore,
56
'sqlite3': sqlstore.SQLiteStore,
60
s = types[settings.DATABASE_ENGINE](connection.connection,
63
raise ImproperlyConfigured, \
64
"Database engine %s not supported by OpenID library" % \
65
(settings.DATABASE_ENGINE,)
69
except (SystemExit, KeyboardInterrupt, MemoryError), e:
72
# XXX This is not the Right Way to do this, but because the
73
# underlying database implementation might differ in behavior
74
# at this point, we can't reliably catch the right
75
# exception(s) here. Ideally, the SQL store in the OpenID
76
# library would catch exceptions that it expects and fail
77
# silently, but that could be bad, too. More ideally, the SQL
78
# store would not attempt to create tables it knows already
84
def renderTemplate(request, template_name, response_data):
85
context = RequestContext(request, response_data)
86
template = loader.get_template(template_name)
87
return template.render(context)
89
def sendResponse(func):
91
A decorator to make Django views nicer to use and easier to read.
92
Wraps a normal Django view and adds these behaviors:
94
* The view may return a tuple of (template_name, template_context)
95
where template_name is a normal Django template name and
96
template_context is a dict of template context data.
98
* The view may return a plain http.HttpResponse object, which will
99
be returned to Django as-is.
101
* The view may return in its template_context a 'response_class'
102
key whose value is an http.HttpResponse subclass. If this is
103
found, it will be used to instantiate the final response object
106
def _responseWrapper(request, *args, **kwargs):
107
result = func(request, *args, **kwargs)
109
if isinstance(result, http.HttpResponse):
112
template_name, response_data = result
114
response_class = response_data.get('response_class', http.HttpResponse)
115
return response_class(renderTemplate(request, template_name, response_data))
116
return _responseWrapper
118
def getTrustRoot(req):
120
Given a Django web request object, returns the OpenID 'trust root'
121
for that request; namely, the absolute URL to the site root which
122
is serving the Django request. The trust root will include the
123
proper scheme and authority. It will lack a port if the port is
126
name = req.META['HTTP_HOST']
128
name = name[:name.index(':')]
133
port = int(req.META['SERVER_PORT'])
137
proto = req.META['SERVER_PROTOCOL']
144
if port in [80, 443] or not port:
147
port = ':%s' % (port,)
149
url = "%s://%s%s/" % (proto, name, port)
152
def normalDict(request_data):
154
Converts a django request MutliValueDict (e.g., request.GET,
155
request.POST) into a standard python dict whose values are the
156
first value from each of the MultiValueDict's value lists. This
157
avoids the OpenID library's refusal to deal with dicts whose
158
values are lists, because in OpenID, each key in the query arg set
159
can have at most one value.
161
return dict((k, v[0]) for k, v in request_data.iteritems())