예제 #1
0
class JwtHasContentOrgFilterForRequestedCourseTests(TestCase):
    """ Tests for JwtHasContentOrgFilterForRequestedCourse permission class. """
    def setUp(self):
        super().setUp()
        self.user = UserFactory()

    @ddt.data(
        (JwtAuthentication(), ['content_org:edX'], {
            'course_id': 'course-v1:edX+DemoX+Demo_Course'
        }, True),
        (JwtAuthentication(), ['content_org:TestX'], {
            'course_id': 'course-v1:edX+DemoX+Demo_Course'
        }, False),
        (JwtAuthentication(), ['test:TestX'], {
            'course_id': 'course-v1:edX+DemoX+Demo_Course'
        }, False),
        (JwtAuthentication(), [], {
            'course_id': 'course-v1:edX+DemoX+Demo_Course'
        }, False),
        (None, [], {
            'course_id': 'course-v1:edX+DemoX+Demo_Course'
        }, False),
    )
    @ddt.unpack
    def test_has_permission(self, authentication_class, jwt_filters,
                            view_kwargs, expected_result):
        request = RequestFactory().get('/')
        request.successful_authenticator = authentication_class
        request.auth = generate_jwt(self.user, filters=jwt_filters)
        view = Mock(kwargs=view_kwargs)
        self.assertEqual(
            permissions.JwtHasContentOrgFilterForRequestedCourse().
            has_permission(request, view),
            expected_result,
        )
예제 #2
0
    def test_authenticate_credentials_user_attributes_new_mergeable_attributes(
            self):
        """ Test whether the user model is being assigned all custom fields from the payload. """

        username = '******'
        email = '*****@*****.**'
        new_tags = {'browser': 'Chrome'}

        user = factories.UserFactory(email=email,
                                     username=username,
                                     is_staff=False)
        self.assertEqual(user.email, email)
        self.assertFalse(user.is_staff)

        payload = {
            'username': username,
            'email': email,
            'is_staff': True,
            'tags': new_tags
        }

        # Patch get_or_create so that our tags attribute is on the user object
        with mock.patch(
                'edx_rest_framework_extensions.auth.jwt.authentication.get_user_model'
        ) as mock_get_user_model:
            mock_get_user_model().objects.get_or_create.return_value = (user,
                                                                        False)

            user = JwtAuthentication().authenticate_credentials(payload)
        self.assertEqual(user.tags, new_tags)
        self.assertEqual(user.email, email)
        self.assertTrue(user.is_staff)
예제 #3
0
 def test_authenticate_with_incorrect_jwt_authorization(self):
     """ With JWT header it continues and validates the credentials and throws error. """
     auth_header = '{token_name} {token}'.format(token_name='JWT',
                                                 token='wrongvalue')
     request = RequestFactory().get('/', HTTP_AUTHORIZATION=auth_header)
     with self.assertRaises(AuthenticationFailed):
         JwtAuthentication().authenticate(request)
예제 #4
0
    def test_authenticate_credentials_user_creation(self, is_staff):
        """ Test whether the user model is being created and assigned fields from the payload. """

        payload = self.get_jwt_payload(administrator=is_staff)
        user = JwtAuthentication().authenticate_credentials(payload)
        self.assertEqual(user.username, payload['preferred_username'])
        self.assertEqual(user.email, payload['email'])
        self.assertEqual(user.is_staff, is_staff)
예제 #5
0
    def test_authenticate_with_correct_jwt_authorization(self):
        """
        With JWT header it continues and validates the credentials and throws error.

        Note: CSRF protection should be skipped for this case, with no PermissionDenied.
        """
        jwt_token = self._get_test_jwt_token()
        request = RequestFactory().get('/', HTTP_AUTHORIZATION=jwt_token)
        JwtAuthentication().authenticate(request)
예제 #6
0
    def test_authenticate_credentials_user_retrieval_failed(self):
        """ Verify exceptions raised during user retrieval are properly logged. """

        with mock.patch.object(User.objects, 'get_or_create', side_effect=ValueError):
            with mock.patch.object(Logger, 'exception') as logger:
                self.assertRaises(
                    AuthenticationFailed,
                    JwtAuthentication().authenticate_credentials,
                    {'username': '******', 'email': '*****@*****.**'}
                )
                logger.assert_called_with('User retrieval failed.')
예제 #7
0
    def test_authenticate(self):
        """ Verify exceptions raised during authentication are properly logged. """
        request = RequestFactory().get('/')

        with mock.patch.object(JSONWebTokenAuthentication, 'authenticate', side_effect=Exception):
            with mock.patch.object(Logger, 'debug') as logger:
                self.assertRaises(
                    Exception,
                    JwtAuthentication().authenticate,
                    request
                )
                self.assertTrue(logger.called)
예제 #8
0
class JwtHasScopeTests(TestCase):
    """ Tests for JwtHasScope permission class. """
    def setUp(self):
        super().setUp()
        self.user = UserFactory()

    @ddt.data(
        (JwtAuthentication(), ('test:read', ), ('test:read', ), True),  # match
        (JwtAuthentication(), ('test:write'),
         ('test:read', ), False),  # mismatch
        (JwtAuthentication(), ('test:read'), (), False),  # empty on API
        (JwtAuthentication(), ('test:read'), None, False),  # missing on API
        (JwtAuthentication(), (), ('test:read', ), False),  # missing on jwt
        (JwtAuthentication(), (), None, False),  # missing on both
        (None, (), ('test:read'), False),  # no auth
    )
    @ddt.unpack
    def test_has_permission(self, authentication_class, jwt_scopes,
                            required_scopes, expected_result):
        request = RequestFactory().get('/')
        request.successful_authenticator = authentication_class
        request.auth = generate_jwt(self.user, scopes=jwt_scopes)
        if required_scopes is None:
            view = APIView()
        else:
            view = Mock(required_scopes=required_scopes)
        self.assertEqual(
            permissions.JwtHasScope().has_permission(request, view),
            expected_result)
예제 #9
0
    def test_authenticate_credentials_user_attributes_custom_attributes(self):
        """ Test whether the user model is being assigned all custom fields from the payload. """

        username = '******'
        old_email = '*****@*****.**'
        new_email = '*****@*****.**'

        user = factories.UserFactory(email=old_email, username=username, is_staff=False)
        self.assertEqual(user.email, old_email)
        self.assertFalse(user.is_staff)

        payload = {'username': username, 'email': new_email, 'is_staff': True}

        user = JwtAuthentication().authenticate_credentials(payload)
        self.assertEqual(user.email, new_email)
        self.assertTrue(user.is_staff)
예제 #10
0
    def test_authenticate_credentials_user_updates_default_attributes(self):
        """ Test whether the user model is being assigned default fields from the payload. """

        username = '******'
        old_email = '*****@*****.**'
        new_email = '*****@*****.**'

        user = factories.UserFactory(email=old_email, username=username, is_staff=False)
        self.assertEqual(user.email, old_email)
        self.assertFalse(user.is_staff)

        payload = {'username': username, 'email': new_email, 'is_staff': True}

        user = JwtAuthentication().authenticate_credentials(payload)
        self.assertEqual(user.email, new_email)
        self.assertFalse(user.is_staff)
예제 #11
0
    def test_authenticate_csrf_protected(self, mock_set_custom_attribute):
        """ Verify authenticate exception for CSRF protected cases. """
        request = RequestFactory().post('/')

        request.META[USE_JWT_COOKIE_HEADER] = 'true'

        with mock.patch.object(JSONWebTokenAuthentication,
                               'authenticate',
                               return_value=('mock-user', "mock-auth")):
            with self.assertRaises(PermissionDenied) as context_manager:
                JwtAuthentication().authenticate(request)

        assert context_manager.exception.detail.startswith('CSRF Failed')
        mock_set_custom_attribute.assert_called_once_with(
            'jwt_auth_failed',
            "Exception:PermissionDenied('CSRF Failed: CSRF cookie not set.')",
        )
예제 #12
0
    def test_authenticate_credentials_user_attributes_merge_attributes(self):
        """ Test whether the user model is being assigned all custom fields from the payload. """

        username = '******'
        email = '*****@*****.**'
        old_tags = {'country': 'USA', 'browser': 'Firefox'}
        new_tags = {'browser': 'Chrome', 'new_attr': 'here!'}
        new_fun_attr = {'shiny': 'object'}
        expected_tags = {
            'country': 'USA',
            'browser': 'Chrome',
            'new_attr': 'here!'
        }
        old_fruit = {'fruit': 'apple'}

        user = factories.UserFactory(email=email,
                                     username=username,
                                     is_staff=False)
        setattr(user, 'tags', old_tags)
        setattr(user, 'fruit', old_fruit)
        self.assertEqual(user.email, email)
        self.assertFalse(user.is_staff)
        self.assertEqual(user.tags, old_tags)
        self.assertEqual(user.fruit, old_fruit)

        payload = {
            'username': username,
            'email': email,
            'is_staff': True,
            'tags': new_tags,
            'fun_attr': new_fun_attr
        }

        # Patch get_or_create so that our tags attribute is on the user object
        with mock.patch(
                'edx_rest_framework_extensions.auth.jwt.authentication.get_user_model'
        ) as mock_get_user_model:
            mock_get_user_model().objects.get_or_create.return_value = (user,
                                                                        False)

            user = JwtAuthentication().authenticate_credentials(payload)
        self.assertEqual(user.tags, expected_tags)
        self.assertEqual(user.email, email)
        self.assertTrue(user.is_staff)
        self.assertEqual(user.fun_attr, new_fun_attr)
        self.assertEqual(user.fruit, old_fruit)
예제 #13
0
    def test_authenticate_csrf_protected(self):
        """ Verify authenticate exception for CSRF protected cases. """
        request = RequestFactory().post('/')

        request.META[USE_JWT_COOKIE_HEADER] = 'true'

        with mock.patch.object(
                JSONWebTokenAuthentication,
                'authenticate',
                return_value=('mock-user',
                              "mock-auth")):  # noqa E501 line too long
            with mock.patch.object(Logger, 'debug') as debug_logger:
                with self.assertRaises(PermissionDenied) as context_manager:
                    JwtAuthentication().authenticate(request)

        self.assertEqual(context_manager.exception.detail,
                         'CSRF Failed: CSRF cookie not set.')
        self.assertTrue(debug_logger.called)
    def get_authenticators(self):  # pragma: no cover
        """
        Allow users authenticated via OAuth2 or normal session authentication.
        """
        try:
            from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUser
            from openedx.core.lib.api.authentication import SessionAuthenticationAllowInactiveUser
        except ImportError:
            from edx_rest_framework_extensions.auth.session.authentication import SessionAuthenticationAllowInactiveUser

        try:
            from edx_rest_framework_extensions.auth.jwt.authentication import JwtAuthentication
        except ImportError:
            from edx_rest_framework_extensions.authentication import JwtAuthentication

        return [
            JwtAuthentication(),
            OAuth2AuthenticationAllowInactiveUser(),
            SessionAuthenticationAllowInactiveUser(),
        ]
예제 #15
0
    def test_authenticate_csrf_exempt(self, enable_rollout, use_jwt_cookies,
                                      mocked_return_value_user_and_auth):
        """ Verify authenticate success for cases that are CSRF exempt. """
        request = RequestFactory().post('/')
        if use_jwt_cookies:
            request.META[USE_JWT_COOKIE_HEADER] = 'true'

        with mock.patch.object(JSONWebTokenAuthentication,
                               'authenticate',
                               return_value=mocked_return_value_user_and_auth
                               ):  # noqa E501 line too long
            with override_settings(
                    EDX_DRF_EXTENSIONS={
                        ENABLE_ANONYMOUS_ACCESS_ROLLOUT: enable_rollout
                    }):
                actual_user_and_auth = JwtAuthentication().authenticate(
                    request)

        self.assertEqual(mocked_return_value_user_and_auth,
                         actual_user_and_auth)
예제 #16
0
    def test_authenticate_csrf_protected(self, enable_rollout, use_jwt_cookies,
                                         mocked_return_value_user_and_auth):
        """ Verify authenticate exception for CSRF protected cases. """
        request = RequestFactory().post('/')
        if use_jwt_cookies:
            request.META[USE_JWT_COOKIE_HEADER] = 'true'

        with mock.patch.object(JSONWebTokenAuthentication,
                               'authenticate',
                               return_value=mocked_return_value_user_and_auth
                               ):  # noqa E501 line too long
            with override_settings(
                    EDX_DRF_EXTENSIONS={
                        ENABLE_ANONYMOUS_ACCESS_ROLLOUT: enable_rollout
                    }):
                with mock.patch.object(Logger, 'debug') as debug_logger:
                    with self.assertRaises(
                            PermissionDenied) as context_manager:
                        JwtAuthentication().authenticate(request)

        self.assertEqual(context_manager.exception.detail,
                         'CSRF Failed: CSRF cookie not set.')
        self.assertTrue(debug_logger.called)
예제 #17
0
 def test_authenticate_credentials_no_usernames(self):
     """ Verify an AuthenticationFailed exception is raised if the payload contains no username claim. """
     with self.assertRaises(AuthenticationFailed):
         JwtAuthentication().authenticate_credentials(
             {'email': '*****@*****.**'})
예제 #18
0
 def test_authenticate_with_bearer_token(self):
     """ Returns a None for bearer header request. """
     auth_header = '{token_name} {token}'.format(token_name='Bearer',
                                                 token='abc123')
     request = RequestFactory().get('/', HTTP_AUTHORIZATION=auth_header)
     self.assertIsNone(JwtAuthentication().authenticate(request))