Merge lp:~mhall119/django-openid-auth/strict-username-requirements into lp:~django-openid-auth/django-openid-auth/trunk

Proposed by Michael Hall
Status: Superseded
Proposed branch: lp:~mhall119/django-openid-auth/strict-username-requirements
Merge into: lp:~django-openid-auth/django-openid-auth/trunk
Diff against target: 129 lines (+72/-2)
2 files modified
django_openid_auth/auth.py (+13/-2)
django_openid_auth/tests/test_views.py (+59/-0)
To merge this branch: bzr merge lp:~mhall119/django-openid-auth/strict-username-requirements
Reviewer Review Type Date Requested Status
James Henstridge Needs Fixing
Anthony Lenton Approve
Review via email: mp+38532@code.launchpad.net

This proposal has been superseded by a proposal from 2011-03-18.

Description of the change

I'm not sure how to write proper tests for this, but I have tested that it works. The error page isn't real nice, but it's not turned on by default, and we're really going to need this for loco-directory and summit.

To post a comment you must log in.
Revision history for this message
Anthony Lenton (elachuni) wrote :

Tests would be nice, but it looks ok to me :)

review: Approve
Revision history for this message
James Henstridge (jamesh) wrote :

I agree with Anthony here.

Here is a quick sketch for the test:

1. add a test to test_views.py. Using test_login_create_users() as a base would probably be easiest.
2. create a User and UserOpenID object with a given nickname and identity.
3. set OPENID_STRICT_USERNAMES, and try to log in using a different identity URL but the same nickname
4. verify that the login has failed.

After adding the test, this change looks fine.

review: Needs Fixing
75. By Anthony Lenton

Merged in lp:~stuartmetcalfe/django-openid-auth/staff-assignment

76. By Anthony Lenton

Merged in lp:~elachuni/django-openid-auth/django1.1-support

77. By Anthony Lenton

Merged in lp:~michael.nelson/django-openid-auth/701484-optional-sreg-fields

78. By Anthony Lenton

Merged lp:~michael.nelson/django-openid-auth/701489-fire-event-with-sreg-response

79. By Anthony Lenton

Merged in lp:~michael.nelson/django-openid-auth/701489-rename-signal-provide-openid-response

80. By Michael Hall

Add tests for strict username restrictions

81. By Michael Hall

Added notes about the new settings option to README.txt

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'django_openid_auth/auth.py'
--- django_openid_auth/auth.py 2010-10-15 09:08:10 +0000
+++ django_openid_auth/auth.py 2011-03-18 20:03:27 +0000
@@ -42,7 +42,9 @@
42class IdentityAlreadyClaimed(Exception):42class IdentityAlreadyClaimed(Exception):
43 pass43 pass
4444
4545class StrictUsernameViolation(Exception):
46 pass
47
46class OpenIDBackend:48class OpenIDBackend:
47 """A django.contrib.auth backend that authenticates the user based on49 """A django.contrib.auth backend that authenticates the user based on
48 an OpenID response."""50 an OpenID response."""
@@ -72,7 +74,10 @@
72 claimed_id__exact=openid_response.identity_url)74 claimed_id__exact=openid_response.identity_url)
73 except UserOpenID.DoesNotExist:75 except UserOpenID.DoesNotExist:
74 if getattr(settings, 'OPENID_CREATE_USERS', False):76 if getattr(settings, 'OPENID_CREATE_USERS', False):
75 user = self.create_user_from_openid(openid_response)77 try:
78 user = self.create_user_from_openid(openid_response)
79 except StrictUsernameViolation:
80 return None
76 else:81 else:
77 user = user_openid.user82 user = user_openid.user
7883
@@ -142,6 +147,12 @@
142 nickname = details['nickname'] or 'openiduser'147 nickname = details['nickname'] or 'openiduser'
143 email = details['email'] or ''148 email = details['email'] or ''
144149
150 if getattr(settings, 'OPENID_STRICT_USERNAMES', False):
151 if details['nickname'] is None or details['nickname'] == '':
152 raise StrictUsernameViolation("No username")
153 if User.objects.filter(username__exact=nickname).count() > 0:
154 raise StrictUsernameViolation("Duplicate username: %s" % nickname)
155
145 # Pick a username for the user based on their nickname,156 # Pick a username for the user based on their nickname,
146 # checking for conflicts.157 # checking for conflicts.
147 i = 1158 i = 1
148159
=== modified file 'django_openid_auth/tests/test_views.py'
--- django_openid_auth/tests/test_views.py 2011-01-13 08:38:01 +0000
+++ django_openid_auth/tests/test_views.py 2011-03-18 20:03:27 +0000
@@ -131,12 +131,14 @@
131131
132 self.old_login_redirect_url = getattr(settings, 'LOGIN_REDIRECT_URL', '/accounts/profile/')132 self.old_login_redirect_url = getattr(settings, 'LOGIN_REDIRECT_URL', '/accounts/profile/')
133 self.old_create_users = getattr(settings, 'OPENID_CREATE_USERS', False)133 self.old_create_users = getattr(settings, 'OPENID_CREATE_USERS', False)
134 self.old_strict_usernames = getattr(settings, 'OPENID_STRICT_USERNAMES', False)
134 self.old_update_details = getattr(settings, 'OPENID_UPDATE_DETAILS_FROM_SREG', False)135 self.old_update_details = getattr(settings, 'OPENID_UPDATE_DETAILS_FROM_SREG', False)
135 self.old_sso_server_url = getattr(settings, 'OPENID_SSO_SERVER_URL', None)136 self.old_sso_server_url = getattr(settings, 'OPENID_SSO_SERVER_URL', None)
136 self.old_teams_map = getattr(settings, 'OPENID_LAUNCHPAD_TEAMS_MAPPING', {})137 self.old_teams_map = getattr(settings, 'OPENID_LAUNCHPAD_TEAMS_MAPPING', {})
137 self.old_use_as_admin_login = getattr(settings, 'OPENID_USE_AS_ADMIN_LOGIN', False)138 self.old_use_as_admin_login = getattr(settings, 'OPENID_USE_AS_ADMIN_LOGIN', False)
138139
139 settings.OPENID_CREATE_USERS = False140 settings.OPENID_CREATE_USERS = False
141 settings.OPENID_STRICT_USERNAMES = False
140 settings.OPENID_UPDATE_DETAILS_FROM_SREG = False142 settings.OPENID_UPDATE_DETAILS_FROM_SREG = False
141 settings.OPENID_SSO_SERVER_URL = None143 settings.OPENID_SSO_SERVER_URL = None
142 settings.OPENID_LAUNCHPAD_TEAMS_MAPPING = {}144 settings.OPENID_LAUNCHPAD_TEAMS_MAPPING = {}
@@ -145,6 +147,7 @@
145 def tearDown(self):147 def tearDown(self):
146 settings.LOGIN_REDIRECT_URL = self.old_login_redirect_url148 settings.LOGIN_REDIRECT_URL = self.old_login_redirect_url
147 settings.OPENID_CREATE_USERS = self.old_create_users149 settings.OPENID_CREATE_USERS = self.old_create_users
150 settings.OPENID_STRICT_USERNAMES = self.old_strict_usernames
148 settings.OPENID_UPDATE_DETAILS_FROM_SREG = self.old_update_details151 settings.OPENID_UPDATE_DETAILS_FROM_SREG = self.old_update_details
149 settings.OPENID_SSO_SERVER_URL = self.old_sso_server_url152 settings.OPENID_SSO_SERVER_URL = self.old_sso_server_url
150 settings.OPENID_LAUNCHPAD_TEAMS_MAPPING = self.old_teams_map153 settings.OPENID_LAUNCHPAD_TEAMS_MAPPING = self.old_teams_map
@@ -286,6 +289,62 @@
286 self.assertEquals(user.last_name, 'User')289 self.assertEquals(user.last_name, 'User')
287 self.assertEquals(user.email, 'foo@example.com')290 self.assertEquals(user.email, 'foo@example.com')
288291
292 def test_strict_username_no_nickname(self):
293 settings.OPENID_CREATE_USERS = True
294 settings.OPENID_STRICT_USERNAMES = True
295
296 # Posting in an identity URL begins the authentication request:
297 response = self.client.post('/openid/login/',
298 {'openid_identifier': 'http://example.com/identity',
299 'next': '/getuser/'})
300 self.assertContains(response, 'OpenID transaction in progress')
301
302 # Complete the request, passing back some simple registration
303 # data. The user is redirected to the next URL.
304 openid_request = self.provider.parseFormPost(response.content)
305 sreg_request = sreg.SRegRequest.fromOpenIDRequest(openid_request)
306 openid_response = openid_request.answer(True)
307 sreg_response = sreg.SRegResponse.extractResponse(
308 sreg_request, {'nickname': '', # No nickname
309 'fullname': 'Some User',
310 'email': 'foo@example.com'})
311 openid_response.addExtension(sreg_response)
312 response = self.complete(openid_response)
313
314 # Status code should be 403: Forbidden
315 self.assertEquals(403, response.status_code)
316
317 def test_strict_username_duplicate_user(self):
318 settings.OPENID_CREATE_USERS = True
319 settings.OPENID_STRICT_USERNAMES = True
320 # Create a user with the same name as we'll pass back via sreg.
321 user = User.objects.create_user('someuser', 'someone@example.com')
322 useropenid = UserOpenID(
323 user=user,
324 claimed_id='http://example.com/different_identity',
325 display_id='http://example.com/different_identity')
326 useropenid.save()
327
328 # Posting in an identity URL begins the authentication request:
329 response = self.client.post('/openid/login/',
330 {'openid_identifier': 'http://example.com/identity',
331 'next': '/getuser/'})
332 self.assertContains(response, 'OpenID transaction in progress')
333
334 # Complete the request, passing back some simple registration
335 # data. The user is redirected to the next URL.
336 openid_request = self.provider.parseFormPost(response.content)
337 sreg_request = sreg.SRegRequest.fromOpenIDRequest(openid_request)
338 openid_response = openid_request.answer(True)
339 sreg_response = sreg.SRegResponse.extractResponse(
340 sreg_request, {'nickname': 'someuser', 'fullname': 'Some User',
341 'email': 'foo@example.com'})
342 openid_response.addExtension(sreg_response)
343 response = self.complete(openid_response)
344
345 # Status code should be 403: Forbidden
346 self.assertEquals(403, response.status_code)
347
289 def test_login_update_details(self):348 def test_login_update_details(self):
290 settings.OPENID_UPDATE_DETAILS_FROM_SREG = True349 settings.OPENID_UPDATE_DETAILS_FROM_SREG = True
291 user = User.objects.create_user('testuser', 'someone@example.com')350 user = User.objects.create_user('testuser', 'someone@example.com')

Subscribers

People subscribed via source and target branches