Remove ThirdPartyAuthProviderApiPermission (#23195)

* Remove ThirdPartyAuthProviderApiPermission

Also removed ProviderApiPermissions and ApiPermissionsAdminForm and removal of DOP for third_party_auth

* Removing model

* Replaced long_token with default_token_generator

* Adding skip to test_migrations_are_in_sync
This commit is contained in:
Manjinder Singh
2020-02-27 15:42:09 -05:00
committed by GitHub
parent 5cce110a91
commit 953b0e728b
8 changed files with 36 additions and 173 deletions

View File

@@ -4,7 +4,6 @@ Third party auth API related permissions
import logging
from edx_django_utils.monitoring import set_custom_metric
from edx_rest_framework_extensions.auth.jwt.decoder import decode_jwt_filters
from edx_rest_framework_extensions.permissions import (
IsSuperuser,
@@ -14,39 +13,12 @@ from edx_rest_framework_extensions.permissions import (
)
from rest_condition import C
from rest_framework.permissions import BasePermission
from third_party_auth.models import ProviderApiPermissions
from openedx.core.lib.api.permissions import ApiKeyHeaderPermission
log = logging.getLogger(__name__)
class ThirdPartyAuthProviderApiPermission(BasePermission):
"""
Allow someone to access the view if they have valid OAuth client credential.
Deprecated: Only works for DOP oauth applications. To be removed as part of DOPrecation.
"""
def has_permission(self, request, view):
"""
Check if the OAuth client associated with auth token in current request has permission to access
the information for provider
"""
provider_id = view.kwargs.get('provider_id')
if not request.auth or not provider_id:
# doesn't have access token or no provider_id specified
return False
try:
ProviderApiPermissions.objects.get(client__pk=request.auth.client_id, provider_id=provider_id)
except ProviderApiPermissions.DoesNotExist:
return False
set_custom_metric('deprecated_ThirdPartyAuthProviderApiPermission', True)
return True
class JwtHasTpaProviderFilterForRequestedProvider(BasePermission):
"""
Ensures the JWT used to authenticate contains the appropriate tpa_provider
@@ -79,7 +51,7 @@ class JwtHasTpaProviderFilterForRequestedProvider(BasePermission):
# TODO: Remove ApiKeyHeaderPermission. Check deprecated_api_key_header custom metric for active usage.
_NOT_JWT_RESTRICTED_TPA_PERMISSIONS = (
C(NotJwtRestrictedApplication) &
(C(IsSuperuser) | ApiKeyHeaderPermission | ThirdPartyAuthProviderApiPermission)
(C(IsSuperuser) | ApiKeyHeaderPermission)
)
_JWT_RESTRICTED_TPA_PERMISSIONS = (
C(JwtRestrictedApplication) &

View File

@@ -10,58 +10,18 @@ from django.conf import settings
from django.test import RequestFactory, TestCase
from edx_rest_framework_extensions.auth.jwt.authentication import JwtAuthentication
from edx_rest_framework_extensions.auth.jwt.tests.utils import generate_jwt
from mock import Mock, patch
from mock import patch
from rest_framework.authentication import SessionAuthentication
from rest_framework.response import Response
from rest_framework.test import APITestCase
from rest_framework.views import APIView
from student.tests.factories import UserFactory
from third_party_auth.api.permissions import ThirdPartyAuthProviderApiPermission, TPA_PERMISSIONS
from third_party_auth.tests.testutil import ThirdPartyAuthTestMixin
from third_party_auth.api.permissions import TPA_PERMISSIONS
IDP_SLUG_TESTSHIB = 'testshib'
PROVIDER_ID_TESTSHIB = 'saml-' + IDP_SLUG_TESTSHIB
@ddt.ddt
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
class ThirdPartyAuthApiPermissionTest(ThirdPartyAuthTestMixin, APITestCase):
""" Tests for third party auth API permission """
@ddt.data(
(1, PROVIDER_ID_TESTSHIB, True),
(1, 'invalid-provider-id', False),
(999, PROVIDER_ID_TESTSHIB, False),
(999, 'invalid-provider-id', False),
(1, None, False),
)
@ddt.unpack
def test_api_permission(self, client_pk, provider_id, expect):
dop_client = self.configure_oauth_dop_client()
self.configure_api_permission(dop_client, PROVIDER_ID_TESTSHIB)
request = Mock()
request.auth = Mock()
request.auth.client_id = client_pk
view = Mock(kwargs={'provider_id': provider_id})
result = ThirdPartyAuthProviderApiPermission().has_permission(request, view)
self.assertEqual(result, expect)
def test_api_permission_unauthorized_client(self):
dop_client = self.configure_oauth_dop_client()
self.configure_api_permission(dop_client, 'saml-anotherprovider')
request = Mock()
request.auth = Mock()
request.auth.client_id = dop_client.pk
view = Mock(kwargs={'provider_id': PROVIDER_ID_TESTSHIB})
result = ThirdPartyAuthProviderApiPermission().has_permission(request, view)
self.assertEqual(result, False)
@ddt.ddt
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
class ThirdPartyAuthPermissionTest(TestCase):

View File

@@ -12,20 +12,16 @@ from django.http import QueryDict
from django.test.utils import override_settings
from django.urls import reverse
from mock import patch
from provider.constants import CONFIDENTIAL
from provider.oauth2.models import AccessToken, Client
from rest_framework.test import APITestCase
from six.moves import range
from social_django.models import UserSocialAuth
from openedx.core.lib.api.permissions import ApiKeyHeaderPermission
from student.tests.factories import UserFactory
from third_party_auth.api.permissions import ThirdPartyAuthProviderApiPermission
from third_party_auth.models import ProviderApiPermissions
from third_party_auth.tests.testutil import ThirdPartyAuthTestMixin
from third_party_auth.api.permissions import (JwtRestrictedApplication,
JwtHasScope,
JwtHasTpaProviderFilterForRequestedProvider)
from edx_rest_framework_extensions.auth.jwt.tests.utils import generate_jwt
VALID_API_KEY = "i am a key"
IDP_SLUG_TESTSHIB = 'testshib'
@@ -247,25 +243,29 @@ class UserMappingViewAPITests(TpaAPITestCase):
response = self.client.get(url, HTTP_X_EDX_API_KEY=api_key)
self._verify_response(response, expect_code, expect_data)
def _create_jwt_header(self, user, is_restricted=False, scopes=None, filters=None):
token = generate_jwt(user, is_restricted=is_restricted, scopes=scopes, filters=filters)
return "JWT {}".format(token)
@ddt.data(
(PROVIDER_ID_TESTSHIB, 'valid-token', 200, get_mapping_data_by_usernames(LINKED_USERS)),
('non-existing-id', 'valid-token', 404, []),
(PROVIDER_ID_TESTSHIB, 'invalid-token', 401, []),
(True, 200, get_mapping_data_by_usernames(LINKED_USERS)),
(False, 401, []),
)
@ddt.unpack
def test_list_all_user_mappings_oauth2(self, provider_id, access_token, expect_code, expect_data):
url = reverse('third_party_auth_user_mapping_api', kwargs={'provider_id': provider_id})
def test_list_all_user_mappings_oauth2(self, valid_call, expect_code, expect_data):
url = reverse('third_party_auth_user_mapping_api', kwargs={'provider_id': PROVIDER_ID_TESTSHIB})
provider_filter = 'tpa_provider:' + PROVIDER_ID_TESTSHIB
filters = [provider_filter, 'tpa_provider:another_tpa_provider']
# create oauth2 auth data
user = UserFactory.create(username='api_user')
client = Client.objects.create(name='oauth2_client', client_type=CONFIDENTIAL)
token = AccessToken.objects.create(user=user, client=client)
ProviderApiPermissions.objects.create(client=client, provider_id=provider_id)
if access_token == 'valid-token':
access_token = token.token
response = self.client.get(url, HTTP_AUTHORIZATION=u'Bearer {}'.format(access_token))
self._verify_response(response, expect_code, expect_data)
if valid_call:
auth_header = self._create_jwt_header(user, is_restricted=True, scopes=['tpa:read'], filters=filters)
else:
auth_header = ''
with patch('edx_rest_framework_extensions.permissions.waffle.switch_is_active') as mock_toggle:
mock_toggle.return_value = True
response = self.client.get(url, HTTP_AUTHORIZATION=auth_header)
self._verify_response(response, expect_code, expect_data)
@ddt.data(
({'username': [ALICE_USERNAME, STAFF_USERNAME]}, 200,
@@ -335,20 +335,6 @@ class UserMappingViewAPITests(TpaAPITestCase):
self.assertEqual(response.status_code, 200)
self._verify_response(response, 200, get_mapping_data_by_usernames(LINKED_USERS))
@ddt.data(
(True, True, 200),
(False, True, 200),
(True, False, 200),
(False, False, 401)
)
@ddt.unpack
def test_user_mapping_permission_logic(self, api_key_permission, token_permission, expect):
url = reverse('third_party_auth_user_mapping_api', kwargs={'provider_id': PROVIDER_ID_TESTSHIB})
with patch.object(ApiKeyHeaderPermission, 'has_permission', return_value=api_key_permission):
with patch.object(ThirdPartyAuthProviderApiPermission, 'has_permission', return_value=token_permission):
response = self.client.get(url)
self.assertEqual(response.status_code, expect)
@ddt.data(
(True, 200),
(False, 401),