Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-analytics-dashboard
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-analytics-dashboard
Commits
269abc54
Commit
269abc54
authored
Nov 10, 2014
by
Carlos Andrés Rocha
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Read list of courses during authentication, if available.
parent
1c63cb59
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
75 additions
and
2 deletions
+75
-2
analytics_dashboard/analytics_dashboard/backends.py
+27
-0
analytics_dashboard/analytics_dashboard/tests/test_backends.py
+29
-0
analytics_dashboard/courses/permissions.py
+19
-2
No files found.
analytics_dashboard/analytics_dashboard/backends.py
View file @
269abc54
...
...
@@ -2,8 +2,10 @@
This file contains Django authentication backends. For more information visit
https://docs.djangoproject.com/en/dev/topics/auth/customizing/.
"""
import
json
from
django.conf
import
settings
import
django.dispatch
from
social.backends.open_id
import
OpenIdConnectAuth
...
...
@@ -31,11 +33,36 @@ class EdXOpenIdConnect(OpenIdConnectAuth):
'locale'
:
u'language'
,
}
auth_complete_signal
=
django
.
dispatch
.
Signal
(
providing_args
=
[
"user"
,
"id_token"
])
def
user_data
(
self
,
_access_token
,
*
_args
,
**
_kwargs
):
# Include decoded id_token fields in user data.
return
self
.
id_token
def
auth_complete_params
(
self
,
state
=
None
):
params
=
super
(
EdXOpenIdConnect
,
self
)
.
auth_complete_params
(
state
)
# TODO: Due a limitation in the oidc provider in the LMS, the list of all course permissions
# is computed during the authentication process. As an optimization, we explicitly request
# the list here, avoiding further roundtrips. This is no longer necessary once the limitation
# is resolved and instead the course permissions can be requested on a need to have basis,
# reducing overhead significantly.
claim_names
=
settings
.
COURSE_PERMISSIONS_CLAIMS
courses_claims_request
=
{
name
:
{
'essential'
:
True
}
for
name
in
claim_names
}
params
[
'claims'
]
=
json
.
dumps
({
'id_token'
:
courses_claims_request
})
return
params
def
auth_complete
(
self
,
*
args
,
**
kwargs
):
# WARNING: during testing, the user model class is `social.tests.models` and not the one
# specified for the application.
user
=
super
(
EdXOpenIdConnect
,
self
)
.
auth_complete
(
*
args
,
**
kwargs
)
self
.
auth_complete_signal
.
send
(
sender
=
self
.
__class__
,
user
=
user
,
id_token
=
self
.
id_token
)
return
user
def
get_user_claims
(
self
,
access_token
,
claims
=
None
):
""" Returns a dictionary with the values for each claim requested. """
data
=
self
.
get_json
(
self
.
USER_INFO_URL
,
headers
=
{
'Authorization'
:
'Bearer {0}'
.
format
(
access_token
)}
...
...
analytics_dashboard/analytics_dashboard/tests/test_backends.py
View file @
269abc54
...
...
@@ -3,7 +3,36 @@ from django.conf import settings
from
social.tests.backends.oauth
import
OAuth2Test
from
social.tests.backends.open_id
import
OpenIdConnectTestMixin
import
courses
DUMMY_AUTHORIZED_COURSE
=
'dummy/course/id'
class
EdXOpenIdConnectTests
(
OpenIdConnectTestMixin
,
OAuth2Test
):
backend_path
=
'analytics_dashboard.backends.EdXOpenIdConnect'
issuer
=
settings
.
SOCIAL_AUTH_EDX_OIDC_URL_ROOT
expected_username
=
'test_user'
def
get_id_token
(
self
,
*
args
,
**
kwargs
):
data
=
super
(
EdXOpenIdConnectTests
,
self
)
.
get_id_token
(
*
args
,
**
kwargs
)
# Set the field used to derive the username of the logged user.
data
[
'preferred_username'
]
=
self
.
expected_username
# Include a dummy list of authorized courses.
claim_name
=
settings
.
COURSE_PERMISSIONS_CLAIMS
[
0
]
data
[
claim_name
]
=
[
DUMMY_AUTHORIZED_COURSE
]
return
data
def
test_login
(
self
):
user
=
self
.
do_login
()
self
.
assertIsNotNone
(
user
)
def
test_course_permissions
(
self
):
user
=
self
.
do_login
()
authorized_courses
=
courses
.
permissions
.
get_user_course_permissions
(
user
)
self
.
assertEqual
(
len
(
authorized_courses
),
1
)
self
.
assertIn
(
DUMMY_AUTHORIZED_COURSE
,
authorized_courses
)
analytics_dashboard/courses/permissions.py
View file @
269abc54
import
datetime
import
logging
from
django.conf
import
settings
from
django.core.cache
import
cache
from
django.dispatch
import
receiver
from
social.apps.django_app
import
load_strategy
from
analytics_dashboard.backends
import
EdXOpenIdConnect
from
courses.exceptions
import
UserNotAssociatedWithBackendError
,
InvalidAccessTokenError
,
\
PermissionsRetrievalFailedError
...
...
@@ -15,8 +20,8 @@ def _get_course_permission_cache_keys(user):
"""
Return the cache keys used for user-course permissions
"""
key_last_updated
=
'course_permissions_updated_at_{}'
.
format
(
user
.
pk
)
key_courses
=
'course_permissions_{}'
.
format
(
user
.
pk
)
key_last_updated
=
'course_permissions_updated_at_{}'
.
format
(
user
.
id
)
key_courses
=
'course_permissions_{}'
.
format
(
user
.
id
)
return
key_courses
,
key_last_updated
...
...
@@ -135,3 +140,15 @@ def user_can_view_course(user, course_id):
courses
=
get_user_course_permissions
(
user
)
return
course_id
in
courses
# pylint: disable=unused-argument
@receiver
(
EdXOpenIdConnect
.
auth_complete_signal
)
def
on_auth_complete
(
sender
,
user
,
id_token
,
**
kwargs
):
""" Callback to cache course permissions if available in the IDToken. """
allowed_courses
=
set
()
for
name
in
settings
.
COURSE_PERMISSIONS_CLAIMS
:
if
name
in
id_token
:
allowed_courses
.
update
(
id_token
[
name
])
if
allowed_courses
:
set_user_course_permissions
(
user
,
allowed_courses
)
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