[Python-checkins] r77754 - tracker/instances/python-dev/extensions/openid_login.py
martin.v.loewis
python-checkins at python.org
Tue Jan 26 00:42:39 CET 2010
Author: martin.v.loewis
Date: Tue Jan 26 00:42:39 2010
New Revision: 77754
Log:
Streamline authentication: recall claimed ID from
session, discover provider-returned ID for consistency.
Modified:
tracker/instances/python-dev/extensions/openid_login.py
Modified: tracker/instances/python-dev/extensions/openid_login.py
==============================================================================
--- tracker/instances/python-dev/extensions/openid_login.py (original)
+++ tracker/instances/python-dev/extensions/openid_login.py Tue Jan 26 00:42:39 2010
@@ -50,7 +50,34 @@
session.mac_key = session_data['mac_key']
session.expires = now + date.Interval(int(session_data['expires_in']))
self.db.commit()
- return session
+ return session
+
+ def authenticate(self, session, query):
+ '''Authenticate an OpenID indirect response, and return the claimed ID'''
+ try:
+ signed = openid.authenticate(session, query)
+ except Exception, e:
+ raise ValueError, "Authentication failed: "+str(e)
+ if openid.is_op_endpoint(session.stypes):
+ # Provider-guided login: provider ought to report claimed ID
+ if 'openid.claimed_id' in query:
+ claimed = query['openid.claimed_id'][0]
+ else:
+ raise ValueError, 'incomplete response'
+ # OpenID 11.2: verify that provider is authorized to assert ID
+ discovered = openid.discover(claimed)
+ if not discovered or discovered[1] != session.url:
+ raise ValueError, "Provider %s is not authorized to make assertions about %s" % (session.url, claimed)
+ else:
+ # User entered claimed ID, stored in session object
+ claimed = session.provider_id
+ if not openid.is_compat_1x(session.stypes):
+ # can only check correct claimed ID for OpenID 2.0
+ if 'openid.claimed_id' not in query or claimed != query['openid.claimed_id'][0]:
+ # assertion is not about an ID, or about a different ID; refuse to accept
+ raise ValueError, "Provider did not assert your ID"
+ return claimed
+
class OpenidLogin(LoginAction, Openid):
'Extended versoin of LoginAction, supporting OpenID identifiers in username field.'
@@ -107,7 +134,7 @@
session.assoc_handle, return_to, realm=realm)
raise Redirect, url
-class OpenidReturn(Action):
+class OpenidReturn(Action, Openid):
def handle(self):
# parse again to get cgi kind of result
query = cgi.parse_qs(self.client.env['QUERY_STRING'])
@@ -152,20 +179,7 @@
except KeyError:
raise ValueError, 'Not authenticated (no session)'
session = self.db.openid_session.getnode(session[0])
- try:
- signed = openid.authenticate(session, query)
- except Exception, e:
- import traceback
- raise ValueError, "Authentication failed: "+traceback.format_exc()
- if 'openid.claimed_id' in query:
- if 'claimed_id' not in signed:
- raise ValueError, 'Incomplete signature'
- claimed = query['openid.claimed_id'][0]
- else:
- # OpenID 1, claimed ID not reported - should set cookie
- if 'identity' not in signed:
- raise ValueError, 'Incomplete signature'
- claimed = query['openid.identity'][0]
+ claimed = self.authenticate(session, query)
if self.user != 'anonymous':
# Existing user claims OpenID
@@ -244,7 +258,7 @@
self.db.user.set(self.userid, openids=' '.join(openids))
self.db.commit()
-class OpenidRegister(RegisterAction):
+class OpenidRegister(RegisterAction, Openid):
def handle(self):
query = {}
if 'openid.identity' not in self.form:
@@ -263,20 +277,7 @@
query[key].append(value)
except KeyError:
query[key] = [value]
- try:
- signed = openid.authenticate(session, query)
- except Exception, e:
- raise ValueError, "Authentication failed: "+repr(e)
- if 'openid.claimed_id' in query:
- if 'claimed_id' not in signed:
- raise ValueError, 'Incomplete signature'
- claimed = query['openid.claimed_id'][0]
- else:
- # OpenID 1, claimed ID not reported - should set cookie
- if 'identity' not in signed:
- raise ValueError, 'Incomplete signature'
- claimed = query['openid.identity'][0]
-
+ claimed = self.authenticate(session, query)
# OpenID signature is still authentic, now pass it on to the base
# register method; also fake password
self.form.value.append(cgi.MiniFieldStorage('openids', claimed))
More information about the Python-checkins
mailing list