Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
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
edx
edx-platform
Commits
f7cabf7f
Commit
f7cabf7f
authored
Sep 23, 2014
by
Bertrand Marron
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix IONISx social provider
parent
e3397cf9
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
96 additions
and
89 deletions
+96
-89
common/djangoapps/student/views.py
+40
-43
common/djangoapps/third_party_auth/middleware.py
+34
-29
common/djangoapps/third_party_auth/portal.py
+22
-17
No files found.
common/djangoapps/student/views.py
View file @
f7cabf7f
...
...
@@ -7,9 +7,9 @@ import re
import
uuid
import
time
import
json
import
requests
from
collections
import
defaultdict
from
pytz
import
UTC
from
requests
import
request
,
ConnectionError
from
django.conf
import
settings
from
django.contrib.auth
import
logout
,
authenticate
,
login
...
...
@@ -372,27 +372,31 @@ def register_user(request, extra_context=None):
"""
This view will display the non-modal registration form
"""
if
not
settings
.
FEATURES
.
get
(
'ENABLE_THIRD_PARTY_AUTH'
):
if
request
.
user
.
is_authenticated
():
return
redirect
(
reverse
(
'dashboard'
))
if
settings
.
FEATURES
.
get
(
'AUTH_USE_CERTIFICATES_IMMEDIATE_SIGNUP'
):
# Redirect to branding to process their certificate if SSL is enabled
# and registration is disabled.
return
external_auth
.
views
.
redirect_with_get
(
'root'
,
request
.
GET
)
if
request
.
user
.
is_authenticated
():
return
redirect
(
reverse
(
'dashboard'
))
context
=
{
'course_id'
:
request
.
GET
.
get
(
'course_id'
),
'email'
:
''
,
'enrollment_action'
:
request
.
GET
.
get
(
'enrollment_action'
),
'name'
:
''
,
'running_pipeline'
:
None
,
'platform_name'
:
microsite
.
get_value
(
'platform_name'
,
settings
.
PLATFORM_NAME
),
'selected_provider'
:
''
,
'username'
:
''
,
}
if
settings
.
FEATURES
.
get
(
'ENABLE_THIRD_PARTY_AUTH'
):
# Redirect to IONISx, we don't want the registration form.
return
external_auth
.
views
.
redirect_with_get
(
'/auth/login/portal-oauth2'
,
request
.
GET
,
do_reverse
=
False
)
if
settings
.
FEATURES
.
get
(
'AUTH_USE_CERTIFICATES_IMMEDIATE_SIGNUP'
):
# Redirect to branding to process their certificate if SSL is enabled
# and registration is disabled.
return
external_auth
.
views
.
redirect_with_get
(
'root'
,
request
.
GET
)
context
=
{
'course_id'
:
request
.
GET
.
get
(
'course_id'
),
'email'
:
''
,
'enrollment_action'
:
request
.
GET
.
get
(
'enrollment_action'
),
'name'
:
''
,
'running_pipeline'
:
None
,
'platform_name'
:
microsite
.
get_value
(
'platform_name'
,
settings
.
PLATFORM_NAME
),
'selected_provider'
:
''
,
'username'
:
''
,
}
# We save this so, later on, we can determine what course motivated a user's signup
# if they actually complete the registration process
...
...
@@ -401,8 +405,8 @@ def register_user(request, extra_context=None):
if
extra_context
is
not
None
:
context
.
update
(
extra_context
)
if
context
.
get
(
"extauth_domain"
,
''
)
.
startswith
(
external_auth
.
views
.
SHIBBOLETH_DOMAIN_PREFIX
):
return
render_to_response
(
'register-shib.html'
,
context
)
if
context
.
get
(
"extauth_domain"
,
''
)
.
startswith
(
external_auth
.
views
.
SHIBBOLETH_DOMAIN_PREFIX
):
return
render_to_response
(
'register-shib.html'
,
context
)
# If third-party auth is enabled, prepopulate the form with data from the
# selected provider.
...
...
@@ -414,15 +418,7 @@ def register_user(request, extra_context=None):
overrides
[
'selected_provider'
]
=
current_provider
.
NAME
context
.
update
(
overrides
)
return
render_to_response
(
'register.html'
,
context
)
else
:
if
request
.
user
.
is_authenticated
():
if
'course_id'
in
request
.
GET
:
return
redirect
(
"/courses/{0}/about"
.
format
(
request
.
GET
.
get
(
'course_id'
)))
else
:
return
redirect
(
'/'
)
else
:
return
redirect
(
"/auth/login/portal-oauth2/?auth_entry=login&next={0}"
.
format
(
urlquote
(
request
.
get_full_path
())))
return
render_to_response
(
'register.html'
,
context
)
def
complete_course_mode_info
(
course_id
,
enrollment
):
...
...
@@ -1094,15 +1090,17 @@ def login_user(request, error=""): # pylint: disable-msg=too-many-statements,un
})
# TODO: this should be status code 400 # pylint: disable=fixme
def
logout_portal
(
user_mail
):
try
:
user
=
models
.
DjangoStorage
.
user
.
objects
.
get
(
uid
=
user_mail
)
response
=
request
(
'POST'
,
settings
.
IONISX_AUTH
[
'SYNC_LOGOUT_URL'
],
params
=
{
'access_token'
:
user
.
extra_data
[
'access_token'
]
})
except
ConnectionError
as
err
:
log
.
warning
(
err
)
except
Exception
as
err
:
log
.
warning
(
err
)
def
logout_portal
(
request
):
if
request
.
user
.
is_authenticated
():
user
=
request
.
user
social_data
=
models
.
DjangoStorage
.
user
.
get_social_auth_for_user
(
user
)[
0
]
try
:
requests
.
post
(
settings
.
IONISX_AUTH
.
get
(
'SYNC_LOGOUT_URL'
),
headers
=
{
'Authorization'
:
'Bearer {0}'
.
format
(
social_data
.
extra_data
[
'access_token'
])}
)
except
requests
.
ConnectionError
as
err
:
log
.
warning
(
err
)
@ensure_csrf_cookie
...
...
@@ -1119,9 +1117,8 @@ def logout_user(request):
else
:
user_mail
=
request
.
user
.
email
logout_portal
(
request
)
logout
(
request
)
if
user_mail
:
logout_portal
(
user_mail
)
if
settings
.
FEATURES
.
get
(
'AUTH_USE_CAS'
):
target
=
reverse
(
'cas-logout'
)
else
:
...
...
common/djangoapps/third_party_auth/middleware.py
View file @
f7cabf7f
...
...
@@ -13,8 +13,9 @@ from social.apps.django_app.default import models
from
social.apps.django_app.middleware
import
SocialAuthExceptionMiddleware
from
.
import
pipeline
from
.
import
portal
log
=
logging
.
getLogger
(
'third_party_auth.middleware'
)
log
=
logging
.
getLogger
(
__file__
)
class
ExceptionMiddleware
(
SocialAuthExceptionMiddleware
):
"""Custom middleware that handles conditional redirection."""
...
...
@@ -32,32 +33,36 @@ class PortalSynchronizerMiddleware(object):
"""Custom middleware to synchronize user status of LMS with Portal provider."""
def
process_request
(
self
,
request
):
if
not
isinstance
(
request
.
user
,
AnonymousUser
):
try
:
email
=
request
.
user
.
email
user
=
models
.
DjangoStorage
.
user
.
objects
.
get
(
uid
=
email
)
response
=
requests
.
request
(
'POST'
,
settings
.
IONISX_AUTH
[
'SYNC_USER_URL'
],
params
=
{
'access_token'
:
user
.
extra_data
[
'access_token'
]
})
response
=
response
.
json
()
if
response
is
None
:
logout
(
request
)
response
=
redirect
(
request
.
get_full_path
())
response
.
delete_cookie
(
settings
.
EDXMKTG_COOKIE_NAME
,
path
=
'/'
,
domain
=
settings
.
SESSION_COOKIE_DOMAIN
,
if
request
.
user
.
is_authenticated
():
user
=
request
.
user
social_auth
=
models
.
DjangoStorage
.
user
.
get_social_auth_for_user
(
user
)
if
len
(
social_auth
)
==
1
:
social_data
=
social_auth
[
0
]
try
:
r
=
requests
.
get
(
settings
.
IONISX_AUTH
.
get
(
'USER_DATA_URL'
),
headers
=
{
'Authorization'
:
'Bearer {0}'
.
format
(
social_data
.
extra_data
[
'access_token'
])}
)
return
response
if
response
[
'updated'
]
is
True
:
log
.
warning
(
'need update !'
)
user
=
request
.
user
user
.
email
=
response
[
'emails'
][
0
][
'email'
]
user
.
username
=
response
[
'username'
]
user
.
save
()
profile
=
UserProfile
.
objects
.
get
(
user
=
request
.
user
)
profile
.
name
=
response
[
'name'
]
profile
.
save
()
except
requests
.
ConnectionError
as
err
:
log
.
warning
(
err
)
except
Exception
as
err
:
log
.
warning
(
err
)
except
requests
.
ConnectionError
as
err
:
log
.
warning
(
err
)
return
user_data
=
r
.
json
()
if
user_data
:
_id
=
user_data
[
'_id'
]
email
=
portal
.
get_primary_email
(
user_data
[
'emails'
])
username
=
user_data
[
'username'
]
name
=
user_data
[
'name'
]
if
(
user
.
email
!=
email
or
user
.
username
!=
user_data
[
'username'
]):
log
.
info
(
'User {} needs to be updated'
.
format
(
_id
))
user
.
email
=
email
user
.
username
=
username
user
.
save
()
if
user
.
profile
.
name
!=
user_data
[
'name'
]:
log
.
info
(
'User profile for {} needs to be updated'
.
format
(
_id
))
user
.
profile
.
name
=
name
user
.
profile
.
save
()
common/djangoapps/third_party_auth/portal.py
View file @
f7cabf7f
...
...
@@ -5,35 +5,40 @@ from django.conf import settings
from
social.backends.oauth
import
BaseOAuth2
from
social.exceptions
import
AuthCanceled
def
get_primary_email
(
emails
):
for
email
in
emails
:
if
email
[
'primary'
]
is
True
:
return
email
[
'email'
]
return
None
class
PortalOAuth2
(
BaseOAuth2
):
"""Portal OAuth2 authentication backend"""
name
=
'portal-oauth2'
auth_settings
=
settings
.
IONISX_AUTH
AUTHORIZATION_URL
=
auth_settings
[
'AUTHORIZATION_URL'
]
ACCESS_TOKEN_URL
=
auth_settings
[
'ACCESS_TOKEN_URL'
]
name
=
'portal-oauth2'
ID_KEY
=
'_id'
AUTHORIZATION_URL
=
auth_settings
.
get
(
'AUTHORIZATION_URL'
)
ACCESS_TOKEN_URL
=
auth_settings
.
get
(
'ACCESS_TOKEN_URL'
)
ACCESS_TOKEN_METHOD
=
'POST'
REDIRECT_STATE
=
False
USER_DATA_URL
=
auth_settings
[
'USER_DATA_URL'
]
def
get_user_id
(
self
,
details
,
response
):
"""Use portal email as unique id"""
if
self
.
setting
(
'USE_UNIQUE_USER_ID'
,
False
):
return
response
[
'id'
]
else
:
return
details
[
'email'
]
USER_DATA_URL
=
auth_settings
.
get
(
'USER_DATA_URL'
)
def
get_user_details
(
self
,
response
):
"""Return user details from Portal account"""
return
{
'username'
:
response
.
get
(
'username'
,
''
),
'email'
:
response
.
get
(
'emails'
,
''
)[
0
][
'email'
],
'fullname'
:
response
.
get
(
'name'
)}
"""Return user details from IONISx account"""
return
{
'username'
:
response
[
'username'
],
'email'
:
get_primary_email
(
response
[
'emails'
]),
'fullname'
:
response
[
'name'
]
}
def
user_data
(
self
,
access_token
,
*
args
,
**
kwargs
):
"""Loads user data from service"""
params
=
self
.
setting
(
'PROFILE_EXTRA_PARAMS'
,
{})
params
[
'access_token'
]
=
access_token
return
self
.
get_json
(
self
.
USER_DATA_URL
,
params
=
params
)
return
self
.
get_json
(
self
.
USER_DATA_URL
,
headers
=
{
'Authorization'
:
'Bearer {0}'
.
format
(
access_token
)}
)
def
process_error
(
self
,
data
):
super
(
PortalOAuth2
,
self
)
.
process_error
(
data
)
...
...
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