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
3a6167d6
Unverified
Commit
3a6167d6
authored
May 05, 2016
by
Giovanni Di Milia
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Authentication and Authorization for Cert Rest APIs fixed
parent
18cddf6e
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 @
3a6167d6
"""
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 @
3a6167d6
...
...
@@ -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