github.com/spg/deis@v1.7.3/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          first_name, last_name = 'Otto', 'Test'
   174          email = 'autotest@deis.io'
   175          submit = {
   176              'username': username,
   177              'password': password,
   178              'first_name': first_name,
   179              'last_name': last_name,
   180              'email': email,
   181              # try to abuse superuser/staff level perms
   182              'is_superuser': True,
   183              'is_staff': True,
   184          }
   185          url = '/v1/auth/register'
   186          response = self.client.post(url, json.dumps(submit), content_type='application/json')
   187          self.assertEqual(response.status_code, 201)
   188          # cancel the account
   189          url = '/v1/auth/cancel'
   190          user = User.objects.get(username=username)
   191          token = Token.objects.get(user=user).key
   192          response = self.client.delete(url,
   193                                        HTTP_AUTHORIZATION='token {}'.format(token))
   194          self.assertEqual(response.status_code, 204)
   195  
   196      def test_passwd(self):
   197          """Test that a registered user can change the password."""
   198          # test registration workflow
   199          username, password = 'newuser', 'password'
   200          first_name, last_name = 'Otto', 'Test'
   201          email = 'autotest@deis.io'
   202          submit = {
   203              'username': username,
   204              'password': password,
   205              'first_name': first_name,
   206              'last_name': last_name,
   207              'email': email,
   208          }
   209          url = '/v1/auth/register'
   210          response = self.client.post(url, json.dumps(submit), content_type='application/json')
   211          self.assertEqual(response.status_code, 201)
   212          # change password
   213          url = '/v1/auth/passwd'
   214          user = User.objects.get(username=username)
   215          token = Token.objects.get(user=user).key
   216          submit = {
   217              'password': 'password2',
   218              'new_password': password,
   219          }
   220          response = self.client.post(url, json.dumps(submit), content_type='application/json',
   221                                      HTTP_AUTHORIZATION='token {}'.format(token))
   222          self.assertEqual(response.status_code, 400)
   223          self.assertEqual(response.data, {'detail': 'Current password does not match'})
   224          self.assertEqual(response.get('content-type'), 'application/json')
   225          submit = {
   226              'password': password,
   227              'new_password': 'password2',
   228          }
   229          response = self.client.post(url, json.dumps(submit), content_type='application/json',
   230                                      HTTP_AUTHORIZATION='token {}'.format(token))
   231          self.assertEqual(response.status_code, 200)
   232          # test login with old password
   233          url = '/v1/auth/login/'
   234          payload = urllib.urlencode({'username': username, 'password': password})
   235          response = self.client.post(url, data=payload,
   236                                      content_type='application/x-www-form-urlencoded')
   237          self.assertEqual(response.status_code, 400)
   238          # test login with new password
   239          payload = urllib.urlencode({'username': username, 'password': 'password2'})
   240          response = self.client.post(url, data=payload,
   241                                      content_type='application/x-www-form-urlencoded')
   242          self.assertEqual(response.status_code, 200)
   243  
   244      def test_change_user_passwd(self):
   245          """
   246          Test that an administrator can change a user's password, while a regular user cannot.
   247          """
   248          # change password
   249          url = '/v1/auth/passwd'
   250          old_password = self.user1.password
   251          new_password = 'password'
   252          submit = {
   253              'username': self.user1.username,
   254              'password': old_password,
   255              'new_password': new_password,
   256          }
   257          response = self.client.post(url, json.dumps(submit), content_type='application/json',
   258                                      HTTP_AUTHORIZATION='token {}'.format(self.admin_token))
   259          self.assertEqual(response.status_code, 400)
   260          # test login with old password
   261          url = '/v1/auth/login/'
   262          payload = urllib.urlencode({'username': self.user1.username, 'password': old_password})
   263          response = self.client.post(url, data=payload,
   264                                      content_type='application/x-www-form-urlencoded')
   265          self.assertEqual(response.status_code, 400)
   266          # test login with new password
   267          payload = urllib.urlencode({'username': self.user1.username, 'password': new_password})
   268          response = self.client.post(url, data=payload,
   269                                      content_type='application/x-www-form-urlencoded')
   270          self.assertEqual(response.status_code, 200)
   271          # try to change back password with a regular user
   272          submit['password'], submit['new_password'] = submit['new_password'], submit['password']
   273          url = '/v1/auth/passwd'
   274          response = self.client.post(url, json.dumps(submit), content_type='application/json',
   275                                      HTTP_AUTHORIZATION='token {}'.format(self.user2_token))
   276          self.assertEqual(response.status_code, 403)
   277          # however, targeting yourself should be fine.
   278          response = self.client.post(url, json.dumps(submit), content_type='application/json',
   279                                      HTTP_AUTHORIZATION='token {}'.format(self.user1_token))
   280          self.assertEqual(response.status_code, 200)