Beispiel #1
0
class TemporaryTokenDestroyTests(APITestCase):
    def setUp(self):
        self.client = APIClient()
        self.user = UserFactory()
        self.user.set_password('Test123!')
        self.user.save()

    def test_logout(self):
        """
        Ensure we can logout of the platform.
        This deletes the TemporaryToken assigned to the user.
        """
        data = {'email': self.user.email, 'password': '******'}

        response = self.client.post(reverse('token_api'), data, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        token = TemporaryToken.objects.get(user__email=self.user.email, )

        self.client.credentials(HTTP_AUTHORIZATION='Token ' + token.key)

        response = self.client.delete(
            reverse(
                'authentication-detail',
                kwargs={'pk': token.key},
            ), )

        self.assertFalse(TemporaryToken.objects.filter(key=token.key))

        self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
class ChangePasswordTests(APITestCase):

    def setUp(self):
        self.client = APIClient()

        self.user = UserFactory()
        self.user.set_password('Test123!')
        self.user.is_active = False
        self.user.save()

        self.token = ActionToken.objects.create(
            user=self.user,
            type='password_change',
        )

    def test_change_password(self):
        """
        Ensure we can change a password with a valid token and a good password
        """

        new_password = '******'

        data = {
            'token': self.token.key,
            'new_password': new_password
        }

        response = self.client.post(
            reverse('change_password'),
            data,
            format='json',
        )

        tokens = ActionToken.objects.filter(
            user=self.user,
            type='password_change',
            expired=False,
        )

        return_user_id = json.loads(response.content)['id']

        self.assertEqual(return_user_id, self.user.id)

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

        # We sync user after this change
        user = User.objects.get(id=self.user.id)
        self.assertTrue(user.check_password(new_password))

        self.assertTrue(len(tokens) == 0)

    def test_change_password_with_bad_token(self):
        """
        Ensure we can't change a password with an invalid token
        """
        data = {
            'token': 'test',
            'new_password': '******'
        }

        response = self.client.post(
            reverse('change_password'),
            data,
            format='json',
        )

        tokens = ActionToken.objects.filter(
            user=self.user,
            type='password_change',
        )

        content = {
            'token': "test is not a valid token.",
        }
        self.assertEqual(json.loads(response.content), content)

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

        self.assertTrue(len(tokens) == 1)

        self.assertFalse(self.user.check_password('dWqq!Kld3#9dw'))

    def test_change_password_without_token(self):
        """
        Ensure we can't change a password without token
        """
        data = {
            'new_password': '******'
        }

        response = self.client.post(
            reverse('change_password'),
            data,
            format='json',
        )

        tokens = ActionToken.objects.filter(
            user=self.user,
            type='password_change',
        )

        content = {
            'token': ["This field is required."],
        }
        self.assertEqual(json.loads(response.content), content)

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

        self.assertTrue(len(tokens) == 1)

        self.assertFalse(self.user.check_password('dWqq!Kld3#9dw'))

    def test_change_password_with_an_empty_token(self):
        """
        Ensure we can't change a password with an empty token
        """
        data = {
            'token': '',
            'new_password': '******'
        }

        response = self.client.post(
            reverse('change_password'),
            data,
            format='json',
        )

        tokens = ActionToken.objects.filter(
            user=self.user,
            type='password_change',
        )

        content = {
            'token': ["This field may not be blank."],
        }
        self.assertEqual(json.loads(response.content), content)

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

        self.assertTrue(len(tokens) == 1)

        self.assertFalse(self.user.check_password('dWqq!Kld3#9dw'))

    def test_change_password_without_new_password(self):
        """
        Ensure we can't change a password without a new password
        """
        data = {
            'token': self.token.key,
        }

        response = self.client.post(
            reverse('change_password'),
            data,
            format='json',
        )

        tokens = ActionToken.objects.filter(
            user=self.user,
            type='password_change',
        )

        content = {
            'new_password': ["This field is required."],
        }
        self.assertEqual(json.loads(response.content), content)

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

        self.assertTrue(len(tokens) == 1)

        self.assertFalse(self.user.check_password('dWqq!Kld3#9dw'))

    def test_change_password_with_an_empty_new_password(self):
        """
        Ensure we can't change a password without a valid new password
        """
        data = {
            'token': self.token.key,
            'new_password': '',
        }

        response = self.client.post(
            reverse('change_password'),
            data,
            format='json',
        )

        tokens = ActionToken.objects.filter(
            user=self.user,
            type='password_change',
        )

        content = {
            'new_password': ["This field may not be blank."],
        }
        self.assertEqual(json.loads(response.content), content)

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

        self.assertTrue(len(tokens) == 1)

        self.assertFalse(self.user.check_password('dWqq!Kld3#9dw'))

    def test_change_password_with_a_weak_new_password(self):
        """
        Ensure we can't change a password with a weak new password
        """
        data = {
            'token': self.token.key,
            'new_password': '******'
        }

        response = self.client.post(
            reverse('change_password'),
            data,
            format='json',
        )

        tokens = ActionToken.objects.filter(
            user=self.user,
            type='password_change',
        )

        content = {
            'new_password': [
                'This password is too short. '
                'It must contain at least 8 characters.',
            ],
        }
        self.assertEqual(json.loads(response.content), content)

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

        self.assertTrue(len(tokens) == 1)

        self.assertFalse(self.user.check_password('akrent'))
class UsersIdTests(SerializerTestCase):
    @classmethod
    def setUpClass(cls):
        super(UsersIdTests, cls).setUpClass()
        cls.user_attrs = [
            'id',
            'url',
            'email',
            'first_name',
            'last_name',
            'is_active',
            'phone',
            'other_phone',
            'is_superuser',
            'is_staff',
            'last_login',
            'date_joined',
            'groups',
            'user_permissions',
        ]

    def setUp(self):
        self.client = APIClient()

        self.user = UserFactory()
        self.user.set_password('Test123!')
        self.user.save()

        self.admin = AdminFactory()
        self.admin.set_password('Test123!')
        self.admin.save()

    def test_retrieve_user_id_not_exist(self):
        """
        Ensure we can't retrieve a user that doesn't exist.
        """
        self.client.force_authenticate(user=self.admin)

        response = self.client.get(reverse(
            'user-detail',
            kwargs={'pk': 999},
        ))

        content = {"detail": "Not found."}
        self.assertEqual(json.loads(response.content), content)

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

    def test_retrieve_user_id_not_exist_without_permission(self):
        """
        Ensure we can't know a user doesn't exist without permission
        """
        self.client.force_authenticate(user=self.user)

        response = self.client.get(reverse(
            'user-detail',
            kwargs={'pk': 999},
        ))

        content = {
            'detail': 'You do not have permission to perform this action.'
        }
        self.assertEqual(json.loads(response.content), content)

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

    def test_retrieve_user(self):
        """
        Ensure we can retrieve a user.
        """
        self.client.force_authenticate(user=self.user)

        response = self.client.get(
            reverse(
                'user-detail',
                kwargs={'pk': self.user.id},
            ))

        content = json.loads(response.content)

        # Check id of the user
        self.assertEqual(content['id'], 1)

        self.validate_attrs(content)

        # Check the status code
        self.assertEqual(response.status_code, status.HTTP_200_OK)

    def test_retrieve_user_profile(self):
        """
        Ensure we can retrieve our details through /profile.
        """
        self.client.force_authenticate(user=self.user)

        response = self.client.get(reverse('profile', ))

        content = json.loads(response.content)

        # Check id of the user
        self.assertEqual(content['id'], 1)

        self.validate_attrs(content)

        # Check the status code
        self.assertEqual(response.status_code, status.HTTP_200_OK)

    def test_partial_update_user_with_permission(self):
        """
        Ensure we can update a specific user if caller has permission.
        """

        data = {
            "phone": "1234567890",
        }

        self.client.force_authenticate(user=self.admin)

        response = self.client.patch(
            reverse(
                'user-detail',
                kwargs={'pk': self.user.id},
            ),
            data,
            format='json',
        )

        content = json.loads(response.content)

        # Check if update was successful
        self.assertEqual(content['phone'], data['phone'])

        # Check id of the user
        self.assertEqual(content['id'], 1)

        self.validate_attrs(content)

        # Check the status code
        self.assertEqual(response.status_code, status.HTTP_200_OK)

    def test_partial_update_user_with_permission_change_password(self):
        """
        Ensure we can change password if current password is provided and the
        new password is validated.
        """

        data = {"password": "******", "new_password": "******"}

        self.client.force_authenticate(user=self.user)

        response = self.client.patch(
            reverse(
                'user-detail',
                kwargs={'pk': self.user.id},
            ),
            data,
            format='json',
        )

        content = json.loads(response.content)

        # Check id of the user
        self.assertEqual(content['id'], 1)

        self.validate_attrs(content)

        self.user.refresh_from_db()

        # Ensure that the password has been changed successfully
        self.assertTrue(self.user.check_password("!321tseT"))

        # Check the status code
        self.assertEqual(response.status_code, status.HTTP_200_OK)

    def test_update_user_with_permission(self):
        """
        Ensure we can update a specific user if caller has permission.
        Put requires a full update, including password.
        """
        data = {
            'password': '******',
            'new_password': '******',
            'phone': '1234567890',
            'first_name': 'Chuck',
            'last_name': 'Norris',
        }

        self.client.force_authenticate(user=self.user)

        response = self.client.put(
            reverse(
                'user-detail',
                kwargs={'pk': self.user.id},
            ),
            data,
            format='json',
        )

        content = json.loads(response.content)

        self.user.refresh_from_db()

        # Check if update was successful
        self.assertEqual(content['phone'], data['phone'])
        self.assertTrue(self.user.check_password("!321tset"))

        # Check id of the user
        self.assertEqual(content['id'], 1)

        self.validate_attrs(content)

        # Check the status code
        self.assertEqual(response.status_code, status.HTTP_200_OK)

    def test_update_user_without_permission(self):
        """
        Ensure we can't update a specific user doesn't have permission.
        """

        data = {
            "phone": "1234567890",
        }

        self.client.force_authenticate(user=self.user)

        response = self.client.patch(
            reverse(
                'user-detail',
                kwargs={'pk': self.admin.id},
            ),
            data,
            format='json',
        )

        content = {
            'detail': 'You do not have permission to perform this action.'
        }
        self.assertEqual(json.loads(response.content), content)

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

    def test_update_non_existent_user(self):
        """
        Ensure we get permission denied when trying to update an invalid user.
        """

        data = {
            "phone": "1234567890",
        }

        self.client.force_authenticate(user=self.user)

        response = self.client.patch(
            reverse(
                'user-detail',
                kwargs={'pk': 9999},
            ),
            data,
            format='json',
        )

        content = {
            'detail': 'You do not have permission to perform this action.'
        }
        self.assertEqual(json.loads(response.content), content)

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

    def test_update_non_existent_user_as_admin(self):
        """
        Ensure we get not found when trying to update an invalid user as
        an admin.
        """

        data = {
            "phone": "1234567890",
        }

        self.client.force_authenticate(user=self.admin)

        response = self.client.patch(
            reverse(
                'user-detail',
                kwargs={'pk': 9999},
            ),
            data,
            format='json',
        )

        content = {'detail': 'Not found.'}

        self.assertEqual(json.loads(response.content), content)

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

    def test_update_user_weak_new_password(self):
        """
        Ensure we can't update our password if it is not validated.
        """

        data = {
            "phone": "1234567890",
            "password": "******",
            "new_password": "******",
        }

        self.client.force_authenticate(user=self.user)

        response = self.client.patch(
            reverse(
                'user-detail',
                kwargs={'pk': self.user.id},
            ),
            data,
            format='json',
        )

        content = {
            'new_password': [
                'This password is too common.',
                'This password is entirely numeric.'
            ]
        }
        self.assertEqual(json.loads(response.content), content)

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

    def test_update_user_missing_old_password(self):
        """
        Ensure we can't update our password if the current one is not provided.
        """

        data = {
            "phone": "1234567890",
            "new_password": "******",
        }

        self.client.force_authenticate(user=self.user)

        response = self.client.patch(
            reverse(
                'user-detail',
                kwargs={'pk': self.user.id},
            ),
            data,
            format='json',
        )

        content = {'password': '******'}
        self.assertEqual(json.loads(response.content), content)

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

    def test_update_user_wrong_old_password(self):
        """
        Ensure we can't update our password if the current one is wrong.
        """

        data = {
            "phone": "1234567890",
            "password": "******",
            "new_password": "******",
        }

        self.client.force_authenticate(user=self.user)

        response = self.client.patch(
            reverse(
                'user-detail',
                kwargs={'pk': self.user.id},
            ),
            data,
            format='json',
        )

        content = {'password': '******'}
        self.assertEqual(json.loads(response.content), content)

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

    def test_delete_user_as_admin(self):
        """
        Ensure we can deactivate a user as an admin.
        """
        self.client.force_authenticate(user=self.admin)

        response = self.client.delete(
            reverse(
                'user-detail',
                kwargs={'pk': self.user.id},
            ), )
        self.user.refresh_from_db()

        self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
        self.assertFalse(self.user.is_active)

        self.user.is_active = True
        self.user.refresh_from_db()

    def test_delete_user(self):
        """
        Ensure that a user can't deactivate its own account.
        """
        self.client.force_authenticate(user=self.user)

        response = self.client.delete(
            reverse(
                'user-detail',
                kwargs={'pk': self.user.id},
            ), )
        self.user.refresh_from_db()

        self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
        self.assertFalse(self.user.is_active)

        self.user.is_active = True
        self.user.refresh_from_db()

    def test_delete_inexistent_user(self):
        """
        Ensure that deleting a non-existent user does nothing.
        """
        self.client.force_authenticate(user=self.user)

        response = self.client.delete(
            reverse(
                'user-detail',
                kwargs={'pk': 999},
            ), )

        self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
Beispiel #4
0
class ObtainTemporaryAuthTokenTests(APITestCase):
    def setUp(self):
        self.client = APIClient()
        self.user = UserFactory()
        self.user.set_password('Test123!')
        self.user.save()
        self.url = reverse('token_api')

    def test_authenticate_email(self):
        """
        Ensure we can authenticate on the platform.
        """
        data = {'email': self.user.email, 'password': '******'}

        response = self.client.post(self.url, data, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        token = TemporaryToken.objects.get(user__email=self.user.email, )
        self.assertContains(response, token)

    def test_authenticate(self):
        """
        Ensure we can authenticate on the platform using a email.
        """
        data = {'email': self.user.email, 'password': '******'}

        response = self.client.post(self.url, data, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        token = TemporaryToken.objects.get(user__email=self.user.email, )
        self.assertContains(response, token)

    def test_authenticate_expired_token(self):
        """
        Ensure we can authenticate on the platform when token is expired.
        """
        data = {'email': self.user.email, 'password': '******'}

        response = self.client.post(self.url, data, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        token_old = TemporaryToken.objects.get(user__email=self.user.email, )
        token_old.expire()

        response = self.client.post(self.url, data, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        token_new = TemporaryToken.objects.get(user__email=self.user.email, )

        self.assertNotContains(response, token_old)
        self.assertContains(response, token_new)

    def test_authenticate_bad_password(self):
        """
        Ensure we can't authenticate with a wrong password'
        """
        data = {
            'email': self.user.email,
            'password': '******'  # No caps on the first letter
        }

        response = self.client.post(self.url, data, format='json')
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

        tokens = TemporaryToken.objects.filter(
            user__email=self.user.email).count()
        self.assertEqual(0, tokens)

    def test_authenticate_bad_email(self):
        """
        Ensure we can't authenticate with a wrong email
        """
        data = {
            'email': 'Jon@john',  # Forget the `h` in `John`
            'password': '******'
        }

        response = self.client.post(self.url, data, format='json')
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

        tokens = TemporaryToken.objects.filter(
            user__email=self.user.email).count()
        self.assertEqual(0, tokens)

    def test_authenticate_inactive(self):
        """
        Ensure we can't authenticate if user is inactive
        """
        data = {'email': self.user.email, 'password': '******'}

        User.objects.filter(id=self.user.id).update(is_active=False)

        response = self.client.post(self.url, data, format='json')

        content = {
            "non_field_errors":
            ["Unable to log in with provided credentials."]
        }

        self.assertEqual(json.loads(response.content), content)
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

        tokens = TemporaryToken.objects.filter(
            user__email=self.user.email).count()
        self.assertEqual(0, tokens)

    def test_authenticate_missing_parameter(self):
        """
        Ensure we can't authenticate if "email" or "password" are not
        provided.
        """
        response = self.client.post(self.url, {}, format='json')

        content = {
            'password': ['This field is required.'],
            'email': ['This field is required.']
        }

        self.assertEqual(json.loads(response.content), content)
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

        tokens = TemporaryToken.objects.filter(
            user__email=self.user.email).count()
        self.assertEqual(0, tokens)
Beispiel #5
0
class ResetPasswordTests(APITestCase):
    def setUp(self):
        self.client = APIClient()

        self.user = UserFactory()
        self.user.set_password('Test123!')
        self.user.is_active = False
        self.user.save()

    @override_settings(
        LOCAL_SETTINGS={
            "EMAIL_SERVICE": True,
            "FRONTEND_INTEGRATION": {
                "FORGOT_PASSWORD_URL": "fake_url",
            }
        })
    def test_create_new_token(self):
        """
        Ensure we can have a new token to change our password
        """
        data = {
            'email': self.user.email,
        }

        response = self.client.post(
            reverse('reset_password'),
            data,
            format='json',
        )

        # The token has been created
        tokens = ActionToken.objects.filter(
            user=self.user,
            type='password_change',
        )

        self.assertEqual(response.content, b'')

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

        self.assertTrue(len(tokens) == 1)

    @override_settings(
        LOCAL_SETTINGS={
            "EMAIL_SERVICE": True,
            "FRONTEND_INTEGRATION": {
                "FORGOT_PASSWORD_URL": "fake_url",
            }
        })
    def test_create_new_token_without_email_param(self):
        """
        Ensure we can't have a new token to change our password without
        give our email in param
        """
        data = dict()

        response = self.client.post(
            reverse('reset_password'),
            data,
            format='json',
        )

        # The token has been created
        tokens = ActionToken.objects.filter(
            user=self.user,
            type='password_change',
        )

        content = {
            'email': ["This field is required."],
        }
        self.assertEqual(json.loads(response.content), content)

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

        self.assertTrue(len(tokens) == 0)

    @override_settings(
        LOCAL_SETTINGS={
            "EMAIL_SERVICE": True,
            "FRONTEND_INTEGRATION": {
                "FORGOT_PASSWORD_URL": "fake_url",
            }
        })
    def test_create_new_token_with_an_empty_email_param(self):
        """
        Ensure we can't have a new token to change our password without
        give our email in param
        """
        data = {
            'email': '',
        }

        response = self.client.post(
            reverse('reset_password'),
            data,
            format='json',
        )

        # The token has been created
        tokens = ActionToken.objects.filter(
            user=self.user,
            type='password_change',
        )

        content = {
            'email': ["This field may not be blank."],
        }
        self.assertEqual(json.loads(response.content), content)

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

        self.assertTrue(len(tokens) == 0)

    @override_settings(
        LOCAL_SETTINGS={
            "EMAIL_SERVICE": True,
            "FRONTEND_INTEGRATION": {
                "FORGOT_PASSWORD_URL": "fake_url",
            }
        })
    def test_create_new_token_with_bad_email(self):
        """
        Ensure we can't have a new token to change our password without
        a valid email
        """
        data = {
            'email': 'test',
        }

        response = self.client.post(
            reverse('reset_password'),
            data,
            format='json',
        )

        # The token has been created
        tokens = ActionToken.objects.filter(
            user=self.user,
            type='password_change',
        )

        content = {'email': ['Enter a valid email address.']}

        self.assertEqual(json.loads(response.content), content)

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

        self.assertTrue(len(tokens) == 0)

    @override_settings(
        LOCAL_SETTINGS={
            "EMAIL_SERVICE": True,
            "FRONTEND_INTEGRATION": {
                "FORGOT_PASSWORD_URL": "fake_url",
            }
        })
    def test_create_new_token_with_non_existent_email(self):
        """
        Ensure we can't have a new token to change our password without
        a valid email
        """
        data = {
            'email': '*****@*****.**',
        }

        response = self.client.post(
            reverse('reset_password'),
            data,
            format='json',
        )

        # The token has been created
        tokens = ActionToken.objects.filter(
            user=self.user,
            type='password_change',
        )

        content = {'email': ['No account associated to this email address.']}

        self.assertEqual(json.loads(response.content), content)

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

        self.assertTrue(len(tokens) == 0)

    @override_settings(
        LOCAL_SETTINGS={
            "EMAIL_SERVICE": True,
            "FRONTEND_INTEGRATION": {
                "FORGOT_PASSWORD_URL": "fake_url",
            }
        })
    def test_create_new_token_when_token_already_exist(self):
        """
        Ensure we can have a new token to change our password
        """
        # We create a token before launch the test
        ActionToken.objects.create(
            user=self.user,
            type='password_change',
        )

        data = {
            'email': self.user.email,
        }

        response = self.client.post(
            reverse('reset_password'),
            data,
            format='json',
        )

        # The token has been created
        tokens = ActionToken.objects.filter(
            user=self.user,
            type='password_change',
            expired=False,
        )

        self.assertEqual(response.content, b'')

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

        self.assertTrue(len(tokens) == 1)

    @override_settings(
        LOCAL_SETTINGS={
            "EMAIL_SERVICE": False,
            "FRONTEND_INTEGRATION": {
                "FORGOT_PASSWORD_URL": "fake_url",
            }
        })
    def test_create_new_token_without_email_service(self):
        """
        Ensure we can have a new token to change our password
        """
        data = {
            'email': self.user.email,
        }

        response = self.client.post(
            reverse('reset_password'),
            data,
            format='json',
        )

        # The token has been created
        tokens = ActionToken.objects.filter(
            user=self.user,
            type='password_change',
        )

        self.assertEqual(response.content, b'')

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

        self.assertTrue(len(tokens) == 0)

    @override_settings(
        LOCAL_SETTINGS={
            "EMAIL_SERVICE": True,
            "FRONTEND_INTEGRATION": {
                "FORGOT_PASSWORD_URL": "fake_url",
            }
        })
    @mock.patch('project.services.EmailMessage.send', return_value=0)
    def test_create_new_token_with_failure_on_email_service(self, send):
        """
        Ensure we can have a new token to change our password
        """
        data = {
            'email': self.user.email,
        }

        response = self.client.post(
            reverse('reset_password'),
            data,
            format='json',
        )

        # The token has been created
        tokens = ActionToken.objects.filter(
            user=self.user,
            type='password_change',
        )

        content = {
            'detail':
            "Your token has been created but no email "
            "has been sent. Please contact the administration.",
        }
        self.assertEqual(json.loads(response.content), content)

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

        self.assertTrue(len(tokens) == 1)
class TemporaryTokenAuthenticationTests(APITestCase):
    def setUp(self):
        self.client = APIClient()
        self.user = UserFactory()
        self.user.set_password('Test123!')
        self.user.save()

    def test_authenticate(self):
        """
        Ensure we can authenticate on the platform by providing a valid
        TemporaryToken.
        """
        data = {'email': self.user.email, 'password': '******'}

        response = self.client.post(reverse('token_api'), data, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        token_key = (json.loads(response.content)['token'])

        self.client.credentials(HTTP_AUTHORIZATION='Token ' + token_key)

        # This could be any url and any method. It is only used to test the
        # token authentication.
        response = self.client.delete(
            reverse(
                'authentication-detail',
                kwargs={'pk': token_key},
            ), )

        self.assertFalse(TemporaryToken.objects.filter(key=token_key))

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

    @override_settings(
        REST_FRAMEWORK_TEMPORARY_TOKENS={
            'MINUTES': 30,
            'RENEW_ON_SUCCESS': False,
            'USE_AUTHENTICATION_BACKENDS': False,
        })
    def test_authenticate_no_renew(self):
        """
        Ensure that a token is not renewed when the authenticated user calls
        the API.
        """
        data = {'email': self.user.email, 'password': '******'}

        response = self.client.post(reverse('token_api'), data, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        token_key = (json.loads(response.content)['token'])

        token = TemporaryToken.objects.get(key=token_key)

        expiration_date = token.expires

        self.client.credentials(HTTP_AUTHORIZATION='Token ' + token_key)

        # This could be any url and any method. It is only used to test the
        # token authentication.
        response = self.client.get(
            reverse(
                'authentication-detail',
                kwargs={'pk': token_key},
            ), )

        token.refresh_from_db()

        self.assertEqual(expiration_date, token.expires)

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

    def test_authenticate_invalid_token(self):
        """
        Ensure we can't authenticate on the platform by providing an invalid
        TemporaryToken.
        """

        self.client.credentials(HTTP_AUTHORIZATION='Token invalid_token')

        # This could be any url and any method. It is only used to test the
        # token authentication.
        response = self.client.delete(
            reverse(
                'authentication-detail',
                kwargs={'pk': 'invalid_token'},
            ), )

        content = {"detail": "Invalid token"}

        self.assertEqual(json.loads(response.content), content)

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

    def test_authenticate_expired_token(self):
        """
        Ensure we can't authenticate on the platform by providing an expired
        TemporaryToken.
        """
        data = {'email': self.user.email, 'password': '******'}

        response = self.client.post(reverse('token_api'), data, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        token = TemporaryToken.objects.get(user__email=self.user.email, )
        token.expire()

        self.client.credentials(HTTP_AUTHORIZATION='Token ' + token.key)

        # This could be any url and any method. It is only used to test the
        # token authentication.
        response = self.client.delete(
            reverse(
                'authentication-detail',
                kwargs={'pk': 'invalid_token'},
            ), )

        content = {'detail': 'Token has expired'}

        self.assertEqual(json.loads(response.content), content)

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

    def test_authenticate_inactive_user(self):
        """
        Ensure we can't authenticate on the platform by providing a valid
        TemporaryToken if user is inactive.
        """
        data = {'email': self.user.email, 'password': '******'}

        response = self.client.post(reverse('token_api'), data, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        token = TemporaryToken.objects.get(user__email=self.user.email, )

        setattr(self.user, 'is_active', False)
        self.user.save()

        self.client.credentials(HTTP_AUTHORIZATION='Token ' + token.key)

        # This could be any url and any method. It is only used to test the
        # token authentication.
        response = self.client.delete(
            reverse(
                'authentication-detail',
                kwargs={'pk': token.key},
            ), )

        content = {'detail': 'User inactive or deleted'}

        self.assertEqual(json.loads(response.content), content)

        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
class UsersActivationTests(APITestCase):
    def setUp(self):
        self.client = APIClient()

        self.user = UserFactory()
        self.user.set_password('Test123!')
        self.user.is_active = False
        self.user.save()

        self.activation_token = ActionToken.objects.create(
            user=self.user,
            type='account_activation',
        )

    def test_activate_user(self):
        """
        Ensure we can activate a user by using an ActionToken.
        """
        self.client.force_authenticate(user=self.user)

        data = {
            'activation_token': self.activation_token.key,
        }

        response = self.client.post(
            reverse('users_activation'),
            data,
            format='json',
        )

        # It's the good user
        self.assertEqual(json.loads(response.content)['id'], self.user.id)

        # We read a new time the user to be synchronized
        user_sync = User.objects.get(id=self.user.id)

        # The user is now active
        self.assertTrue(user_sync.is_active)

        # The token has been removed
        tokens = ActionToken.objects.filter(
            user=user_sync,
            type='account_activation',
        )
        self.assertTrue(len(tokens) == 0)

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

    def test_activate_user_with_bad_token(self):
        """
        Ensure we can't activate a user without a good ActionToken.
        """
        self.client.force_authenticate(user=self.user)

        data = {
            'activation_token': 'bad_token',
        }

        response = self.client.post(
            reverse('users_activation'),
            data,
            format='json',
        )

        content = {
            'activation_token': '"bad_token" is not a valid activation_token.'
        }
        self.assertEqual(json.loads(response.content), content)

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