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
d13e4569
Commit
d13e4569
authored
Jul 11, 2016
by
sanfordstudent
Committed by
GitHub
Jul 11, 2016
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #12939 from edx/sstudent/TNL-4924
moving milestones/gating check to access.py
parents
d82292cb
5db58c00
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
39 additions
and
40 deletions
+39
-40
common/djangoapps/util/milestones_helpers.py
+7
-2
lms/djangoapps/courseware/access.py
+27
-11
lms/djangoapps/courseware/grades.py
+0
-7
lms/djangoapps/courseware/module_render.py
+1
-7
lms/djangoapps/courseware/tests/test_module_render.py
+1
-0
lms/djangoapps/courseware/tests/test_views.py
+3
-2
lms/djangoapps/courseware/views/index.py
+0
-11
No files found.
common/djangoapps/util/milestones_helpers.py
View file @
d13e4569
...
...
@@ -345,14 +345,19 @@ def add_course_content_milestone(course_id, content_id, relationship, milestone)
return
milestones_api
.
add_course_content_milestone
(
course_id
,
content_id
,
relationship
,
milestone
)
def
get_course_content_milestones
(
course_id
,
content_id
,
relationship
):
def
get_course_content_milestones
(
course_id
,
content_id
,
relationship
,
user_id
=
None
):
"""
Client API operation adapter/wrapper
"""
if
not
settings
.
FEATURES
.
get
(
'MILESTONES_APP'
,
False
):
return
[]
from
milestones
import
api
as
milestones_api
return
milestones_api
.
get_course_content_milestones
(
course_id
,
content_id
,
relationship
)
return
milestones_api
.
get_course_content_milestones
(
course_id
,
content_id
,
relationship
,
{
'id'
:
user_id
}
if
user_id
else
None
)
def
remove_course_content_user_milestones
(
course_key
,
content_key
,
user
,
relationship
):
...
...
lms/djangoapps/courseware/access.py
View file @
d13e4569
...
...
@@ -20,6 +20,7 @@ from django.utils.timezone import UTC
from
opaque_keys.edx.keys
import
CourseKey
,
UsageKey
from
util
import
milestones_helpers
as
milestones_helpers
from
xblock.core
import
XBlock
from
xmodule.course_module
import
(
...
...
@@ -552,19 +553,18 @@ def _has_access_descriptor(user, action, descriptor, course_key=None):
students to see modules. If not, views should check the course, so we
don't have to hit the enrollments table on every module load.
"""
response
=
(
_visible_to_nonstaff_users
(
descriptor
)
and
_has_group_access
(
descriptor
,
user
,
course_key
)
and
(
_has_detached_class_tag
(
descriptor
)
or
_can_access_descriptor_with_start_date
(
user
,
descriptor
,
course_key
)
)
)
if
_has_staff_access_to_descriptor
(
user
,
descriptor
,
course_key
):
return
ACCESS_GRANTED
# if the user has staff access, they can load the module so this code doesn't need to run
return
(
ACCESS_GRANTED
if
(
response
or
_has_staff_access_to_descriptor
(
user
,
descriptor
,
course_key
))
else
response
_visible_to_nonstaff_users
(
descriptor
)
and
_can_access_descriptor_with_milestones
(
user
,
descriptor
,
course_key
)
and
_has_group_access
(
descriptor
,
user
,
course_key
)
and
(
_has_detached_class_tag
(
descriptor
)
or
_can_access_descriptor_with_start_date
(
user
,
descriptor
,
course_key
)
)
)
checkers
=
{
...
...
@@ -801,6 +801,22 @@ def _visible_to_nonstaff_users(descriptor):
return
VisibilityError
()
if
descriptor
.
visible_to_staff_only
else
ACCESS_GRANTED
def
_can_access_descriptor_with_milestones
(
user
,
descriptor
,
course_key
):
"""
Returns if the object is blocked by an unfulfilled milestone.
Args:
user: the user trying to access this content
descriptor: the object being accessed
course_key: key for the course for this descriptor
"""
if
milestones_helpers
.
get_course_content_milestones
(
course_key
,
descriptor
.
location
,
'requires'
,
user
.
id
):
debug
(
"Deny: user has not completed all milestones for content"
)
return
ACCESS_DENIED
else
:
return
ACCESS_GRANTED
def
_has_detached_class_tag
(
descriptor
):
"""
Returns if the given descriptor's type is marked as detached.
...
...
lms/djangoapps/courseware/grades.py
View file @
d13e4569
...
...
@@ -17,7 +17,6 @@ from opaque_keys.edx.keys import CourseKey
from
opaque_keys.edx.locator
import
BlockUsageLocator
from
openedx.core.djangoapps.content.block_structure.api
import
get_course_in_cache
from
openedx.core.lib.cache_utils
import
memoized
from
openedx.core.lib.gating
import
api
as
gating_api
from
courseware.model_data
import
FieldDataCache
,
ScoresClient
from
openedx.core.djangoapps.signals.signals
import
GRADES_UPDATED
from
student.models
import
anonymous_id_for_user
...
...
@@ -513,9 +512,6 @@ def _progress_summary(student, course, course_structure=None):
unicode
(
course
.
id
),
anonymous_id_for_user
(
student
,
course
.
id
)
)
# Check for gated content
gated_content
=
gating_api
.
get_gated_content
(
course
,
student
)
chapters
=
[]
locations_to_weighted_scores
=
{}
...
...
@@ -523,9 +519,6 @@ def _progress_summary(student, course, course_structure=None):
chapter
=
course_structure
[
chapter_key
]
sections
=
[]
for
section_key
in
course_structure
.
get_children
(
chapter_key
):
if
unicode
(
section_key
)
in
gated_content
:
continue
section
=
course_structure
[
section_key
]
graded
=
getattr
(
section
,
'graded'
,
False
)
...
...
lms/djangoapps/courseware/module_render.py
View file @
d13e4569
...
...
@@ -32,7 +32,6 @@ from xblock.exceptions import NoSuchHandlerError, NoSuchViewError
from
xblock.reference.plugins
import
FSService
import
static_replace
from
openedx.core.lib.gating
import
api
as
gating_api
from
courseware.access
import
has_access
,
get_user_role
from
courseware.entrance_exams
import
(
get_entrance_exam_score
,
...
...
@@ -164,9 +163,6 @@ def toc_for_course(user, request, course, active_chapter, active_section, field_
# before the rest of the content is made available
required_content
=
milestones_helpers
.
get_required_content
(
course
,
user
)
# Check for gated content
gated_content
=
gating_api
.
get_gated_content
(
course
,
user
)
# The user may not actually have to complete the entrance exam, if one is required
if
not
user_must_complete_entrance_exam
(
request
,
user
,
course
):
required_content
=
[
content
for
content
in
required_content
if
not
content
==
course
.
entrance_exam_id
]
...
...
@@ -189,9 +185,7 @@ def toc_for_course(user, request, course, active_chapter, active_section, field_
sections
=
list
()
for
section
in
chapter
.
get_display_items
():
# skip the section if it is gated/hidden from the user
if
gated_content
and
unicode
(
section
.
location
)
in
gated_content
:
continue
# skip the section if it is hidden from the user
if
section
.
hide_from_toc
:
continue
...
...
lms/djangoapps/courseware/tests/test_module_render.py
View file @
d13e4569
...
...
@@ -1112,6 +1112,7 @@ class TestGatedSubsectionRendering(SharedModuleStoreTestCase, MilestonesTestCase
return
None
@patch.dict
(
settings
.
FEATURES
,
{
'MILESTONES_APP'
:
True
})
def
test_toc_with_gated_sequential
(
self
):
"""
Test generation of TOC for a course with a gated subsection
...
...
lms/djangoapps/courseware/tests/test_views.py
View file @
d13e4569
...
...
@@ -1787,7 +1787,7 @@ class TestIndexView(ModuleStoreTestCase):
@ddt.ddt
class
TestInde
w
ViewWithVerticalPositions
(
ModuleStoreTestCase
):
class
TestInde
x
ViewWithVerticalPositions
(
ModuleStoreTestCase
):
"""
Test the index view to handle vertical positions. Confirms that first position is loaded
if input position is non-positive or greater than number of positions available.
...
...
@@ -1797,7 +1797,7 @@ class TestIndewViewWithVerticalPositions(ModuleStoreTestCase):
"""
Set up initial test data
"""
super
(
TestInde
w
ViewWithVerticalPositions
,
self
)
.
setUp
()
super
(
TestInde
x
ViewWithVerticalPositions
,
self
)
.
setUp
()
self
.
user
=
UserFactory
()
...
...
@@ -1875,6 +1875,7 @@ class TestIndexViewWithGating(ModuleStoreTestCase, MilestonesTestCaseMixin):
CourseEnrollmentFactory
(
user
=
self
.
user
,
course_id
=
self
.
course
.
id
)
@patch.dict
(
settings
.
FEATURES
,
{
'MILESTONES_APP'
:
True
})
def
test_index_with_gated_sequential
(
self
):
"""
Test index view with a gated sequential raises Http404
...
...
lms/djangoapps/courseware/views/index.py
View file @
d13e4569
...
...
@@ -25,7 +25,6 @@ import urllib
from
lang_pref
import
LANGUAGE_KEY
from
xblock.fragment
import
Fragment
from
opaque_keys.edx.keys
import
CourseKey
from
openedx.core.lib.gating
import
api
as
gating_api
from
openedx.core.lib.time_zone_utils
import
get_user_time_zone
from
openedx.core.djangoapps.user_api.preferences.api
import
get_user_preference
from
shoppingcart.models
import
CourseRegistrationCode
...
...
@@ -143,7 +142,6 @@ class CoursewareIndex(View):
if
self
.
chapter
and
self
.
section
:
self
.
_redirect_if_not_requested_section
()
self
.
_verify_section_not_gated
()
self
.
_save_positions
()
self
.
_prefetch_and_bind_section
()
...
...
@@ -272,15 +270,6 @@ class CoursewareIndex(View):
self
.
chapter_url_name
=
exam_chapter
.
url_name
self
.
section_url_name
=
exam_section
.
url_name
def
_verify_section_not_gated
(
self
):
"""
Verify whether the section is gated and accessible to the user.
"""
gated_content
=
gating_api
.
get_gated_content
(
self
.
course
,
self
.
effective_user
)
if
gated_content
:
if
unicode
(
self
.
section
.
location
)
in
gated_content
:
raise
Http404
def
_get_language_preference
(
self
):
"""
Returns the preferred language for the actual user making the request.
...
...
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