import pytest from freezegun import freeze_time from rest_framework.status import HTTP_200_OK, HTTP_400_BAD_REQUEST from django.contrib.auth import get_user_model from django.shortcuts import reverse from baserow.core.user.handler import UserHandler User = get_user_model() @pytest.mark.django_db def test_create_user(client): response = client.post(reverse('api:user:index'), { 'name': 'Test1', 'email': 'test@test.nl', 'password': 'test12' }, format='json') assert response.status_code == HTTP_200_OK user = User.objects.get(email='test@test.nl') assert user.first_name == 'Test1' assert user.email == 'test@test.nl' assert user.password != '' response_failed = client.post(reverse('api:user:index'), { 'name': 'Test1', 'email': 'test@test.nl', 'password': 'test12' }, format='json') assert response_failed.status_code == 400 assert response_failed.json()['error'] == 'ERROR_EMAIL_ALREADY_EXISTS' response_failed = client.post(reverse('api:user:index'), { 'name': 'Test1', 'email': ' teSt@teST.nl ', 'password': 'test12' }, format='json') assert response_failed.status_code == 400 assert response_failed.json()['error'] == 'ERROR_EMAIL_ALREADY_EXISTS' response_failed_2 = client.post(reverse('api:user:index'), { 'email': 'test' }, format='json') assert response_failed_2.status_code == 400 long_password = 'x' * 256 response = client.post(reverse('api:user:index'), { 'name': 'Test2', 'email': 'test2@test.nl', 'password': long_password }, format='json') assert response.status_code == HTTP_200_OK user = User.objects.get(email='test2@test.nl') assert user.check_password(long_password) long_password = 'x' * 257 response = client.post(reverse('api:user:index'), { 'name': 'Test2', 'email': 'test2@test.nl', 'password': long_password }, format='json') response_json = response.json() assert response.status_code == HTTP_400_BAD_REQUEST assert response_json['error'] == 'ERROR_REQUEST_BODY_VALIDATION' assert response_json['detail']['password'][0]['code'] == 'max_length' @pytest.mark.django_db def test_send_reset_password_email(data_fixture, client, mailoutbox): data_fixture.create_user(email='test@localhost.nl') response = client.post( reverse('api:user:send_reset_password_email'), {}, format='json' ) response_json = response.json() assert response.status_code == HTTP_400_BAD_REQUEST assert response_json['error'] == 'ERROR_REQUEST_BODY_VALIDATION' response = client.post( reverse('api:user:send_reset_password_email'), { 'email': 'unknown@localhost.nl', 'base_url': 'http://localhost:3000' }, format='json' ) assert response.status_code == 204 assert len(mailoutbox) == 0 response = client.post( reverse('api:user:send_reset_password_email'), { 'email': 'test@localhost.nl', 'base_url': 'http://test.nl' }, format='json' ) response_json = response.json() assert response.status_code == HTTP_400_BAD_REQUEST assert response_json['error'] == 'ERROR_HOSTNAME_IS_NOT_ALLOWED' assert len(mailoutbox) == 0 response = client.post( reverse('api:user:send_reset_password_email'), { 'email': 'test@localhost.nl', 'base_url': 'http://localhost:3000' }, format='json' ) assert response.status_code == 204 assert len(mailoutbox) == 1 response = client.post( reverse('api:user:send_reset_password_email'), { 'email': ' teST@locAlhost.nl ', 'base_url': 'http://localhost:3000' }, format='json' ) assert response.status_code == 204 assert len(mailoutbox) == 2 email = mailoutbox[0] assert 'test@localhost.nl' in email.to assert email.body.index('http://localhost:3000') @pytest.mark.django_db def test_password_reset(data_fixture, client): user = data_fixture.create_user(email='test@localhost') handler = UserHandler() signer = handler.get_reset_password_signer() response = client.post( reverse('api:user:reset_password'), {}, format='json' ) response_json = response.json() assert response.status_code == HTTP_400_BAD_REQUEST assert response_json['error'] == 'ERROR_REQUEST_BODY_VALIDATION' response = client.post( reverse('api:user:reset_password'), { 'token': 'test', 'password': 'test' }, format='json' ) response_json = response.json() assert response.status_code == HTTP_400_BAD_REQUEST assert response_json['error'] == 'BAD_TOKEN_SIGNATURE' with freeze_time('2020-01-01 12:00'): token = signer.dumps(user.id) with freeze_time('2020-01-04 12:00'): response = client.post( reverse('api:user:reset_password'), { 'token': token, 'password': 'test' }, format='json' ) response_json = response.json() assert response.status_code == HTTP_400_BAD_REQUEST assert response_json['error'] == 'EXPIRED_TOKEN_SIGNATURE' with freeze_time('2020-01-01 12:00'): token = signer.dumps(9999) with freeze_time('2020-01-02 12:00'): response = client.post( reverse('api:user:reset_password'), { 'token': token, 'password': 'test' }, format='json' ) response_json = response.json() assert response.status_code == HTTP_400_BAD_REQUEST assert response_json['error'] == 'ERROR_USER_NOT_FOUND' with freeze_time('2020-01-01 12:00'): token = signer.dumps(user.id) with freeze_time('2020-01-02 12:00'): response = client.post( reverse('api:user:reset_password'), { 'token': token, 'password': 'test' }, format='json' ) assert response.status_code == 204 user.refresh_from_db() assert user.check_password('test') @pytest.mark.django_db def test_change_password(data_fixture, client): user, token = data_fixture.create_user_and_token( email='test@localhost', password='test' ) response = client.post( reverse('api:user:change_password'), {}, format='json', HTTP_AUTHORIZATION=f'JWT {token}' ) response_json = response.json() assert response.status_code == HTTP_400_BAD_REQUEST assert response_json['error'] == 'ERROR_REQUEST_BODY_VALIDATION' response = client.post( reverse('api:user:change_password'), { 'old_password': 'INCORRECT', 'new_password': 'new' }, format='json', HTTP_AUTHORIZATION=f'JWT {token}' ) response_json = response.json() assert response.status_code == HTTP_400_BAD_REQUEST assert response_json['error'] == 'ERROR_INVALID_OLD_PASSWORD' user.refresh_from_db() assert user.check_password('test') response = client.post( reverse('api:user:change_password'), { 'old_password': 'test', 'new_password': 'new' }, format='json', HTTP_AUTHORIZATION=f'JWT {token}' ) assert response.status_code == 204 user.refresh_from_db() assert user.check_password('new')