Commit 54e4bcfa by Vedran Karačić Committed by GitHub

Merge pull request #14455 from edx/vkaracic/deactivate-jwt

User deactivation endpoint should use JWT auth.
parents f7d5e7e1 036e0596
......@@ -27,6 +27,7 @@ from openedx.core.djangoapps.user_api.accounts import ACCOUNT_VISIBILITY_PREF_KE
from openedx.core.djangoapps.user_api.models import UserPreference
from openedx.core.djangoapps.user_api.preferences.api import set_user_preference
from openedx.core.djangolib.testing.utils import CacheIsolationTestCase, skip_unless_lms
from openedx.core.lib.token_utils import JwtBuilder
from student.models import UserProfile, LanguageProficiency, PendingEmailChange
from student.tests.factories import (
AdminFactory, ContentTypeFactory, TEST_PASSWORD, PermissionFactory, SuperuserFactory, UserFactory
......@@ -829,12 +830,20 @@ class TestAccountDeactivation(TestCase):
def setUp(self):
super(TestAccountDeactivation, self).setUp()
self.superuser = SuperuserFactory()
self.staff_user = AdminFactory()
self.test_user = UserFactory()
self.url = reverse('accounts_deactivation', kwargs={'username': self.test_user.username})
def assert_activation_status(self, expected_status=status.HTTP_200_OK, expected_activation_status=False):
def build_jwt_headers(self, user):
"""
Helper function for creating headers for the JWT authentication.
"""
token = JwtBuilder(user).build_token([])
headers = {
'HTTP_AUTHORIZATION': 'JWT ' + token
}
return headers
def assert_activation_status(self, headers, expected_status=status.HTTP_200_OK, expected_activation_status=False):
"""
Helper function for making a request to the deactivation endpoint, and asserting the status.
......@@ -842,7 +851,8 @@ class TestAccountDeactivation(TestCase):
expected_status(int): Expected request's response status.
expected_activation_status(bool): Expected user has_usable_password attribute value.
"""
response = self.client.post(self.url)
self.assertTrue(self.test_user.has_usable_password()) # pylint: disable=no-member
response = self.client.post(self.url, **headers)
self.assertEqual(response.status_code, expected_status)
self.test_user.refresh_from_db() # pylint: disable=no-member
self.assertEqual(self.test_user.has_usable_password(), expected_activation_status) # pylint: disable=no-member
......@@ -851,9 +861,9 @@ class TestAccountDeactivation(TestCase):
"""
Verify a user is deactivated when a superuser posts to the deactivation endpoint.
"""
self.client.login(username=self.superuser.username, password=TEST_PASSWORD)
self.assertTrue(self.test_user.has_usable_password()) # pylint: disable=no-member
self.assert_activation_status()
superuser = SuperuserFactory()
headers = self.build_jwt_headers(superuser)
self.assert_activation_status(headers)
def test_user_with_permission_deactivates_user(self):
"""
......@@ -867,17 +877,28 @@ class TestAccountDeactivation(TestCase):
)
)
user.user_permissions.add(permission) # pylint: disable=no-member
self.client.login(username=user.username, password=TEST_PASSWORD)
headers = self.build_jwt_headers(user)
self.assertTrue(self.test_user.has_usable_password()) # pylint: disable=no-member
self.assert_activation_status()
self.assert_activation_status(headers)
def test_unauthorized_rejection(self):
"""
Verify unauthorized users cannot deactivate accounts.
"""
self.client.login(username=self.test_user.username, password=TEST_PASSWORD)
self.assertTrue(self.test_user.has_usable_password()) # pylint: disable=no-member
headers = self.build_jwt_headers(self.test_user)
self.assert_activation_status(
headers,
expected_status=status.HTTP_403_FORBIDDEN,
expected_activation_status=True
)
def test_on_jwt_headers_rejection(self):
"""
Verify users who are not JWT authenticated are rejected.
"""
user = UserFactory()
self.assert_activation_status(
{},
expected_status=status.HTTP_401_UNAUTHORIZED,
expected_activation_status=True
)
......@@ -229,6 +229,7 @@ class AccountDeactivationView(APIView):
Account deactivation viewset. Currently only supports POST requests.
Only admins can deactivate accounts.
"""
authentication_classes = (JwtAuthentication, )
permission_classes = (permissions.IsAuthenticated, CanDeactivateUser)
def post(self, request, username):
......
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