github.com/jiasir/deis@v1.12.2/controller/api/tests/test_auth.py (about)

     1  """
     2  Unit tests for the Deis api app.
     3  
     4  Run the tests with "./manage.py test api"
     5  """
     6  
     7  from __future__ import unicode_literals
     8  
     9  import json
    10  import urllib
    11  
    12  from django.contrib.auth.models import User
    13  from django.test import TestCase
    14  from django.test.utils import override_settings
    15  from rest_framework.authtoken.models import Token
    16  
    17  
    18  class AuthTest(TestCase):
    19  
    20      fixtures = ['test_auth.json']
    21  
    22      """Tests user registration, authentication and authorization"""
    23  
    24      def setUp(self):
    25          self.admin = User.objects.get(username='autotest')
    26          self.admin_token = Token.objects.get(user=self.admin).key
    27          self.user1 = User.objects.get(username='autotest2')
    28          self.user1_token = Token.objects.get(user=self.user1).key
    29          self.user2 = User.objects.get(username='autotest3')
    30          self.user2_token = Token.objects.get(user=self.user2).key
    31  
    32      def test_auth(self):
    33          """
    34          Test that a user can register using the API, login and logout
    35          """
    36          # test registration workflow
    37          username, password = 'newuser', 'password'
    38          first_name, last_name = 'Otto', 'Test'
    39          email = 'autotest@deis.io'
    40          submit = {
    41              'username': username,
    42              'password': password,
    43              'first_name': first_name,
    44              'last_name': last_name,
    45              'email': email,
    46              # try to abuse superuser/staff level perms (not the first signup!)
    47              'is_superuser': True,
    48              'is_staff': True,
    49          }
    50          url = '/v1/auth/register'
    51          response = self.client.post(url, json.dumps(submit), content_type='application/json')
    52          self.assertEqual(response.status_code, 201)
    53          for key in response.data:
    54              self.assertIn(key, ['id', 'last_login', 'is_superuser', 'username', 'first_name',
    55                                  'last_name', 'email', 'is_active', 'is_superuser', 'is_staff',
    56                                  'date_joined', 'groups', 'user_permissions'])
    57          expected = {
    58              'username': username,
    59              'email': email,
    60              'first_name': first_name,
    61              'last_name': last_name,
    62              'is_active': True,
    63              'is_superuser': False,
    64              'is_staff': False
    65          }
    66          self.assertDictContainsSubset(expected, response.data)
    67          # test login
    68          url = '/v1/auth/login/'
    69          payload = urllib.urlencode({'username': username, 'password': password})
    70          response = self.client.post(url, data=payload,
    71                                      content_type='application/x-www-form-urlencoded')
    72          self.assertEqual(response.status_code, 200)
    73  
    74      @override_settings(REGISTRATION_MODE="disabled")
    75      def test_auth_registration_disabled(self):
    76          """test that a new user cannot register when registration is disabled."""
    77          url = '/v1/auth/register'
    78          submit = {
    79              'username': 'testuser',
    80              'password': 'password',
    81              'first_name': 'test',
    82              'last_name': 'user',
    83              'email': 'test@user.com',
    84              'is_superuser': False,
    85              'is_staff': False,
    86          }
    87          response = self.client.post(url, json.dumps(submit), content_type='application/json')
    88          self.assertEqual(response.status_code, 403)
    89  
    90      @override_settings(REGISTRATION_MODE="admin_only")
    91      def test_auth_registration_admin_only_fails_if_not_admin(self):
    92          """test that a non superuser cannot register when registration is admin only."""
    93          url = '/v1/auth/register'
    94          submit = {
    95              'username': 'testuser',
    96              'password': 'password',
    97              'first_name': 'test',
    98              'last_name': 'user',
    99              'email': 'test@user.com',
   100              'is_superuser': False,
   101              'is_staff': False,
   102          }
   103          response = self.client.post(url, json.dumps(submit), content_type='application/json')
   104          self.assertEqual(response.status_code, 403)
   105  
   106      @override_settings(REGISTRATION_MODE="admin_only")
   107      def test_auth_registration_admin_only_works(self):
   108          """test that a superuser can register when registration is admin only."""
   109          url = '/v1/auth/register'
   110  
   111          username, password = 'newuser_by_admin', 'password'
   112          first_name, last_name = 'Otto', 'Test'
   113          email = 'autotest@deis.io'
   114  
   115          submit = {
   116              'username': username,
   117              'password': password,
   118              'first_name': first_name,
   119              'last_name': last_name,
   120              'email': email,
   121              # try to abuse superuser/staff level perms (not the first signup!)
   122              'is_superuser': True,
   123              'is_staff': True,
   124          }
   125          response = self.client.post(url, json.dumps(submit), content_type='application/json',
   126                                      HTTP_AUTHORIZATION='token {}'.format(self.admin_token))
   127  
   128          self.assertEqual(response.status_code, 201)
   129          for key in response.data:
   130              self.assertIn(key, ['id', 'last_login', 'is_superuser', 'username', 'first_name',
   131                                  'last_name', 'email', 'is_active', 'is_superuser', 'is_staff',
   132                                  'date_joined', 'groups', 'user_permissions'])
   133          expected = {
   134              'username': username,
   135              'email': email,
   136              'first_name': first_name,
   137              'last_name': last_name,
   138              'is_active': True,
   139              'is_superuser': False,
   140              'is_staff': False
   141          }
   142          self.assertDictContainsSubset(expected, response.data)
   143          # test login
   144          url = '/v1/auth/login/'
   145          payload = urllib.urlencode({'username': username, 'password': password})
   146          response = self.client.post(url, data=payload,
   147                                      content_type='application/x-www-form-urlencoded')
   148          self.assertEqual(response.status_code, 200)
   149  
   150      @override_settings(REGISTRATION_MODE="not_a_mode")
   151      def test_auth_registration_fails_with_nonexistant_mode(self):
   152          """test that a registration should fail with a nonexistant mode"""
   153          url = '/v1/auth/register'
   154          submit = {
   155              'username': 'testuser',
   156              'password': 'password',
   157              'first_name': 'test',
   158              'last_name': 'user',
   159              'email': 'test@user.com',
   160              'is_superuser': False,
   161              'is_staff': False,
   162          }
   163  
   164          try:
   165              self.client.post(url, json.dumps(submit), content_type='application/json')
   166          except Exception, e:
   167              self.assertEqual(str(e), 'not_a_mode is not a valid registation mode')
   168  
   169      def test_cancel(self):
   170          """Test that a registered user can cancel her account."""
   171          # test registration workflow
   172          username, password = 'newuser', 'password'
   173          submit = {
   174              'username': username,
   175              'password': password,
   176              'first_name': 'Otto',
   177              'last_name': 'Test',
   178              'email': 'autotest@deis.io',
   179              # try to abuse superuser/staff level perms
   180              'is_superuser': True,
   181              'is_staff': True,
   182          }
   183  
   184          other_username, other_password = 'newuser2', 'password'
   185          other_submit = {
   186              'username': other_username,
   187              'password': other_password,
   188              'first_name': 'Test',
   189              'last_name': 'Tester',
   190              'email': 'autotest-2@deis.io',
   191              'is_superuser': False,
   192              'is_staff': False,
   193          }
   194          url = '/v1/auth/register'
   195          response = self.client.post(url, json.dumps(submit), content_type='application/json')
   196          self.assertEqual(response.status_code, 201)
   197  
   198          # cancel the account
   199          url = '/v1/auth/cancel'
   200          user = User.objects.get(username=username)
   201          token = Token.objects.get(user=user).key
   202          response = self.client.delete(url,
   203                                        HTTP_AUTHORIZATION='token {}'.format(token))
   204          self.assertEqual(response.status_code, 204)
   205  
   206          url = '/v1/auth/register'
   207          response = self.client.post(url, json.dumps(other_submit), content_type='application/json')
   208          self.assertEqual(response.status_code, 201)
   209  
   210          # normal user can't delete another user
   211          url = '/v1/auth/cancel'
   212          other_user = User.objects.get(username=other_username)
   213          other_token = Token.objects.get(user=other_user).key
   214          response = self.client.delete(url, json.dumps({'username': self.admin.username}),
   215                                        content_type='application/json',
   216                                        HTTP_AUTHORIZATION='token {}'.format(other_token))
   217          self.assertEqual(response.status_code, 403)
   218  
   219          # admin can delete another user
   220          response = self.client.delete(url, json.dumps({'username': other_username}),
   221                                        content_type='application/json',
   222                                        HTTP_AUTHORIZATION='token {}'.format(self.admin_token))
   223          self.assertEqual(response.status_code, 204)
   224  
   225      def test_passwd(self):
   226          """Test that a registered user can change the password."""
   227          # test registration workflow
   228          username, password = 'newuser', 'password'
   229          first_name, last_name = 'Otto', 'Test'
   230          email = 'autotest@deis.io'
   231          submit = {
   232              'username': username,
   233              'password': password,
   234              'first_name': first_name,
   235              'last_name': last_name,
   236              'email': email,
   237          }
   238          url = '/v1/auth/register'
   239          response = self.client.post(url, json.dumps(submit), content_type='application/json')
   240          self.assertEqual(response.status_code, 201)
   241          # change password
   242          url = '/v1/auth/passwd'
   243          user = User.objects.get(username=username)
   244          token = Token.objects.get(user=user).key
   245          submit = {
   246              'password': 'password2',
   247              'new_password': password,
   248          }
   249          response = self.client.post(url, json.dumps(submit), content_type='application/json',
   250                                      HTTP_AUTHORIZATION='token {}'.format(token))
   251          self.assertEqual(response.status_code, 400)
   252          self.assertEqual(response.data, {'detail': 'Current password does not match'})
   253          self.assertEqual(response.get('content-type'), 'application/json')
   254          submit = {
   255              'password': password,
   256              'new_password': 'password2',
   257          }
   258          response = self.client.post(url, json.dumps(submit), content_type='application/json',
   259                                      HTTP_AUTHORIZATION='token {}'.format(token))
   260          self.assertEqual(response.status_code, 200)
   261          # test login with old password
   262          url = '/v1/auth/login/'
   263          payload = urllib.urlencode({'username': username, 'password': password})
   264          response = self.client.post(url, data=payload,
   265                                      content_type='application/x-www-form-urlencoded')
   266          self.assertEqual(response.status_code, 400)
   267          # test login with new password
   268          payload = urllib.urlencode({'username': username, 'password': 'password2'})
   269          response = self.client.post(url, data=payload,
   270                                      content_type='application/x-www-form-urlencoded')
   271          self.assertEqual(response.status_code, 200)
   272  
   273      def test_change_user_passwd(self):
   274          """
   275          Test that an administrator can change a user's password, while a regular user cannot.
   276          """
   277          # change password
   278          url = '/v1/auth/passwd'
   279          old_password = self.user1.password
   280          new_password = 'password'
   281          submit = {
   282              'username': self.user1.username,
   283              'new_password': new_password,
   284          }
   285          response = self.client.post(url, json.dumps(submit), content_type='application/json',
   286                                      HTTP_AUTHORIZATION='token {}'.format(self.admin_token))
   287          self.assertEqual(response.status_code, 200)
   288          # test login with old password
   289          url = '/v1/auth/login/'
   290          payload = urllib.urlencode({'username': self.user1.username, 'password': old_password})
   291          response = self.client.post(url, data=payload,
   292                                      content_type='application/x-www-form-urlencoded')
   293          self.assertEqual(response.status_code, 400)
   294          # test login with new password
   295          payload = urllib.urlencode({'username': self.user1.username, 'password': new_password})
   296          response = self.client.post(url, data=payload,
   297                                      content_type='application/x-www-form-urlencoded')
   298          self.assertEqual(response.status_code, 200)
   299          # Non-admins can't change another user's password
   300          submit['password'], submit['new_password'] = submit['new_password'], old_password
   301          url = '/v1/auth/passwd'
   302          response = self.client.post(url, json.dumps(submit), content_type='application/json',
   303                                      HTTP_AUTHORIZATION='token {}'.format(self.user2_token))
   304          self.assertEqual(response.status_code, 403)
   305          # change back password with a regular user
   306          response = self.client.post(url, json.dumps(submit), content_type='application/json',
   307                                      HTTP_AUTHORIZATION='token {}'.format(self.user1_token))
   308          self.assertEqual(response.status_code, 200)
   309          # test login with new password
   310          url = '/v1/auth/login/'
   311          payload = urllib.urlencode({'username': self.user1.username, 'password': old_password})
   312          response = self.client.post(url, data=payload,
   313                                      content_type='application/x-www-form-urlencoded')
   314          self.assertEqual(response.status_code, 200)
   315  
   316      def test_regenerate(self):
   317          """ Test that token regeneration works"""
   318  
   319          url = '/v1/auth/tokens/'
   320  
   321          response = self.client.post(url, '{}', content_type='application/json',
   322                                      HTTP_AUTHORIZATION='token {}'.format(self.admin_token))
   323  
   324          self.assertEqual(response.status_code, 200)
   325          self.assertNotEqual(response.data['token'], self.admin_token)
   326  
   327          self.admin_token = Token.objects.get(user=self.admin)
   328  
   329          response = self.client.post(url, '{"username" : "autotest2"}',
   330                                      content_type='application/json',
   331                                      HTTP_AUTHORIZATION='token {}'.format(self.admin_token))
   332  
   333          self.assertEqual(response.status_code, 200)
   334          self.assertNotEqual(response.data['token'], self.user1_token)
   335  
   336          response = self.client.post(url, '{"all" : "true"}',
   337                                      content_type='application/json',
   338                                      HTTP_AUTHORIZATION='token {}'.format(self.admin_token))
   339          self.assertEqual(response.status_code, 200)
   340  
   341          response = self.client.post(url, '{}', content_type='application/json',
   342                                      HTTP_AUTHORIZATION='token {}'.format(self.admin_token))
   343  
   344          self.assertEqual(response.status_code, 401)