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
913252d4
Commit
913252d4
authored
May 06, 2014
by
Matt Drayer
Committed by
Jonathan Piacenti
Aug 20, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mattdrayer/api-quality: Quality updates
parent
af299af1
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
177 additions
and
178 deletions
+177
-178
lms/djangoapps/api_manager/courses/content.py
+69
-65
lms/djangoapps/api_manager/courses/tests.py
+4
-7
lms/djangoapps/api_manager/courses/urls.py
+2
-1
lms/djangoapps/api_manager/courses/views.py
+25
-17
lms/djangoapps/api_manager/groups/tests.py
+0
-5
lms/djangoapps/api_manager/groups/urls.py
+2
-1
lms/djangoapps/api_manager/groups/views.py
+16
-18
lms/djangoapps/api_manager/migrations/0001_initial.py
+1
-4
lms/djangoapps/api_manager/migrations/0002_auto__add_coursegrouprelationship__add_groupprofile.py
+1
-4
lms/djangoapps/api_manager/migrations/0003_move_name_to_profile.py
+1
-4
lms/djangoapps/api_manager/sessions/test_login_ratelimit.py
+0
-2
lms/djangoapps/api_manager/sessions/test_security.py
+1
-1
lms/djangoapps/api_manager/sessions/urls.py
+2
-1
lms/djangoapps/api_manager/sessions/views.py
+3
-3
lms/djangoapps/api_manager/system/views.py
+5
-5
lms/djangoapps/api_manager/urls.py
+9
-8
lms/djangoapps/api_manager/users/test_user_password_reset.py
+12
-12
lms/djangoapps/api_manager/users/tests.py
+3
-4
lms/djangoapps/api_manager/users/urls.py
+2
-1
lms/djangoapps/api_manager/users/views.py
+19
-15
No files found.
lms/djangoapps/api_manager/courses/content.py
View file @
913252d4
...
@@ -5,80 +5,84 @@ text space
...
@@ -5,80 +5,84 @@ text space
from
textwrap
import
dedent
from
textwrap
import
dedent
TEST_COURSE_UPDATES_CONTENT
=
dedent
(
"""
TEST_COURSE_UPDATES_CONTENT
=
dedent
(
<ol>
"""
<li>
<ol>
<h2>April 18, 2014</h2>
<li>
This does not have a paragraph tag around it
<h2>April 18, 2014</h2>
</li>
This does not have a paragraph tag around it
<li>
</li>
<h2>April 17, 2014</h2>
<li>
Some text before paragraph tag<p>This is inside paragraph tag</p>Some text after tag
<h2>April 17, 2014</h2>
</li>
Some text before paragraph tag<p>This is inside paragraph tag</p>Some text after tag
<li>
</li>
<h2>April 16, 2014</h2>
<li>
Some text before paragraph tag<p>This is inside paragraph tag</p>Some text after tag<p>one more</p>
<h2>April 16, 2014</h2>
</li>
Some text before paragraph tag<p>This is inside paragraph tag</p>Some text after tag<p>one more</p>
<li>
</li>
<h2>April 15, 2014</h2>
<li>
<p>A perfectly</p><p>formatted piece</p><p>of HTML</p>
<h2>April 15, 2014</h2>
</li>
<p>A perfectly</p><p>formatted piece</p><p>of HTML</p>
</ol>
</li>
"""
</ol>
"""
)
)
TEST_STATIC_TAB1_CONTENT
=
dedent
(
"""
TEST_STATIC_TAB1_CONTENT
=
dedent
(
<div>This is static tab1</div>
"""
"""
<div>This is static tab1</div>
"""
)
)
TEST_STATIC_TAB2_CONTENT
=
dedent
(
"""
TEST_STATIC_TAB2_CONTENT
=
dedent
(
<div>This is static tab2</div>
"""
"""
<div>This is static tab2</div>
"""
)
)
TEST_COURSE_OVERVIEW_CONTENT
=
dedent
(
"""
TEST_COURSE_OVERVIEW_CONTENT
=
dedent
(
<section class="about">
"""
<h2>About This Course</h2>
<section class="about">
<p>Include your long course description here. The long course description should contain 150-400 words.</p>
<h2>About This Course</h2>
<p>Include your long course description here. The long course description should contain 150-400 words.</p>
<p>This is paragraph 2 of the long course description. Add more paragraphs as needed. Make sure to enclose them in paragraph tags.</p>
<p>This is paragraph 2 of the long course description. Add more paragraphs as needed. Make sure to enclose them in paragraph tags.</p>
</section>
</section>
<section class="prerequisites">
<section class="prerequisites">
<h2>Prerequisites</h2>
<h2>Prerequisites</h2>
<p>Add information about course prerequisites here.</p>
<p>Add information about course prerequisites here.</p>
</section>
</section>
<section class="course-staff">
<section class="course-staff">
<h2>Course Staff</h2>
<h2>Course Staff</h2>
<article class="teacher">
<article class="teacher">
<div class="teacher-image">
<div class="teacher-image">
<img src="/images/pl-faculty.png" align="left" style="margin:0 20 px 0" alt="Course Staff Image #1">
<img src="/images/pl-faculty.png" align="left" style="margin:0 20 px 0" alt="Course Staff Image #1">
</div>
</div>
<h3>Staff Member #1</h3>
<h3>Staff Member #1</h3>
<p>Biography of instructor/staff member #1</p>
<p>Biography of instructor/staff member #1</p>
</article>
</article>
<article class="teacher">
<article class="teacher">
<div class="teacher-image">
<div class="teacher-image">
<img src="/images/pl-faculty.png" align="left" style="margin:0 20 px 0" alt="Course Staff Image #2">
<img src="/images/pl-faculty.png" align="left" style="margin:0 20 px 0" alt="Course Staff Image #2">
</div>
</div>
<h3>Staff Member #2</h3>
<h3>Staff Member #2</h3>
<p>Biography of instructor/staff member #2</p>
<p>Biography of instructor/staff member #2</p>
</article>
</article>
<article class="author">
<article class="author">
<div class="author-image">
<div class="author-image">
<img src="/images/pl-author.png" align="left" style="margin:0 20 px 0" alt="Author Name">
<img src="/images/pl-author.png" align="left" style="margin:0 20 px 0" alt="Author Name">
</div>
</div>
<h3>Author Name</h3>
<h3>Author Name</h3>
<p>Biography of Author Name</p>
<p>Biography of Author Name</p>
</article>
</article>
</section>
</section>
<section class="faq">
<p>Some text here</p>
</section>
"""
)
<section class="faq">
<p>Some text here</p>
</section>
"""
)
lms/djangoapps/api_manager/courses/tests.py
View file @
913252d4
...
@@ -2,10 +2,9 @@
...
@@ -2,10 +2,9 @@
"""
"""
Run these tests @ Devstack:
Run these tests @ Devstack:
rake fasttest_lms[common/djangoapps/api_manager/
tests/test_group_view
s.py]
rake fasttest_lms[common/djangoapps/api_manager/
courses/test
s.py]
"""
"""
import
simplejson
as
json
import
simplejson
as
json
import
unittest
import
uuid
import
uuid
from
random
import
randint
from
random
import
randint
...
@@ -36,7 +35,6 @@ class CoursesApiTests(TestCase):
...
@@ -36,7 +35,6 @@ class CoursesApiTests(TestCase):
""" Test suite for Courses API views """
""" Test suite for Courses API views """
def
setUp
(
self
):
def
setUp
(
self
):
self
.
maxDiff
=
3000
self
.
test_server_prefix
=
'https://testserver'
self
.
test_server_prefix
=
'https://testserver'
self
.
base_courses_uri
=
'/api/courses'
self
.
base_courses_uri
=
'/api/courses'
self
.
base_groups_uri
=
'/api/groups'
self
.
base_groups_uri
=
'/api/groups'
...
@@ -137,6 +135,7 @@ class CoursesApiTests(TestCase):
...
@@ -137,6 +135,7 @@ class CoursesApiTests(TestCase):
return
response
return
response
def
_find_item_by_class
(
self
,
items
,
class_name
):
def
_find_item_by_class
(
self
,
items
,
class_name
):
"""Helper method to match a single matching item"""
for
item
in
items
:
for
item
in
items
:
if
item
[
'class'
]
==
class_name
:
if
item
[
'class'
]
==
class_name
:
return
item
return
item
...
@@ -444,7 +443,7 @@ class CoursesApiTests(TestCase):
...
@@ -444,7 +443,7 @@ class CoursesApiTests(TestCase):
#try a bogus course_id to test failure case
#try a bogus course_id to test failure case
test_course
=
CourseFactory
.
create
()
test_course
=
CourseFactory
.
create
()
test_uri
=
'{}/{}/overview'
.
format
(
self
.
base_courses_uri
,
test_course
.
id
)
test_uri
=
'{}/{}/overview'
.
format
(
self
.
base_courses_uri
,
test_course
.
id
)
test_updates
=
ItemFactory
.
create
(
ItemFactory
.
create
(
category
=
"about"
,
category
=
"about"
,
parent_location
=
test_course
.
location
,
parent_location
=
test_course
.
location
,
data
=
''
,
data
=
''
,
...
@@ -487,8 +486,7 @@ class CoursesApiTests(TestCase):
...
@@ -487,8 +486,7 @@ class CoursesApiTests(TestCase):
def
test_courses_updates_get_invalid_content
(
self
):
def
test_courses_updates_get_invalid_content
(
self
):
#try a bogus course_id to test failure case
#try a bogus course_id to test failure case
test_course
=
CourseFactory
.
create
()
test_course
=
CourseFactory
.
create
()
test_course_data
=
'<html>{}</html>'
.
format
(
str
(
uuid
.
uuid4
()))
ItemFactory
.
create
(
test_updates
=
ItemFactory
.
create
(
category
=
"course_info"
,
category
=
"course_info"
,
parent_location
=
test_course
.
location
,
parent_location
=
test_course
.
location
,
data
=
''
,
data
=
''
,
...
@@ -604,7 +602,6 @@ class CoursesApiTests(TestCase):
...
@@ -604,7 +602,6 @@ class CoursesApiTests(TestCase):
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertEqual
(
len
(
response
.
data
[
'enrollments'
]),
0
)
self
.
assertEqual
(
len
(
response
.
data
[
'enrollments'
]),
0
)
def
test_courses_users_list_post_existing_user
(
self
):
def
test_courses_users_list_post_existing_user
(
self
):
# create a new user (note, this calls into the /users/ subsystem)
# create a new user (note, this calls into the /users/ subsystem)
test_uri
=
self
.
base_courses_uri
+
'/'
+
self
.
test_course_id
+
'/users'
test_uri
=
self
.
base_courses_uri
+
'/'
+
self
.
test_course_id
+
'/users'
...
...
lms/djangoapps/api_manager/courses/urls.py
View file @
913252d4
...
@@ -8,7 +8,8 @@ from rest_framework.urlpatterns import format_suffix_patterns
...
@@ -8,7 +8,8 @@ from rest_framework.urlpatterns import format_suffix_patterns
from
api_manager.courses
import
views
as
courses_views
from
api_manager.courses
import
views
as
courses_views
urlpatterns
=
patterns
(
''
,
urlpatterns
=
patterns
(
''
,
url
(
r'/*$^'
,
courses_views
.
CoursesList
.
as_view
()),
url
(
r'/*$^'
,
courses_views
.
CoursesList
.
as_view
()),
url
(
r'^(?P<course_id>[^/]+/[^/]+/[^/]+)$'
,
courses_views
.
CoursesDetail
.
as_view
()),
url
(
r'^(?P<course_id>[^/]+/[^/]+/[^/]+)$'
,
courses_views
.
CoursesDetail
.
as_view
()),
url
(
r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/modules/(?P<module_id>[a-zA-Z0-9/_:]+)/submodules/*$'
,
courses_views
.
ModulesList
.
as_view
()),
url
(
r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/modules/(?P<module_id>[a-zA-Z0-9/_:]+)/submodules/*$'
,
courses_views
.
ModulesList
.
as_view
()),
...
...
lms/djangoapps/api_manager/courses/views.py
View file @
913252d4
...
@@ -27,6 +27,7 @@ from xmodule.modulestore import Location, InvalidLocationError
...
@@ -27,6 +27,7 @@ from xmodule.modulestore import Location, InvalidLocationError
log
=
logging
.
getLogger
(
__name__
)
log
=
logging
.
getLogger
(
__name__
)
def
_generate_base_uri
(
request
):
def
_generate_base_uri
(
request
):
"""
"""
Constructs the protocol:host:path component of the resource uri
Constructs the protocol:host:path component of the resource uri
...
@@ -129,7 +130,7 @@ def _serialize_module_with_children(request, course_descriptor, descriptor, dept
...
@@ -129,7 +130,7 @@ def _serialize_module_with_children(request, course_descriptor, descriptor, dept
request
,
request
,
course_descriptor
,
course_descriptor
,
child
,
child
,
depth
-
1
depth
-
1
))
))
return
data
return
data
...
@@ -240,7 +241,7 @@ def _parse_updates_html(html):
...
@@ -240,7 +241,7 @@ def _parse_updates_html(html):
class
ModulesList
(
APIView
):
class
ModulesList
(
APIView
):
permission_classes
=
(
ApiKeyHeaderPermission
,)
permission_classes
=
(
ApiKeyHeaderPermission
,)
def
get
(
self
,
request
,
course_id
,
module_id
=
None
,
format
=
None
):
def
get
(
self
,
request
,
course_id
,
module_id
=
None
):
"""
"""
GET retrieves the list of submodules for a given module
GET retrieves the list of submodules for a given module
We don't know where in the module hierarchy we are -- could even be the top
We don't know where in the module hierarchy we are -- could even be the top
...
@@ -273,7 +274,7 @@ class ModulesList(APIView):
...
@@ -273,7 +274,7 @@ class ModulesList(APIView):
class
ModulesDetail
(
APIView
):
class
ModulesDetail
(
APIView
):
permission_classes
=
(
ApiKeyHeaderPermission
,)
permission_classes
=
(
ApiKeyHeaderPermission
,)
def
get
(
self
,
request
,
course_id
,
module_id
,
format
=
None
):
def
get
(
self
,
request
,
course_id
,
module_id
):
"""
"""
GET retrieves an existing module from the system
GET retrieves an existing module from the system
"""
"""
...
@@ -308,7 +309,7 @@ class ModulesDetail(APIView):
...
@@ -308,7 +309,7 @@ class ModulesDetail(APIView):
class
CoursesList
(
APIView
):
class
CoursesList
(
APIView
):
permission_classes
=
(
ApiKeyHeaderPermission
,)
permission_classes
=
(
ApiKeyHeaderPermission
,)
def
get
(
self
,
request
,
format
=
None
):
def
get
(
self
,
request
):
"""
"""
GET returns the list of available courses
GET returns the list of available courses
"""
"""
...
@@ -328,7 +329,7 @@ class CoursesList(APIView):
...
@@ -328,7 +329,7 @@ class CoursesList(APIView):
class
CoursesDetail
(
APIView
):
class
CoursesDetail
(
APIView
):
permission_classes
=
(
ApiKeyHeaderPermission
,)
permission_classes
=
(
ApiKeyHeaderPermission
,)
def
get
(
self
,
request
,
course_id
,
format
=
None
):
def
get
(
self
,
request
,
course_id
):
"""
"""
GET retrieves an existing course from the system and returns summary information about the submodules
GET retrieves an existing course from the system and returns summary information about the submodules
to the specified depth
to the specified depth
...
@@ -365,7 +366,7 @@ class CoursesDetail(APIView):
...
@@ -365,7 +366,7 @@ class CoursesDetail(APIView):
class
CoursesGroupsList
(
APIView
):
class
CoursesGroupsList
(
APIView
):
permission_classes
=
(
ApiKeyHeaderPermission
,)
permission_classes
=
(
ApiKeyHeaderPermission
,)
def
post
(
self
,
request
,
course_id
,
format
=
None
):
def
post
(
self
,
request
,
course_id
):
"""
"""
POST creates a new course-group relationship in the system
POST creates a new course-group relationship in the system
"""
"""
...
@@ -402,7 +403,7 @@ class CoursesGroupsList(APIView):
...
@@ -402,7 +403,7 @@ class CoursesGroupsList(APIView):
class
CoursesGroupsDetail
(
APIView
):
class
CoursesGroupsDetail
(
APIView
):
permission_classes
=
(
ApiKeyHeaderPermission
,)
permission_classes
=
(
ApiKeyHeaderPermission
,)
def
get
(
self
,
request
,
course_id
,
group_id
,
format
=
None
):
def
get
(
self
,
request
,
course_id
,
group_id
):
"""
"""
GET retrieves an existing course-group relationship from the system
GET retrieves an existing course-group relationship from the system
"""
"""
...
@@ -432,7 +433,7 @@ class CoursesGroupsDetail(APIView):
...
@@ -432,7 +433,7 @@ class CoursesGroupsDetail(APIView):
response_status
=
status
.
HTTP_404_NOT_FOUND
response_status
=
status
.
HTTP_404_NOT_FOUND
return
Response
(
response_data
,
status
=
response_status
)
return
Response
(
response_data
,
status
=
response_status
)
def
delete
(
self
,
request
,
course_id
,
group_id
,
format
=
None
):
def
delete
(
self
,
request
,
course_id
,
group_id
):
"""
"""
DELETE removes/inactivates/etc. an existing course-group relationship
DELETE removes/inactivates/etc. an existing course-group relationship
"""
"""
...
@@ -441,13 +442,15 @@ class CoursesGroupsDetail(APIView):
...
@@ -441,13 +442,15 @@ class CoursesGroupsDetail(APIView):
existing_relationship
=
CourseGroupRelationship
.
objects
.
get
(
course_id
=
course_id
,
group
=
existing_group
)
.
delete
()
existing_relationship
=
CourseGroupRelationship
.
objects
.
get
(
course_id
=
course_id
,
group
=
existing_group
)
.
delete
()
except
ObjectDoesNotExist
:
except
ObjectDoesNotExist
:
pass
pass
return
Response
({},
status
=
status
.
HTTP_204_NO_CONTENT
)
response_data
=
{}
response_data
[
'uri'
]
=
_generate_base_uri
(
request
)
return
Response
(
response_data
,
status
=
status
.
HTTP_204_NO_CONTENT
)
class
CoursesOverview
(
APIView
):
class
CoursesOverview
(
APIView
):
permission_classes
=
(
ApiKeyHeaderPermission
,)
permission_classes
=
(
ApiKeyHeaderPermission
,)
def
get
(
self
,
request
,
course_id
,
format
=
None
):
def
get
(
self
,
request
,
course_id
):
"""
"""
GET retrieves the course overview module, which - in MongoDB - is stored with the following
GET retrieves the course overview module, which - in MongoDB - is stored with the following
naming convention {"_id.org":"i4x", "_id.course":<course_num>, "_id.category":"about", "_id.name":"overview"}
naming convention {"_id.org":"i4x", "_id.course":<course_num>, "_id.category":"about", "_id.name":"overview"}
...
@@ -474,7 +477,7 @@ class CoursesOverview(APIView):
...
@@ -474,7 +477,7 @@ class CoursesOverview(APIView):
class
CoursesUpdates
(
APIView
):
class
CoursesUpdates
(
APIView
):
permission_classes
=
(
ApiKeyHeaderPermission
,)
permission_classes
=
(
ApiKeyHeaderPermission
,)
def
get
(
self
,
request
,
course_id
,
format
=
None
):
def
get
(
self
,
request
,
course_id
):
"""
"""
GET retrieves the course overview module, which - in MongoDB - is stored with the following
GET retrieves the course overview module, which - in MongoDB - is stored with the following
naming convention {"_id.org":"i4x", "_id.course":<course_num>, "_id.category":"course_info", "_id.name":"updates"}
naming convention {"_id.org":"i4x", "_id.course":<course_num>, "_id.category":"course_info", "_id.name":"updates"}
...
@@ -561,7 +564,7 @@ class CoursesStaticTabsDetail(APIView):
...
@@ -561,7 +564,7 @@ class CoursesStaticTabsDetail(APIView):
class
CoursesUsersList
(
APIView
):
class
CoursesUsersList
(
APIView
):
permission_classes
=
(
ApiKeyHeaderPermission
,)
permission_classes
=
(
ApiKeyHeaderPermission
,)
def
post
(
self
,
request
,
course_id
,
format
=
None
):
def
post
(
self
,
request
,
course_id
):
"""
"""
POST enrolls a student in the course. Note, this can be a user_id or
POST enrolls a student in the course. Note, this can be a user_id or
just an email, in case the user does not exist in the system
just an email, in case the user does not exist in the system
...
@@ -603,11 +606,13 @@ class CoursesUsersList(APIView):
...
@@ -603,11 +606,13 @@ class CoursesUsersList(APIView):
else
:
else
:
return
Response
({},
status
=
status
.
HTTP_400_BAD_REQUEST
)
return
Response
({},
status
=
status
.
HTTP_400_BAD_REQUEST
)
def
get
(
self
,
request
,
course_id
,
format
=
None
):
def
get
(
self
,
request
,
course_id
):
"""
"""
GET returns a list of users enrolled in the course_id
GET returns a list of users enrolled in the course_id
"""
"""
response_data
=
OrderedDict
()
response_data
=
OrderedDict
()
base_uri
=
_generate_base_uri
(
request
)
response_data
[
'uri'
]
=
base_uri
try
:
try
:
existing_course
=
get_course
(
course_id
)
existing_course
=
get_course
(
course_id
)
except
ValueError
:
except
ValueError
:
...
@@ -634,10 +639,11 @@ class CoursesUsersList(APIView):
...
@@ -634,10 +639,11 @@ class CoursesUsersList(APIView):
response_data
[
'pending_enrollments'
]
.
append
(
cea
.
email
)
response_data
[
'pending_enrollments'
]
.
append
(
cea
.
email
)
return
Response
(
response_data
)
return
Response
(
response_data
)
class
CoursesUsersDetail
(
APIView
):
class
CoursesUsersDetail
(
APIView
):
permission_classes
=
(
ApiKeyHeaderPermission
,)
permission_classes
=
(
ApiKeyHeaderPermission
,)
def
get
(
self
,
request
,
course_id
,
user_id
,
format
=
None
):
def
get
(
self
,
request
,
course_id
,
user_id
):
"""
"""
GET identifies an ACTIVE course enrollment for the specified user
GET identifies an ACTIVE course enrollment for the specified user
"""
"""
...
@@ -671,11 +677,10 @@ class CoursesUsersDetail(APIView):
...
@@ -671,11 +677,10 @@ class CoursesUsersDetail(APIView):
response_status
=
status
.
HTTP_404_NOT_FOUND
response_status
=
status
.
HTTP_404_NOT_FOUND
return
Response
(
response_data
,
status
=
response_status
)
return
Response
(
response_data
,
status
=
response_status
)
def
delete
(
self
,
request
,
course_id
,
user_id
,
format
=
None
):
def
delete
(
self
,
request
,
course_id
,
user_id
):
"""
"""
DELETE unenrolls the specified user from the specified course
DELETE unenrolls the specified user from the specified course
"""
"""
response_data
=
OrderedDict
()
try
:
try
:
existing_course
=
get_course
(
course_id
)
existing_course
=
get_course
(
course_id
)
except
ValueError
:
except
ValueError
:
...
@@ -688,4 +693,7 @@ class CoursesUsersDetail(APIView):
...
@@ -688,4 +693,7 @@ class CoursesUsersDetail(APIView):
user
=
None
user
=
None
if
user
:
if
user
:
CourseEnrollment
.
unenroll
(
user
,
course_id
)
CourseEnrollment
.
unenroll
(
user
,
course_id
)
return
Response
({},
status
=
status
.
HTTP_204_NO_CONTENT
)
response_data
=
{}
base_uri
=
_generate_base_uri
(
request
)
response_data
[
'uri'
]
=
base_uri
return
Response
(
response_data
,
status
=
status
.
HTTP_204_NO_CONTENT
)
lms/djangoapps/api_manager/groups/tests.py
View file @
913252d4
...
@@ -344,7 +344,6 @@ class GroupsApiTests(ModuleStoreTestCase):
...
@@ -344,7 +344,6 @@ class GroupsApiTests(ModuleStoreTestCase):
self
.
assertEqual
(
users
[
0
][
'first_name'
],
'Joe'
)
self
.
assertEqual
(
users
[
0
][
'first_name'
],
'Joe'
)
self
.
assertEqual
(
users
[
0
][
'last_name'
],
'Smith'
)
self
.
assertEqual
(
users
[
0
][
'last_name'
],
'Smith'
)
def
test_group_users_list_get_invalid_group
(
self
):
def
test_group_users_list_get_invalid_group
(
self
):
test_uri
=
self
.
base_groups_uri
+
'/1231241/users'
test_uri
=
self
.
base_groups_uri
+
'/1231241/users'
response
=
self
.
do_get
(
test_uri
)
response
=
self
.
do_get
(
test_uri
)
...
@@ -582,7 +581,6 @@ class GroupsApiTests(ModuleStoreTestCase):
...
@@ -582,7 +581,6 @@ class GroupsApiTests(ModuleStoreTestCase):
data
=
{
'name'
:
'Tango Group'
}
data
=
{
'name'
:
'Tango Group'
}
tango_response
=
self
.
do_post
(
self
.
base_groups_uri
,
data
)
tango_response
=
self
.
do_post
(
self
.
base_groups_uri
,
data
)
self
.
assertEqual
(
tango_response
.
status_code
,
201
)
self
.
assertEqual
(
tango_response
.
status_code
,
201
)
tango_group_id
=
tango_response
.
data
[
'id'
]
tango_uri
=
tango_response
.
data
[
'uri'
]
tango_uri
=
tango_response
.
data
[
'uri'
]
data
=
{
'group_id'
:
bravo_group_id
,
'relationship_type'
:
relationship_type
}
data
=
{
'group_id'
:
bravo_group_id
,
'relationship_type'
:
relationship_type
}
tango_groups_uri
=
tango_uri
+
'/groups'
tango_groups_uri
=
tango_uri
+
'/groups'
...
@@ -756,7 +754,6 @@ class GroupsApiTests(ModuleStoreTestCase):
...
@@ -756,7 +754,6 @@ class GroupsApiTests(ModuleStoreTestCase):
data
=
{
'name'
:
self
.
test_group_name
}
data
=
{
'name'
:
self
.
test_group_name
}
response
=
self
.
do_post
(
self
.
base_groups_uri
,
data
)
response
=
self
.
do_post
(
self
.
base_groups_uri
,
data
)
self
.
assertEqual
(
response
.
status_code
,
201
)
self
.
assertEqual
(
response
.
status_code
,
201
)
group_id
=
response
.
data
[
'id'
]
test_uri
=
response
.
data
[
'uri'
]
+
'/courses'
test_uri
=
response
.
data
[
'uri'
]
+
'/courses'
data
=
{
'course_id'
:
self
.
test_course_id
}
data
=
{
'course_id'
:
self
.
test_course_id
}
response
=
self
.
do_post
(
test_uri
,
data
)
response
=
self
.
do_post
(
test_uri
,
data
)
...
@@ -774,7 +771,6 @@ class GroupsApiTests(ModuleStoreTestCase):
...
@@ -774,7 +771,6 @@ class GroupsApiTests(ModuleStoreTestCase):
data
=
{
'name'
:
self
.
test_group_name
}
data
=
{
'name'
:
self
.
test_group_name
}
response
=
self
.
do_post
(
self
.
base_groups_uri
,
data
)
response
=
self
.
do_post
(
self
.
base_groups_uri
,
data
)
self
.
assertEqual
(
response
.
status_code
,
201
)
self
.
assertEqual
(
response
.
status_code
,
201
)
group_id
=
response
.
data
[
'id'
]
test_uri
=
response
.
data
[
'uri'
]
+
'/courses'
test_uri
=
response
.
data
[
'uri'
]
+
'/courses'
data
=
{
'course_id'
:
"987/23/896"
}
data
=
{
'course_id'
:
"987/23/896"
}
response
=
self
.
do_post
(
test_uri
,
data
)
response
=
self
.
do_post
(
test_uri
,
data
)
...
@@ -859,7 +855,6 @@ class GroupsApiTests(ModuleStoreTestCase):
...
@@ -859,7 +855,6 @@ class GroupsApiTests(ModuleStoreTestCase):
data
=
{
'name'
:
self
.
test_group_name
}
data
=
{
'name'
:
self
.
test_group_name
}
response
=
self
.
do_post
(
self
.
base_groups_uri
,
data
)
response
=
self
.
do_post
(
self
.
base_groups_uri
,
data
)
self
.
assertEqual
(
response
.
status_code
,
201
)
self
.
assertEqual
(
response
.
status_code
,
201
)
group_id
=
response
.
data
[
'id'
]
test_uri
=
'{}/courses/{}'
.
format
(
response
.
data
[
'uri'
],
self
.
course
.
id
)
test_uri
=
'{}/courses/{}'
.
format
(
response
.
data
[
'uri'
],
self
.
course
.
id
)
response
=
self
.
do_get
(
test_uri
)
response
=
self
.
do_get
(
test_uri
)
self
.
assertEqual
(
response
.
status_code
,
404
)
self
.
assertEqual
(
response
.
status_code
,
404
)
lms/djangoapps/api_manager/groups/urls.py
View file @
913252d4
...
@@ -5,7 +5,8 @@ from rest_framework.urlpatterns import format_suffix_patterns
...
@@ -5,7 +5,8 @@ from rest_framework.urlpatterns import format_suffix_patterns
from
api_manager.groups
import
views
as
groups_views
from
api_manager.groups
import
views
as
groups_views
urlpatterns
=
patterns
(
''
,
urlpatterns
=
patterns
(
''
,
url
(
r'/*$^'
,
groups_views
.
GroupsList
.
as_view
()),
url
(
r'/*$^'
,
groups_views
.
GroupsList
.
as_view
()),
url
(
r'^(?P<group_id>[0-9]+)$'
,
groups_views
.
GroupsDetail
.
as_view
()),
url
(
r'^(?P<group_id>[0-9]+)$'
,
groups_views
.
GroupsDetail
.
as_view
()),
url
(
r'^(?P<group_id>[0-9]+)/courses/*$'
,
groups_views
.
GroupsCoursesList
.
as_view
()),
url
(
r'^(?P<group_id>[0-9]+)/courses/*$'
,
groups_views
.
GroupsCoursesList
.
as_view
()),
...
...
lms/djangoapps/api_manager/groups/views.py
View file @
913252d4
...
@@ -38,7 +38,7 @@ def _generate_base_uri(request):
...
@@ -38,7 +38,7 @@ def _generate_base_uri(request):
class
GroupsList
(
APIView
):
class
GroupsList
(
APIView
):
permissions_classes
=
(
ApiKeyHeaderPermission
,)
permissions_classes
=
(
ApiKeyHeaderPermission
,)
def
post
(
self
,
request
,
format
=
None
):
def
post
(
self
,
request
):
"""
"""
POST creates a new group in the system
POST creates a new group in the system
"""
"""
...
@@ -74,7 +74,7 @@ class GroupsList(APIView):
...
@@ -74,7 +74,7 @@ class GroupsList(APIView):
response_status
=
status
.
HTTP_201_CREATED
response_status
=
status
.
HTTP_201_CREATED
return
Response
(
response_data
,
status
=
response_status
)
return
Response
(
response_data
,
status
=
response_status
)
def
get
(
self
,
request
,
format
=
None
):
def
get
(
self
,
request
):
"""
"""
GET retrieves a list of groups in the system filtered by type
GET retrieves a list of groups in the system filtered by type
"""
"""
...
@@ -103,7 +103,7 @@ class GroupsList(APIView):
...
@@ -103,7 +103,7 @@ class GroupsList(APIView):
class
GroupsDetail
(
APIView
):
class
GroupsDetail
(
APIView
):
permission_classes
=
(
ApiKeyHeaderPermission
,)
permission_classes
=
(
ApiKeyHeaderPermission
,)
def
post
(
self
,
request
,
group_id
,
format
=
None
):
def
post
(
self
,
request
,
group_id
):
response_data
=
{}
response_data
=
{}
base_uri
=
_generate_base_uri
(
request
)
base_uri
=
_generate_base_uri
(
request
)
print
base_uri
print
base_uri
...
@@ -124,7 +124,7 @@ class GroupsDetail(APIView):
...
@@ -124,7 +124,7 @@ class GroupsDetail(APIView):
response_data
[
'uri'
]
=
_generate_base_uri
(
request
)
response_data
[
'uri'
]
=
_generate_base_uri
(
request
)
return
Response
(
response_data
,
status
=
status
.
HTTP_201_CREATED
)
return
Response
(
response_data
,
status
=
status
.
HTTP_201_CREATED
)
def
get
(
self
,
request
,
group_id
,
format
=
None
):
def
get
(
self
,
request
,
group_id
):
"""
"""
GET retrieves an existing group from the system
GET retrieves an existing group from the system
"""
"""
...
@@ -163,7 +163,7 @@ class GroupsDetail(APIView):
...
@@ -163,7 +163,7 @@ class GroupsDetail(APIView):
class
GroupsUsersList
(
APIView
):
class
GroupsUsersList
(
APIView
):
permission_classes
=
(
ApiKeyHeaderPermission
,)
permission_classes
=
(
ApiKeyHeaderPermission
,)
def
post
(
self
,
request
,
group_id
,
format
=
None
):
def
post
(
self
,
request
,
group_id
):
"""
"""
POST creates a new group-user relationship in the system
POST creates a new group-user relationship in the system
"""
"""
...
@@ -194,7 +194,7 @@ class GroupsUsersList(APIView):
...
@@ -194,7 +194,7 @@ class GroupsUsersList(APIView):
response_status
=
status
.
HTTP_409_CONFLICT
response_status
=
status
.
HTTP_409_CONFLICT
return
Response
(
response_data
,
status
=
response_status
)
return
Response
(
response_data
,
status
=
response_status
)
def
get
(
self
,
request
,
group_id
,
format
=
None
):
def
get
(
self
,
request
,
group_id
):
"""
"""
GET retrieves the list of users related to the specified group
GET retrieves the list of users related to the specified group
"""
"""
...
@@ -220,7 +220,7 @@ class GroupsUsersList(APIView):
...
@@ -220,7 +220,7 @@ class GroupsUsersList(APIView):
class
GroupsUsersDetail
(
APIView
):
class
GroupsUsersDetail
(
APIView
):
permission_classes
=
(
ApiKeyHeaderPermission
,)
permission_classes
=
(
ApiKeyHeaderPermission
,)
def
get
(
self
,
request
,
group_id
,
user_id
,
format
=
None
):
def
get
(
self
,
request
,
group_id
,
user_id
):
"""
"""
GET retrieves an existing group-user relationship from the system
GET retrieves an existing group-user relationship from the system
"""
"""
...
@@ -241,8 +241,7 @@ class GroupsUsersDetail(APIView):
...
@@ -241,8 +241,7 @@ class GroupsUsersDetail(APIView):
response_status
=
status
.
HTTP_404_NOT_FOUND
response_status
=
status
.
HTTP_404_NOT_FOUND
return
Response
(
response_data
,
status
=
response_status
)
return
Response
(
response_data
,
status
=
response_status
)
def
delete
(
self
,
request
,
group_id
,
user_id
):
def
delete
(
self
,
request
,
group_id
,
user_id
,
format
=
None
):
"""
"""
DELETE removes/inactivates/etc. an existing group-user relationship
DELETE removes/inactivates/etc. an existing group-user relationship
"""
"""
...
@@ -258,7 +257,7 @@ class GroupsUsersDetail(APIView):
...
@@ -258,7 +257,7 @@ class GroupsUsersDetail(APIView):
class
GroupsGroupsList
(
APIView
):
class
GroupsGroupsList
(
APIView
):
permission_classes
=
(
ApiKeyHeaderPermission
,)
permission_classes
=
(
ApiKeyHeaderPermission
,)
def
post
(
self
,
request
,
group_id
,
format
=
None
):
def
post
(
self
,
request
,
group_id
):
"""
"""
POST creates a new group-group relationship in the system
POST creates a new group-group relationship in the system
"""
"""
...
@@ -290,8 +289,7 @@ class GroupsGroupsList(APIView):
...
@@ -290,8 +289,7 @@ class GroupsGroupsList(APIView):
response_status
=
status
.
HTTP_404_NOT_FOUND
response_status
=
status
.
HTTP_404_NOT_FOUND
return
Response
(
response_data
,
status
=
response_status
)
return
Response
(
response_data
,
status
=
response_status
)
def
get
(
self
,
request
,
group_id
):
def
get
(
self
,
request
,
group_id
,
format
=
None
):
"""
"""
GET retrieves the existing group-group relationships for the specified group
GET retrieves the existing group-group relationships for the specified group
"""
"""
...
@@ -333,7 +331,7 @@ class GroupsGroupsList(APIView):
...
@@ -333,7 +331,7 @@ class GroupsGroupsList(APIView):
class
GroupsGroupsDetail
(
APIView
):
class
GroupsGroupsDetail
(
APIView
):
permission_classes
=
(
ApiKeyHeaderPermission
,)
permission_classes
=
(
ApiKeyHeaderPermission
,)
def
get
(
self
,
request
,
group_id
,
related_group_id
,
format
=
None
):
def
get
(
self
,
request
,
group_id
,
related_group_id
):
"""
"""
GET retrieves an existing group-group relationship from the system
GET retrieves an existing group-group relationship from the system
"""
"""
...
@@ -357,7 +355,7 @@ class GroupsGroupsDetail(APIView):
...
@@ -357,7 +355,7 @@ class GroupsGroupsDetail(APIView):
response_status
=
status
.
HTTP_200_OK
response_status
=
status
.
HTTP_200_OK
return
Response
(
response_data
,
response_status
)
return
Response
(
response_data
,
response_status
)
def
delete
(
self
,
request
,
group_id
,
related_group_id
,
format
=
None
):
def
delete
(
self
,
request
,
group_id
,
related_group_id
):
"""
"""
DELETE removes/inactivates/etc. an existing group-group relationship
DELETE removes/inactivates/etc. an existing group-group relationship
"""
"""
...
@@ -388,7 +386,7 @@ class GroupsGroupsDetail(APIView):
...
@@ -388,7 +386,7 @@ class GroupsGroupsDetail(APIView):
class
GroupsCoursesList
(
APIView
):
class
GroupsCoursesList
(
APIView
):
permission_classes
=
(
ApiKeyHeaderPermission
,)
permission_classes
=
(
ApiKeyHeaderPermission
,)
def
post
(
self
,
request
,
group_id
,
format
=
None
):
def
post
(
self
,
request
,
group_id
):
"""
"""
POST creates a new group-course relationship in the system
POST creates a new group-course relationship in the system
"""
"""
...
@@ -422,7 +420,7 @@ class GroupsCoursesList(APIView):
...
@@ -422,7 +420,7 @@ class GroupsCoursesList(APIView):
response_status
=
status
.
HTTP_409_CONFLICT
response_status
=
status
.
HTTP_409_CONFLICT
return
Response
(
response_data
,
status
=
response_status
)
return
Response
(
response_data
,
status
=
response_status
)
def
get
(
self
,
request
,
group_id
,
format
=
None
):
def
get
(
self
,
request
,
group_id
):
"""
"""
GET returns all courses that has a relationship to the group
GET returns all courses that has a relationship to the group
"""
"""
...
@@ -448,7 +446,7 @@ class GroupsCoursesList(APIView):
...
@@ -448,7 +446,7 @@ class GroupsCoursesList(APIView):
class
GroupsCoursesDetail
(
APIView
):
class
GroupsCoursesDetail
(
APIView
):
permission_classes
=
(
ApiKeyHeaderPermission
,)
permission_classes
=
(
ApiKeyHeaderPermission
,)
def
get
(
self
,
request
,
group_id
,
course_id
,
format
=
None
):
def
get
(
self
,
request
,
group_id
,
course_id
):
"""
"""
GET retrieves an existing group-course relationship from the system
GET retrieves an existing group-course relationship from the system
"""
"""
...
@@ -469,7 +467,7 @@ class GroupsCoursesDetail(APIView):
...
@@ -469,7 +467,7 @@ class GroupsCoursesDetail(APIView):
response_status
=
status
.
HTTP_404_NOT_FOUND
response_status
=
status
.
HTTP_404_NOT_FOUND
return
Response
(
response_data
,
status
=
response_status
)
return
Response
(
response_data
,
status
=
response_status
)
def
delete
(
self
,
request
,
group_id
,
course_id
,
format
=
None
):
def
delete
(
self
,
request
,
group_id
,
course_id
):
"""
"""
DELETE removes/inactivates/etc. an existing group-course relationship
DELETE removes/inactivates/etc. an existing group-course relationship
"""
"""
...
...
lms/djangoapps/api_manager/migrations/0001_initial.py
View file @
913252d4
...
@@ -30,7 +30,6 @@ class Migration(SchemaMigration):
...
@@ -30,7 +30,6 @@ class Migration(SchemaMigration):
))
))
db
.
send_create_signal
(
'api_manager'
,
[
'LinkedGroupRelationship'
])
db
.
send_create_signal
(
'api_manager'
,
[
'LinkedGroupRelationship'
])
def
backwards
(
self
,
orm
):
def
backwards
(
self
,
orm
):
# Deleting model 'GroupRelationship'
# Deleting model 'GroupRelationship'
db
.
delete_table
(
'api_manager_grouprelationship'
)
db
.
delete_table
(
'api_manager_grouprelationship'
)
...
@@ -38,7 +37,6 @@ class Migration(SchemaMigration):
...
@@ -38,7 +37,6 @@ class Migration(SchemaMigration):
# Deleting model 'LinkedGroupRelationship'
# Deleting model 'LinkedGroupRelationship'
db
.
delete_table
(
'api_manager_linkedgrouprelationship'
)
db
.
delete_table
(
'api_manager_linkedgrouprelationship'
)
models
=
{
models
=
{
'api_manager.grouprelationship'
:
{
'api_manager.grouprelationship'
:
{
'Meta'
:
{
'object_name'
:
'GroupRelationship'
},
'Meta'
:
{
'object_name'
:
'GroupRelationship'
},
...
@@ -80,4 +78,4 @@ class Migration(SchemaMigration):
...
@@ -80,4 +78,4 @@ class Migration(SchemaMigration):
}
}
}
}
complete_apps
=
[
'api_manager'
]
complete_apps
=
[
'api_manager'
]
\ No newline at end of file
lms/djangoapps/api_manager/migrations/0002_auto__add_coursegrouprelationship__add_groupprofile.py
View file @
913252d4
...
@@ -25,7 +25,6 @@ class Migration(SchemaMigration):
...
@@ -25,7 +25,6 @@ class Migration(SchemaMigration):
))
))
db
.
send_create_signal
(
'api_manager'
,
[
'GroupProfile'
])
db
.
send_create_signal
(
'api_manager'
,
[
'GroupProfile'
])
def
backwards
(
self
,
orm
):
def
backwards
(
self
,
orm
):
# Deleting model 'CourseGroupRelationship'
# Deleting model 'CourseGroupRelationship'
db
.
delete_table
(
'api_manager_coursegrouprelationship'
)
db
.
delete_table
(
'api_manager_coursegrouprelationship'
)
...
@@ -33,7 +32,6 @@ class Migration(SchemaMigration):
...
@@ -33,7 +32,6 @@ class Migration(SchemaMigration):
# Deleting model 'GroupProfile'
# Deleting model 'GroupProfile'
db
.
delete_table
(
'auth_groupprofile'
)
db
.
delete_table
(
'auth_groupprofile'
)
models
=
{
models
=
{
'api_manager.coursegrouprelationship'
:
{
'api_manager.coursegrouprelationship'
:
{
'Meta'
:
{
'object_name'
:
'CourseGroupRelationship'
},
'Meta'
:
{
'object_name'
:
'CourseGroupRelationship'
},
...
@@ -88,4 +86,4 @@ class Migration(SchemaMigration):
...
@@ -88,4 +86,4 @@ class Migration(SchemaMigration):
}
}
}
}
complete_apps
=
[
'api_manager'
]
complete_apps
=
[
'api_manager'
]
\ No newline at end of file
lms/djangoapps/api_manager/migrations/0003_move_name_to_profile.py
View file @
913252d4
...
@@ -13,12 +13,10 @@ class Migration(SchemaMigration):
...
@@ -13,12 +13,10 @@ class Migration(SchemaMigration):
self
.
gf
(
'django.db.models.fields.CharField'
)(
max_length
=
255
,
null
=
True
,
blank
=
True
),
self
.
gf
(
'django.db.models.fields.CharField'
)(
max_length
=
255
,
null
=
True
,
blank
=
True
),
keep_default
=
False
)
keep_default
=
False
)
def
backwards
(
self
,
orm
):
def
backwards
(
self
,
orm
):
# Deleting field 'GroupProfile.name'
# Deleting field 'GroupProfile.name'
db
.
delete_column
(
'auth_groupprofile'
,
'name'
)
db
.
delete_column
(
'auth_groupprofile'
,
'name'
)
models
=
{
models
=
{
'api_manager.coursegrouprelationship'
:
{
'api_manager.coursegrouprelationship'
:
{
'Meta'
:
{
'object_name'
:
'CourseGroupRelationship'
},
'Meta'
:
{
'object_name'
:
'CourseGroupRelationship'
},
...
@@ -74,4 +72,4 @@ class Migration(SchemaMigration):
...
@@ -74,4 +72,4 @@ class Migration(SchemaMigration):
}
}
}
}
complete_apps
=
[
'api_manager'
]
complete_apps
=
[
'api_manager'
]
\ No newline at end of file
lms/djangoapps/api_manager/sessions/test_login_ratelimit.py
View file @
913252d4
...
@@ -19,7 +19,6 @@ TEST_API_KEY = str(uuid.uuid4())
...
@@ -19,7 +19,6 @@ TEST_API_KEY = str(uuid.uuid4())
@override_settings
(
EDX_API_KEY
=
TEST_API_KEY
)
@override_settings
(
EDX_API_KEY
=
TEST_API_KEY
)
@patch.dict
(
"django.conf.settings.FEATURES"
,
{
'ENABLE_MAX_FAILED_LOGIN_ATTEMPTS'
:
False
})
@patch.dict
(
"django.conf.settings.FEATURES"
,
{
'ENABLE_MAX_FAILED_LOGIN_ATTEMPTS'
:
False
})
class
SessionApiRateLimitingProtectionTest
(
TestCase
):
class
SessionApiRateLimitingProtectionTest
(
TestCase
):
"""
"""
Test api_manager.session.login.ratelimit
Test api_manager.session.login.ratelimit
...
@@ -37,7 +36,6 @@ class SessionApiRateLimitingProtectionTest(TestCase):
...
@@ -37,7 +36,6 @@ class SessionApiRateLimitingProtectionTest(TestCase):
cache
.
clear
()
cache
.
clear
()
self
.
session_url
=
'/api/sessions'
self
.
session_url
=
'/api/sessions'
def
test_login_ratelimiting_protection
(
self
):
def
test_login_ratelimiting_protection
(
self
):
""" Try (and fail) login user 30 times on invalid password """
""" Try (and fail) login user 30 times on invalid password """
...
...
lms/djangoapps/api_manager/sessions/test_security.py
View file @
913252d4
...
@@ -222,7 +222,7 @@ class SessionApiSecurityTest(TestCase):
...
@@ -222,7 +222,7 @@ class SessionApiSecurityTest(TestCase):
"""
"""
Make Post/Delete/Get requests with params
Make Post/Delete/Get requests with params
"""
"""
post_params
,
extra
,
=
{
'username'
:
username
,
'password'
:
password
},
{}
post_params
,
extra
,
=
{
'username'
:
username
,
'password'
:
password
},
{}
patched_audit_log
=
'api_manager.sessions.views.AUDIT_LOG'
patched_audit_log
=
'api_manager.sessions.views.AUDIT_LOG'
request_method
=
kwargs
.
get
(
'request_method'
,
'POST'
)
request_method
=
kwargs
.
get
(
'request_method'
,
'POST'
)
if
kwargs
.
get
(
'email'
):
if
kwargs
.
get
(
'email'
):
...
...
lms/djangoapps/api_manager/sessions/urls.py
View file @
913252d4
...
@@ -5,7 +5,8 @@ from rest_framework.urlpatterns import format_suffix_patterns
...
@@ -5,7 +5,8 @@ from rest_framework.urlpatterns import format_suffix_patterns
from
api_manager.sessions
import
views
as
sessions_views
from
api_manager.sessions
import
views
as
sessions_views
urlpatterns
=
patterns
(
''
,
urlpatterns
=
patterns
(
''
,
url
(
r'/*$^'
,
sessions_views
.
SessionsList
.
as_view
()),
url
(
r'/*$^'
,
sessions_views
.
SessionsList
.
as_view
()),
url
(
r'^(?P<session_id>[a-z0-9]+)$'
,
sessions_views
.
SessionsDetail
.
as_view
()),
url
(
r'^(?P<session_id>[a-z0-9]+)$'
,
sessions_views
.
SessionsDetail
.
as_view
()),
)
)
...
...
lms/djangoapps/api_manager/sessions/views.py
View file @
913252d4
...
@@ -43,7 +43,7 @@ def _generate_base_uri(request):
...
@@ -43,7 +43,7 @@ def _generate_base_uri(request):
class
SessionsList
(
APIView
):
class
SessionsList
(
APIView
):
permission_classes
=
(
ApiKeyHeaderPermission
,)
permission_classes
=
(
ApiKeyHeaderPermission
,)
def
post
(
self
,
request
,
format
=
None
):
def
post
(
self
,
request
):
"""
"""
POST creates a new system session, supported authentication modes:
POST creates a new system session, supported authentication modes:
1. Open edX username/password
1. Open edX username/password
...
@@ -116,7 +116,7 @@ class SessionsList(APIView):
...
@@ -116,7 +116,7 @@ class SessionsList(APIView):
class
SessionsDetail
(
APIView
):
class
SessionsDetail
(
APIView
):
permission_classes
=
(
ApiKeyHeaderPermission
,)
permission_classes
=
(
ApiKeyHeaderPermission
,)
def
get
(
self
,
request
,
session_id
,
format
=
None
):
def
get
(
self
,
request
,
session_id
):
"""
"""
GET retrieves an existing system session
GET retrieves an existing system session
"""
"""
...
@@ -140,7 +140,7 @@ class SessionsDetail(APIView):
...
@@ -140,7 +140,7 @@ class SessionsDetail(APIView):
else
:
else
:
return
Response
(
response_data
,
status
=
status
.
HTTP_404_NOT_FOUND
)
return
Response
(
response_data
,
status
=
status
.
HTTP_404_NOT_FOUND
)
def
delete
(
self
,
request
,
session_id
,
format
=
None
):
def
delete
(
self
,
request
,
session_id
):
"""
"""
DELETE flushes an existing system session from the system
DELETE flushes an existing system session from the system
"""
"""
...
...
lms/djangoapps/api_manager/system/views.py
View file @
913252d4
""" BASE API VIEWS """
""" BASE API VIEWS """
from
rest_framework
import
status
from
rest_framework
import
status
from
rest_framework.decorators
import
api_view
,
permission_classes
from
rest_framework.response
import
Response
from
rest_framework.response
import
Response
from
rest_framework.views
import
APIView
from
rest_framework.views
import
APIView
...
@@ -22,11 +21,12 @@ def _generate_base_uri(request):
...
@@ -22,11 +21,12 @@ def _generate_base_uri(request):
)
)
return
resource_uri
return
resource_uri
class
SystemDetail
(
APIView
):
class
SystemDetail
(
APIView
):
"""Manages system-level information about the Open edX API"""
permission_classes
=
(
ApiKeyHeaderPermission
,)
permission_classes
=
(
ApiKeyHeaderPermission
,)
def
get
(
self
,
request
,
format
=
None
):
def
get
(
self
,
request
):
"""Returns top-level descriptive information about the Open edX API"""
base_uri
=
_generate_base_uri
(
request
)
base_uri
=
_generate_base_uri
(
request
)
response_data
=
{}
response_data
=
{}
response_data
[
'name'
]
=
"Open edX System API"
response_data
[
'name'
]
=
"Open edX System API"
...
@@ -37,10 +37,10 @@ class SystemDetail(APIView):
...
@@ -37,10 +37,10 @@ class SystemDetail(APIView):
class
ApiDetail
(
APIView
):
class
ApiDetail
(
APIView
):
"""Manages top-level information about the Open edX API"""
permission_classes
=
(
ApiKeyHeaderPermission
,)
permission_classes
=
(
ApiKeyHeaderPermission
,)
def
get
(
self
,
request
,
format
=
None
):
def
get
(
self
,
request
):
"""Returns top-level descriptive information about the Open edX API"""
base_uri
=
_generate_base_uri
(
request
)
base_uri
=
_generate_base_uri
(
request
)
response_data
=
{}
response_data
=
{}
response_data
[
'name'
]
=
"Open edX API"
response_data
[
'name'
]
=
"Open edX API"
...
...
lms/djangoapps/api_manager/urls.py
View file @
913252d4
...
@@ -12,11 +12,12 @@ from django.conf.urls import include, patterns, url
...
@@ -12,11 +12,12 @@ from django.conf.urls import include, patterns, url
from
api_manager.system
import
views
as
system_views
from
api_manager.system
import
views
as
system_views
urlpatterns
=
patterns
(
''
,
urlpatterns
=
patterns
(
url
(
r'^$'
,
system_views
.
ApiDetail
.
as_view
()),
''
,
url
(
r'^system$'
,
system_views
.
SystemDetail
.
as_view
()),
url
(
r'^$'
,
system_views
.
ApiDetail
.
as_view
()),
url
(
r'^users/*'
,
include
(
'api_manager.users.urls'
)),
url
(
r'^system$'
,
system_views
.
SystemDetail
.
as_view
()),
url
(
r'^groups/*'
,
include
(
'api_manager.groups.urls'
)),
url
(
r'^users/*'
,
include
(
'api_manager.users.urls'
)),
url
(
r'^sessions/*'
,
include
(
'api_manager.sessions.urls'
)),
url
(
r'^groups/*'
,
include
(
'api_manager.groups.urls'
)),
url
(
r'^courses/*'
,
include
(
'api_manager.courses.urls'
)),
url
(
r'^sessions/*'
,
include
(
'api_manager.sessions.urls'
)),
)
url
(
r'^courses/*'
,
include
(
'api_manager.courses.urls'
)),
)
lms/djangoapps/api_manager/users/test_user_password_reset.py
View file @
913252d4
...
@@ -12,8 +12,10 @@ from django.core.cache import cache
...
@@ -12,8 +12,10 @@ from django.core.cache import cache
from
datetime
import
datetime
,
timedelta
from
datetime
import
datetime
,
timedelta
from
freezegun
import
freeze_time
from
freezegun
import
freeze_time
from
pytz
import
UTC
from
pytz
import
UTC
TEST_API_KEY
=
str
(
uuid
.
uuid4
())
TEST_API_KEY
=
str
(
uuid
.
uuid4
())
@override_settings
(
EDX_API_KEY
=
TEST_API_KEY
)
@override_settings
(
EDX_API_KEY
=
TEST_API_KEY
)
@patch.dict
(
"django.conf.settings.FEATURES"
,
{
'ENFORCE_PASSWORD_POLICY'
:
True
})
@patch.dict
(
"django.conf.settings.FEATURES"
,
{
'ENFORCE_PASSWORD_POLICY'
:
True
})
@patch.dict
(
"django.conf.settings.FEATURES"
,
{
'ADVANCED_SECURITY'
:
True
})
@patch.dict
(
"django.conf.settings.FEATURES"
,
{
'ADVANCED_SECURITY'
:
True
})
...
@@ -52,7 +54,7 @@ class UserPasswordResetTest(TestCase):
...
@@ -52,7 +54,7 @@ class UserPasswordResetTest(TestCase):
reset_time
=
timezone
.
now
()
+
timedelta
(
days
=
5
)
reset_time
=
timezone
.
now
()
+
timedelta
(
days
=
5
)
with
patch
.
object
(
timezone
,
'now'
,
return_value
=
reset_time
):
with
patch
.
object
(
timezone
,
'now'
,
return_value
=
reset_time
):
response
=
self
.
_do_post_request
(
self
.
session_url
,
'test2'
,
'Test.Me64!'
,
secure
=
True
)
response
=
self
.
_do_post_request
(
self
.
session_url
,
'test2'
,
'Test.Me64!'
,
secure
=
True
)
message
=
_
(
message
=
_
(
'Your password has expired due to password policy on this account. '
'Your password has expired due to password policy on this account. '
'You must reset your password before you can log in again.'
'You must reset your password before you can log in again.'
)
)
...
@@ -63,7 +65,7 @@ class UserPasswordResetTest(TestCase):
...
@@ -63,7 +65,7 @@ class UserPasswordResetTest(TestCase):
response
=
self
.
_do_post_pass_reset_request
(
response
=
self
.
_do_post_pass_reset_request
(
pass_reset_url
,
password
=
'Test.Me64@'
,
secure
=
True
pass_reset_url
,
password
=
'Test.Me64@'
,
secure
=
True
)
)
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertEqual
(
response
.
status_code
,
200
)
#login successful after reset password
#login successful after reset password
response
=
self
.
_do_post_request
(
self
.
session_url
,
'test2'
,
'Test.Me64@'
,
secure
=
True
)
response
=
self
.
_do_post_request
(
self
.
session_url
,
'test2'
,
'Test.Me64@'
,
secure
=
True
)
...
@@ -167,11 +169,13 @@ class UserPasswordResetTest(TestCase):
...
@@ -167,11 +169,13 @@ class UserPasswordResetTest(TestCase):
pass_reset_url
=
'{}/{}'
.
format
(
self
.
user_url
,
user_id
)
pass_reset_url
=
'{}/{}'
.
format
(
self
.
user_url
,
user_id
)
for
i
in
xrange
(
30
):
for
i
in
xrange
(
30
):
password
=
u'test_password{0}'
.
format
(
i
)
password
=
u'test_password{0}'
.
format
(
i
)
response
=
self
.
_do_post_pass_reset_request
(
response
=
self
.
_do_post_pass_reset_request
(
'{}/{}'
.
format
(
self
.
user_url
,
i
+
200
),
password
=
password
,
secure
=
True
'{}/{}'
.
format
(
self
.
user_url
,
i
+
200
),
)
password
=
password
,
self
.
_assert_response
(
response
,
status
=
404
)
secure
=
True
)
self
.
_assert_response
(
response
,
status
=
404
)
response
=
self
.
_do_post_pass_reset_request
(
response
=
self
.
_do_post_pass_reset_request
(
'{}/{}'
.
format
(
self
.
user_url
,
'31'
),
password
=
'Test.Me64@'
,
secure
=
True
'{}/{}'
.
format
(
self
.
user_url
,
'31'
),
password
=
'Test.Me64@'
,
secure
=
True
...
@@ -215,14 +219,11 @@ class UserPasswordResetTest(TestCase):
...
@@ -215,14 +219,11 @@ class UserPasswordResetTest(TestCase):
extra
[
'wsgi.url_scheme'
]
=
'https'
extra
[
'wsgi.url_scheme'
]
=
'https'
return
self
.
client
.
post
(
url
,
post_params
,
headers
=
headers
,
**
extra
)
return
self
.
client
.
post
(
url
,
post_params
,
headers
=
headers
,
**
extra
)
def
_assert_response
(
self
,
response
,
status
=
200
,
success
=
None
,
message
=
None
):
def
_assert_response
(
self
,
response
,
status
=
200
,
message
=
None
):
"""
"""
Assert that the response had status 200 and returned a valid
Assert that the response had status 200 and returned a valid
JSON-parseable dict.
JSON-parseable dict.
If success is provided, assert that the response had that
value for 'success' in the JSON dict.
If message is provided, assert that the response contained that
If message is provided, assert that the response contained that
value for 'message' in the JSON dict.
value for 'message' in the JSON dict.
"""
"""
...
@@ -233,4 +234,3 @@ class UserPasswordResetTest(TestCase):
...
@@ -233,4 +234,3 @@ class UserPasswordResetTest(TestCase):
msg
=
(
"'
%
s' did not contain '
%
s'"
%
msg
=
(
"'
%
s' did not contain '
%
s'"
%
(
response_dict
[
'message'
],
message
))
(
response_dict
[
'message'
],
message
))
self
.
assertTrue
(
message
in
response_dict
[
'message'
],
msg
)
self
.
assertTrue
(
message
in
response_dict
[
'message'
],
msg
)
lms/djangoapps/api_manager/users/tests.py
View file @
913252d4
...
@@ -90,12 +90,11 @@ class UsersApiTests(TestCase):
...
@@ -90,12 +90,11 @@ class UsersApiTests(TestCase):
def
test_user_list_post_inactive
(
self
):
def
test_user_list_post_inactive
(
self
):
test_uri
=
'/api/users'
test_uri
=
'/api/users'
local_username
=
self
.
test_username
+
str
(
randint
(
11
,
99
))
local_username
=
self
.
test_username
+
str
(
randint
(
11
,
99
))
data
=
{
'email'
:
self
.
test_email
,
'username'
:
local_username
,
'password'
:
self
.
test_password
,
'first_name'
:
self
.
test_first_name
,
'last_name'
:
self
.
test_last_name
,
'is_active'
:
False
}
data
=
{
'email'
:
self
.
test_email
,
'username'
:
local_username
,
'password'
:
self
.
test_password
,
'first_name'
:
self
.
test_first_name
,
'last_name'
:
self
.
test_last_name
,
'is_active'
:
False
}
response
=
self
.
do_post
(
test_uri
,
data
)
response
=
self
.
do_post
(
test_uri
,
data
)
self
.
assertEqual
(
response
.
status_code
,
201
)
self
.
assertEqual
(
response
.
status_code
,
201
)
self
.
assertEqual
(
response
.
data
[
'is_active'
],
False
)
self
.
assertEqual
(
response
.
data
[
'is_active'
],
False
)
def
test_user_list_post_duplicate
(
self
):
def
test_user_list_post_duplicate
(
self
):
test_uri
=
'/api/users'
test_uri
=
'/api/users'
local_username
=
self
.
test_username
+
str
(
randint
(
11
,
99
))
local_username
=
self
.
test_username
+
str
(
randint
(
11
,
99
))
...
@@ -135,7 +134,7 @@ class UsersApiTests(TestCase):
...
@@ -135,7 +134,7 @@ class UsersApiTests(TestCase):
data
=
{
'email'
:
self
.
test_email
,
'username'
:
local_username
,
'password'
:
self
.
test_password
,
'first_name'
:
self
.
test_first_name
,
'last_name'
:
self
.
test_last_name
}
data
=
{
'email'
:
self
.
test_email
,
'username'
:
local_username
,
'password'
:
self
.
test_password
,
'first_name'
:
self
.
test_first_name
,
'last_name'
:
self
.
test_last_name
}
response
=
self
.
do_post
(
test_uri
,
data
)
response
=
self
.
do_post
(
test_uri
,
data
)
test_uri
=
test_uri
+
'/'
+
str
(
response
.
data
[
'id'
])
test_uri
=
test_uri
+
'/'
+
str
(
response
.
data
[
'id'
])
data
=
{
'is_active'
:
False
}
data
=
{
'is_active'
:
False
}
response
=
self
.
do_post
(
test_uri
,
data
)
response
=
self
.
do_post
(
test_uri
,
data
)
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertEqual
(
response
.
status_code
,
200
)
self
.
assertEqual
(
response
.
data
[
'is_active'
],
False
)
self
.
assertEqual
(
response
.
data
[
'is_active'
],
False
)
...
@@ -145,7 +144,7 @@ class UsersApiTests(TestCase):
...
@@ -145,7 +144,7 @@ class UsersApiTests(TestCase):
def
test_user_detail_post_invalid_user
(
self
):
def
test_user_detail_post_invalid_user
(
self
):
test_uri
=
'/api/users/123124124'
test_uri
=
'/api/users/123124124'
data
=
{
'is_active'
:
False
}
data
=
{
'is_active'
:
False
}
response
=
self
.
do_post
(
test_uri
,
data
)
response
=
self
.
do_post
(
test_uri
,
data
)
self
.
assertEqual
(
response
.
status_code
,
404
)
self
.
assertEqual
(
response
.
status_code
,
404
)
...
...
lms/djangoapps/api_manager/users/urls.py
View file @
913252d4
...
@@ -5,7 +5,8 @@ from rest_framework.urlpatterns import format_suffix_patterns
...
@@ -5,7 +5,8 @@ from rest_framework.urlpatterns import format_suffix_patterns
from
api_manager.users
import
views
as
users_views
from
api_manager.users
import
views
as
users_views
urlpatterns
=
patterns
(
''
,
urlpatterns
=
patterns
(
''
,
url
(
r'/*$^'
,
users_views
.
UsersList
.
as_view
()),
url
(
r'/*$^'
,
users_views
.
UsersList
.
as_view
()),
url
(
r'^(?P<user_id>[0-9]+)$'
,
users_views
.
UsersDetail
.
as_view
()),
url
(
r'^(?P<user_id>[0-9]+)$'
,
users_views
.
UsersDetail
.
as_view
()),
url
(
r'^(?P<user_id>[0-9]+)/courses/*$'
,
users_views
.
UsersCoursesList
.
as_view
()),
url
(
r'^(?P<user_id>[0-9]+)/courses/*$'
,
users_views
.
UsersCoursesList
.
as_view
()),
...
...
lms/djangoapps/api_manager/users/views.py
View file @
913252d4
...
@@ -30,6 +30,7 @@ from util.bad_request_rate_limiter import BadRequestRateLimiter
...
@@ -30,6 +30,7 @@ from util.bad_request_rate_limiter import BadRequestRateLimiter
log
=
logging
.
getLogger
(
__name__
)
log
=
logging
.
getLogger
(
__name__
)
AUDIT_LOG
=
logging
.
getLogger
(
"audit"
)
AUDIT_LOG
=
logging
.
getLogger
(
"audit"
)
def
_generate_base_uri
(
request
):
def
_generate_base_uri
(
request
):
"""
"""
Constructs the protocol:host:path component of the resource uri
Constructs the protocol:host:path component of the resource uri
...
@@ -44,6 +45,7 @@ def _generate_base_uri(request):
...
@@ -44,6 +45,7 @@ def _generate_base_uri(request):
)
)
return
resource_uri
return
resource_uri
def
_serialize_user
(
response_data
,
user
):
def
_serialize_user
(
response_data
,
user
):
"""
"""
Loads the object data into the response dict
Loads the object data into the response dict
...
@@ -57,6 +59,7 @@ def _serialize_user(response_data, user):
...
@@ -57,6 +59,7 @@ def _serialize_user(response_data, user):
response_data
[
'is_active'
]
=
user
.
is_active
response_data
[
'is_active'
]
=
user
.
is_active
return
response_data
return
response_data
def
_save_module_position
(
request
,
user
,
course_id
,
course_descriptor
,
position
):
def
_save_module_position
(
request
,
user
,
course_id
,
course_descriptor
,
position
):
"""
"""
Records the indicated position for the specified course
Records the indicated position for the specified course
...
@@ -94,7 +97,7 @@ def _save_module_position(request, user, course_id, course_descriptor, position)
...
@@ -94,7 +97,7 @@ def _save_module_position(request, user, course_id, course_descriptor, position)
class
UsersList
(
APIView
):
class
UsersList
(
APIView
):
permission_classes
=
(
ApiKeyHeaderPermission
,)
permission_classes
=
(
ApiKeyHeaderPermission
,)
def
post
(
self
,
request
,
format
=
None
):
def
post
(
self
,
request
):
"""
"""
POST creates a new user in the system
POST creates a new user in the system
"""
"""
...
@@ -176,7 +179,7 @@ class UsersList(APIView):
...
@@ -176,7 +179,7 @@ class UsersList(APIView):
class
UsersDetail
(
APIView
):
class
UsersDetail
(
APIView
):
permission_classes
=
(
ApiKeyHeaderPermission
,)
permission_classes
=
(
ApiKeyHeaderPermission
,)
def
get
(
self
,
request
,
user_id
,
format
=
None
):
def
get
(
self
,
request
,
user_id
):
"""
"""
GET retrieves an existing user from the system
GET retrieves an existing user from the system
"""
"""
...
@@ -195,7 +198,7 @@ class UsersDetail(APIView):
...
@@ -195,7 +198,7 @@ class UsersDetail(APIView):
except
ObjectDoesNotExist
:
except
ObjectDoesNotExist
:
return
Response
(
response_data
,
status
=
status
.
HTTP_404_NOT_FOUND
)
return
Response
(
response_data
,
status
=
status
.
HTTP_404_NOT_FOUND
)
def
post
(
self
,
request
,
user_id
,
format
=
None
):
def
post
(
self
,
request
,
user_id
):
"""
"""
POST provides the ability to update information about an existing user
POST provides the ability to update information about an existing user
"""
"""
...
@@ -287,7 +290,7 @@ class UsersDetail(APIView):
...
@@ -287,7 +290,7 @@ class UsersDetail(APIView):
class
UsersGroupsList
(
APIView
):
class
UsersGroupsList
(
APIView
):
permission_classes
=
(
ApiKeyHeaderPermission
,)
permission_classes
=
(
ApiKeyHeaderPermission
,)
def
post
(
self
,
request
,
user_id
,
format
=
None
):
def
post
(
self
,
request
,
user_id
):
"""
"""
POST creates a new user-group relationship in the system
POST creates a new user-group relationship in the system
"""
"""
...
@@ -320,7 +323,7 @@ class UsersGroupsList(APIView):
...
@@ -320,7 +323,7 @@ class UsersGroupsList(APIView):
response_status
=
status
.
HTTP_404_NOT_FOUND
response_status
=
status
.
HTTP_404_NOT_FOUND
return
Response
(
response_data
,
status
=
response_status
)
return
Response
(
response_data
,
status
=
response_status
)
def
get
(
self
,
request
,
user_id
,
format
=
None
):
def
get
(
self
,
request
,
user_id
):
"""
"""
GET retrieves the list of groups related to the specified user
GET retrieves the list of groups related to the specified user
"""
"""
...
@@ -328,8 +331,10 @@ class UsersGroupsList(APIView):
...
@@ -328,8 +331,10 @@ class UsersGroupsList(APIView):
existing_user
=
User
.
objects
.
get
(
id
=
user_id
)
existing_user
=
User
.
objects
.
get
(
id
=
user_id
)
except
ObjectDoesNotExist
:
except
ObjectDoesNotExist
:
return
Response
({},
status
.
HTTP_404_NOT_FOUND
)
return
Response
({},
status
.
HTTP_404_NOT_FOUND
)
groups
=
existing_user
.
groups
.
all
()
response_data
=
{}
response_data
=
{}
base_uri
=
_generate_base_uri
(
request
)
response_data
[
'uri'
]
=
base_uri
groups
=
existing_user
.
groups
.
all
()
response_data
[
'groups'
]
=
[]
response_data
[
'groups'
]
=
[]
for
group
in
groups
:
for
group
in
groups
:
group_profile
=
GroupProfile
.
objects
.
get
(
group_id
=
group
.
id
)
group_profile
=
GroupProfile
.
objects
.
get
(
group_id
=
group
.
id
)
...
@@ -344,12 +349,11 @@ class UsersGroupsList(APIView):
...
@@ -344,12 +349,11 @@ class UsersGroupsList(APIView):
class
UsersGroupsDetail
(
APIView
):
class
UsersGroupsDetail
(
APIView
):
permission_classes
=
(
ApiKeyHeaderPermission
,)
permission_classes
=
(
ApiKeyHeaderPermission
,)
def
get
(
self
,
request
,
user_id
,
group_id
,
format
=
None
):
def
get
(
self
,
request
,
user_id
,
group_id
):
"""
"""
GET retrieves an existing user-group relationship from the system
GET retrieves an existing user-group relationship from the system
"""
"""
response_data
=
{}
response_data
=
{}
base_uri
=
_generate_base_uri
(
request
)
try
:
try
:
existing_user
=
User
.
objects
.
get
(
id
=
user_id
,
is_active
=
True
)
existing_user
=
User
.
objects
.
get
(
id
=
user_id
,
is_active
=
True
)
existing_relationship
=
existing_user
.
groups
.
get
(
id
=
group_id
)
existing_relationship
=
existing_user
.
groups
.
get
(
id
=
group_id
)
...
@@ -359,13 +363,13 @@ class UsersGroupsDetail(APIView):
...
@@ -359,13 +363,13 @@ class UsersGroupsDetail(APIView):
if
existing_user
and
existing_relationship
:
if
existing_user
and
existing_relationship
:
response_data
[
'user_id'
]
=
existing_user
.
id
response_data
[
'user_id'
]
=
existing_user
.
id
response_data
[
'group_id'
]
=
existing_relationship
.
id
response_data
[
'group_id'
]
=
existing_relationship
.
id
response_data
[
'uri'
]
=
base_uri
response_data
[
'uri'
]
=
_generate_base_uri
(
request
)
response_status
=
status
.
HTTP_200_OK
response_status
=
status
.
HTTP_200_OK
else
:
else
:
response_status
=
status
.
HTTP_404_NOT_FOUND
response_status
=
status
.
HTTP_404_NOT_FOUND
return
Response
(
response_data
,
status
=
response_status
)
return
Response
(
response_data
,
status
=
response_status
)
def
delete
(
self
,
request
,
user_id
,
group_id
,
format
=
None
):
def
delete
(
self
,
request
,
user_id
,
group_id
):
"""
"""
DELETE removes/inactivates/etc. an existing user-group relationship
DELETE removes/inactivates/etc. an existing user-group relationship
"""
"""
...
@@ -378,7 +382,7 @@ class UsersGroupsDetail(APIView):
...
@@ -378,7 +382,7 @@ class UsersGroupsDetail(APIView):
class
UsersCoursesList
(
APIView
):
class
UsersCoursesList
(
APIView
):
permission_classes
=
(
ApiKeyHeaderPermission
,)
permission_classes
=
(
ApiKeyHeaderPermission
,)
def
post
(
self
,
request
,
user_id
,
format
=
None
):
def
post
(
self
,
request
,
user_id
):
"""
"""
POST creates a new course enrollment for a user
POST creates a new course enrollment for a user
"""
"""
...
@@ -404,7 +408,7 @@ class UsersCoursesList(APIView):
...
@@ -404,7 +408,7 @@ class UsersCoursesList(APIView):
status_code
=
status
.
HTTP_404_NOT_FOUND
status_code
=
status
.
HTTP_404_NOT_FOUND
return
Response
(
response_data
,
status
=
status_code
)
return
Response
(
response_data
,
status
=
status_code
)
def
get
(
self
,
request
,
user_id
,
format
=
None
):
def
get
(
self
,
request
,
user_id
):
"""
"""
GET creates the list of enrolled courses for a user
GET creates the list of enrolled courses for a user
"""
"""
...
@@ -435,7 +439,7 @@ class UsersCoursesList(APIView):
...
@@ -435,7 +439,7 @@ class UsersCoursesList(APIView):
class
UsersCoursesDetail
(
APIView
):
class
UsersCoursesDetail
(
APIView
):
permission_classes
=
(
ApiKeyHeaderPermission
,)
permission_classes
=
(
ApiKeyHeaderPermission
,)
def
post
(
self
,
request
,
user_id
,
course_id
,
format
=
None
):
def
post
(
self
,
request
,
user_id
,
course_id
):
"""
"""
POST creates an ACTIVE course enrollment for the specified user
POST creates an ACTIVE course enrollment for the specified user
"""
"""
...
@@ -465,7 +469,7 @@ class UsersCoursesDetail(APIView):
...
@@ -465,7 +469,7 @@ class UsersCoursesDetail(APIView):
response_status
=
status
.
HTTP_404_NOT_FOUND
response_status
=
status
.
HTTP_404_NOT_FOUND
return
Response
(
response_data
,
status
=
response_status
)
return
Response
(
response_data
,
status
=
response_status
)
def
get
(
self
,
request
,
user_id
,
course_id
,
format
=
None
):
def
get
(
self
,
request
,
user_id
,
course_id
):
"""
"""
GET identifies an ACTIVE course enrollment for the specified user
GET identifies an ACTIVE course enrollment for the specified user
"""
"""
...
@@ -495,7 +499,7 @@ class UsersCoursesDetail(APIView):
...
@@ -495,7 +499,7 @@ class UsersCoursesDetail(APIView):
response_status
=
status
.
HTTP_404_NOT_FOUND
response_status
=
status
.
HTTP_404_NOT_FOUND
return
Response
(
response_data
,
status
=
response_status
)
return
Response
(
response_data
,
status
=
response_status
)
def
delete
(
self
,
request
,
user_id
,
course_id
,
format
=
None
):
def
delete
(
self
,
request
,
user_id
,
course_id
):
"""
"""
DELETE unenrolls the specified user from a course
DELETE unenrolls the specified user from a course
"""
"""
...
...
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