~joe-topjian-v/django-openid-auth/jtopjian-dev

« back to all changes in this revision

Viewing changes to django_openid_auth/tests/test_views.py

Add support for requesting user details via the Attribute Exchange extension.  This allows us to retrieve user details from providers that don't implement the Simple Registration extension (e.g. Google).  Fixes bug #517393.

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
from django.conf import settings
35
35
from django.contrib.auth.models import User, Group
36
36
from django.test import TestCase
37
 
from openid.extensions.sreg import SRegRequest, SRegResponse
 
37
from openid.extensions import ax, sreg
38
38
from openid.fetchers import (
39
39
    HTTPFetcher, HTTPFetchingError, HTTPResponse, setDefaultFetcher)
40
40
from openid.oidutil import importElementTree
58
58
        self.endpoint_url = base_url + 'endpoint'
59
59
        self.server = Server(self.store, self.endpoint_url)
60
60
        self.last_request = None
 
61
        self.type_uris = ['http://specs.openid.net/auth/2.0/signon']
61
62
 
62
63
    def fetch(self, url, body=None, headers=None):
63
64
        if url == self.identity_url:
64
 
            # Serve an XRDS document directly, which is the 
 
65
            # Serve an XRDS document directly, pointing at our endpoint.
 
66
            type_uris = ['<Type>%s</Type>' % uri for uri in self.type_uris]
65
67
            return HTTPResponse(
66
68
                url, 200, {'content-type': 'application/xrds+xml'}, """\
67
69
<?xml version="1.0"?>
70
72
    xmlns:xrds="xri://$xrds">
71
73
  <XRD>
72
74
    <Service priority="0">
73
 
      <Type>http://specs.openid.net/auth/2.0/signon</Type>
 
75
      %s
74
76
      <URI>%s</URI>
75
77
      <LocalID>%s</LocalID>
76
78
    </Service>
77
79
  </XRD>
78
80
</xrds:XRDS>
79
 
""" % (self.endpoint_url, self.localid_url))
 
81
""" % ('\n'.join(type_uris), self.endpoint_url, self.localid_url))
80
82
        elif url.startswith(self.endpoint_url):
81
83
            # Gather query parameters
82
84
            query = {}
260
262
        # Complete the request, passing back some simple registration
261
263
        # data.  The user is redirected to the next URL.
262
264
        openid_request = self.provider.parseFormPost(response.content)
263
 
        sreg_request = SRegRequest.fromOpenIDRequest(openid_request)
 
265
        sreg_request = sreg.SRegRequest.fromOpenIDRequest(openid_request)
264
266
        openid_response = openid_request.answer(True)
265
 
        sreg_response = SRegResponse.extractResponse(
 
267
        sreg_response = sreg.SRegResponse.extractResponse(
266
268
            sreg_request, {'nickname': 'someuser', 'fullname': 'Some User',
267
269
                           'email': 'foo@example.com'})
268
270
        openid_response.addExtension(sreg_response)
298
300
        # Complete the request, passing back some simple registration
299
301
        # data.  The user is redirected to the next URL.
300
302
        openid_request = self.provider.parseFormPost(response.content)
301
 
        sreg_request = SRegRequest.fromOpenIDRequest(openid_request)
 
303
        sreg_request = sreg.SRegRequest.fromOpenIDRequest(openid_request)
302
304
        openid_response = openid_request.answer(True)
303
 
        sreg_response = SRegResponse.extractResponse(
 
305
        sreg_response = sreg.SRegResponse.extractResponse(
304
306
            sreg_request, {'nickname': 'someuser', 'fullname': 'Some User',
305
307
                           'email': 'foo@example.com'})
306
308
        openid_response.addExtension(sreg_response)
318
320
        self.assertEquals(user.last_name, 'User')
319
321
        self.assertEquals(user.email, 'foo@example.com')
320
322
 
 
323
    def test_login_attribute_exchange(self):
 
324
        settings.OPENID_UPDATE_DETAILS_FROM_SREG = True
 
325
        user = User.objects.create_user('testuser', 'someone@example.com')
 
326
        useropenid = UserOpenID(
 
327
            user=user,
 
328
            claimed_id='http://example.com/identity',
 
329
            display_id='http://example.com/identity')
 
330
        useropenid.save()
 
331
 
 
332
        # Configure the provider to advertise attribute exchange
 
333
        # protocol and start the authentication process:
 
334
        self.provider.type_uris.append('http://openid.net/srv/ax/1.0')
 
335
        response = self.client.post('/openid/login/',
 
336
            {'openid_identifier': 'http://example.com/identity',
 
337
             'next': '/getuser/'})
 
338
        self.assertContains(response, 'OpenID transaction in progress')
 
339
 
 
340
        # The resulting OpenID request uses the Attribute Exchange
 
341
        # extension rather than the Simple Registration extension.
 
342
        openid_request = self.provider.parseFormPost(response.content)
 
343
        sreg_request = sreg.SRegRequest.fromOpenIDRequest(openid_request)
 
344
        self.assertEqual(sreg_request.required, [])
 
345
        self.assertEqual(sreg_request.optional, [])
 
346
 
 
347
        fetch_request = ax.FetchRequest.fromOpenIDRequest(openid_request)
 
348
        self.assertTrue(fetch_request.has_key(
 
349
                'http://axschema.org/contact/email'))
 
350
        self.assertTrue(fetch_request.has_key(
 
351
                'http://axschema.org/namePerson'))
 
352
        self.assertTrue(fetch_request.has_key(
 
353
                'http://axschema.org/namePerson/first'))
 
354
        self.assertTrue(fetch_request.has_key(
 
355
                'http://axschema.org/namePerson/last'))
 
356
        self.assertTrue(fetch_request.has_key(
 
357
                'http://axschema.org/namePerson/friendly'))
 
358
 
 
359
        # Build up a response including AX data.
 
360
        openid_response = openid_request.answer(True)
 
361
        fetch_response = ax.FetchResponse(fetch_request)
 
362
        fetch_response.addValue(
 
363
            'http://axschema.org/contact/email', 'foo@example.com')
 
364
        fetch_response.addValue(
 
365
            'http://axschema.org/namePerson/first', 'Firstname')
 
366
        fetch_response.addValue(
 
367
            'http://axschema.org/namePerson/last', 'Lastname')
 
368
        fetch_response.addValue(
 
369
            'http://axschema.org/namePerson/friendly', 'someuser')
 
370
        openid_response.addExtension(fetch_response)
 
371
        response = self.complete(openid_response)
 
372
        self.assertRedirects(response, 'http://testserver/getuser/')
 
373
 
 
374
        # And they are now logged in as testuser (the passed in
 
375
        # nickname has not caused the username to change).
 
376
        response = self.client.get('/getuser/')
 
377
        self.assertEquals(response.content, 'testuser')
 
378
 
 
379
        # The user's full name and email have been updated.
 
380
        user = User.objects.get(username='testuser')
 
381
        self.assertEquals(user.first_name, 'Firstname')
 
382
        self.assertEquals(user.last_name, 'Lastname')
 
383
        self.assertEquals(user.email, 'foo@example.com')
 
384
 
321
385
    def test_login_teams(self):
322
386
        settings.OPENID_LAUNCHPAD_TEAMS_MAPPING = {'teamname': 'groupname',
323
387
                                                   'otherteam': 'othergroup'}