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
e26efea2
Commit
e26efea2
authored
Aug 12, 2014
by
Waheed Ahmed
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed 500 error on views with incomplete course id in url.
LMS-11217
parent
14de1a3f
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
78 additions
and
18 deletions
+78
-18
lms/djangoapps/courseware/tests/test_lti_integration.py
+3
-4
lms/djangoapps/courseware/tests/test_views.py
+28
-1
lms/djangoapps/courseware/views.py
+47
-13
No files found.
lms/djangoapps/courseware/tests/test_lti_integration.py
View file @
e26efea2
...
@@ -178,11 +178,10 @@ class TestLTIModuleListing(ModuleStoreTestCase):
...
@@ -178,11 +178,10 @@ class TestLTIModuleListing(ModuleStoreTestCase):
def
test_lti_rest_bad_course
(
self
):
def
test_lti_rest_bad_course
(
self
):
"""Tests what happens when the lti listing rest endpoint gets a bad course_id"""
"""Tests what happens when the lti listing rest endpoint gets a bad course_id"""
bad_ids
=
[
u"sf"
,
u"dne/dne/dne"
,
u"fo/ey/
\u5305
"
]
bad_ids
=
[
u"sf"
,
u"dne/dne/dne"
,
u"fo/ey/
\\
u5305"
]
request
=
mock
.
Mock
()
request
.
method
=
'GET'
for
bad_course_id
in
bad_ids
:
for
bad_course_id
in
bad_ids
:
response
=
get_course_lti_endpoints
(
request
,
bad_course_id
)
lti_rest_endpoints_url
=
'courses/{}/lti_rest_endpoints/'
.
format
(
bad_course_id
)
response
=
self
.
client
.
get
(
lti_rest_endpoints_url
)
self
.
assertEqual
(
404
,
response
.
status_code
)
self
.
assertEqual
(
404
,
response
.
status_code
)
def
test_lti_rest_listing
(
self
):
def
test_lti_rest_listing
(
self
):
...
...
lms/djangoapps/courseware/tests/test_views.py
View file @
e26efea2
...
@@ -5,7 +5,7 @@ Tests courseware views.py
...
@@ -5,7 +5,7 @@ Tests courseware views.py
import
unittest
import
unittest
from
datetime
import
datetime
from
datetime
import
datetime
from
mock
import
MagicMock
,
patch
from
mock
import
MagicMock
,
patch
,
create_autospec
from
pytz
import
UTC
from
pytz
import
UTC
from
django.test
import
TestCase
from
django.test
import
TestCase
...
@@ -152,6 +152,10 @@ class ViewsTestCase(TestCase):
...
@@ -152,6 +152,10 @@ class ViewsTestCase(TestCase):
response
=
self
.
client
.
get
(
'/courses/MITx/3.091X/'
)
response
=
self
.
client
.
get
(
'/courses/MITx/3.091X/'
)
self
.
assertEqual
(
response
.
status_code
,
404
)
self
.
assertEqual
(
response
.
status_code
,
404
)
def
test_incomplete_course_id
(
self
):
response
=
self
.
client
.
get
(
'/courses/MITx/'
)
self
.
assertEqual
(
response
.
status_code
,
404
)
def
test_index_invalid_position
(
self
):
def
test_index_invalid_position
(
self
):
request_url
=
'/'
.
join
([
request_url
=
'/'
.
join
([
'/courses'
,
'/courses'
,
...
@@ -562,3 +566,26 @@ class ProgressPageTests(ModuleStoreTestCase):
...
@@ -562,3 +566,26 @@ class ProgressPageTests(ModuleStoreTestCase):
def
test_non_asci_grade_cutoffs
(
self
):
def
test_non_asci_grade_cutoffs
(
self
):
resp
=
views
.
progress
(
self
.
request
,
self
.
course
.
id
.
to_deprecated_string
())
resp
=
views
.
progress
(
self
.
request
,
self
.
course
.
id
.
to_deprecated_string
())
self
.
assertEqual
(
resp
.
status_code
,
200
)
self
.
assertEqual
(
resp
.
status_code
,
200
)
class
TestVerifyCourseIdDecorator
(
TestCase
):
"""
Tests for the verify_course_id decorator.
"""
def
setUp
(
self
):
self
.
request
=
RequestFactory
()
.
get
(
"foo"
)
self
.
valid_course_id
=
"edX/test/1"
self
.
invalid_course_id
=
"edX/"
def
test_decorator_with_valid_course_id
(
self
):
mocked_view
=
create_autospec
(
views
.
course_about
)
view_function
=
views
.
verify_course_id
(
mocked_view
)
view_function
(
self
.
request
,
self
.
valid_course_id
)
self
.
assertTrue
(
mocked_view
.
called
)
def
test_decorator_with_invalid_course_id
(
self
):
mocked_view
=
create_autospec
(
views
.
course_about
)
view_function
=
views
.
verify_course_id
(
mocked_view
)
self
.
assertRaises
(
Http404
,
view_function
,
self
.
request
,
self
.
invalid_course_id
)
self
.
assertFalse
(
mocked_view
.
called
)
lms/djangoapps/courseware/views.py
View file @
e26efea2
...
@@ -23,6 +23,7 @@ from edxmako.shortcuts import render_to_response, render_to_string
...
@@ -23,6 +23,7 @@ from edxmako.shortcuts import render_to_response, render_to_string
from
django_future.csrf
import
ensure_csrf_cookie
from
django_future.csrf
import
ensure_csrf_cookie
from
django.views.decorators.cache
import
cache_control
from
django.views.decorators.cache
import
cache_control
from
django.db
import
transaction
from
django.db
import
transaction
from
functools
import
wraps
from
markupsafe
import
escape
from
markupsafe
import
escape
from
courseware
import
grades
from
courseware
import
grades
...
@@ -81,6 +82,24 @@ def user_groups(user):
...
@@ -81,6 +82,24 @@ def user_groups(user):
return
group_names
return
group_names
def
verify_course_id
(
view_func
):
"""
This decorator should only be used with views whose second argument is course_id.
If course_id is not valid raise 404.
"""
@wraps
(
view_func
)
def
_decorated
(
request
,
course_id
,
*
args
,
**
kwargs
):
try
:
SlashSeparatedCourseKey
.
from_deprecated_string
(
course_id
)
except
InvalidKeyError
:
raise
Http404
response
=
view_func
(
request
,
course_id
,
*
args
,
**
kwargs
)
return
response
return
_decorated
@ensure_csrf_cookie
@ensure_csrf_cookie
@cache_if_anonymous
@cache_if_anonymous
def
courses
(
request
):
def
courses
(
request
):
...
@@ -242,6 +261,7 @@ def chat_settings(course, user):
...
@@ -242,6 +261,7 @@ def chat_settings(course, user):
@login_required
@login_required
@ensure_csrf_cookie
@ensure_csrf_cookie
@cache_control
(
no_cache
=
True
,
no_store
=
True
,
must_revalidate
=
True
)
@cache_control
(
no_cache
=
True
,
no_store
=
True
,
must_revalidate
=
True
)
@verify_course_id
def
index
(
request
,
course_id
,
chapter
=
None
,
section
=
None
,
def
index
(
request
,
course_id
,
chapter
=
None
,
section
=
None
,
position
=
None
):
position
=
None
):
"""
"""
...
@@ -266,7 +286,9 @@ def index(request, course_id, chapter=None, section=None,
...
@@ -266,7 +286,9 @@ def index(request, course_id, chapter=None, section=None,
- HTTPresponse
- HTTPresponse
"""
"""
course_key
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
course_id
)
course_key
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
course_id
)
user
=
User
.
objects
.
prefetch_related
(
"groups"
)
.
get
(
id
=
request
.
user
.
id
)
user
=
User
.
objects
.
prefetch_related
(
"groups"
)
.
get
(
id
=
request
.
user
.
id
)
request
.
user
=
user
# keep just one instance of User
request
.
user
=
user
# keep just one instance of User
course
=
get_course_with_access
(
user
,
'load'
,
course_key
,
depth
=
2
)
course
=
get_course_with_access
(
user
,
'load'
,
course_key
,
depth
=
2
)
...
@@ -458,6 +480,7 @@ def index(request, course_id, chapter=None, section=None,
...
@@ -458,6 +480,7 @@ def index(request, course_id, chapter=None, section=None,
@ensure_csrf_cookie
@ensure_csrf_cookie
@verify_course_id
def
jump_to_id
(
request
,
course_id
,
module_id
):
def
jump_to_id
(
request
,
course_id
,
module_id
):
"""
"""
This entry point allows for a shorter version of a jump to where just the id of the element is
This entry point allows for a shorter version of a jump to where just the id of the element is
...
@@ -516,13 +539,16 @@ def jump_to(request, course_id, location):
...
@@ -516,13 +539,16 @@ def jump_to(request, course_id, location):
@ensure_csrf_cookie
@ensure_csrf_cookie
@verify_course_id
def
course_info
(
request
,
course_id
):
def
course_info
(
request
,
course_id
):
"""
"""
Display the course's info.html, or 404 if there is no such course.
Display the course's info.html, or 404 if there is no such course.
Assumes the course_id is in a valid format.
Assumes the course_id is in a valid format.
"""
"""
course_key
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
course_id
)
course_key
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
course_id
)
course
=
get_course_with_access
(
request
.
user
,
'load'
,
course_key
)
course
=
get_course_with_access
(
request
.
user
,
'load'
,
course_key
)
staff_access
=
has_access
(
request
.
user
,
'staff'
,
course
)
staff_access
=
has_access
(
request
.
user
,
'staff'
,
course
)
masq
=
setup_masquerade
(
request
,
staff_access
)
# allow staff to toggle masquerade on info page
masq
=
setup_masquerade
(
request
,
staff_access
)
# allow staff to toggle masquerade on info page
...
@@ -544,16 +570,15 @@ def course_info(request, course_id):
...
@@ -544,16 +570,15 @@ def course_info(request, course_id):
@ensure_csrf_cookie
@ensure_csrf_cookie
@verify_course_id
def
static_tab
(
request
,
course_id
,
tab_slug
):
def
static_tab
(
request
,
course_id
,
tab_slug
):
"""
"""
Display the courses tab with the given name.
Display the courses tab with the given name.
Assumes the course_id is in a valid format.
Assumes the course_id is in a valid format.
"""
"""
try
:
course_key
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
course_id
)
course_key
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
course_id
)
except
InvalidKeyError
:
raise
Http404
course
=
get_course_with_access
(
request
.
user
,
'load'
,
course_key
)
course
=
get_course_with_access
(
request
.
user
,
'load'
,
course_key
)
...
@@ -579,13 +604,16 @@ def static_tab(request, course_id, tab_slug):
...
@@ -579,13 +604,16 @@ def static_tab(request, course_id, tab_slug):
@ensure_csrf_cookie
@ensure_csrf_cookie
@verify_course_id
def
syllabus
(
request
,
course_id
):
def
syllabus
(
request
,
course_id
):
"""
"""
Display the course's syllabus.html, or 404 if there is no such course.
Display the course's syllabus.html, or 404 if there is no such course.
Assumes the course_id is in a valid format.
Assumes the course_id is in a valid format.
"""
"""
course_key
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
course_id
)
course_key
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
course_id
)
course
=
get_course_with_access
(
request
.
user
,
'load'
,
course_key
)
course
=
get_course_with_access
(
request
.
user
,
'load'
,
course_key
)
staff_access
=
has_access
(
request
.
user
,
'staff'
,
course
)
staff_access
=
has_access
(
request
.
user
,
'staff'
,
course
)
...
@@ -621,7 +649,9 @@ def course_about(request, course_id):
...
@@ -621,7 +649,9 @@ def course_about(request, course_id):
settings
.
FEATURES
.
get
(
'ENABLE_MKTG_SITE'
,
False
)
settings
.
FEATURES
.
get
(
'ENABLE_MKTG_SITE'
,
False
)
):
):
raise
Http404
raise
Http404
course_key
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
course_id
)
course_key
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
course_id
)
course
=
get_course_with_access
(
request
.
user
,
'see_exists'
,
course_key
)
course
=
get_course_with_access
(
request
.
user
,
'see_exists'
,
course_key
)
registered
=
registered_for_course
(
course
,
request
.
user
)
registered
=
registered_for_course
(
course
,
request
.
user
)
staff_access
=
has_access
(
request
.
user
,
'staff'
,
course
)
staff_access
=
has_access
(
request
.
user
,
'staff'
,
course
)
...
@@ -683,12 +713,14 @@ def course_about(request, course_id):
...
@@ -683,12 +713,14 @@ def course_about(request, course_id):
@ensure_csrf_cookie
@ensure_csrf_cookie
@cache_if_anonymous
@cache_if_anonymous
@verify_course_id
def
mktg_course_about
(
request
,
course_id
):
def
mktg_course_about
(
request
,
course_id
):
"""
"""
This is the button that gets put into an iframe on the Drupal site
This is the button that gets put into an iframe on the Drupal site
"""
"""
course_key
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
course_id
)
course_key
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
course_id
)
try
:
try
:
course
=
get_course_with_access
(
request
.
user
,
'see_exists'
,
course_key
)
course
=
get_course_with_access
(
request
.
user
,
'see_exists'
,
course_key
)
except
(
ValueError
,
Http404
)
as
e
:
except
(
ValueError
,
Http404
)
as
e
:
...
@@ -739,13 +771,17 @@ def mktg_course_about(request, course_id):
...
@@ -739,13 +771,17 @@ def mktg_course_about(request, course_id):
@login_required
@login_required
@cache_control
(
no_cache
=
True
,
no_store
=
True
,
must_revalidate
=
True
)
@cache_control
(
no_cache
=
True
,
no_store
=
True
,
must_revalidate
=
True
)
@transaction.commit_manually
@transaction.commit_manually
@verify_course_id
def
progress
(
request
,
course_id
,
student_id
=
None
):
def
progress
(
request
,
course_id
,
student_id
=
None
):
"""
"""
Wraps "_progress" with the manual_transaction context manager just in case
Wraps "_progress" with the manual_transaction context manager just in case
there are unanticipated errors.
there are unanticipated errors.
"""
"""
course_key
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
course_id
)
with
grades
.
manual_transaction
():
with
grades
.
manual_transaction
():
return
_progress
(
request
,
SlashSeparatedCourseKey
.
from_deprecated_string
(
course_id
)
,
student_id
)
return
_progress
(
request
,
course_key
,
student_id
)
def
_progress
(
request
,
course_key
,
student_id
):
def
_progress
(
request
,
course_key
,
student_id
):
...
@@ -816,16 +852,15 @@ def fetch_reverify_banner_info(request, course_key):
...
@@ -816,16 +852,15 @@ def fetch_reverify_banner_info(request, course_key):
@login_required
@login_required
@verify_course_id
def
submission_history
(
request
,
course_id
,
student_username
,
location
):
def
submission_history
(
request
,
course_id
,
student_username
,
location
):
"""Render an HTML fragment (meant for inclusion elsewhere) that renders a
"""Render an HTML fragment (meant for inclusion elsewhere) that renders a
history of all state changes made by this user for this problem location.
history of all state changes made by this user for this problem location.
Right now this only works for problems because that's all
Right now this only works for problems because that's all
StudentModuleHistory records.
StudentModuleHistory records.
"""
"""
try
:
course_key
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
course_id
)
course_key
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
course_id
)
except
(
InvalidKeyError
,
AssertionError
):
return
HttpResponse
(
escape
(
_
(
u'Invalid course id.'
)))
try
:
try
:
usage_key
=
course_key
.
make_usage_key_from_deprecated_string
(
location
)
usage_key
=
course_key
.
make_usage_key_from_deprecated_string
(
location
)
...
@@ -925,6 +960,7 @@ def get_static_tab_contents(request, course, tab):
...
@@ -925,6 +960,7 @@ def get_static_tab_contents(request, course, tab):
@require_GET
@require_GET
@verify_course_id
def
get_course_lti_endpoints
(
request
,
course_id
):
def
get_course_lti_endpoints
(
request
,
course_id
):
"""
"""
View that, given a course_id, returns the a JSON object that enumerates all of the LTI endpoints for that course.
View that, given a course_id, returns the a JSON object that enumerates all of the LTI endpoints for that course.
...
@@ -941,10 +977,8 @@ def get_course_lti_endpoints(request, course_id):
...
@@ -941,10 +977,8 @@ def get_course_lti_endpoints(request, course_id):
Returns:
Returns:
(django response object): HTTP response. 404 if course is not found, otherwise 200 with JSON body.
(django response object): HTTP response. 404 if course is not found, otherwise 200 with JSON body.
"""
"""
try
:
course_key
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
course_id
)
course_key
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
course_id
)
except
InvalidKeyError
:
return
HttpResponse
(
status
=
404
)
try
:
try
:
course
=
get_course
(
course_key
,
depth
=
2
)
course
=
get_course
(
course_key
,
depth
=
2
)
...
...
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