~gary/python-openid/python-openid-2.2.1-patched

« back to all changes in this revision

Viewing changes to examples/djopenid/util.py

  • Committer: Launchpad Patch Queue Manager
  • Date: 2007-11-30 02:46:28 UTC
  • mfrom: (1.1.1 pyopenid-2.0)
  • Revision ID: launchpad@pqm.canonical.com-20071130024628-qktwsew3383iawmq
[rs=SteveA] upgrade to python-openid-2.0.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
"""
 
3
Utility code for the Django example consumer and server.
 
4
"""
 
5
 
 
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
 
11
 
 
12
from django.conf import settings
 
13
 
 
14
from openid.store.filestore import FileOpenIDStore
 
15
from openid.store import sqlstore
 
16
 
 
17
def getOpenIDStore(filestore_path, table_prefix):
 
18
    """
 
19
    Returns an OpenID association store object based on the database
 
20
    engine chosen for this Django application.
 
21
 
 
22
    * If no database engine is chosen, a filesystem-based store will
 
23
      be used whose path is filestore_path.
 
24
 
 
25
    * If a database engine is chosen, a store object for that database
 
26
      type will be returned.
 
27
 
 
28
    * If the chosen engine is not supported by the OpenID library,
 
29
      raise ImproperlyConfigured.
 
30
 
 
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.
 
35
 
 
36
    The result of this function should be passed to the Consumer
 
37
    constructor as the store parameter.
 
38
    """
 
39
    if not settings.DATABASE_ENGINE:
 
40
        return FileOpenIDStore(filestore_path)
 
41
 
 
42
    # Possible side-effect: create a database connection if one isn't
 
43
    # already open.
 
44
    connection.cursor()
 
45
 
 
46
    # Create table names to specify for SQL-backed stores.
 
47
    tablenames = {
 
48
        'settings_table': table_prefix + 'openid_settings',
 
49
        'associations_table': table_prefix + 'openid_associations',
 
50
        'nonces_table': table_prefix + 'openid_nonces',
 
51
        }
 
52
 
 
53
    types = {
 
54
        'postgresql': sqlstore.PostgreSQLStore,
 
55
        'mysql': sqlstore.MySQLStore,
 
56
        'sqlite3': sqlstore.SQLiteStore,
 
57
        }
 
58
 
 
59
    try:
 
60
        s = types[settings.DATABASE_ENGINE](connection.connection,
 
61
                                            **tablenames)
 
62
    except KeyError:
 
63
        raise ImproperlyConfigured, \
 
64
              "Database engine %s not supported by OpenID library" % \
 
65
              (settings.DATABASE_ENGINE,)
 
66
 
 
67
    try:
 
68
        s.createTables()
 
69
    except (SystemExit, KeyboardInterrupt, MemoryError), e:
 
70
        raise
 
71
    except:
 
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
 
79
        # exists.
 
80
        pass
 
81
 
 
82
    return s
 
83
 
 
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)
 
88
 
 
89
def sendResponse(func):
 
90
    """
 
91
    A decorator to make Django views nicer to use and easier to read.
 
92
    Wraps a normal Django view and adds these behaviors:
 
93
 
 
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.
 
97
 
 
98
    * The view may return a plain http.HttpResponse object, which will
 
99
      be returned to Django as-is.
 
100
 
 
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
 
104
      returned to Django.
 
105
    """
 
106
    def _responseWrapper(request, *args, **kwargs):
 
107
        result = func(request, *args, **kwargs)
 
108
 
 
109
        if isinstance(result, http.HttpResponse):
 
110
            return result
 
111
        else:
 
112
            template_name, response_data = result
 
113
 
 
114
            response_class = response_data.get('response_class', http.HttpResponse)
 
115
            return response_class(renderTemplate(request, template_name, response_data))
 
116
    return _responseWrapper
 
117
 
 
118
def getTrustRoot(req):
 
119
    """
 
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
 
124
    standard (80, 443).
 
125
    """
 
126
    name = req.META['HTTP_HOST']
 
127
    try:
 
128
        name = name[:name.index(':')]
 
129
    except:
 
130
        pass
 
131
 
 
132
    try:
 
133
        port = int(req.META['SERVER_PORT'])
 
134
    except:
 
135
        port = 80
 
136
 
 
137
    proto = req.META['SERVER_PROTOCOL']
 
138
 
 
139
    if 'HTTPS' in proto:
 
140
        proto = 'https'
 
141
    else:
 
142
        proto = 'http'
 
143
 
 
144
    if port in [80, 443] or not port:
 
145
        port = ''
 
146
    else:
 
147
        port = ':%s' % (port,)
 
148
 
 
149
    url = "%s://%s%s/" % (proto, name, port)
 
150
    return url
 
151
 
 
152
def normalDict(request_data):
 
153
    """
 
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.
 
160
    """
 
161
    return dict((k, v[0]) for k, v in request_data.iteritems())