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
babd972c
Commit
babd972c
authored
Aug 20, 2014
by
Matt Drayer
Committed by
Jonathan Piacenti
Aug 20, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mattdrayer/api-course-exists-check: Refactored course lookup logic
parent
7cab70b6
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
202 additions
and
169 deletions
+202
-169
lms/djangoapps/api_manager/courses/tests.py
+1
-5
lms/djangoapps/api_manager/courses/views.py
+62
-68
lms/djangoapps/api_manager/courseware_access.py
+83
-46
lms/djangoapps/api_manager/users/tests.py
+33
-33
lms/djangoapps/api_manager/users/views.py
+11
-13
lms/djangoapps/projects/views.py
+4
-4
lms/envs/test.py
+8
-0
No files found.
lms/djangoapps/api_manager/courses/tests.py
View file @
babd972c
...
...
@@ -474,7 +474,7 @@ class CoursesApiTests(TestCase):
def
test_courses_groups_list_get
(
self
):
test_uri
=
'{}/{}/groups'
.
format
(
self
.
base_courses_uri
,
self
.
test_course_id
)
course_fail_uri
=
'{}/{}/groups'
.
format
(
self
.
base_courses_uri
,
'
/
ed/Open_DemoX/edx_demo_course'
)
course_fail_uri
=
'{}/{}/groups'
.
format
(
self
.
base_courses_uri
,
'ed/Open_DemoX/edx_demo_course'
)
for
i
in
xrange
(
2
):
data_dict
=
{
'name'
:
'Alpha Group {}'
.
format
(
i
),
'type'
:
'Programming'
,
...
...
@@ -1311,7 +1311,6 @@ class CoursesApiTests(TestCase):
data
=
{
'group_id'
:
group_id
}
response
=
self
.
do_post
(
test_uri
,
data
)
self
.
assertEqual
(
response
.
status_code
,
201
)
# Create another group and add it to course module
data
=
{
'name'
:
'Beta Group'
,
'type'
:
'project'
}
response
=
self
.
do_post
(
self
.
base_groups_uri
,
data
)
...
...
@@ -1320,7 +1319,6 @@ class CoursesApiTests(TestCase):
data
=
{
'group_id'
:
another_group_id
}
response
=
self
.
do_post
(
test_uri
,
data
)
self
.
assertEqual
(
response
.
status_code
,
201
)
# create a 5 new users
for
i
in
xrange
(
1
,
6
):
data
=
{
...
...
@@ -1344,12 +1342,10 @@ class CoursesApiTests(TestCase):
data
=
{
'user_id'
:
created_user_id
}
response
=
self
.
do_post
(
test_group_users_uri
,
data
)
self
.
assertEqual
(
response
.
status_code
,
201
)
#enroll one user in Alpha Group and one in Beta Group created user
if
i
>=
2
:
response
=
self
.
do_post
(
test_course_users_uri
,
data
)
self
.
assertEqual
(
response
.
status_code
,
201
)
response
=
self
.
do_get
(
'{}?enrolled={}'
.
format
(
test_uri_users
,
'True'
))
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertEqual
(
len
(
response
.
data
),
2
)
...
...
lms/djangoapps/api_manager/courses/views.py
View file @
babd972c
...
...
@@ -27,7 +27,7 @@ from student.roles import CourseRole, CourseAccessRole, CourseInstructorRole, Co
from
xmodule.modulestore.django
import
modulestore
from
api_manager.courseware_access
import
get_course
,
get_course_child
,
get_course_leaf_nodes
from
api_manager.courseware_access
import
get_course
,
get_course_child
,
get_course_leaf_nodes
,
get_course_key
,
course_exists
from
api_manager.models
import
CourseGroupRelationship
,
CourseContentGroupRelationship
,
GroupProfile
,
\
CourseModuleCompletion
from
api_manager.permissions
import
SecureAPIView
,
SecureListAPIView
...
...
@@ -387,7 +387,7 @@ class CourseContentList(SecureAPIView):
response_data
=
[]
content_type
=
request
.
QUERY_PARAMS
.
get
(
'type'
,
None
)
if
course_id
!=
content_id
:
content_descriptor
,
content_key
,
content
=
get_course_child
(
request
,
request
.
user
,
course_key
,
content_id
)
# pylint: disable=W0612
content_descriptor
,
content_key
,
content
=
get_course_child
(
request
,
request
.
user
,
course_key
,
content_id
,
load_content
=
True
)
# pylint: disable=W0612
else
:
content
=
course_descriptor
if
content
:
...
...
@@ -460,7 +460,7 @@ class CourseContentDetail(SecureAPIView):
response_data
[
'uri'
]
=
base_uri
if
course_id
!=
content_id
:
element_name
=
'children'
content_descriptor
,
content_key
,
content
=
get_course_child
(
request
,
request
.
user
,
course_key
,
content_id
)
# pylint: disable=W0612
content_descriptor
,
content_key
,
content
=
get_course_child
(
request
,
request
.
user
,
course_key
,
content_id
,
load_content
=
True
)
# pylint: disable=W0612
else
:
element_name
=
'content'
protocol
=
'http'
...
...
@@ -666,9 +666,9 @@ class CoursesGroupsList(SecureAPIView):
response_data
=
{}
group_id
=
request
.
DATA
[
'group_id'
]
base_uri
=
generate_base_uri
(
request
)
course_descriptor
,
course_key
,
course_content
=
get_course
(
request
,
request
.
user
,
course_id
)
# pylint: disable=W0612
if
not
course_descriptor
:
if
not
course_exists
(
request
,
request
.
user
,
course_id
):
return
Response
({},
status
=
status
.
HTTP_404_NOT_FOUND
)
course_key
=
get_course_key
(
course_id
)
try
:
existing_group
=
Group
.
objects
.
get
(
id
=
group_id
)
except
ObjectDoesNotExist
:
...
...
@@ -695,12 +695,11 @@ class CoursesGroupsList(SecureAPIView):
"""
GET /api/courses/{course_id}/groups?type=workgroup
"""
course_descriptor
,
course_key
,
course_content
=
get_course
(
request
,
request
.
user
,
course_id
)
# pylint: disable=W0612
if
not
course_descriptor
:
if
not
course_exists
(
request
,
request
.
user
,
course_id
):
return
Response
({},
status
=
status
.
HTTP_404_NOT_FOUND
)
group_type
=
request
.
QUERY_PARAMS
.
get
(
'type'
,
None
)
course_key
=
get_course_key
(
course_id
)
course_groups
=
CourseGroupRelationship
.
objects
.
filter
(
course_id
=
course_key
)
if
group_type
:
course_groups
=
course_groups
.
filter
(
group__groupprofile__group_type
=
group_type
)
response_data
=
[]
...
...
@@ -727,14 +726,14 @@ class CoursesGroupsDetail(SecureAPIView):
"""
GET /api/courses/{course_id}/groups/{group_id}
"""
course_descriptor
,
course_key
,
course_content
=
get_course
(
request
,
request
.
user
,
course_id
)
# pylint: disable=W0612
if
not
course_descriptor
:
if
not
course_exists
(
request
,
request
.
user
,
course_id
):
return
Response
({},
status
=
status
.
HTTP_404_NOT_FOUND
)
try
:
existing_group
=
Group
.
objects
.
get
(
id
=
group_id
)
except
ObjectDoesNotExist
:
return
Response
({},
status
=
status
.
HTTP_404_NOT_FOUND
)
try
:
course_key
=
get_course_key
(
course_id
)
CourseGroupRelationship
.
objects
.
get
(
course_id
=
course_key
,
group
=
existing_group
)
except
ObjectDoesNotExist
:
return
Response
({},
status
=
status
.
HTTP_404_NOT_FOUND
)
...
...
@@ -749,11 +748,11 @@ class CoursesGroupsDetail(SecureAPIView):
"""
DELETE /api/courses/{course_id}/groups/{group_id}
"""
course_descriptor
,
course_key
,
course_content
=
get_course
(
request
,
request
.
user
,
course_id
)
# pylint: disable=W0612
if
not
course_descriptor
:
if
not
course_exists
(
request
,
request
.
user
,
course_id
):
return
Response
({},
status
=
status
.
HTTP_204_NO_CONTENT
)
try
:
existing_group
=
Group
.
objects
.
get
(
id
=
group_id
)
course_key
=
get_course_key
(
course_id
)
CourseGroupRelationship
.
objects
.
get
(
course_id
=
course_key
,
group
=
existing_group
)
.
delete
()
except
ObjectDoesNotExist
:
pass
...
...
@@ -994,9 +993,9 @@ class CoursesUsersList(SecureAPIView):
"""
POST /api/courses/{course_id}/users
"""
course_descriptor
,
course_key
,
course_content
=
get_course
(
request
,
request
.
user
,
course_id
)
# pylint: disable=W0612
if
not
course_descriptor
:
if
not
course_exists
(
request
,
request
.
user
,
course_id
):
return
Response
({},
status
=
status
.
HTTP_404_NOT_FOUND
)
course_key
=
get_course_key
(
course_id
)
if
'user_id'
in
request
.
DATA
:
user_id
=
request
.
DATA
[
'user_id'
]
try
:
...
...
@@ -1034,9 +1033,9 @@ class CoursesUsersList(SecureAPIView):
response_data
=
OrderedDict
()
base_uri
=
generate_base_uri
(
request
)
response_data
[
'uri'
]
=
base_uri
course_descriptor
,
course_key
,
course_content
=
get_course
(
request
,
request
.
user
,
course_id
)
# pylint: disable=W0612
if
not
course_descriptor
:
if
not
course_exists
(
request
,
request
.
user
,
course_id
):
return
Response
({},
status
=
status
.
HTTP_404_NOT_FOUND
)
course_key
=
get_course_key
(
course_id
)
# Get a list of all enrolled students
users
=
CourseEnrollment
.
users_enrolled_in
(
course_key
)
upper_bound
=
getattr
(
settings
,
'API_LOOKUP_UPPER_BOUND'
,
100
)
...
...
@@ -1106,7 +1105,7 @@ class CoursesUsersDetail(SecureAPIView):
user
=
User
.
objects
.
get
(
id
=
user_id
,
is_active
=
True
)
except
ObjectDoesNotExist
:
return
Response
(
response_data
,
status
=
status
.
HTTP_404_NOT_FOUND
)
course_descriptor
,
course_key
,
course_content
=
get_course
(
request
,
user
,
course_id
)
course_descriptor
,
course_key
,
course_content
=
get_course
(
request
,
user
,
course_id
,
load_content
=
True
)
if
not
course_descriptor
:
return
Response
(
response_data
,
status
=
status
.
HTTP_404_NOT_FOUND
)
if
CourseEnrollment
.
is_enrolled
(
user
,
course_key
):
...
...
@@ -1124,9 +1123,9 @@ class CoursesUsersDetail(SecureAPIView):
user
=
User
.
objects
.
get
(
id
=
user_id
,
is_active
=
True
)
except
ObjectDoesNotExist
:
return
Response
({},
status
=
status
.
HTTP_204_NO_CONTENT
)
course_descriptor
,
course_key
,
course_content
=
get_course
(
request
,
user
,
course_id
)
# pylint: disable=W0612
if
not
course_descriptor
:
if
not
course_exists
(
request
,
request
.
user
,
course_id
):
return
Response
({},
status
=
status
.
HTTP_404_NOT_FOUND
)
course_key
=
get_course_key
(
course_id
)
CourseEnrollment
.
unenroll
(
user
,
course_key
)
response_data
=
{}
base_uri
=
generate_base_uri
(
request
)
...
...
@@ -1157,11 +1156,11 @@ class CourseContentGroupsList(SecureAPIView):
"""
POST /api/courses/{course_id}/content/{content_id}/groups
"""
course_descriptor
,
course_key
,
course_content
=
get_course
(
request
,
request
.
user
,
course_id
)
# pylint: disable=W0612
if
not
course_descriptor
:
if
not
course_exists
(
request
,
request
.
user
,
course_id
):
return
Response
({},
status
=
status
.
HTTP_404_NOT_FOUND
)
course_key
=
get_course_key
(
course_id
)
content_descriptor
,
content_key
,
existing_content
=
get_course_child
(
request
,
request
.
user
,
course_key
,
content_id
)
# pylint: disable=W0612
if
not
existing_content
:
if
not
content_descriptor
:
return
Response
({},
status
=
status
.
HTTP_404_NOT_FOUND
)
group_id
=
request
.
DATA
.
get
(
'group_id'
)
if
group_id
is
None
:
...
...
@@ -1174,12 +1173,12 @@ class CourseContentGroupsList(SecureAPIView):
base_uri
=
generate_base_uri
(
request
)
response_data
[
'uri'
]
=
'{}/{}'
.
format
(
base_uri
,
existing_profile
.
group_id
)
response_data
[
'course_id'
]
=
unicode
(
course_key
)
response_data
[
'content_id'
]
=
unicode
(
existing_content
.
scope_ids
.
usage_id
)
response_data
[
'content_id'
]
=
unicode
(
content_key
)
response_data
[
'group_id'
]
=
str
(
existing_profile
.
group_id
)
try
:
CourseContentGroupRelationship
.
objects
.
get
(
course_id
=
course_key
,
content_id
=
existing_content
.
location
,
content_id
=
content_key
,
group_profile
=
existing_profile
)
response_data
[
'message'
]
=
"Relationship already exists."
...
...
@@ -1187,7 +1186,7 @@ class CourseContentGroupsList(SecureAPIView):
except
ObjectDoesNotExist
:
CourseContentGroupRelationship
.
objects
.
create
(
course_id
=
course_key
,
content_id
=
existing_content
.
location
,
content_id
=
content_key
,
group_profile
=
existing_profile
)
return
Response
(
response_data
,
status
=
status
.
HTTP_201_CREATED
)
...
...
@@ -1198,15 +1197,15 @@ class CourseContentGroupsList(SecureAPIView):
"""
response_data
=
[]
group_type
=
request
.
QUERY_PARAMS
.
get
(
'type'
)
course_descriptor
,
course_key
,
course_content
=
get_course
(
request
,
request
.
user
,
course_id
)
# pylint: disable=W0612
if
not
course_descriptor
:
if
not
course_exists
(
request
,
request
.
user
,
course_id
):
return
Response
({},
status
=
status
.
HTTP_404_NOT_FOUND
)
course_key
=
get_course_key
(
course_id
)
content_descriptor
,
content_key
,
existing_content
=
get_course_child
(
request
,
request
.
user
,
course_key
,
content_id
)
# pylint: disable=W0612
if
not
existing_content
:
if
not
content_descriptor
:
return
Response
({},
status
=
status
.
HTTP_404_NOT_FOUND
)
relationships
=
CourseContentGroupRelationship
.
objects
.
filter
(
course_id
=
course_key
,
content_id
=
existing_content
.
location
,
content_id
=
content_key
,
)
.
select_related
(
"groupprofile"
)
if
group_type
:
relationships
=
relationships
.
filter
(
group_profile__group_type
=
group_type
)
...
...
@@ -1230,16 +1229,16 @@ class CourseContentGroupsDetail(SecureAPIView):
"""
GET /api/courses/{course_id}/content/{content_id}/groups/{group_id}
"""
course_descriptor
,
course_key
,
course_content
=
get_course
(
request
,
request
.
user
,
course_id
)
# pylint: disable=W0612
if
not
course_descriptor
:
if
not
course_exists
(
request
,
request
.
user
,
course_id
):
return
Response
({},
status
=
status
.
HTTP_404_NOT_FOUND
)
course_key
=
get_course_key
(
course_id
)
content_descriptor
,
content_key
,
existing_content
=
get_course_child
(
request
,
request
.
user
,
course_key
,
content_id
)
# pylint: disable=W0612
if
not
existing_content
:
if
not
content_descriptor
:
return
Response
({},
status
=
status
.
HTTP_404_NOT_FOUND
)
try
:
CourseContentGroupRelationship
.
objects
.
get
(
course_id
=
course_key
,
content_id
=
existing_content
.
location
,
content_id
=
content_key
,
group_profile__group_id
=
group_id
)
except
ObjectDoesNotExist
:
...
...
@@ -1271,17 +1270,17 @@ class CourseContentUsersList(SecureAPIView):
"""
GET /api/courses/{course_id}/content/{content_id}/users
"""
course_descriptor
,
course_key
,
course_content
=
get_course
(
request
,
request
.
user
,
course_id
)
# pylint: disable=W0612
if
not
course_descriptor
:
if
not
course_exists
(
request
,
request
.
user
,
course_id
):
return
Response
({},
status
=
status
.
HTTP_404_NOT_FOUND
)
course_key
=
get_course_key
(
course_id
)
content_descriptor
,
content_key
,
existing_content
=
get_course_child
(
request
,
request
.
user
,
course_key
,
content_id
)
# pylint: disable=W0612
if
not
existing_content
:
if
not
content_descriptor
:
return
Response
({},
status
=
status
.
HTTP_404_NOT_FOUND
)
enrolled
=
self
.
request
.
QUERY_PARAMS
.
get
(
'enrolled'
,
'True'
)
group_type
=
self
.
request
.
QUERY_PARAMS
.
get
(
'type'
,
None
)
group_id
=
self
.
request
.
QUERY_PARAMS
.
get
(
'group_id'
,
None
)
relationships
=
CourseContentGroupRelationship
.
objects
.
filter
(
course_id
=
course_key
,
content_id
=
existing_content
.
location
)
.
select_related
(
"groupprofile"
)
course_id
=
course_key
,
content_id
=
content_key
)
.
select_related
(
"groupprofile"
)
if
group_id
:
relationships
=
relationships
.
filter
(
group_profile__group__id
=
group_id
)
...
...
@@ -1351,9 +1350,9 @@ class CourseModuleCompletionList(SecureListAPIView):
content_id
=
self
.
request
.
QUERY_PARAMS
.
get
(
'content_id'
,
None
)
stage
=
self
.
request
.
QUERY_PARAMS
.
get
(
'stage'
,
None
)
course_id
=
self
.
kwargs
[
'course_id'
]
course_descriptor
,
course_key
,
course_content
=
get_course
(
self
.
request
,
self
.
request
.
user
,
course_id
)
# pylint: disable=W0612
if
not
course_descriptor
:
if
not
course_exists
(
self
.
request
,
self
.
request
.
user
,
course_id
):
raise
Http404
course_key
=
get_course_key
(
course_id
)
queryset
=
CourseModuleCompletion
.
objects
.
filter
(
course_id
=
course_key
)
upper_bound
=
getattr
(
settings
,
'API_LOOKUP_UPPER_BOUND'
,
100
)
if
user_ids
:
...
...
@@ -1362,9 +1361,9 @@ class CourseModuleCompletionList(SecureListAPIView):
if
content_id
:
content_descriptor
,
content_key
,
existing_content
=
get_course_child
(
self
.
request
,
self
.
request
.
user
,
course_key
,
content_id
)
# pylint: disable=W0612
if
not
existing_content
:
if
not
content_descriptor
:
raise
Http404
queryset
=
queryset
.
filter
(
content_id
=
existing_content
.
location
)
queryset
=
queryset
.
filter
(
content_id
=
content_key
)
if
stage
:
queryset
=
queryset
.
filter
(
stage
=
stage
)
...
...
@@ -1382,16 +1381,16 @@ class CourseModuleCompletionList(SecureListAPIView):
return
Response
({
'message'
:
_
(
'content_id is missing'
)},
status
.
HTTP_400_BAD_REQUEST
)
if
not
user_id
:
return
Response
({
'message'
:
_
(
'user_id is missing'
)},
status
.
HTTP_400_BAD_REQUEST
)
course_descriptor
,
course_key
,
course_content
=
get_course
(
request
,
request
.
user
,
course_id
)
# pylint: disable=W0612
if
not
course_descriptor
:
if
not
course_exists
(
request
,
request
.
user
,
course_id
):
return
Response
({},
status
=
status
.
HTTP_404_NOT_FOUND
)
course_key
=
get_course_key
(
course_id
)
content_descriptor
,
content_key
,
existing_content
=
get_course_child
(
request
,
request
.
user
,
course_key
,
content_id
)
# pylint: disable=W0612
if
not
existing_content
:
if
not
content_descriptor
:
return
Response
({
'message'
:
_
(
'content_id is invalid'
)},
status
.
HTTP_400_BAD_REQUEST
)
completion
,
created
=
CourseModuleCompletion
.
objects
.
get_or_create
(
user_id
=
user_id
,
course_id
=
course_key
,
content_id
=
existing_content
.
location
,
content_id
=
content_key
,
stage
=
stage
)
serializer
=
CourseModuleCompletionSerializer
(
completion
)
if
created
:
...
...
@@ -1413,9 +1412,9 @@ class CoursesGradesList(SecureListAPIView):
"""
GET /api/courses/{course_id}/grades?user_ids=1,2&content_ids=i4x://1/2/3,i4x://a/b/c
"""
course_descriptor
,
course_key
,
course_content
=
get_course
(
request
,
request
.
user
,
course_id
)
# pylint: disable=W0612
if
not
course_descriptor
:
if
not
course_exists
(
request
,
request
.
user
,
course_id
):
return
Response
({},
status
=
status
.
HTTP_404_NOT_FOUND
)
course_key
=
get_course_key
(
course_id
)
queryset
=
StudentModule
.
objects
.
filter
(
course_id__exact
=
course_key
,
grade__isnull
=
False
,
...
...
@@ -1432,9 +1431,9 @@ class CoursesGradesList(SecureListAPIView):
content_id
=
self
.
request
.
QUERY_PARAMS
.
get
(
'content_id'
,
None
)
if
content_id
:
content_descriptor
,
content_key
,
existing_content
=
get_course_child
(
request
,
request
.
user
,
course_key
,
content_id
)
# pylint: disable=W0612
if
not
existing_content
:
if
not
content_descriptor
:
return
Response
({},
status
=
status
.
HTTP_400_BAD_REQUEST
)
queryset
=
queryset
.
filter
(
module_state_key
=
existing_content
.
location
)
queryset
=
queryset
.
filter
(
module_state_key
=
content_key
)
queryset_grade_avg
=
queryset
.
aggregate
(
Avg
(
'grade'
))
queryset_grade_sum
=
queryset
.
aggregate
(
Sum
(
'grade'
))
...
...
@@ -1478,7 +1477,7 @@ class CoursesProjectList(SecureListAPIView):
def
get_queryset
(
self
):
course_id
=
self
.
kwargs
[
'course_id'
]
course_
descriptor
,
course_key
,
course_content
=
get_course
(
self
.
request
,
self
.
request
.
user
,
course_id
)
# pylint: disable=W0612
course_
key
=
get_course_key
(
course_id
)
return
Project
.
objects
.
filter
(
course_id
=
course_key
)
...
...
@@ -1495,9 +1494,9 @@ class CourseMetrics(SecureAPIView):
"""
GET /api/courses/{course_id}/metrics/
"""
course_descriptor
,
course_key
,
course_content
=
get_course
(
request
,
request
.
user
,
course_id
)
# pylint: disable=W0612
if
not
course_descriptor
:
if
not
course_exists
(
request
,
request
.
user
,
course_id
):
return
Response
({},
status
=
status
.
HTTP_404_NOT_FOUND
)
course_key
=
get_course_key
(
course_id
)
users_enrolled
=
CourseEnrollment
.
num_enrolled_in
(
course_key
)
data
=
{
'users_enrolled'
:
users_enrolled
...
...
@@ -1530,10 +1529,9 @@ class CoursesLeadersList(SecureListAPIView):
count
=
self
.
request
.
QUERY_PARAMS
.
get
(
'count'
,
3
)
data
=
{}
course_avg
=
0
course_descriptor
,
course_key
,
course_content
=
get_course
(
request
,
request
.
user
,
course_id
)
# pylint: disable=W0612
if
not
course_descriptor
:
if
not
course_exists
(
request
,
request
.
user
,
course_id
):
return
Response
({},
status
=
status
.
HTTP_404_NOT_FOUND
)
course_key
=
get_course_key
(
course_id
)
exclude_users
=
_get_aggregate_exclusion_user_ids
(
course_key
)
queryset
=
StudentModule
.
objects
.
filter
(
course_id__exact
=
course_key
,
...
...
@@ -1545,9 +1543,9 @@ class CoursesLeadersList(SecureListAPIView):
if
content_id
:
content_descriptor
,
content_key
,
existing_content
=
get_course_child
(
request
,
request
.
user
,
course_key
,
content_id
)
# pylint: disable=W0612
if
not
existing_content
:
if
not
content_descriptor
:
return
Response
({},
status
=
status
.
HTTP_400_BAD_REQUEST
)
queryset
=
queryset
.
filter
(
module_state_key
=
existing_content
.
location
)
queryset
=
queryset
.
filter
(
module_state_key
=
content_key
)
if
user_id
:
user_points
=
StudentModule
.
objects
.
filter
(
course_id__exact
=
course_key
,
...
...
@@ -1600,10 +1598,9 @@ class CoursesCompletionsLeadersList(SecureAPIView):
count
=
self
.
request
.
QUERY_PARAMS
.
get
(
'count'
,
3
)
data
=
{}
course_avg
=
0
course_descriptor
,
course_key
,
course_content
=
get_course
(
request
,
request
.
user
,
course_id
)
# pylint: disable=W0612
if
not
course_descriptor
:
if
not
course_exists
(
request
,
request
.
user
,
course_id
):
return
Response
({},
status
=
status
.
HTTP_404_NOT_FOUND
)
course_key
=
get_course_key
(
course_id
)
total_possible_completions
=
len
(
get_course_leaf_nodes
(
course_key
,
[
'discussion-course'
,
'group-project'
]))
exclude_users
=
_get_aggregate_exclusion_user_ids
(
course_key
)
...
...
@@ -1647,8 +1644,7 @@ class CoursesWorkgroupsList(SecureListAPIView):
def
get_queryset
(
self
):
course_id
=
self
.
kwargs
[
'course_id'
]
course_descriptor
,
course_key
,
course_content
=
get_course
(
self
.
request
,
self
.
request
.
user
,
course_id
)
# pylint: disable=W0612
if
not
course_descriptor
:
if
not
course_exists
(
self
.
request
,
self
.
request
.
user
,
course_id
):
raise
Http404
queryset
=
Workgroup
.
objects
.
filter
(
project__course_id
=
course_id
)
...
...
@@ -1712,10 +1708,9 @@ class CoursesCitiesMetrics(SecureListAPIView):
course_id
=
self
.
kwargs
[
'course_id'
]
city
=
self
.
request
.
QUERY_PARAMS
.
get
(
'city'
,
None
)
upper_bound
=
getattr
(
settings
,
'API_LOOKUP_UPPER_BOUND'
,
100
)
course_descriptor
,
course_key
,
course_content
=
get_course
(
self
.
request
,
self
.
request
.
user
,
course_id
)
# pylint: disable=W0612
if
not
course_descriptor
:
if
not
course_exists
(
self
.
request
,
self
.
request
.
user
,
course_id
):
raise
Http404
course_key
=
get_course_key
(
course_id
)
exclude_users
=
_get_aggregate_exclusion_user_ids
(
course_key
)
queryset
=
CourseEnrollment
.
users_enrolled_in
(
course_key
)
.
exclude
(
id__in
=
exclude_users
)
if
city
:
...
...
@@ -1745,12 +1740,11 @@ class CoursesRolesList(SecureAPIView):
GET /api/courses/{course_id}/roles/
"""
course_id
=
self
.
kwargs
[
'course_id'
]
course_descriptor
,
course_key
,
course_content
=
get_course
(
self
.
request
,
self
.
request
.
user
,
course_id
)
# pylint: disable=W0612
if
not
course_descriptor
:
if
not
course_exists
(
request
,
request
.
user
,
course_id
):
raise
Http404
response_data
=
[]
course_key
=
get_course_key
(
course_id
)
instructors
=
CourseInstructorRole
(
course_key
)
.
users_with_role
()
for
instructor
in
instructors
:
response_data
.
append
({
'id'
:
instructor
.
id
,
'role'
:
'instructor'
})
...
...
lms/djangoapps/api_manager/courseware_access.py
View file @
babd972c
...
...
@@ -10,64 +10,32 @@ from xmodule.modulestore.django import modulestore
from
xmodule.modulestore.exceptions
import
ItemNotFoundError
def
get_course
(
request
,
user
,
course_id
,
depth
=
0
):
def
get_course
(
request
,
user
,
course_id
,
depth
=
0
,
load_content
=
False
):
"""
Utility method to obtain course components
"""
course_descriptor
=
None
course_key
=
None
course_content
=
None
try
:
course_key
=
CourseKey
.
from_string
(
course_id
)
except
InvalidKeyError
:
try
:
course_key
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
course_id
)
except
InvalidKeyError
:
pass
course_key
=
get_course_key
(
course_id
)
if
course_key
:
try
:
course_descriptor
=
courses
.
get_course
(
course_key
,
depth
)
except
ValueError
:
pass
if
course_descriptor
:
field_data_cache
=
FieldDataCache
([
course_descriptor
],
course_key
,
user
)
course_content
=
module_render
.
get_module_for_descriptor
(
user
,
request
,
course_descriptor
,
field_data_cache
,
course_key
)
course_descriptor
=
get_course_descriptor
(
course_key
,
depth
)
if
course_descriptor
and
load_content
:
course_content
=
get_course_content
(
request
,
user
,
course_key
,
course_descriptor
)
return
course_descriptor
,
course_key
,
course_content
def
get_course_child
(
request
,
user
,
course_key
,
content_id
):
def
get_course_child
(
request
,
user
,
course_key
,
content_id
,
load_content
=
False
):
"""
Return a course xmodule/xblock to the caller
"""
content_descriptor
=
None
content_key
=
None
content
=
None
try
:
content_key
=
UsageKey
.
from_string
(
content_id
)
except
InvalidKeyError
:
try
:
content_key
=
Location
.
from_deprecated_string
(
content_id
)
except
(
InvalidLocationError
,
InvalidKeyError
):
pass
if
content_key
:
try
:
content_descriptor
=
modulestore
()
.
get_item
(
content_key
)
except
ItemNotFoundError
:
pass
if
content_descriptor
:
field_data_cache
=
FieldDataCache
([
content_descriptor
],
course_key
,
user
)
content
=
module_render
.
get_module_for_descriptor
(
user
,
request
,
content_descriptor
,
field_data_cache
,
course_key
)
return
content_descriptor
,
content_key
,
content
child_descriptor
=
None
child_content
=
None
child_key
=
get_course_child_key
(
content_id
)
if
child_key
:
child_descriptor
=
get_course_child_descriptor
(
child_key
)
if
child_descriptor
and
load_content
:
child_content
=
get_course_child_content
(
request
,
user
,
course_key
,
child_descriptor
)
return
child_descriptor
,
child_key
,
child_content
def
get_course_total_score
(
course_summary
):
...
...
@@ -92,3 +60,72 @@ def get_course_leaf_nodes(course_key, detached_categories):
nodes
.
extend
([
unit
.
location
for
unit
in
vertical
.
get_children
()
if
getattr
(
unit
,
'category'
)
not
in
detached_categories
])
return
nodes
def
get_course_key
(
course_id
):
try
:
course_key
=
CourseKey
.
from_string
(
course_id
)
except
InvalidKeyError
:
try
:
course_key
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
course_id
)
except
InvalidKeyError
:
course_key
=
None
return
course_key
def
get_course_descriptor
(
course_key
,
depth
):
try
:
course_descriptor
=
courses
.
get_course
(
course_key
,
depth
)
except
ValueError
:
course_descriptor
=
None
return
course_descriptor
def
get_course_content
(
request
,
user
,
course_key
,
course_descriptor
):
field_data_cache
=
FieldDataCache
([
course_descriptor
],
course_key
,
user
)
course_content
=
module_render
.
get_module_for_descriptor
(
user
,
request
,
course_descriptor
,
field_data_cache
,
course_key
)
return
course_content
def
course_exists
(
request
,
user
,
course_id
):
course_key
=
get_course_key
(
course_id
)
if
not
course_key
:
return
False
if
not
modulestore
()
.
has_course
(
course_key
):
return
False
return
True
def
get_course_child_key
(
content_id
):
try
:
content_key
=
UsageKey
.
from_string
(
content_id
)
except
InvalidKeyError
:
try
:
content_key
=
Location
.
from_deprecated_string
(
content_id
)
except
(
InvalidLocationError
,
InvalidKeyError
):
content_key
=
None
return
content_key
def
get_course_child_descriptor
(
child_key
):
try
:
content_descriptor
=
modulestore
()
.
get_item
(
child_key
)
except
ItemNotFoundError
:
content_descriptor
=
None
return
content_descriptor
def
get_course_child_content
(
request
,
user
,
course_key
,
child_descriptor
):
field_data_cache
=
FieldDataCache
([
child_descriptor
],
course_key
,
user
)
child_content
=
module_render
.
get_module_for_descriptor
(
user
,
request
,
child_descriptor
,
field_data_cache
,
course_key
)
return
child_content
lms/djangoapps/api_manager/users/tests.py
View file @
babd972c
...
...
@@ -22,7 +22,7 @@ from capa.tests.response_xml_factory import StringResponseXMLFactory
from
courseware.tests.factories
import
StudentModuleFactory
from
django_comment_common.models
import
Role
,
FORUM_ROLE_MODERATOR
from
instructor.access
import
allow_access
from
projects.models
import
Project
from
projects.models
import
Project
,
Workgroup
from
student.tests.factories
import
UserFactory
from
student.models
import
anonymous_id_for_user
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
...
...
@@ -60,6 +60,7 @@ class UsersApiTests(ModuleStoreTestCase):
self
.
groups_base_uri
=
'/api/server/groups'
self
.
org_base_uri
=
'/api/server/organizations/'
self
.
workgroups_base_uri
=
'/api/server/workgroups/'
self
.
projects_base_uri
=
'/api/server/projects/'
self
.
users_base_uri
=
'/api/server/users'
self
.
sessions_base_uri
=
'/api/server/sessions'
self
.
test_bogus_course_id
=
'foo/bar/baz'
...
...
@@ -1251,47 +1252,46 @@ class UsersApiTests(ModuleStoreTestCase):
def
test_user_workgroups_list
(
self
):
test_workgroups_uri
=
self
.
workgroups_base_uri
user_id
=
self
.
user
.
id
# create anonymous user
anonymous_id
=
anonymous_id_for_user
(
self
.
user
,
self
.
course
.
id
)
for
i
in
xrange
(
1
,
12
):
course
=
CourseFactory
.
create
(
display_name
=
"TEST COURSE {}"
.
format
(
i
),
)
course_content
=
ItemFactory
.
create
(
category
=
"videosequence"
,
parent_location
=
course
.
location
,
data
=
self
.
test_course_data
,
display_name
=
"View_Sequence"
)
project_1
=
Project
.
objects
.
create
(
course_id
=
unicode
(
self
.
course
.
id
),
content_id
=
unicode
(
self
.
course_content
.
scope_ids
.
usage_id
),
)
p1_workgroup_1
=
Workgroup
.
objects
.
create
(
name
=
'Workgroup 1'
,
project
=
project_1
)
test_project
=
Project
.
objects
.
create
(
course_id
=
unicode
(
course
.
id
),
content_id
=
unicode
(
course_content
.
scope_ids
.
usage_id
)
)
data
=
{
'name'
:
'Workgroup '
+
str
(
i
),
'project'
:
test_project
.
id
}
response
=
self
.
do_post
(
test_workgroups_uri
,
data
)
self
.
assertEqual
(
response
.
status_code
,
201
)
test_uri
=
'{}{}/'
.
format
(
test_workgroups_uri
,
str
(
response
.
data
[
'id'
]))
users_uri
=
'{}users/'
.
format
(
test_uri
)
data
=
{
"id"
:
user_id
}
project_2
=
Project
.
objects
.
create
(
course_id
=
unicode
(
self
.
course2
.
id
),
content_id
=
unicode
(
self
.
course2_content
.
scope_ids
.
usage_id
),
)
p2_workgroup_1
=
Workgroup
.
objects
.
create
(
name
=
'Workgroup 2'
,
project
=
project_2
)
for
i
in
xrange
(
1
,
12
):
test_user
=
UserFactory
()
users_uri
=
'{}{}/users/'
.
format
(
self
.
workgroups_base_uri
,
1
)
data
=
{
"id"
:
test_user
.
id
}
response
=
self
.
do_post
(
users_uri
,
data
)
self
.
assertEqual
(
response
.
status_code
,
201
)
if
test_user
.
id
>
6
:
users_uri
=
'{}{}/users/'
.
format
(
self
.
workgroups_base_uri
,
2
)
data
=
{
"id"
:
test_user
.
id
}
response
=
self
.
do_post
(
users_uri
,
data
)
self
.
assertEqual
(
response
.
status_code
,
201
)
# test with anonymous user id
test_uri
=
'{}/{}/workgroups/?page_size=10'
.
format
(
self
.
users_base_uri
,
anonymous_id
)
anonymous_id
=
anonymous_id_for_user
(
test_user
,
self
.
course
.
id
)
test_uri
=
'{}/{}/workgroups/?page_size=1'
.
format
(
self
.
users_base_uri
,
anonymous_id
)
response
=
self
.
do_get
(
test_uri
)
self
.
assertEqual
(
response
.
data
[
'count'
],
11
)
self
.
assertEqual
(
len
(
response
.
data
[
'results'
]),
1
0
)
self
.
assertEqual
(
response
.
data
[
'count'
],
2
)
self
.
assertEqual
(
len
(
response
.
data
[
'results'
]),
1
)
self
.
assertEqual
(
response
.
data
[
'num_pages'
],
2
)
# test with course_id filter and integer user id
course_id
=
{
'course_id'
:
unicode
(
course
.
id
)}
response
=
self
.
do_get
(
'{}/{}/workgroups/?{}'
.
format
(
self
.
users_base_uri
,
user_
id
,
urlencode
(
course_id
)))
course_id
=
{
'course_id'
:
unicode
(
self
.
course
.
id
)}
response
=
self
.
do_get
(
'{}/{}/workgroups/?{}'
.
format
(
self
.
users_base_uri
,
test_user
.
id
,
urlencode
(
course_id
)))
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertEqual
(
response
.
data
[
'count'
],
1
)
self
.
assertEqual
(
len
(
response
.
data
[
'results'
]),
1
)
...
...
lms/djangoapps/api_manager/users/views.py
View file @
babd972c
...
...
@@ -34,7 +34,7 @@ from util.password_policy_validators import (
)
from
api_manager.courses.serializers
import
CourseModuleCompletionSerializer
from
api_manager.courseware_access
import
get_course
,
get_course_child
,
get_course_total_score
from
api_manager.courseware_access
import
get_course
,
get_course_child
,
get_course_total_score
,
get_course_key
,
course_exists
from
api_manager.permissions
import
SecureAPIView
,
SecureListAPIView
,
IdsInFilterBackend
,
HasOrgsFilterBackend
from
api_manager.models
import
GroupProfile
,
APIUser
as
User
from
api_manager.organizations.serializers
import
OrganizationSerializer
...
...
@@ -90,10 +90,9 @@ def _save_content_position(request, user, course_key, position):
parent_content_id
=
position
[
'parent_content_id'
]
child_content_id
=
position
[
'child_content_id'
]
if
unicode
(
course_key
)
==
parent_content_id
:
parent_descriptor
,
parent_key
,
parent_content
=
get_course
(
request
,
user
,
parent_content_id
)
# pylint: disable=W0612
parent_descriptor
,
parent_key
,
parent_content
=
get_course
(
request
,
user
,
parent_content_id
,
load_content
=
True
)
# pylint: disable=W0612
else
:
parent_descriptor
,
parent_key
,
parent_content
=
get_course_child
(
request
,
user
,
course_key
,
parent_content_id
)
# pylint: disable=W0612
parent_descriptor
,
parent_key
,
parent_content
=
get_course_child
(
request
,
user
,
course_key
,
parent_content_id
,
load_content
=
True
)
# pylint: disable=W0612
if
not
parent_descriptor
:
return
None
...
...
@@ -126,8 +125,7 @@ def _save_child_position(parent_descriptor, target_child_location):
# Only save if position changed
if
position
!=
parent_descriptor
.
position
:
parent_descriptor
.
position
=
position
# Save this new position to the underlying KeyValueStore
parent_descriptor
.
save
()
parent_descriptor
.
save
()
def
_manage_role
(
course_descriptor
,
user
,
role
,
action
):
...
...
@@ -807,13 +805,13 @@ class UsersCoursesDetail(SecureAPIView):
user
=
User
.
objects
.
get
(
id
=
user_id
,
is_active
=
True
)
except
ObjectDoesNotExist
:
return
Response
({},
status
=
status
.
HTTP_404_NOT_FOUND
)
course_descriptor
,
course_key
,
course_content
=
get_course
(
request
,
user
,
course_id
)
# pylint: disable=W0612
if
not
course_descriptor
:
if
not
course_exists
(
request
,
user
,
course_id
):
return
Response
({},
status
=
status
.
HTTP_404_NOT_FOUND
)
response_data
[
'user_id'
]
=
user
.
id
response_data
[
'course_id'
]
=
course_id
if
request
.
DATA
[
'positions'
]:
course_key
=
get_course_key
(
course_id
)
response_data
[
'positions'
]
=
[]
for
position
in
request
.
DATA
[
'positions'
]:
content_position
=
_save_content_position
(
...
...
@@ -865,7 +863,7 @@ class UsersCoursesDetail(SecureAPIView):
response_data
[
'position_tree'
][
current_child_loc
.
category
]
=
{}
response_data
[
'position_tree'
][
current_child_loc
.
category
][
'id'
]
=
unicode
(
current_child_loc
)
_
,
_
,
parent_module
=
get_course_child
(
request
,
user
,
course_key
,
unicode
(
current_child_loc
))
_
,
_
,
parent_module
=
get_course_child
(
request
,
user
,
course_key
,
unicode
(
current_child_loc
)
,
load_content
=
True
)
else
:
parent_module
=
None
...
...
@@ -879,9 +877,9 @@ class UsersCoursesDetail(SecureAPIView):
user
=
User
.
objects
.
get
(
id
=
user_id
,
is_active
=
True
)
except
ObjectDoesNotExist
:
return
Response
({},
status
=
status
.
HTTP_204_NO_CONTENT
)
course_descriptor
,
course_key
,
course_content
=
get_course
(
request
,
user
,
course_id
)
# pylint: disable=W0612
if
not
course_descriptor
:
if
not
course_exists
(
request
,
user
,
course_id
):
return
Response
({},
status
=
status
.
HTTP_204_NO_CONTENT
)
course_key
=
get_course_key
(
course_id
)
CourseEnrollment
.
unenroll
(
user
,
course_key
)
return
Response
({},
status
=
status
.
HTTP_204_NO_CONTENT
)
...
...
@@ -1234,9 +1232,9 @@ class UsersRolesList(SecureListAPIView):
course_id
=
self
.
request
.
QUERY_PARAMS
.
get
(
'course_id'
,
None
)
if
course_id
:
course_descriptor
,
course_key
,
course_content
=
get_course
(
self
.
request
,
user
,
course_id
)
# pylint: disable=W0612
if
not
course_descriptor
:
if
not
course_exists
(
self
.
request
,
user
,
course_id
):
raise
Http404
course_key
=
get_course_key
(
course_id
)
queryset
=
queryset
.
filter
(
course_id
=
course_key
)
role
=
self
.
request
.
QUERY_PARAMS
.
get
(
'role'
,
None
)
...
...
lms/djangoapps/projects/views.py
View file @
babd972c
...
...
@@ -30,7 +30,7 @@ from .serializers import ProjectSerializer, WorkgroupSerializer, WorkgroupSubmis
from
.serializers
import
WorkgroupReviewSerializer
,
WorkgroupSubmissionReviewSerializer
,
WorkgroupPeerReviewSerializer
def
_get_course
(
request
,
user
,
course_id
,
depth
=
0
):
def
_get_course
(
request
,
user
,
course_id
,
depth
=
0
,
load_content
=
False
):
"""
Utility method to obtain course components
"""
...
...
@@ -49,7 +49,7 @@ def _get_course(request, user, course_id, depth=0):
course_descriptor
=
get_course
(
course_key
,
depth
=
depth
)
except
ValueError
:
pass
if
course_descriptor
:
if
course_descriptor
and
load_content
:
field_data_cache
=
FieldDataCache
([
course_descriptor
],
course_key
,
user
)
course_content
=
module_render
.
get_module
(
user
,
...
...
@@ -60,7 +60,7 @@ def _get_course(request, user, course_id, depth=0):
return
course_descriptor
,
course_key
,
course_content
def
_get_course_child
(
request
,
user
,
course_key
,
content_id
):
def
_get_course_child
(
request
,
user
,
course_key
,
content_id
,
load_content
=
False
):
"""
Return a course xmodule/xblock to the caller
"""
...
...
@@ -77,7 +77,7 @@ def _get_course_child(request, user, course_key, content_id):
if
content_key
:
store
=
modulestore
()
content_descriptor
=
store
.
get_item
(
content_key
)
if
content_descriptor
:
if
content_descriptor
and
load_content
:
field_data_cache
=
FieldDataCache
([
content_descriptor
],
course_key
,
user
)
content
=
module_render
.
get_module
(
user
,
...
...
lms/envs/test.py
View file @
babd972c
...
...
@@ -500,3 +500,11 @@ PROFILE_IMAGE_MIN_BYTES = 100
FEATURES
[
'ENABLE_LTI_PROVIDER'
]
=
True
INSTALLED_APPS
+=
(
'lti_provider'
,)
AUTHENTICATION_BACKENDS
+=
(
'lti_provider.users.LtiBackend'
,)
########################## SECURITY #######################
FEATURES
[
'ENFORCE_PASSWORD_POLICY'
]
=
False
FEATURES
[
'ENABLE_MAX_FAILED_LOGIN_ATTEMPTS'
]
=
False
FEATURES
[
'SQUELCH_PII_IN_LOGS'
]
=
False
FEATURES
[
'PREVENT_CONCURRENT_LOGINS'
]
=
False
FEATURES
[
'ADVANCED_SECURITY'
]
=
False
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