Commit 531ed418 by Clinton Blackburn

Updated the Credit API to support JWT authentication

parent 1e9649e0
...@@ -5,30 +5,31 @@ Tests for credit app views. ...@@ -5,30 +5,31 @@ Tests for credit app views.
# pylint: disable=no-member # pylint: disable=no-member
from __future__ import unicode_literals from __future__ import unicode_literals
import datetime import datetime
import json import json
from nose.plugins.attrib import attr
import unittest import unittest
import ddt import ddt
import pytz
from django.conf import settings from django.conf import settings
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.test import TestCase, Client from django.test import TestCase, Client
from django.test.utils import override_settings from django.test.utils import override_settings
from edx_oauth2_provider.tests.factories import AccessTokenFactory, ClientFactory from edx_oauth2_provider.tests.factories import AccessTokenFactory, ClientFactory
from nose.plugins.attrib import attr
from opaque_keys.edx.keys import CourseKey from opaque_keys.edx.keys import CourseKey
import pytz
from openedx.core.djangoapps.credit.signature import signature from openedx.core.djangoapps.credit.models import (
CreditCourse, CreditProvider, CreditRequest, CreditRequirement, CreditRequirementStatus,
)
from openedx.core.djangoapps.credit.serializers import CreditProviderSerializer, CreditEligibilitySerializer from openedx.core.djangoapps.credit.serializers import CreditProviderSerializer, CreditEligibilitySerializer
from openedx.core.djangoapps.credit.signature import signature
from openedx.core.djangoapps.credit.tests.factories import ( from openedx.core.djangoapps.credit.tests.factories import (
CreditProviderFactory, CreditProviderFactory, CreditEligibilityFactory, CreditCourseFactory, CreditRequestFactory,
CreditEligibilityFactory, )
CreditCourseFactory, CreditRequestFactory) from openedx.core.lib.token_utils import JwtBuilder
from student.tests.factories import UserFactory, AdminFactory from student.tests.factories import UserFactory, AdminFactory
from openedx.core.djangoapps.credit.models import (
CreditCourse,
CreditProvider, CreditRequest, CreditRequirement, CreditRequirementStatus)
from util.date_utils import to_timestamp from util.date_utils import to_timestamp
JSON = 'application/json' JSON = 'application/json'
...@@ -87,6 +88,18 @@ class AuthMixin(object): ...@@ -87,6 +88,18 @@ class AuthMixin(object):
response = self.client.get(self.path) response = self.client.get(self.path)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
def test_jwt_auth(self):
""" verify the endpoints JWT authentication. """
scopes = ['email', 'profile']
expires_in = settings.OAUTH_ID_TOKEN_EXPIRATION
token = JwtBuilder(self.user).build_token(scopes, expires_in)
headers = {
'HTTP_AUTHORIZATION': 'JWT ' + token
}
self.client.logout()
response = self.client.get(self.path, **headers)
self.assertEqual(response.status_code, 200)
@ddt.ddt @ddt.ddt
class ReadOnlyMixin(object): class ReadOnlyMixin(object):
...@@ -101,7 +114,7 @@ class ReadOnlyMixin(object): ...@@ -101,7 +114,7 @@ class ReadOnlyMixin(object):
@attr(shard=2) @attr(shard=2)
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms') @unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
class CreditCourseViewSetTests(UserMixin, TestCase): class CreditCourseViewSetTests(AuthMixin, UserMixin, TestCase):
""" Tests for the CreditCourse endpoints. """ Tests for the CreditCourse endpoints.
GET/POST /api/v1/credit/creditcourse/ GET/POST /api/v1/credit/creditcourse/
......
...@@ -2,15 +2,17 @@ ...@@ -2,15 +2,17 @@
Views for the credit Django app. Views for the credit Django app.
""" """
from __future__ import unicode_literals from __future__ import unicode_literals
import logging
import datetime import datetime
import logging
import pytz
from django.conf import settings from django.conf import settings
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt
from edx_rest_framework_extensions.authentication import JwtAuthentication
from opaque_keys import InvalidKeyError from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey from opaque_keys.edx.keys import CourseKey
import pytz
from rest_framework import viewsets, mixins, permissions, views, generics from rest_framework import viewsets, mixins, permissions, views, generics
from rest_framework.authentication import SessionAuthentication from rest_framework.authentication import SessionAuthentication
from rest_framework.exceptions import ValidationError from rest_framework.exceptions import ValidationError
...@@ -18,16 +20,22 @@ from rest_framework.response import Response ...@@ -18,16 +20,22 @@ from rest_framework.response import Response
from rest_framework_oauth.authentication import OAuth2Authentication from rest_framework_oauth.authentication import OAuth2Authentication
from openedx.core.djangoapps.credit.api import create_credit_request from openedx.core.djangoapps.credit.api import create_credit_request
from openedx.core.djangoapps.credit.exceptions import (UserNotEligibleException, InvalidCourseKey, CreditApiBadRequest, from openedx.core.djangoapps.credit.exceptions import (
InvalidCreditRequest) UserNotEligibleException, InvalidCourseKey, CreditApiBadRequest, InvalidCreditRequest,
from openedx.core.djangoapps.credit.models import (CreditCourse, CreditProvider, CREDIT_PROVIDER_ID_REGEX, )
CreditEligibility, CreditRequest) from openedx.core.djangoapps.credit.models import (
from openedx.core.djangoapps.credit.serializers import (CreditCourseSerializer, CreditProviderSerializer, CreditCourse, CreditProvider, CREDIT_PROVIDER_ID_REGEX,
CreditEligibilitySerializer, CreditProviderCallbackSerializer) CreditEligibility, CreditRequest,
)
from openedx.core.djangoapps.credit.serializers import (
CreditCourseSerializer, CreditProviderSerializer,
CreditEligibilitySerializer, CreditProviderCallbackSerializer,
)
from openedx.core.lib.api.mixins import PutAsCreateMixin from openedx.core.lib.api.mixins import PutAsCreateMixin
from openedx.core.lib.api.permissions import IsStaffOrOwner from openedx.core.lib.api.permissions import IsStaffOrOwner
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
AUTHENTICATION_CLASSES = (JwtAuthentication, OAuth2Authentication, SessionAuthentication,)
class CreditProviderViewSet(viewsets.ReadOnlyModelViewSet): class CreditProviderViewSet(viewsets.ReadOnlyModelViewSet):
...@@ -35,7 +43,7 @@ class CreditProviderViewSet(viewsets.ReadOnlyModelViewSet): ...@@ -35,7 +43,7 @@ class CreditProviderViewSet(viewsets.ReadOnlyModelViewSet):
lookup_field = 'provider_id' lookup_field = 'provider_id'
lookup_value_regex = CREDIT_PROVIDER_ID_REGEX lookup_value_regex = CREDIT_PROVIDER_ID_REGEX
authentication_classes = (OAuth2Authentication, SessionAuthentication,) authentication_classes = AUTHENTICATION_CLASSES
pagination_class = None pagination_class = None
permission_classes = (permissions.IsAuthenticated,) permission_classes = (permissions.IsAuthenticated,)
queryset = CreditProvider.objects.all() queryset = CreditProvider.objects.all()
...@@ -57,7 +65,7 @@ class CreditProviderViewSet(viewsets.ReadOnlyModelViewSet): ...@@ -57,7 +65,7 @@ class CreditProviderViewSet(viewsets.ReadOnlyModelViewSet):
class CreditProviderRequestCreateView(views.APIView): class CreditProviderRequestCreateView(views.APIView):
""" Creates a credit request for the given user and course, if the user is eligible for credit.""" """ Creates a credit request for the given user and course, if the user is eligible for credit."""
authentication_classes = (OAuth2Authentication, SessionAuthentication,) authentication_classes = AUTHENTICATION_CLASSES
permission_classes = (permissions.IsAuthenticated, IsStaffOrOwner,) permission_classes = (permissions.IsAuthenticated, IsStaffOrOwner,)
def post(self, request, provider_id): def post(self, request, provider_id):
...@@ -127,7 +135,7 @@ class CreditProviderCallbackView(views.APIView): ...@@ -127,7 +135,7 @@ class CreditProviderCallbackView(views.APIView):
class CreditEligibilityView(generics.ListAPIView): class CreditEligibilityView(generics.ListAPIView):
""" Returns eligibility for a user-course combination. """ """ Returns eligibility for a user-course combination. """
authentication_classes = (OAuth2Authentication, SessionAuthentication,) authentication_classes = AUTHENTICATION_CLASSES
pagination_class = None pagination_class = None
permission_classes = (permissions.IsAuthenticated, IsStaffOrOwner) permission_classes = (permissions.IsAuthenticated, IsStaffOrOwner)
serializer_class = CreditEligibilitySerializer serializer_class = CreditEligibilitySerializer
...@@ -161,7 +169,7 @@ class CreditCourseViewSet(PutAsCreateMixin, mixins.UpdateModelMixin, viewsets.Re ...@@ -161,7 +169,7 @@ class CreditCourseViewSet(PutAsCreateMixin, mixins.UpdateModelMixin, viewsets.Re
lookup_value_regex = settings.COURSE_KEY_REGEX lookup_value_regex = settings.COURSE_KEY_REGEX
queryset = CreditCourse.objects.all() queryset = CreditCourse.objects.all()
serializer_class = CreditCourseSerializer serializer_class = CreditCourseSerializer
authentication_classes = (OAuth2Authentication, SessionAuthentication,) authentication_classes = AUTHENTICATION_CLASSES
permission_classes = (permissions.IsAuthenticated, permissions.IsAdminUser) permission_classes = (permissions.IsAuthenticated, permissions.IsAdminUser)
# In Django Rest Framework v3, there is a default pagination # In Django Rest Framework v3, there is a default pagination
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment