From 2a55af216375448d6d1c733f3f5059a74aa0eba6 Mon Sep 17 00:00:00 2001 From: Renzo Lucioni Date: Tue, 16 Feb 2016 14:56:41 -0500 Subject: [PATCH] Add support for OAuth2 authentication --- .travis.yml | 1 - organizations/v0/tests/test_views.py | 29 ++++++++++++++++++++++++++-- organizations/v0/views.py | 3 ++- settings.py | 2 ++ setup.py | 4 +++- 5 files changed, 34 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index bb2de93b..83b46232 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,4 +29,3 @@ deploy: on: tags: true repo: edx/edx-organizations - diff --git a/organizations/v0/tests/test_views.py b/organizations/v0/tests/test_views.py index b1ed1503..f5b4c268 100644 --- a/organizations/v0/tests/test_views.py +++ b/organizations/v0/tests/test_views.py @@ -3,6 +3,8 @@ """ from django.test import TestCase from django.core.urlresolvers import reverse +from provider.constants import CONFIDENTIAL +from provider.oauth2.models import AccessToken, Client from organizations.serializers import OrganizationSerializer from organizations.tests.factories import UserFactory, OrganizationFactory @@ -25,10 +27,10 @@ def _get_organization_url(self, organization): return reverse('v0:organization-detail', kwargs={'short_name': organization.short_name}) def test_authentication_required(self): - """ Verify that the authentication is required to access view.""" + """ Verify that authentication is required to access view.""" self.client.logout() response = self.client.get(self.organization_list_url) - self.assertEqual(response.status_code, 403) + self.assertEqual(response.status_code, 401) def test_authenticated_user(self): """ Verify that the authenticated user gets data.""" @@ -56,3 +58,26 @@ def test_nonexistent_organization(self): url = reverse('v0:organization-detail', kwargs={'short_name': 'dummy'}) response = self.client.get(url) self.assertEqual(response.status_code, 404) + + def test_oauth2(self): + """Verify that the API can handle OAuth 2.0 access tokens.""" + oauth2_client = Client.objects.create(client_type=CONFIDENTIAL) + access_token = AccessToken.objects.create( + token='fake-access-token', + client=oauth2_client, + user=self.user, + ) + + self.client.logout() + + response = self.client.get( + self.organization_list_url, + HTTP_AUTHORIZATION='Bearer {}'.format(access_token) + ) + self.assertEqual(response.status_code, 200) + + response = self.client.get( + self.organization_list_url, + HTTP_AUTHORIZATION='Bearer {}'.format('nonexistent-access-token') + ) + self.assertEqual(response.status_code, 401) diff --git a/organizations/v0/views.py b/organizations/v0/views.py index 4f4365c9..e80e0804 100644 --- a/organizations/v0/views.py +++ b/organizations/v0/views.py @@ -6,6 +6,7 @@ from rest_framework.authentication import SessionAuthentication from rest_framework.permissions import IsAuthenticated from rest_framework_jwt.authentication import JSONWebTokenAuthentication +from rest_framework_oauth.authentication import OAuth2Authentication from organizations.models import Organization from organizations.serializers import OrganizationSerializer @@ -18,5 +19,5 @@ class OrganizationsViewSet(viewsets.ReadOnlyModelViewSet): queryset = Organization.objects.filter(active=True) # pylint: disable=no-member serializer_class = OrganizationSerializer lookup_field = 'short_name' - authentication_classes = (SessionAuthentication, JSONWebTokenAuthentication,) + authentication_classes = (OAuth2Authentication, JSONWebTokenAuthentication, SessionAuthentication) permission_classes = (IsAuthenticated,) diff --git a/settings.py b/settings.py index f9899928..4225d7af 100644 --- a/settings.py +++ b/settings.py @@ -23,6 +23,8 @@ 'organizations', 'django_nose', + + 'provider.oauth2', ) MIDDLEWARE_CLASSES = ( diff --git a/setup.py b/setup.py index 8227d55d..1da5dc81 100755 --- a/setup.py +++ b/setup.py @@ -4,7 +4,7 @@ setup( name='edx-organizations', - version='0.3.1', + version='0.4.0', description='Organization management module for Open edX', long_description=open('README.rst').read(), author='edX', @@ -26,5 +26,7 @@ 'djangorestframework>=3.2.0,<3.4.0', 'djangorestframework-jwt>=1.6.0,<=1.7.2', 'edx-opaque-keys>=0.1.2,<1.0.0', + 'djangorestframework-oauth>=1.1.0,<2.0.0', + 'edx-django-oauth2-provider>=0.5.0,<1.0.0', ], )