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
8855f127
Commit
8855f127
authored
May 23, 2016
by
Clinton Blackburn
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #12435 from mitocw/gdm_certificates_api_key
Authentication and Authorization for Cert Rest APIs fixed
parents
21ff5f4e
3a6167d6
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
88 additions
and
13 deletions
+88
-13
lms/djangoapps/certificates/apis/v0/tests/test_views.py
+75
-8
lms/djangoapps/certificates/apis/v0/views.py
+13
-5
No files found.
lms/djangoapps/certificates/apis/v0/tests/test_views.py
View file @
8855f127
"""
Tests for the Certificate REST APIs.
"""
from
datetime
import
datetime
,
timedelta
from
django.core.urlresolvers
import
reverse
from
oauth2_provider
import
models
as
dot_models
from
rest_framework
import
status
from
rest_framework.test
import
APITestCase
...
...
@@ -12,6 +15,8 @@ from student.tests.factories import UserFactory
from
xmodule.modulestore.tests.django_utils
import
SharedModuleStoreTestCase
from
xmodule.modulestore.tests.factories
import
CourseFactory
USER_PASSWORD
=
'test'
class
CertificatesRestApiTest
(
SharedModuleStoreTestCase
,
APITestCase
):
"""
...
...
@@ -29,9 +34,9 @@ class CertificatesRestApiTest(SharedModuleStoreTestCase, APITestCase):
def
setUp
(
self
):
super
(
CertificatesRestApiTest
,
self
)
.
setUp
()
self
.
student
=
UserFactory
.
create
(
password
=
'test'
)
self
.
student_no_cert
=
UserFactory
.
create
(
password
=
'test'
)
self
.
staff_user
=
UserFactory
.
create
(
password
=
'test'
,
is_staff
=
True
)
self
.
student
=
UserFactory
.
create
(
password
=
USER_PASSWORD
)
self
.
student_no_cert
=
UserFactory
.
create
(
password
=
USER_PASSWORD
)
self
.
staff_user
=
UserFactory
.
create
(
password
=
USER_PASSWORD
,
is_staff
=
True
)
GeneratedCertificateFactory
.
create
(
user
=
self
.
student
,
...
...
@@ -44,6 +49,23 @@ class CertificatesRestApiTest(SharedModuleStoreTestCase, APITestCase):
self
.
namespaced_url
=
'certificates_api:v0:certificates:detail'
# create a configuration for django-oauth-toolkit (DOT)
dot_app_user
=
UserFactory
.
create
(
password
=
USER_PASSWORD
)
dot_app
=
dot_models
.
Application
.
objects
.
create
(
name
=
'test app'
,
user
=
dot_app_user
,
client_type
=
'confidential'
,
authorization_grant_type
=
'authorization-code'
,
redirect_uris
=
'http://localhost:8079/complete/edxorg/'
)
self
.
dot_access_token
=
dot_models
.
AccessToken
.
objects
.
create
(
user
=
self
.
student
,
application
=
dot_app
,
expires
=
datetime
.
utcnow
()
+
timedelta
(
weeks
=
1
),
scope
=
'read write'
,
token
=
'16MGyP3OaQYHmpT1lK7Q6MMNAZsjwF'
)
def
get_url
(
self
,
username
):
"""
Helper function to create the url for certificates
...
...
@@ -56,6 +78,15 @@ class CertificatesRestApiTest(SharedModuleStoreTestCase, APITestCase):
}
)
def
assert_oauth_status
(
self
,
access_token
,
expected_status
):
"""
Helper method for requests with OAUTH token
"""
self
.
client
.
logout
()
auth_header
=
"Bearer {0}"
.
format
(
access_token
)
response
=
self
.
client
.
get
(
self
.
get_url
(
self
.
student
.
username
),
HTTP_AUTHORIZATION
=
auth_header
)
self
.
assertEqual
(
response
.
status_code
,
expected_status
)
def
test_permissions
(
self
):
"""
Test that only the owner of the certificate can access the url
...
...
@@ -65,7 +96,7 @@ class CertificatesRestApiTest(SharedModuleStoreTestCase, APITestCase):
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_401_UNAUTHORIZED
)
# another student
self
.
client
.
login
(
username
=
self
.
student_no_cert
.
username
,
password
=
'test'
)
self
.
client
.
login
(
username
=
self
.
student_no_cert
.
username
,
password
=
USER_PASSWORD
)
resp
=
self
.
client
.
get
(
self
.
get_url
(
self
.
student
.
username
))
# gets 404 instead of 403 for security reasons
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_404_NOT_FOUND
)
...
...
@@ -73,21 +104,57 @@ class CertificatesRestApiTest(SharedModuleStoreTestCase, APITestCase):
self
.
client
.
logout
()
# same student of the certificate
self
.
client
.
login
(
username
=
self
.
student
.
username
,
password
=
'test'
)
self
.
client
.
login
(
username
=
self
.
student
.
username
,
password
=
USER_PASSWORD
)
resp
=
self
.
client
.
get
(
self
.
get_url
(
self
.
student
.
username
))
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_200_OK
)
self
.
client
.
logout
()
# staff user
self
.
client
.
login
(
username
=
self
.
staff_user
.
username
,
password
=
'test'
)
self
.
client
.
login
(
username
=
self
.
staff_user
.
username
,
password
=
USER_PASSWORD
)
resp
=
self
.
client
.
get
(
self
.
get_url
(
self
.
student
.
username
))
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_200_OK
)
def
test_inactive_user_access
(
self
):
"""
Verify inactive users - those who have not verified their email addresses -
are allowed to access the endpoint.
"""
self
.
client
.
login
(
username
=
self
.
student
.
username
,
password
=
USER_PASSWORD
)
self
.
student
.
is_active
=
False
self
.
student
.
save
()
resp
=
self
.
client
.
get
(
self
.
get_url
(
self
.
student
.
username
))
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_200_OK
)
def
test_dot_valid_accesstoken
(
self
):
"""
Verify access with a valid Django Oauth Toolkit access token.
"""
self
.
assert_oauth_status
(
self
.
dot_access_token
,
status
.
HTTP_200_OK
)
def
test_dot_invalid_accesstoken
(
self
):
"""
Verify the endpoint is inaccessible for authorization
attempts made with an invalid OAuth access token.
"""
self
.
assert_oauth_status
(
"fooooooooooToken"
,
status
.
HTTP_401_UNAUTHORIZED
)
def
test_dot_expired_accesstoken
(
self
):
"""
Verify the endpoint is inaccessible for authorization
attempts made with an expired OAuth access token.
"""
# set the expiration date in the past
self
.
dot_access_token
.
expires
=
datetime
.
utcnow
()
-
timedelta
(
weeks
=
1
)
self
.
dot_access_token
.
save
()
self
.
assert_oauth_status
(
self
.
dot_access_token
,
status
.
HTTP_401_UNAUTHORIZED
)
def
test_no_certificate_for_user
(
self
):
"""
Test for case with no certificate available
"""
self
.
client
.
login
(
username
=
self
.
student_no_cert
.
username
,
password
=
'test'
)
self
.
client
.
login
(
username
=
self
.
student_no_cert
.
username
,
password
=
USER_PASSWORD
)
resp
=
self
.
client
.
get
(
self
.
get_url
(
self
.
student_no_cert
.
username
))
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_404_NOT_FOUND
)
self
.
assertIn
(
'error_code'
,
resp
.
data
)
# pylint: disable=no-member
...
...
@@ -100,7 +167,7 @@ class CertificatesRestApiTest(SharedModuleStoreTestCase, APITestCase):
"""
Tests case user that pulls her own certificate
"""
self
.
client
.
login
(
username
=
self
.
student
.
username
,
password
=
'test'
)
self
.
client
.
login
(
username
=
self
.
student
.
username
,
password
=
USER_PASSWORD
)
resp
=
self
.
client
.
get
(
self
.
get_url
(
self
.
student
.
username
))
self
.
assertEqual
(
resp
.
status_code
,
status
.
HTTP_200_OK
)
self
.
assertEqual
(
...
...
lms/djangoapps/certificates/apis/v0/views.py
View file @
8855f127
...
...
@@ -3,14 +3,16 @@ import logging
from
opaque_keys
import
InvalidKeyError
from
opaque_keys.edx.keys
import
CourseKey
from
rest_framework.authentication
import
SessionAuthentication
from
rest_framework.generics
import
GenericAPIView
from
rest_framework.permissions
import
IsAuthenticated
from
rest_framework.response
import
Response
from
rest_framework_oauth.authentication
import
OAuth2Authentication
from
lms.djangoapps.certificates.api
import
get_certificate_for_user
from
openedx.core.lib.api
import
permissions
from
openedx.core.lib.api
import
(
authentication
,
permissions
,
)
log
=
logging
.
getLogger
(
__name__
)
...
...
@@ -64,8 +66,14 @@ class CertificatesDetailView(GenericAPIView):
}
"""
authentication_classes
=
(
OAuth2Authentication
,
SessionAuthentication
,)
permission_classes
=
(
IsAuthenticated
,
permissions
.
IsUserInUrlOrStaff
)
authentication_classes
=
(
authentication
.
OAuth2AuthenticationAllowInactiveUser
,
authentication
.
SessionAuthenticationAllowInactiveUser
,
)
permission_classes
=
(
IsAuthenticated
,
permissions
.
IsUserInUrlOrStaff
)
def
get
(
self
,
request
,
username
,
course_id
):
"""
...
...
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