Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
D
django-openid-auth
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenEdx
django-openid-auth
Commits
b5f6cb7f
Commit
b5f6cb7f
authored
Apr 24, 2007
by
swillison
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Ready for launch
parent
9d4964cc
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
275 additions
and
38 deletions
+275
-38
README.txt
+2
-0
django_openidconsumer/templates/openid_failure.html
+14
-0
django_openidconsumer/templates/openid_signin.html
+7
-0
django_openidconsumer/util.py
+5
-0
django_openidconsumer/views.py
+50
-28
example/urls.py
+5
-2
example/views.py
+27
-8
openid.html
+0
-0
openid.txt
+165
-0
No files found.
README.txt
View file @
b5f6cb7f
This is currently incomplete.
TODO:
- Docs
django_openidconsumer/templates/openid_failure.html
0 → 100644
View file @
b5f6cb7f
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>
OpenID failed
</title>
</head>
<body>
<h1>
OpenID failed
</h1>
<p>
{{ message|escape }}
</p>
</body>
</html>
\ No newline at end of file
django_openidconsumer/templates/openid_signin.html
View file @
b5f6cb7f
...
...
@@ -3,6 +3,13 @@
<html>
<head>
<title>
Sign in with your OpenID
</title>
<style
type=
"text/css"
>
input
.openid
{
background
:
url({{ action }}?logo=1)
no-repeat
;
background-position
:
0
50%
;
padding-left
:
16px
;
}
</style>
</head>
<body>
<h1>
Sign in with your OpenID
</h1>
...
...
django_openidconsumer/util.py
View file @
b5f6cb7f
from
openid.store.interface
import
OpenIDStore
from
openid.association
import
Association
as
OIDAssociation
from
yadis
import
xri
import
time
,
base64
,
md5
from
django.conf
import
settings
...
...
@@ -11,8 +13,11 @@ class OpenID:
self
.
issued
=
issued
self
.
attrs
=
attrs
or
{}
self
.
sreg
=
sreg
or
{}
self
.
is_iname
=
(
xri
.
identifierScheme
(
openid
)
==
'XRI'
)
def
__repr__
(
self
):
return
'<OpenID:
%
s>'
%
self
.
openid
def
__str__
(
self
):
return
self
.
openid
...
...
django_openidconsumer/views.py
View file @
b5f6cb7f
from
django.http
import
HttpResponse
,
HttpResponseRedirect
,
Http404
from
django.http
import
HttpResponse
,
HttpResponseRedirect
,
get_host
from
django.shortcuts
import
render_to_response
as
render
from
django.template
import
RequestContext
from
django.conf
import
settings
import
md5
,
time
import
md5
,
re
,
time
from
openid.consumer.consumer
import
Consumer
,
\
SUCCESS
,
CANCEL
,
FAILURE
,
SETUP_NEEDED
from
openid.consumer.discover
import
DiscoveryFailure
from
yadis
import
xri
from
util
import
OpenID
,
DjangoOpenIDStore
,
from_openid_response
from
django.utils.html
import
escape
...
...
@@ -16,7 +18,7 @@ def get_url_host(request):
protocol
=
'https'
else
:
protocol
=
'http'
host
=
escape
(
request
.
META
[
'HTTP_HOST'
]
)
host
=
escape
(
get_host
(
request
)
)
return
'
%
s://
%
s'
%
(
protocol
,
host
)
def
get_full_url
(
request
):
...
...
@@ -27,49 +29,58 @@ def get_full_url(request):
host
=
escape
(
request
.
META
[
'HTTP_HOST'
])
return
get_url_host
(
request
)
+
request
.
get_full_path
()
def
is_valid_after_url
(
after
):
next_url_re
=
re
.
compile
(
'^/[-
\
w/]+$'
)
def
is_valid_next_url
(
next
):
# When we allow this:
# /openid/?
after
=/welcome/
# For security reasons we want to restrict the
after
= bit to being a local
# /openid/?
next
=/welcome/
# For security reasons we want to restrict the
next
= bit to being a local
# path, not a complete URL.
if
not
after
.
startswith
(
'/'
):
return
False
if
'://'
in
after
:
return
False
for
c
in
after
:
if
c
.
isspace
():
return
False
return
True
return
bool
(
next_url_re
.
match
(
next
))
def
begin
(
request
,
sreg
=
None
,
extension_args
=
None
):
def
begin
(
request
,
sreg
=
None
,
extension_args
=
None
,
redirect_to
=
None
):
if
request
.
GET
.
get
(
'logo'
):
# Makes for a better demo
return
HttpResponse
(
OPENID_LOGO_BASE_64
.
decode
(
'base64'
),
mimetype
=
'image/gif'
)
extension_args
=
extension_args
or
{}
if
sreg
:
extension_args
[
'sreg.optional'
]
=
sreg
trust_root
=
getattr
(
settings
,
'OPENID_TRUST_ROOT'
,
get_url_host
(
request
)
+
'/'
)
redirect_to
=
getattr
(
redirect_to
=
redirect_to
or
getattr
(
settings
,
'OPENID_REDIRECT_TO'
,
# If not explicitly set, assume current URL with complete/ appended
get_full_url
(
request
)
.
split
(
'?'
)[
0
]
+
'complete/'
)
# In case they were lazy...
if
not
redirect_to
.
startswith
(
'http://'
):
redirect_to
=
get_url_host
(
request
)
+
redirect_to
if
request
.
GET
.
get
(
'
after'
)
and
is_valid_after_url
(
request
.
GET
[
'after
'
]):
if
request
.
GET
.
get
(
'
next'
)
and
is_valid_next_url
(
request
.
GET
[
'next
'
]):
if
'?'
in
redirect_to
:
join
=
'&'
else
:
join
=
'?'
redirect_to
+=
join
+
'
after='
+
urllib
.
urlencode
(
request
.
GET
[
'after
'
])
redirect_to
+=
join
+
'
next='
+
urllib
.
urlencode
(
request
.
GET
[
'next
'
])
user_url
=
request
.
POST
.
get
(
'openid_url'
,
None
)
user_url
=
request
.
POST
.
get
(
'openid_url'
,
None
)
if
not
user_url
:
return
render
(
'openid_signin.html'
)
return
render
(
'openid_signin.html'
,
{
'action'
:
request
.
path
})
if
xri
.
identifierScheme
(
user_url
)
==
'XRI'
and
getattr
(
settings
,
'OPENID_DISALLOW_INAMES'
,
False
):
return
failure
(
request
,
'i-names are not supported'
)
consumer
=
Consumer
(
request
.
session
,
DjangoOpenIDStore
())
try
:
auth_request
=
consumer
.
begin
(
user_url
)
except
DiscoveryFailure
:
r
aise
Http404
,
"Discovery failure"
r
eturn
failure
(
request
,
"The OpenID was invalid"
)
# Add extension args (for things like simple registration)
for
name
,
value
in
extension_args
.
items
():
...
...
@@ -103,19 +114,30 @@ def success(request, identity_url, openid_response):
]
request
.
session
[
'openids'
]
.
append
(
from_openid_response
(
openid_response
))
after
=
request
.
GET
.
get
(
'after
'
,
''
)
.
strip
()
if
not
after
or
not
is_valid_after_url
(
after
):
after
=
getattr
(
settings
,
'OPENID_REDIRECT_AFTER
'
,
'/'
)
next
=
request
.
GET
.
get
(
'next
'
,
''
)
.
strip
()
if
not
next
or
not
is_valid_next_url
(
next
):
next
=
getattr
(
settings
,
'OPENID_REDIRECT_NEXT
'
,
'/'
)
return
HttpResponseRedirect
(
after
)
return
HttpResponseRedirect
(
next
)
def
failure
(
request
,
message
):
return
render
(
'openid_failure.html'
,
{
'message'
:
message
})
# , context_instance = RequestContext(request))
})
def
signout
(
request
):
request
.
session
.
openids
=
[]
request
.
session
.
openid
=
None
request
.
session
[
'openids'
]
=
[]
next
=
request
.
GET
.
get
(
'next'
,
'/'
)
if
not
is_valid_next_url
(
next
):
next
=
'/'
return
HttpResponseRedirect
(
next
)
# Logo from http://openid.net/login-bg.gif
# Embedded here for convenience; you should serve this as a static file
OPENID_LOGO_BASE_64
=
"""
R0lGODlhEAAQAMQAAO3t7eHh4srKyvz8/P5pDP9rENLS0v/28P/17tXV1dHEvPDw8M3Nzfn5+d3d
3f5jA97Syvnv6MfLzcfHx/1mCPx4Kc/S1Pf189C+tP+xgv/k1N3OxfHy9NLV1/39/f///yH5BAAA
AAAALAAAAAAQABAAAAVq4CeOZGme6KhlSDoexdO6H0IUR+otwUYRkMDCUwIYJhLFTyGZJACAwQcg
EAQ4kVuEE2AIGAOPQQAQwXCfS8KQGAwMjIYIUSi03B7iJ+AcnmclHg4TAh0QDzIpCw4WGBUZeikD
Fzk0lpcjIQA7
"""
example/urls.py
View file @
b5f6cb7f
...
...
@@ -3,8 +3,11 @@ import views
urlpatterns
=
patterns
(
''
,
(
r'^$'
,
views
.
index
),
(
r'^openid/$'
,
'django_openidconsumer.views.begin'
,
{
'sreg'
:
'email,nickname'
(
r'^openid/$'
,
'django_openidconsumer.views.begin'
),
(
r'^openid/with-sreg/$'
,
'django_openidconsumer.views.begin'
,
{
'sreg'
:
'email,nickname'
,
'redirect_to'
:
'/openid/complete/'
,
}),
(
r'^openid/complete/$'
,
'django_openidconsumer.views.complete'
),
(
r'^openid/signout/$'
,
'django_openidconsumer.views.signout'
),
)
example/views.py
View file @
b5f6cb7f
...
...
@@ -4,11 +4,30 @@ from pprint import pformat
from
django.utils.html
import
escape
def
index
(
request
):
s
=
"""
<p>OpenID is <pre>
%
s</pre>.</p>
<p><a href="/openid/">Sign in with OpenID</a></p><pre>
"""
%
escape
(
pformat
(
request
.
openid
.
__dict__
.
items
()))
s
+=
escape
(
pformat
(
request
.
session
.
_session
))
s
+=
'
\n\n\n
'
s
+=
escape
(
pformat
(
request
.
META
))
return
HttpResponse
(
s
)
s
=
[]
if
request
.
openid
:
s
.
append
(
'<p>You are signed in as <strong>
%
s</strong>'
%
escape
(
str
(
request
.
openid
)
))
if
request
.
openid
.
is_iname
:
s
.
append
(
' (an i-name)'
)
s
.
append
(
'</p>'
)
if
request
.
openid
.
sreg
:
s
.
append
(
'<p>sreg data:
%
s</p>'
%
escape
(
str
(
request
.
openid
.
sreg
)))
if
len
(
request
.
openids
)
>
1
:
s
.
append
(
'<p>Also signed in as
%
s</p>'
%
', '
.
join
([
escape
(
str
(
o
))
for
o
in
request
.
openids
[:
-
1
]
]))
s
.
append
(
'<a href="/openid/">Sign in with OpenID</a>'
)
s
.
append
(
' | <a href="/openid/with-sreg/">'
)
s
.
append
(
'Sign in with OpenID using simple registration</a>'
)
if
request
.
openid
:
s
.
append
(
' | <a href="/openid/signout/">Sign out</a>'
)
s
.
append
(
'</p>'
)
return
HttpResponse
(
'
\n
'
.
join
(
s
))
openid.html
0 → 100644
View file @
b5f6cb7f
This diff is collapsed.
Click to expand it.
openid.txt
0 → 100644
View file @
b5f6cb7f
================
OpenID in Django
================
The ``django_openidconsumer`` package contains all of the code needed to set up
your Django application as an OpenID consumer. You can use it to allow OpenID
users to sign in to your site without having to create a new username and
password.
Overview
========
The OpenID consumer system consists of:
* Views for you to hook in to your application.
* Database models implementing the persistence layer of an OpenID consumer.
* Middleware that makes ``request.openid`` and ``request.openids``
properties available to your application views.
Dependencies
============
``django_openidconsumer`` uses the `python-openid library`_, which must be
installed separately somewhere on the Python path. You should install the 1.2.0
"combo" package which includes the ``yadis`` and ``urljr`` libraries.
The package also depends on the availability of Django's `session support`_.
.. _python-openid library: http://www.openidenabled.com/openid/libraries/python/
.. _session support: http://www.djangoproject.com/documentation/sessions/
Installation
============
Having ensured that both the ``python-openid`` library and the ``django_openidconsumer`` package are available on your Python path, you can
add OpenID consumer support to an application by doing the following:
1. Put ``django_openidconsumer`` in your ``INSTALLED_APPS`` setting.
2. Run the command ``manage.py syncdb`` to create the necessary tables.
3. Add ``django_openidconsumer.middleware.OpenIDMiddleware`` to your list
of ``MIDDLEWARE_CLASSES``, somewhere after the Session middleware.
4. Add the following views to your urlconf::
(r'^openid/$', 'django_openidconsumer.views.begin'),
(r'^openid/complete/$', 'django_openidconsumer.views.complete'),
(r'^openid/signout/$', 'django_openidconsumer.views.signout'),
You will then be able to browse to ``example.com/openid/`` and sign in using
an OpenID.
Using the OpenID middleware
===========================
With the Middleware installed, your views will have access to the user's OpenID
as the ``request.openid`` property. This will be ``None`` if the user has not
yet authenticated; otherwise it will be a ``django_openidconsumer.util.OpenID``
instance.
If you want the user's OpenID as a string, call the ``str()`` builtin on the
OpenID instance::
def example_view(request):
if request.openid:
return HttpResponse("OpenID is %s" % escape(str(request.openid)))
else:
return HttpResponse("No OpenID")
Users can sign in with more than one OpenID. This is supported by the
``request.openids`` property, which is a list of ``OpenID`` objects in the order
in which they were authenticated. ``request.openid`` merely returns the last
item in this list.
Using simple registration
=========================
Simple registration (or `sreg`_) is an extension to the OpenID specification
that allows you to request extra details about a user from their OpenID
provider. It is frequently used to pre-populate registration forms with
information such as the user's name, e-mail address or date of birth.
.. _sreg: http://openid.net/specs/openid-simple-registration-extension-1_0.html
Be aware that not all OpenID providers support sreg, and there is no guarantee
that the information you have requested will be returned. Simple registration
should be used as a convenience for your users rather than as a required step in
your authentication process.
Available simple registration fields are ``nickname``, ``email``, ``fullname``,
``dob``, ``gender``, ``postcode``, ``country``, ``language`` and ``timezone``.
Full details are available in the `spec`_.
.. _spec: http://openid.net/specs/openid-simple-registration-extension-1_0.html
To request this information, pass the fields that you wish to retrieve as an
additional ``sreg`` argument to the ``django_openidconsumer.views.begin`` view::
(r'^openid/$', 'django_openidconsumer.views.begin', {
'sreg': 'email,nickname'
}),
Any simple registration fields that are returned will be available in a
dictionary as the ``sreg`` property of the OpenID object::
def example_sreg(request):
if request.openid and request.openid.sreg.has_key('email'):
return HttpResponse("Your e-mail address is: %s" % escape(
request.openid.sreg['email']
))
else:
return HttpResponse("No e-mail address")
Customisation
=============
``django_openidconsumer`` uses two templates:
``openid_signin.html``
The form presented to the user when they sign in.
``openid_failure.html``
The template used to display an error message when something goes wrong.
You can over-ride the default templates by creating templates of the same name
and placing them somewhere on your template path. You can find the example
templates in the ``django_openidconsumer/templates`` directory.
The OpenID specification strongly recommends that any OpenID registration form
has a ``name`` attribute of ``openid_url`` to aid browser autocompletion, and
displays the `OpenID logo`_ inline in the form field using the following CSS::
input.openid {
background: url(/path/to/login-bg.gif) no-repeat;
background-position: 0 50%;
padding-left: 16px;
}
.. _OpenID logo: http://openid.net/login-bg.gif
By default, the package expects the ``django_openidconsumer.views.complete``
view to be located at ``/openid/complete/``. This is the view that the OpenID
provider will redirect the user to after they have authenticated. If you want to
put it somewhere else you can either pass an extra ``redirect_to`` argument to
``django_openidconsumer.views.begin`` or add an ``OPENID_REDIRECT_TO`` setting
to ``settings.py``.
You can pass a ``?next=`` query string argument containing a relative URL to
the ``begin`` view to control where the user will be redirected to having
returned to your site. You can also set the default redirection location
using the ``OPENID_REDIRECT_NEXT`` setting; if you do set set a default the user
will be redirected to your homepage.
i-names
=======
`i-names`_ are part of the OpenID 2.0 specification, which is currently being
developed. They are supported by the python-openid library, and hence are also
supported by ``django_openidconsumer``. You can tell if an OpenID is an i-name
by checking the ``request.openid.is_iname`` property.
.. _i-names: http://www.inames.net/
If you wish to disable i-name support, you can do so by adding the following to
your ``settings.py``::
OPENID_DISALLOW_INAMES = True
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment