Commit bef0509f by Michael Hall

Extra renaming considerations and tests for conflicts and false positives

parent 4f029169
...@@ -81,7 +81,7 @@ class OpenIDBackend: ...@@ -81,7 +81,7 @@ class OpenIDBackend:
if getattr(settings, 'OPENID_UPDATE_DETAILS_FROM_SREG', False): if getattr(settings, 'OPENID_UPDATE_DETAILS_FROM_SREG', False):
details = self._extract_user_details(openid_response) details = self._extract_user_details(openid_response)
self.update_user_details(user, details) self.update_user_details(user, details, openid_response)
teams_response = teams.TeamsResponse.fromSuccessResponse( teams_response = teams.TeamsResponse.fromSuccessResponse(
openid_response) openid_response)
...@@ -98,7 +98,6 @@ class OpenIDBackend: ...@@ -98,7 +98,6 @@ class OpenIDBackend:
email = sreg_response.get('email') email = sreg_response.get('email')
fullname = sreg_response.get('fullname') fullname = sreg_response.get('fullname')
nickname = sreg_response.get('nickname') nickname = sreg_response.get('nickname')
# If any attributes are provided via Attribute Exchange, use # If any attributes are provided via Attribute Exchange, use
# them in preference. # them in preference.
fetch_response = ax.FetchResponse.fromSuccessResponse(openid_response) fetch_response = ax.FetchResponse.fromSuccessResponse(openid_response)
...@@ -137,10 +136,36 @@ class OpenIDBackend: ...@@ -137,10 +136,36 @@ class OpenIDBackend:
return dict(email=email, nickname=nickname, return dict(email=email, nickname=nickname,
first_name=first_name, last_name=last_name) first_name=first_name, last_name=last_name)
def create_user_from_openid(self, openid_response): def _get_available_username(self, nickname, identity_url):
details = self._extract_user_details(openid_response) nickname = nickname or 'openiduser'
nickname = details['nickname'] or 'openiduser' # See if we already have this nickname assigned to a username
email = details['email'] or '' try:
user = User.objects.get(username__exact=nickname)
except User.DoesNotExist:
# No conflict, we can use this nickname
return nickname
# Check if we already have nickname+i for this identity_url
try:
user_openid = UserOpenID.objects.get(
claimed_id__exact=identity_url,
user__username__startswith=nickname)
# No exception means we have an existing user for this identity
# that starts with this nickname, so it's possible we've had to
# assign them to nickname+i already.
oid_username = user_openid.user.username
if len(oid_username) > len(nickname):
try:
# check that it ends with a number
int(oid_username[len(nickname):])
return oid_username
except ValueError:
# username starts with nickname, but isn't nickname+#
pass
except UserOpenID.DoesNotExist:
# No user associated with this identity_url
pass
# Pick a username for the user based on their nickname, # Pick a username for the user based on their nickname,
# checking for conflicts. # checking for conflicts.
...@@ -150,15 +175,27 @@ class OpenIDBackend: ...@@ -150,15 +175,27 @@ class OpenIDBackend:
if i > 1: if i > 1:
username += str(i) username += str(i)
try: try:
User.objects.get(username__exact=username) user = User.objects.get(username__exact=username)
if user.useropenid_set.filter(claimed_id__exact=identity_url).count() > 0:
# username already belongs to this openid user, so it's okay
return username
except User.DoesNotExist: except User.DoesNotExist:
break break
i += 1 i += 1
return username
def create_user_from_openid(self, openid_response):
details = self._extract_user_details(openid_response)
nickname = details['nickname'] or 'openiduser'
email = details['email'] or ''
user = User.objects.create_user(username, email, password=None) username = self._get_available_username(details['nickname'], openid_response.identity_url)
self.update_user_details(user, details)
user = User.objects.create_user(username, email, password=None)
self.associate_openid(user, openid_response) self.associate_openid(user, openid_response)
self.update_user_details(user, details, openid_response)
return user return user
def associate_openid(self, user, openid_response): def associate_openid(self, user, openid_response):
...@@ -181,7 +218,7 @@ class OpenIDBackend: ...@@ -181,7 +218,7 @@ class OpenIDBackend:
return user_openid return user_openid
def update_user_details(self, user, details): def update_user_details(self, user, details, openid_response):
updated = False updated = False
if details['first_name']: if details['first_name']:
user.first_name = details['first_name'] user.first_name = details['first_name']
...@@ -193,7 +230,7 @@ class OpenIDBackend: ...@@ -193,7 +230,7 @@ class OpenIDBackend:
user.email = details['email'] user.email = details['email']
updated = True updated = True
if getattr(settings, 'OPENID_FOLLOW_RENAMES', False): if getattr(settings, 'OPENID_FOLLOW_RENAMES', False):
user.username = details['nickname'] user.username = self._get_available_username(details['nickname'], openid_response.identity_url)
updated = True updated = True
if updated: if updated:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment