Commits

Peter Troeger  committed 5a49d50

Switch to usage of verify(), adding discovery cache

  • Participants
  • Parent commits 1249ce2

Comments (0)

Files changed (2)

File openid2rp/django/auth.py

 from django.conf import settings
 from django.contrib.auth.models import User
 from django.contrib.auth.backends import ModelBackend
-from openid2rp.django.models import UserOpenID, OpenIDSession, OpenIDNonce
+from openid2rp.django.models import UserOpenID, OpenIDSession, OpenIDNonce, DiscoveryCache
 from django.http import HttpResponse
 from django.db.models import Q
 from django.contrib.auth.models import AnonymousUser
 		raise IncorrectURIError(str(e))
 	res = openid2rp.discover(claimedId)
 	if res != None:
-		services, url, op_local = res
+		services, op_endpoint, op_local = res
+		try:
+			dcache=DiscoveryCache.objects.get(uri=claimedId)
+		except:
+			dcache=DiscoveryCache()
+			dcache.uri=claimedId
+		dcache.services=" ".join(services)
+		dcache.op_local=op_local
+		dcache.op_endpoint=op_endpoint
+		dcache.save()
 		# re-use session in order to avoid provider roundtrip here
 		# some providers (Wordpress) do not like that, and send 'invalidate_handle' then,
 		# which would need another user roundtrip - therefore, the app can switch it off
 		else:
 			session = None
 		if not session:
-			session = openid2rp.associate(services, url)
+			session = openid2rp.associate(services, op_endpoint)
 			storeSession(session, claimedId)
-		redirect_url=openid2rp.request_authentication( services, url, session['assoc_handle'], answer_url, claimedId, op_local, sreg=sreg, ax=ax )
+		redirect_url=openid2rp.request_authentication( services, op_endpoint, session['assoc_handle'], answer_url, claimedId, op_local, sreg=sreg, ax=ax )
 		response=HttpResponse()
 		response['Location']=redirect_url
 		response.status_code=303
 		except User.DoesNotExist:
 			return None
 
+	def discovered_get(self, uri):
+		try:
+			dcache=DiscoveryCache.objects.get(uri=uri)
+			return dcache.services.split(" "), dcache.op_endpoint, dcache.op_local		
+		except DiscoveryCache.DoesNotExist:
+			return None
+
+
 	def authenticate(self, **credentials):
 		global maxTimeShift, maxLoginDelay
 
 		request=credentials['openidrequest']
 		query=request.META['QUERY_STRING']
 		handle = request.GET['openid.assoc_handle']
-		session=getSessionByHandle(handle)
-		if not session:
-			raise MissingSessionError
+
 		try:
-			signed=openid2rp.authenticate(session, query)
+			signed, claimedId = openid2rp.verify(query, self.discovered_get, getSessionByHandle, knownNonce)
 		except Exception, e:
 			raise AuthenticationError(str(e))
-		# check for replay attack, only available with OpenID 2 providers
+
 		if 'openid.response_nonce' in request.GET:
-			nonce = request.GET['openid.response_nonce']
-			timestamp = openid2rp.parse_nonce(nonce)		
-			if timestamp < datetime.datetime.utcnow() - maxTimeShift - maxLoginDelay: 
-				raise TookTooLongError()
-			elif knownNonce(nonce):
-				raise ReplayAttackError()
-			storeNonce(nonce)
-
-		# provider-based auth returns claim id, OpenID not (if I got that right) - in this case we take the one stored in the session found by assocHandle
-		if 'openid.claimed_id' in request.GET:
-			if 'claimed_id' not in signed:
-				raise IncompleteAnswerError()
-			claimedId = request.GET['openid.claimed_id']
-		else:
-			if 'identity' not in signed:
-				raise IncompleteAnswerError()
-			claimedId = session['claimedId']
+			storeNonce(request.GET['openid.response_nonce'])
 
 		# look up OpenID claim string in local database
 		idrecord=UserOpenID.objects.filter(Q(uri=claimedId))

File openid2rp/django/models.py

 	expiration_date = models.DateTimeField(null=False, blank=False, editable=False)
 	def __unicode__(self):
 		return smart_unicode("OpenID nonce '"+str(self.nonce)+"', expires at "+str(self.expiration_date))
+
+class DiscoveryCache(models.Model):
+	uri = models.CharField(max_length=255, blank=False, null=False)
+	services = models.TextField(blank=True, null=True)
+	op_endpoint = models.TextField(blank=True, null=True)
+	op_local = models.TextField(blank=True, null=True)