Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
D
django-openid-auth
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenEdx
django-openid-auth
Commits
bef0509f
Commit
bef0509f
authored
Mar 20, 2011
by
Michael Hall
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Extra renaming considerations and tests for conflicts and false positives
parent
4f029169
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
220 additions
and
36 deletions
+220
-36
django_openid_auth/auth.py
+48
-11
django_openid_auth/tests/test_views.py
+172
-25
No files found.
django_openid_auth/auth.py
View file @
bef0509f
...
@@ -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
:
...
...
django_openid_auth/tests/test_views.py
View file @
bef0509f
...
@@ -135,12 +135,14 @@ class RelyingPartyTests(TestCase):
...
@@ -135,12 +135,14 @@ class RelyingPartyTests(TestCase):
self
.
old_sso_server_url
=
getattr
(
settings
,
'OPENID_SSO_SERVER_URL'
,
None
)
self
.
old_sso_server_url
=
getattr
(
settings
,
'OPENID_SSO_SERVER_URL'
,
None
)
self
.
old_teams_map
=
getattr
(
settings
,
'OPENID_LAUNCHPAD_TEAMS_MAPPING'
,
{})
self
.
old_teams_map
=
getattr
(
settings
,
'OPENID_LAUNCHPAD_TEAMS_MAPPING'
,
{})
self
.
old_use_as_admin_login
=
getattr
(
settings
,
'OPENID_USE_AS_ADMIN_LOGIN'
,
False
)
self
.
old_use_as_admin_login
=
getattr
(
settings
,
'OPENID_USE_AS_ADMIN_LOGIN'
,
False
)
self
.
old_follow_renames
=
getattr
(
settings
,
'OPENID_FOLLOW_RENAMES'
,
False
)
settings
.
OPENID_CREATE_USERS
=
False
settings
.
OPENID_CREATE_USERS
=
False
settings
.
OPENID_UPDATE_DETAILS_FROM_SREG
=
False
settings
.
OPENID_UPDATE_DETAILS_FROM_SREG
=
False
settings
.
OPENID_SSO_SERVER_URL
=
None
settings
.
OPENID_SSO_SERVER_URL
=
None
settings
.
OPENID_LAUNCHPAD_TEAMS_MAPPING
=
{}
settings
.
OPENID_LAUNCHPAD_TEAMS_MAPPING
=
{}
settings
.
OPENID_USE_AS_ADMIN_LOGIN
=
False
settings
.
OPENID_USE_AS_ADMIN_LOGIN
=
False
settings
.
OPENID_FOLLOW_RENAMES
=
False
def
tearDown
(
self
):
def
tearDown
(
self
):
settings
.
LOGIN_REDIRECT_URL
=
self
.
old_login_redirect_url
settings
.
LOGIN_REDIRECT_URL
=
self
.
old_login_redirect_url
...
@@ -149,6 +151,7 @@ class RelyingPartyTests(TestCase):
...
@@ -149,6 +151,7 @@ class RelyingPartyTests(TestCase):
settings
.
OPENID_SSO_SERVER_URL
=
self
.
old_sso_server_url
settings
.
OPENID_SSO_SERVER_URL
=
self
.
old_sso_server_url
settings
.
OPENID_LAUNCHPAD_TEAMS_MAPPING
=
self
.
old_teams_map
settings
.
OPENID_LAUNCHPAD_TEAMS_MAPPING
=
self
.
old_teams_map
settings
.
OPENID_USE_AS_ADMIN_LOGIN
=
self
.
old_use_as_admin_login
settings
.
OPENID_USE_AS_ADMIN_LOGIN
=
self
.
old_use_as_admin_login
settings
.
OPENID_FOLLOW_RENAMES
=
self
.
old_follow_renames
setDefaultFetcher
(
None
)
setDefaultFetcher
(
None
)
super
(
RelyingPartyTests
,
self
)
.
tearDown
()
super
(
RelyingPartyTests
,
self
)
.
tearDown
()
...
@@ -286,23 +289,9 @@ class RelyingPartyTests(TestCase):
...
@@ -286,23 +289,9 @@ class RelyingPartyTests(TestCase):
self
.
assertEquals
(
user
.
last_name
,
'User'
)
self
.
assertEquals
(
user
.
last_name
,
'User'
)
self
.
assertEquals
(
user
.
email
,
'foo@example.com'
)
self
.
assertEquals
(
user
.
email
,
'foo@example.com'
)
def
test_login_update_details_rename
(
self
):
def
_do_user_login
(
self
,
openid_req
,
openid_resp
):
settings
.
OPENID_FOLLOW_RENAMES
=
True
return
self
.
test_login_update_details
()
def
test_login_update_details
(
self
):
settings
.
OPENID_UPDATE_DETAILS_FROM_SREG
=
True
user
=
User
.
objects
.
create_user
(
'testuser'
,
'someone@example.com'
)
useropenid
=
UserOpenID
(
user
=
user
,
claimed_id
=
'http://example.com/identity'
,
display_id
=
'http://example.com/identity'
)
useropenid
.
save
()
# Posting in an identity URL begins the authentication request:
# Posting in an identity URL begins the authentication request:
response
=
self
.
client
.
post
(
'/openid/login/'
,
response
=
self
.
client
.
post
(
'/openid/login/'
,
openid_req
)
{
'openid_identifier'
:
'http://example.com/identity'
,
'next'
:
'/getuser/'
})
self
.
assertContains
(
response
,
'OpenID transaction in progress'
)
self
.
assertContains
(
response
,
'OpenID transaction in progress'
)
# Complete the request, passing back some simple registration
# Complete the request, passing back some simple registration
...
@@ -311,22 +300,180 @@ class RelyingPartyTests(TestCase):
...
@@ -311,22 +300,180 @@ class RelyingPartyTests(TestCase):
sreg_request
=
sreg
.
SRegRequest
.
fromOpenIDRequest
(
openid_request
)
sreg_request
=
sreg
.
SRegRequest
.
fromOpenIDRequest
(
openid_request
)
openid_response
=
openid_request
.
answer
(
True
)
openid_response
=
openid_request
.
answer
(
True
)
sreg_response
=
sreg
.
SRegResponse
.
extractResponse
(
sreg_response
=
sreg
.
SRegResponse
.
extractResponse
(
sreg_request
,
{
'nickname'
:
'someuser'
,
'fullname'
:
'Some User'
,
sreg_request
,
openid_resp
)
'email'
:
'foo@example.com'
})
openid_response
.
addExtension
(
sreg_response
)
openid_response
.
addExtension
(
sreg_response
)
response
=
self
.
complete
(
openid_response
)
response
=
self
.
complete
(
openid_response
)
# self.assertEqual(openid_resp, (response.status_code, response.content))
self
.
assertRedirects
(
response
,
'http://testserver/getuser/'
)
self
.
assertRedirects
(
response
,
'http://testserver/getuser/'
)
def
test_login_without_nickname
(
self
):
settings
.
OPENID_CREATE_USERS
=
True
openid_req
=
{
'openid_identifier'
:
'http://example.com/identity'
,
'next'
:
'/getuser/'
}
openid_resp
=
{
'nickname'
:
''
,
'fullname'
:
'Openid User'
,
'email'
:
'foo@example.com'
}
self
.
_do_user_login
(
openid_req
,
openid_resp
)
response
=
self
.
client
.
get
(
'/getuser/'
)
# username defaults to 'openiduser'
self
.
assertEquals
(
response
.
content
,
'openiduser'
)
# The user's full name and email have been updated.
user
=
User
.
objects
.
get
(
username
=
response
.
content
)
self
.
assertEquals
(
user
.
first_name
,
'Openid'
)
self
.
assertEquals
(
user
.
last_name
,
'User'
)
self
.
assertEquals
(
user
.
email
,
'foo@example.com'
)
def
test_login_follow_rename
(
self
):
settings
.
OPENID_FOLLOW_RENAMES
=
True
settings
.
OPENID_UPDATE_DETAILS_FROM_SREG
=
True
user
=
User
.
objects
.
create_user
(
'testuser'
,
'someone@example.com'
)
useropenid
=
UserOpenID
(
user
=
user
,
claimed_id
=
'http://example.com/identity'
,
display_id
=
'http://example.com/identity'
)
useropenid
.
save
()
openid_req
=
{
'openid_identifier'
:
'http://example.com/identity'
,
'next'
:
'/getuser/'
}
openid_resp
=
{
'nickname'
:
'someuser'
,
'fullname'
:
'Some User'
,
'email'
:
'foo@example.com'
}
self
.
_do_user_login
(
openid_req
,
openid_resp
)
response
=
self
.
client
.
get
(
'/getuser/'
)
# If OPENID_FOLLOW_RENAMES, they are logged in as
# If OPENID_FOLLOW_RENAMES, they are logged in as
# someuser (the passed in nickname has changed the username)
# someuser (the passed in nickname has changed the username)
#
self
.
assertEquals
(
response
.
content
,
'someuser'
)
# Otherwise they are now logged in as testuser (the passed in
# nickname has not caused the username to change).
# The user's full name and email have been updated.
user
=
User
.
objects
.
get
(
username
=
response
.
content
)
self
.
assertEquals
(
user
.
first_name
,
'Some'
)
self
.
assertEquals
(
user
.
last_name
,
'User'
)
self
.
assertEquals
(
user
.
email
,
'foo@example.com'
)
def
test_login_follow_rename_conflict
(
self
):
settings
.
OPENID_FOLLOW_RENAMES
=
True
settings
.
OPENID_UPDATE_DETAILS_FROM_SREG
=
True
# Setup existing user who's name we're going to switch to
user
=
User
.
objects
.
create_user
(
'testuser'
,
'someone@example.com'
)
UserOpenID
.
objects
.
get_or_create
(
user
=
user
,
claimed_id
=
'http://example.com/existing_identity'
,
display_id
=
'http://example.com/existing_identity'
)
# Setup user who is going to try to change username to 'testuser'
renamed_user
=
User
.
objects
.
create_user
(
'renameuser'
,
'someone@example.com'
)
UserOpenID
.
objects
.
get_or_create
(
user
=
renamed_user
,
claimed_id
=
'http://example.com/identity'
,
display_id
=
'http://example.com/identity'
)
# identity url is for 'renameuser'
openid_req
=
{
'openid_identifier'
:
'http://example.com/identity'
,
'next'
:
'/getuser/'
}
# but returned username is for 'testuser', which already exists for another identity
openid_resp
=
{
'nickname'
:
'testuser'
,
'fullname'
:
'Rename User'
,
'email'
:
'rename@example.com'
}
self
.
_do_user_login
(
openid_req
,
openid_resp
)
response
=
self
.
client
.
get
(
'/getuser/'
)
response
=
self
.
client
.
get
(
'/getuser/'
)
if
getattr
(
settings
,
'OPENID_FOLLOW_RENAMES'
,
False
):
self
.
assertEquals
(
response
.
content
,
'someuser'
)
# If OPENID_FOLLOW_RENAMES, attempt to change username to 'testuser'
else
:
# but since that username is already taken by someone else, we go through
self
.
assertEquals
(
response
.
content
,
'testuser'
)
# the process of adding +i to it, and get testuser2.
self
.
assertEquals
(
response
.
content
,
'testuser2'
)
# The user's full name and email have been updated.
user
=
User
.
objects
.
get
(
username
=
response
.
content
)
self
.
assertEquals
(
user
.
first_name
,
'Rename'
)
self
.
assertEquals
(
user
.
last_name
,
'User'
)
self
.
assertEquals
(
user
.
email
,
'rename@example.com'
)
def
test_login_follow_rename_conflict_onlyonce
(
self
):
settings
.
OPENID_FOLLOW_RENAMES
=
True
settings
.
OPENID_UPDATE_DETAILS_FROM_SREG
=
True
# Setup existing user who's name we're going to switch to
user
=
User
.
objects
.
create_user
(
'testuser'
,
'someone@example.com'
)
UserOpenID
.
objects
.
get_or_create
(
user
=
user
,
claimed_id
=
'http://example.com/existing_identity'
,
display_id
=
'http://example.com/existing_identity'
)
# Setup user who is going to try to change username to 'testuser'
renamed_user
=
User
.
objects
.
create_user
(
'testuser2000'
,
'someone@example.com'
)
UserOpenID
.
objects
.
get_or_create
(
user
=
renamed_user
,
claimed_id
=
'http://example.com/identity'
,
display_id
=
'http://example.com/identity'
)
# identity url is for 'testuser2000'
openid_req
=
{
'openid_identifier'
:
'http://example.com/identity'
,
'next'
:
'/getuser/'
}
# but returned username is for 'testuser', which already exists for another identity
openid_resp
=
{
'nickname'
:
'testuser'
,
'fullname'
:
'Rename User'
,
'email'
:
'rename@example.com'
}
self
.
_do_user_login
(
openid_req
,
openid_resp
)
response
=
self
.
client
.
get
(
'/getuser/'
)
# If OPENID_FOLLOW_RENAMES, attempt to change username to 'testuser'
# but since that username is already taken by someone else, we go through
# the process of adding +i to it. Since the user for this identity url
# already has a name matching that pattern, check if first.
self
.
assertEquals
(
response
.
content
,
'testuser2000'
)
# The user's full name and email have been updated.
user
=
User
.
objects
.
get
(
username
=
response
.
content
)
self
.
assertEquals
(
user
.
first_name
,
'Rename'
)
self
.
assertEquals
(
user
.
last_name
,
'User'
)
self
.
assertEquals
(
user
.
email
,
'rename@example.com'
)
def
test_login_follow_rename_false_conflict
(
self
):
settings
.
OPENID_FOLLOW_RENAMES
=
True
settings
.
OPENID_UPDATE_DETAILS_FROM_SREG
=
True
# Setup existing user who's username matches the name+i pattern
user
=
User
.
objects
.
create_user
(
'testuser2'
,
'someone@example.com'
)
UserOpenID
.
objects
.
get_or_create
(
user
=
user
,
claimed_id
=
'http://example.com/identity'
,
display_id
=
'http://example.com/identity'
)
# identity url is for 'testuser2'
openid_req
=
{
'openid_identifier'
:
'http://example.com/identity'
,
'next'
:
'/getuser/'
}
# but returned username is for 'testuser', which looks like we've done
# a username+1 for them already, but 'testuser' isn't actually taken
openid_resp
=
{
'nickname'
:
'testuser'
,
'fullname'
:
'Same User'
,
'email'
:
'same@example.com'
}
self
.
_do_user_login
(
openid_req
,
openid_resp
)
response
=
self
.
client
.
get
(
'/getuser/'
)
# If OPENID_FOLLOW_RENAMES, username should be changed to 'testuser'
# because it wasn't currently taken
self
.
assertEquals
(
response
.
content
,
'testuser'
)
# The user's full name and email have been updated.
user
=
User
.
objects
.
get
(
username
=
response
.
content
)
self
.
assertEquals
(
user
.
first_name
,
'Same'
)
self
.
assertEquals
(
user
.
last_name
,
'User'
)
self
.
assertEquals
(
user
.
email
,
'same@example.com'
)
def
test_login_update_details
(
self
):
settings
.
OPENID_UPDATE_DETAILS_FROM_SREG
=
True
user
=
User
.
objects
.
create_user
(
'testuser'
,
'someone@example.com'
)
useropenid
=
UserOpenID
(
user
=
user
,
claimed_id
=
'http://example.com/identity'
,
display_id
=
'http://example.com/identity'
)
useropenid
.
save
()
openid_req
=
{
'openid_identifier'
:
'http://example.com/identity'
,
'next'
:
'/getuser/'
}
openid_resp
=
{
'nickname'
:
'testuser'
,
'fullname'
:
'Some User'
,
'email'
:
'foo@example.com'
}
self
.
_do_user_login
(
openid_req
,
openid_resp
)
response
=
self
.
client
.
get
(
'/getuser/'
)
self
.
assertEquals
(
response
.
content
,
'testuser'
)
# The user's full name and email have been updated.
# The user's full name and email have been updated.
user
=
User
.
objects
.
get
(
username
=
response
.
content
)
user
=
User
.
objects
.
get
(
username
=
response
.
content
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment