def setUp(self):
     self.csrf_client = APIClient(enforce_csrf_checks=True)
     self.username = '******'
     self.email = '*****@*****.**'
     self.password = '******'
     self.user = User.objects.create_user(self.username, self.email,
                                          self.password)
    def test_refresh_jwt(self):
        """
        Test getting a refreshed token from original token works

        No date/time modifications are neccessary because it is assumed
        that this operation will take less than 300 seconds.
        """
        client = APIClient(enforce_csrf_checks=True)
        orig_token = self.get_token()
        orig_token_decoded = utils.jwt_decode_handler(orig_token)

        expected_orig_iat = timegm(datetime.utcnow().utctimetuple())

        # Make sure 'orig_iat' exists and is the current time (give some slack)
        orig_iat = orig_token_decoded['orig_iat']
        self.assertLessEqual(orig_iat - expected_orig_iat, 1)

        time.sleep(1)

        # Now try to get a refreshed token
        response = client.post('/auth-token-refresh/', {'token': orig_token},
                               format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        new_token = response.data['token']
        new_token_decoded = utils.jwt_decode_handler(new_token)

        # Make sure 'orig_iat' on the new token is same as original
        self.assertEquals(new_token_decoded['orig_iat'], orig_iat)
        self.assertGreater(new_token_decoded['exp'], orig_token_decoded['exp'])
 def test_token_login_form(self):
     """Ensure token login view using form POST works."""
     client = APIClient(enforce_csrf_checks=True)
     response = client.post('/auth-token/', {
         'username': self.username,
         'password': self.password
     })
     assert response.status_code == status.HTTP_200_OK
     assert response.data['token'] == self.key
    def setUp(self):
        self.csrf_client = APIClient(enforce_csrf_checks=True)
        self.username = '******'
        self.email = '*****@*****.**'
        self.password = '******'
        self.user = User.objects.create_user(self.username, self.email,
                                             self.password)

        self.key = 'abcd1234'
        self.token = self.model.objects.create(key=self.key, user=self.user)
    def test_jwt_login_json_missing_fields(self):
        """
        Ensure JWT login view using JSON POST fails if missing fields.
        """
        client = APIClient(enforce_csrf_checks=True)

        response = client.post('/auth-token/', {'username': self.username},
                               format='json')

        self.assertEqual(response.status_code, 400)
class DropdownWithAuthTests(TestCase):
    """Tests correct dropdown behaviour with Auth views enabled."""
    def setUp(self):
        self.client = APIClient(enforce_csrf_checks=True)
        self.username = '******'
        self.email = '*****@*****.**'
        self.password = '******'
        self.user = User.objects.create_user(self.username, self.email,
                                             self.password)

    def tearDown(self):
        self.client.logout()

    def test_name_shown_when_logged_in(self):
        self.client.login(username=self.username, password=self.password)
        response = self.client.get('/')
        content = response.content.decode('utf8')
        assert 'john' in content

    def test_logout_shown_when_logged_in(self):
        self.client.login(username=self.username, password=self.password)
        response = self.client.get('/')
        content = response.content.decode('utf8')
        assert '>Log out<' in content

    def test_login_shown_when_logged_out(self):
        response = self.client.get('/')
        content = response.content.decode('utf8')
        assert '>Log in<' in content
    def test_jwt_login_using_zero(self):
        """
        Test to reproduce issue #33
        """
        client = APIClient(enforce_csrf_checks=True)

        data = {'username': '******', 'password': '******'}

        response = client.post('/auth-token/', data, format='json')

        self.assertEqual(response.status_code, 400)
Exemple #8
0
 def test_explicitly_enforce_csrf_checks(self):
     """
     The test client can enforce CSRF checks.
     """
     client = APIClient(enforce_csrf_checks=True)
     User.objects.create_user('example', '*****@*****.**', 'password')
     client.login(username='******', password='******')
     response = client.post('/view/')
     expected = {'detail': 'CSRF Failed: CSRF cookie not set.'}
     assert response.status_code == 403
     assert response.data == expected
    def test_jwt_login_json_bad_creds(self):
        """
        Ensure JWT login view using JSON POST fails
        if bad credentials are used.
        """
        client = APIClient(enforce_csrf_checks=True)

        self.data['password'] = '******'
        response = client.post('/auth-token/', self.data, format='json')

        self.assertEqual(response.status_code, 400)
    def test_jwt_login_json(self):
        """
        Ensure JWT login view using JSON POST works.
        """
        client = APIClient(enforce_csrf_checks=True)

        response = client.post('/auth-token/', self.data, format='json')

        self.assertEqual(response.status_code, status.HTTP_200_OK)
        decoded_payload = utils.jwt_decode_handler(response.data['token'])
        self.assertEqual(decoded_payload['user_id'], str(self.user.id))
 def test_token_login_json_bad_creds(self):
     """
     Ensure token login view using JSON POST fails if
     bad credentials are used
     """
     client = APIClient(enforce_csrf_checks=True)
     response = client.post('/auth-token/', {
         'username': self.username,
         'password': "******"
     },
                            format='json')
     assert response.status_code == 400
    def test_verify_jwt_fails_with_bad_token(self):
        """
        Test that an invalid token will fail with the correct error.
        """
        client = APIClient(enforce_csrf_checks=True)

        token = "i am not a correctly formed token"

        response = client.post('/auth-token-verify/', {'token': token},
                               format='json')
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
        self.assertRegexpMatches(response.data['non_field_errors'][0],
                                 'Error decoding signature')
    def test_verify_jwt_with_pub_pvt_key(self):
        """
        Test that a token can be signed with asymmetrics keys
        """
        client = APIClient(enforce_csrf_checks=True)

        orig_token = self.get_token()

        # Now try to get a refreshed token
        response = client.post('/auth-token-verify/', {'token': orig_token},
                               format='json')

        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['token'], orig_token)
    def test_verify_jwt(self):
        """
        Test that a valid, non-expired token will return a 200 response
        and itself when passed to the validation endpoint.
        """
        client = APIClient(enforce_csrf_checks=True)
        orig_token = self.get_token()

        # Now try to get a refreshed token
        response = client.post('/auth-token-verify/', {'token': orig_token},
                               format='json')

        self.assertEqual(response.status_code, status.HTTP_200_OK)

        self.assertEqual(response.data['token'], orig_token)
    def test_verify_jwt_fails_with_expired_token(self):
        """
        Test that an expired token will fail with the correct error.
        """
        client = APIClient(enforce_csrf_checks=True)

        # Make an expired token..
        token = self.create_token(self.user,
                                  exp=datetime.utcnow() - timedelta(seconds=5),
                                  orig_iat=datetime.utcnow() -
                                  timedelta(hours=1))

        response = client.post('/auth-token-verify/', {'token': token},
                               format='json')
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
        self.assertRegexpMatches(response.data['non_field_errors'][0],
                                 'Signature has expired')
    def test_refresh_jwt_after_refresh_expiration(self):
        """
        Test that token can't be refreshed after token refresh limit
        """
        client = APIClient(enforce_csrf_checks=True)

        orig_iat = (datetime.utcnow() -
                    api_settings.JWT_REFRESH_EXPIRATION_DELTA -
                    timedelta(seconds=5))
        token = self.create_token(self.user,
                                  exp=datetime.utcnow() + timedelta(hours=1),
                                  orig_iat=orig_iat)

        response = client.post('/auth-token-refresh/', {'token': token},
                               format='json')
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
        self.assertEqual(response.data['non_field_errors'][0],
                         'Refresh has expired.')
    def test_verify_jwt_fails_with_missing_user(self):
        """
        Test that an invalid token will fail with a user that does not exist.
        """
        client = APIClient(enforce_csrf_checks=True)

        user = User.objects.create_user(email='*****@*****.**',
                                        username='******',
                                        password='******')

        token = self.create_token(user)
        # Delete the user used to make the token
        user.delete()

        response = client.post('/auth-token-verify/', {'token': token},
                               format='json')
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
        self.assertRegexpMatches(response.data['non_field_errors'][0],
                                 "User doesn't exist")
    def test_jwt_login_with_expired_token(self):
        """
        Ensure JWT login view works even if expired token is provided
        """
        payload = utils.jwt_payload_handler(self.user)
        payload['exp'] = 1
        token = utils.jwt_encode_handler(payload)

        auth = 'JWT {0}'.format(token)
        client = APIClient(enforce_csrf_checks=True)
        response = client.post('/auth-token/',
                               self.data,
                               HTTP_AUTHORIZATION=auth,
                               format='json')

        decoded_payload = utils.jwt_decode_handler(response.data['token'])

        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(decoded_payload['username'], self.username)
    def test_verify_jwt_fails_with_bad_pvt_key(self):
        """
        Test that an mismatched private key token will fail with
        the correct error.
        """

        # Generate a new private key
        private_key = rsa.generate_private_key(public_exponent=65537,
                                               key_size=2048,
                                               backend=default_backend())

        # Don't set the private key
        api_settings.JWT_PRIVATE_KEY = private_key

        client = APIClient(enforce_csrf_checks=True)
        orig_token = self.get_token()

        # Now try to get a refreshed token
        response = client.post('/auth-token-verify/', {'token': orig_token},
                               format='json')

        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
        self.assertRegexpMatches(response.data['non_field_errors'][0],
                                 'Error decoding signature')
    def test_duplicate_request_stream_parsing_exception(self):
        """
        Check assumption that duplicate stream parsing will result in a
        `RawPostDataException` being raised.
        """
        response = APIClient().post('/echo/', data={'a': 'b'}, format='json')
        request = response.renderer_context['request']

        # ensure that request stream was consumed by json parser
        assert request.content_type.startswith('application/json')
        assert response.data == {'a': 'b'}

        # pass same HttpRequest to view, stream already consumed
        with pytest.raises(RawPostDataException):
            EchoView.as_view()(request._request)
class TestContentParsingWithAuthentication(TestCase):
    def setUp(self):
        self.csrf_client = APIClient(enforce_csrf_checks=True)
        self.username = '******'
        self.email = '*****@*****.**'
        self.password = '******'
        self.user = User.objects.create_user(self.username, self.email,
                                             self.password)

    def test_user_logged_in_authentication_has_POST_when_not_logged_in(self):
        """
        Ensures request.POST exists after SessionAuthentication when user
        doesn't log in.
        """
        content = {'example': 'example'}

        response = self.client.post('/', content)
        assert status.HTTP_200_OK == response.status_code

        response = self.csrf_client.post('/', content)
        assert status.HTTP_200_OK == response.status_code
    def test_duplicate_request_form_data_access(self):
        """
        Form data is copied to the underlying django request for middleware
        and file closing reasons. Duplicate processing of a request with form
        data is 'safe' in so far as accessing `request.POST` does not trigger
        the duplicate stream parse exception.
        """
        response = APIClient().post('/echo/', data={'a': 'b'})
        request = response.renderer_context['request']

        # ensure that request stream was consumed by form parser
        assert request.content_type.startswith('multipart/form-data')
        assert response.data == {'a': ['b']}

        # pass same HttpRequest to view, form data set on underlying request
        response = EchoView.as_view()(request._request)
        request = response.renderer_context['request']

        # ensure that request stream was consumed by form parser
        assert request.content_type.startswith('multipart/form-data')
        assert response.data == {'a': ['b']}
 def setUp(self):
     self.csrf_client = APIClient(enforce_csrf_checks=True)
     self.username = '******'
     self.email = '*****@*****.**'
     self.user = User.objects.create_user(self.username, self.email)
class BasicAuthTests(TestCase):
    """Basic authentication"""
    def setUp(self):
        self.csrf_client = APIClient(enforce_csrf_checks=True)
        self.username = '******'
        self.email = '*****@*****.**'
        self.password = '******'
        self.user = User.objects.create_user(self.username, self.email,
                                             self.password)

    def test_post_form_passing_basic_auth(self):
        """Ensure POSTing json over basic auth with correct credentials passes and does not require CSRF"""
        credentials = ('%s:%s' % (self.username, self.password))
        base64_credentials = base64.b64encode(
            credentials.encode(HTTP_HEADER_ENCODING)).decode(
                HTTP_HEADER_ENCODING)
        auth = 'Basic %s' % base64_credentials
        response = self.csrf_client.post('/basic/', {'example': 'example'},
                                         HTTP_AUTHORIZATION=auth)
        assert response.status_code == status.HTTP_200_OK

    def test_post_json_passing_basic_auth(self):
        """Ensure POSTing form over basic auth with correct credentials passes and does not require CSRF"""
        credentials = ('%s:%s' % (self.username, self.password))
        base64_credentials = base64.b64encode(
            credentials.encode(HTTP_HEADER_ENCODING)).decode(
                HTTP_HEADER_ENCODING)
        auth = 'Basic %s' % base64_credentials
        response = self.csrf_client.post('/basic/', {'example': 'example'},
                                         format='json',
                                         HTTP_AUTHORIZATION=auth)
        assert response.status_code == status.HTTP_200_OK

    def test_regression_handle_bad_base64_basic_auth_header(self):
        """Ensure POSTing JSON over basic auth with incorrectly padded Base64 string is handled correctly"""
        # regression test for issue in 'mind_core.authentication.BasicAuthentication.authenticate'
        # https://github.com/encode/django-rest-framework/issues/4089
        auth = 'Basic =a='
        response = self.csrf_client.post('/basic/', {'example': 'example'},
                                         format='json',
                                         HTTP_AUTHORIZATION=auth)
        assert response.status_code == status.HTTP_401_UNAUTHORIZED

    def test_post_form_failing_basic_auth(self):
        """Ensure POSTing form over basic auth without correct credentials fails"""
        response = self.csrf_client.post('/basic/', {'example': 'example'})
        assert response.status_code == status.HTTP_401_UNAUTHORIZED

    def test_post_json_failing_basic_auth(self):
        """Ensure POSTing json over basic auth without correct credentials fails"""
        response = self.csrf_client.post('/basic/', {'example': 'example'},
                                         format='json')
        assert response.status_code == status.HTTP_401_UNAUTHORIZED
        assert response['WWW-Authenticate'] == 'Basic realm="api"'

    def test_fail_post_if_credentials_are_missing(self):
        response = self.csrf_client.post('/basic/', {'example': 'example'},
                                         HTTP_AUTHORIZATION='Basic ')
        assert response.status_code == status.HTTP_401_UNAUTHORIZED

    def test_fail_post_if_credentials_contain_spaces(self):
        response = self.csrf_client.post('/basic/', {'example': 'example'},
                                         HTTP_AUTHORIZATION='Basic foo bar')
        assert response.status_code == status.HTTP_401_UNAUTHORIZED
class BaseTokenAuthTests(object):
    """Token authentication"""
    model = None
    path = None
    header_prefix = 'Token '

    def setUp(self):
        self.csrf_client = APIClient(enforce_csrf_checks=True)
        self.username = '******'
        self.email = '*****@*****.**'
        self.password = '******'
        self.user = User.objects.create_user(self.username, self.email,
                                             self.password)

        self.key = 'abcd1234'
        self.token = self.model.objects.create(key=self.key, user=self.user)

    def test_post_form_passing_token_auth(self):
        """
        Ensure POSTing json over token auth with correct
        credentials passes and does not require CSRF
        """
        auth = self.header_prefix + self.key
        response = self.csrf_client.post(self.path, {'example': 'example'},
                                         HTTP_AUTHORIZATION=auth)
        assert response.status_code == status.HTTP_200_OK

    def test_fail_authentication_if_user_is_not_active(self):
        user = User.objects.create_user('foo', 'bar', 'baz')
        user.is_active = False
        user.save()
        self.model.objects.create(key='foobar_token', user=user)
        response = self.csrf_client.post(
            self.path, {'example': 'example'},
            HTTP_AUTHORIZATION=self.header_prefix + 'foobar_token')
        assert response.status_code == status.HTTP_401_UNAUTHORIZED

    def test_fail_post_form_passing_nonexistent_token_auth(self):
        # use a nonexistent token key
        auth = self.header_prefix + 'wxyz6789'
        response = self.csrf_client.post(self.path, {'example': 'example'},
                                         HTTP_AUTHORIZATION=auth)
        assert response.status_code == status.HTTP_401_UNAUTHORIZED

    def test_fail_post_if_token_is_missing(self):
        response = self.csrf_client.post(self.path, {'example': 'example'},
                                         HTTP_AUTHORIZATION=self.header_prefix)
        assert response.status_code == status.HTTP_401_UNAUTHORIZED

    def test_fail_post_if_token_contains_spaces(self):
        response = self.csrf_client.post(
            self.path, {'example': 'example'},
            HTTP_AUTHORIZATION=self.header_prefix + 'foo bar')
        assert response.status_code == status.HTTP_401_UNAUTHORIZED

    def test_fail_post_form_passing_invalid_token_auth(self):
        # add an 'invalid' unicode character
        auth = self.header_prefix + self.key + "¸"
        response = self.csrf_client.post(self.path, {'example': 'example'},
                                         HTTP_AUTHORIZATION=auth)
        assert response.status_code == status.HTTP_401_UNAUTHORIZED

    def test_post_json_passing_token_auth(self):
        """
        Ensure POSTing form over token auth with correct
        credentials passes and does not require CSRF
        """
        auth = self.header_prefix + self.key
        response = self.csrf_client.post(self.path, {'example': 'example'},
                                         format='json',
                                         HTTP_AUTHORIZATION=auth)
        assert response.status_code == status.HTTP_200_OK

    def test_post_json_makes_one_db_query(self):
        """
        Ensure that authenticating a user using a
        token performs only one DB query
        """
        auth = self.header_prefix + self.key

        def func_to_test():
            return self.csrf_client.post(self.path, {'example': 'example'},
                                         format='json',
                                         HTTP_AUTHORIZATION=auth)

        self.assertNumQueries(1, func_to_test)

    def test_post_form_failing_token_auth(self):
        """
        Ensure POSTing form over token auth without correct credentials fails
        """
        response = self.csrf_client.post(self.path, {'example': 'example'})
        assert response.status_code == status.HTTP_401_UNAUTHORIZED

    def test_post_json_failing_token_auth(self):
        """
        Ensure POSTing json over token auth without correct credentials fails
        """
        response = self.csrf_client.post(self.path, {'example': 'example'},
                                         format='json')
        assert response.status_code == status.HTTP_401_UNAUTHORIZED
Exemple #26
0
class TestAPITestClient(TestCase):
    def setUp(self):
        self.client = APIClient()

    def test_credentials(self):
        """
        Setting `.credentials()` adds the required headers to each request.
        """
        self.client.credentials(HTTP_AUTHORIZATION='example')
        for _ in range(0, 3):
            response = self.client.get('/view/')
            assert response.data['auth'] == 'example'

    def test_force_authenticate(self):
        """
        Setting `.force_authenticate()` forcibly authenticates each request.
        """
        user = User.objects.create_user('example', '*****@*****.**')
        self.client.force_authenticate(user)
        response = self.client.get('/view/')
        assert response.data['user'] == 'example'

    def test_force_authenticate_with_sessions(self):
        """
        Setting `.force_authenticate()` forcibly authenticates each request.
        """
        user = User.objects.create_user('example', '*****@*****.**')
        self.client.force_authenticate(user)

        # First request does not yet have an active session
        response = self.client.get('/session-view/')
        assert response.data['active_session'] is False

        # Subsequent requests have an active session
        response = self.client.get('/session-view/')
        assert response.data['active_session'] is True

        # Force authenticating as `None` should also logout the user session.
        self.client.force_authenticate(None)
        response = self.client.get('/session-view/')
        assert response.data['active_session'] is False

    def test_csrf_exempt_by_default(self):
        """
        By default, the test client is CSRF exempt.
        """
        User.objects.create_user('example', '*****@*****.**', 'password')
        self.client.login(username='******', password='******')
        response = self.client.post('/view/')
        assert response.status_code == 200

    def test_explicitly_enforce_csrf_checks(self):
        """
        The test client can enforce CSRF checks.
        """
        client = APIClient(enforce_csrf_checks=True)
        User.objects.create_user('example', '*****@*****.**', 'password')
        client.login(username='******', password='******')
        response = client.post('/view/')
        expected = {'detail': 'CSRF Failed: CSRF cookie not set.'}
        assert response.status_code == 403
        assert response.data == expected

    def test_can_logout(self):
        """
        `logout()` resets stored credentials
        """
        self.client.credentials(HTTP_AUTHORIZATION='example')
        response = self.client.get('/view/')
        assert response.data['auth'] == 'example'
        self.client.logout()
        response = self.client.get('/view/')
        assert response.data['auth'] == b''

    def test_logout_resets_force_authenticate(self):
        """
        `logout()` resets any `force_authenticate`
        """
        user = User.objects.create_user('example', '*****@*****.**', 'password')
        self.client.force_authenticate(user)
        response = self.client.get('/view/')
        assert response.data['user'] == 'example'
        self.client.logout()
        response = self.client.get('/view/')
        assert response.data['user'] == ''

    def test_follow_redirect(self):
        """
        Follow redirect by setting follow argument.
        """
        response = self.client.get('/redirect-view/')
        assert response.status_code == 302
        response = self.client.get('/redirect-view/', follow=True)
        assert response.redirect_chain is not None
        assert response.status_code == 200

        response = self.client.post('/redirect-view/')
        assert response.status_code == 302
        response = self.client.post('/redirect-view/', follow=True)
        assert response.redirect_chain is not None
        assert response.status_code == 200

        response = self.client.put('/redirect-view/')
        assert response.status_code == 302
        response = self.client.put('/redirect-view/', follow=True)
        assert response.redirect_chain is not None
        assert response.status_code == 200

        response = self.client.patch('/redirect-view/')
        assert response.status_code == 302
        response = self.client.patch('/redirect-view/', follow=True)
        assert response.redirect_chain is not None
        assert response.status_code == 200

        response = self.client.delete('/redirect-view/')
        assert response.status_code == 302
        response = self.client.delete('/redirect-view/', follow=True)
        assert response.redirect_chain is not None
        assert response.status_code == 200

        response = self.client.options('/redirect-view/')
        assert response.status_code == 302
        response = self.client.options('/redirect-view/', follow=True)
        assert response.redirect_chain is not None
        assert response.status_code == 200

    def test_invalid_multipart_data(self):
        """
        MultiPart encoding cannot support nested data, so raise a helpful
        error if the user attempts to do so.
        """
        self.assertRaises(
            AssertionError, self.client.post,
            path='/view/', data={'valid': 123, 'invalid': {'a': 123}}
        )

    def test_empty_post_uses_default_boolean_value(self):
        response = self.client.post(
            '/post-view/',
            data=None,
            content_type='application/json'
        )
        assert response.status_code == 200
        assert response.data == {"flag": True}
Exemple #27
0
 def setUp(self):
     self.client = APIClient()
class JSONWebTokenAuthenticationTests(TestCase):
    """JSON Web Token Authentication"""
    def setUp(self):
        self.csrf_client = APIClient(enforce_csrf_checks=True)
        self.username = '******'
        self.email = '*****@*****.**'
        self.user = User.objects.create_user(self.username, self.email)

    def test_post_form_passing_jwt_auth(self):
        """
        Ensure POSTing form over JWT auth with correct credentials
        passes and does not require CSRF
        """
        payload = utils.jwt_payload_handler(self.user)
        token = utils.jwt_encode_handler(payload)

        auth = 'JWT {0}'.format(token)
        response = self.csrf_client.post('/jwt/', {'example': 'example'},
                                         HTTP_AUTHORIZATION=auth)

        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.content, b'mockview-post')

        # Ensure `authenticate` returned the decoded payload.
        self.assertEqual(response.wsgi_request.user, self.user)
        payload = response.wsgi_request.auth
        self.assertIsInstance(payload, dict)
        self.assertEqual(set(payload.keys()),
                         {'user_id', 'username', 'exp', 'email'})

    def test_post_json_passing_jwt_auth(self):
        """
        Ensure POSTing JSON over JWT auth with correct credentials
        passes and does not require CSRF
        """
        payload = utils.jwt_payload_handler(self.user)
        token = utils.jwt_encode_handler(payload)

        auth = 'JWT {0}'.format(token)
        response = self.csrf_client.post('/jwt/', {'example': 'example'},
                                         HTTP_AUTHORIZATION=auth,
                                         format='json')

        self.assertEqual(response.status_code, status.HTTP_200_OK)

    def test_post_form_failing_jwt_auth(self):
        """
        Ensure POSTing form over JWT auth without correct credentials fails
        """
        response = self.csrf_client.post('/jwt/', {'example': 'example'})
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
        self.assertEqual(response['WWW-Authenticate'], 'JWT realm="api"')

    def test_post_json_failing_jwt_auth(self):
        """
        Ensure POSTing json over JWT auth without correct credentials fails
        """
        response = self.csrf_client.post('/jwt/', {'example': 'example'},
                                         format='json')
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
        self.assertEqual(response['WWW-Authenticate'], 'JWT realm="api"')

    def test_post_no_jwt_header_failing_jwt_auth(self):
        """
        Ensure POSTing over JWT auth without credentials fails
        """
        auth = 'JWT'
        response = self.csrf_client.post('/jwt/', {'example': 'example'},
                                         HTTP_AUTHORIZATION=auth,
                                         format='json')

        msg = 'Invalid Authorization header. No credentials provided.'

        self.assertEqual(response.data['detail'], msg)
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
        self.assertEqual(response['WWW-Authenticate'], 'JWT realm="api"')

    def test_post_invalid_jwt_header_failing_jwt_auth(self):
        """
        Ensure POSTing over JWT auth without correct credentials fails
        """
        auth = 'JWT abc abc'
        response = self.csrf_client.post('/jwt/', {'example': 'example'},
                                         HTTP_AUTHORIZATION=auth,
                                         format='json')

        msg = ('Invalid Authorization header. Credentials string '
               'should not contain spaces.')

        self.assertEqual(response.data['detail'], msg)
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
        self.assertEqual(response['WWW-Authenticate'], 'JWT realm="api"')

    def test_post_expired_token_failing_jwt_auth(self):
        """
        Ensure POSTing over JWT auth with expired token fails
        """
        payload = utils.jwt_payload_handler(self.user)
        payload['exp'] = 1
        token = utils.jwt_encode_handler(payload)

        auth = 'JWT {0}'.format(token)
        response = self.csrf_client.post('/jwt/', {'example': 'example'},
                                         HTTP_AUTHORIZATION=auth,
                                         format='json')

        msg = 'Signature has expired.'

        self.assertEqual(response.data['detail'], msg)
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
        self.assertEqual(response['WWW-Authenticate'], 'JWT realm="api"')

    @override_settings(AUTH_USER_MODEL='tests.CustomUser')
    def test_post_form_failing_jwt_auth_changed_user_secret_key(self):
        """
        Ensure changin secret key on USER level makes tokens invalid
        """
        # fine tune settings
        api_settings.JWT_GET_USER_SECRET_KEY = get_jwt_secret

        tmp_user = CustomUser.objects.create(email='*****@*****.**')
        payload = utils.jwt_payload_handler(tmp_user)
        token = utils.jwt_encode_handler(payload)

        auth = 'JWT {0}'.format(token)
        response = self.csrf_client.post('/jwt/', {'example': 'example'},
                                         HTTP_AUTHORIZATION=auth,
                                         format='json')

        self.assertEqual(response.status_code, status.HTTP_200_OK)

        # change token, verify
        tmp_user.jwt_secret = uuid.uuid4()
        tmp_user.save()

        response = self.csrf_client.post('/jwt/', {'example': 'example'},
                                         HTTP_AUTHORIZATION=auth)

        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

        # revert api settings
        api_settings.JWT_GET_USER_SECRET_KEY = DEFAULTS[
            'JWT_GET_USER_SECRET_KEY']

    def test_post_invalid_token_failing_jwt_auth(self):
        """
        Ensure POSTing over JWT auth with invalid token fails
        """
        auth = 'JWT abc123'
        response = self.csrf_client.post('/jwt/', {'example': 'example'},
                                         HTTP_AUTHORIZATION=auth,
                                         format='json')

        msg = 'Error decoding signature.'

        self.assertEqual(response.data['detail'], msg)
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
        self.assertEqual(response['WWW-Authenticate'], 'JWT realm="api"')

    @unittest.skipUnless(oauth2_provider, DJANGO_OAUTH2_PROVIDER_NOT_INSTALLED)
    def test_post_passing_jwt_auth_with_oauth2_priority(self):
        """
        Ensure POSTing over JWT auth with correct credentials
        passes and does not require CSRF when OAuth2Authentication
        has priority on authentication_classes
        """
        payload = utils.jwt_payload_handler(self.user)
        token = utils.jwt_encode_handler(payload)

        auth = 'JWT {0}'.format(token)
        response = self.csrf_client.post('/oauth2-jwt/',
                                         {'example': 'example'},
                                         HTTP_AUTHORIZATION=auth,
                                         format='json')

        self.assertEqual(response.status_code, status.HTTP_200_OK, response)

    @unittest.skipUnless(oauth2_provider, DJANGO_OAUTH2_PROVIDER_NOT_INSTALLED)
    def test_post_passing_oauth2_with_jwt_auth_priority(self):
        """
        Ensure POSTing over OAuth2 with correct credentials
        passes and does not require CSRF when JSONWebTokenAuthentication
        has priority on authentication_classes
        """
        Client = oauth2_provider.oauth2.models.Client
        AccessToken = oauth2_provider.oauth2.models.AccessToken

        oauth2_client = Client.objects.create(
            user=self.user,
            client_type=0,
        )

        access_token = AccessToken.objects.create(
            user=self.user,
            client=oauth2_client,
        )

        auth = 'Bearer {0}'.format(access_token.token)
        response = self.csrf_client.post('/jwt-oauth2/',
                                         {'example': 'example'},
                                         HTTP_AUTHORIZATION=auth,
                                         format='json')

        self.assertEqual(response.status_code, status.HTTP_200_OK, response)

    def test_post_form_passing_jwt_invalid_payload(self):
        """
        Ensure POSTing json over JWT auth with invalid payload fails
        """
        payload = dict(email=None)
        token = utils.jwt_encode_handler(payload)

        auth = 'JWT {0}'.format(token)
        response = self.csrf_client.post('/jwt/', {'example': 'example'},
                                         HTTP_AUTHORIZATION=auth)

        msg = 'Invalid payload.'

        self.assertEqual(response.data['detail'], msg)
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

    def test_different_auth_header_prefix(self):
        """
        Ensure using a different setting for `JWT_AUTH_HEADER_PREFIX` and
        with correct credentials passes.
        """
        api_settings.JWT_AUTH_HEADER_PREFIX = 'Bearer'

        payload = utils.jwt_payload_handler(self.user)
        token = utils.jwt_encode_handler(payload)

        auth = 'Bearer {0}'.format(token)
        response = self.csrf_client.post('/jwt/', {'example': 'example'},
                                         HTTP_AUTHORIZATION=auth,
                                         format='json')

        self.assertEqual(response.status_code, status.HTTP_200_OK)

        # Restore original settings
        api_settings.JWT_AUTH_HEADER_PREFIX = DEFAULTS[
            'JWT_AUTH_HEADER_PREFIX']

    def test_post_form_failing_jwt_auth_different_auth_header_prefix(self):
        """
        Ensure using a different setting for `JWT_AUTH_HEADER_PREFIX` and
        POSTing form over JWT auth without correct credentials fails and
        generated correct WWW-Authenticate header
        """
        api_settings.JWT_AUTH_HEADER_PREFIX = 'Bearer'

        response = self.csrf_client.post('/jwt/', {'example': 'example'})
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
        self.assertEqual(response['WWW-Authenticate'], 'Bearer realm="api"')

        # Restore original settings
        api_settings.JWT_AUTH_HEADER_PREFIX = DEFAULTS[
            'JWT_AUTH_HEADER_PREFIX']
class SessionAuthTests(TestCase):
    """User session authentication"""
    def setUp(self):
        self.csrf_client = APIClient(enforce_csrf_checks=True)
        self.non_csrf_client = APIClient(enforce_csrf_checks=False)
        self.username = '******'
        self.email = '*****@*****.**'
        self.password = '******'
        self.user = User.objects.create_user(self.username, self.email,
                                             self.password)

    def tearDown(self):
        self.csrf_client.logout()

    def test_login_view_renders_on_get(self):
        """
        Ensure the login template renders for a basic GET.

        cf. [#1810](https://github.com/encode/django-rest-framework/pull/1810)
        """
        response = self.csrf_client.get('/auth/login/')
        content = response.content.decode('utf8')
        assert '<label for="id_username">Username:</label>' in content

    def test_post_form_session_auth_failing_csrf(self):
        """
        Ensure POSTing form over session authentication without CSRF token fails.
        """
        self.csrf_client.login(username=self.username, password=self.password)
        response = self.csrf_client.post('/session/', {'example': 'example'})
        assert response.status_code == status.HTTP_403_FORBIDDEN

    def test_post_form_session_auth_passing_csrf(self):
        """
        Ensure POSTing form over session authentication with CSRF token succeeds.
        Regression test for #6088
        """
        from django.middleware.csrf import _get_new_csrf_token

        self.csrf_client.login(username=self.username, password=self.password)

        # Set the csrf_token cookie so that CsrfViewMiddleware._get_token() works
        token = _get_new_csrf_token()
        self.csrf_client.cookies[settings.CSRF_COOKIE_NAME] = token

        # Post the token matching the cookie value
        response = self.csrf_client.post('/session/', {
            'example': 'example',
            'csrfmiddlewaretoken': token,
        })
        assert response.status_code == status.HTTP_200_OK

    def test_post_form_session_auth_passing(self):
        """
        Ensure POSTing form over session authentication with logged in
        user and CSRF token passes.
        """
        self.non_csrf_client.login(username=self.username,
                                   password=self.password)
        response = self.non_csrf_client.post('/session/',
                                             {'example': 'example'})
        assert response.status_code == status.HTTP_200_OK

    def test_put_form_session_auth_passing(self):
        """
        Ensure PUTting form over session authentication with
        logged in user and CSRF token passes.
        """
        self.non_csrf_client.login(username=self.username,
                                   password=self.password)
        response = self.non_csrf_client.put('/session/',
                                            {'example': 'example'})
        assert response.status_code == status.HTTP_200_OK

    def test_post_form_session_auth_failing(self):
        """
        Ensure POSTing form over session authentication without logged in user fails.
        """
        response = self.csrf_client.post('/session/', {'example': 'example'})
        assert response.status_code == status.HTTP_403_FORBIDDEN
 def get_token(self):
     client = APIClient(enforce_csrf_checks=True)
     response = client.post('/auth-token/', self.data, format='json')
     return response.data['token']