From d8c4106fcf9a648f74a30a53b938d5cf474c60fe Mon Sep 17 00:00:00 2001 From: Sam Date: Sun, 13 Mar 2022 08:39:50 +0100 Subject: [PATCH] API & Client - remove password confirmation --- fittrackee/tests/users/test_auth_api.py | 143 +----------------- fittrackee/tests/users/test_users_utils.py | 31 +--- fittrackee/users/auth.py | 20 +-- fittrackee/users/utils/controls.py | 25 ++- .../User/ProfileEdition/UserInfosEdition.vue | 10 -- .../src/components/User/UserAuthForm.vue | 18 --- fittrackee_client/src/locales/en/user.json | 3 - fittrackee_client/src/locales/fr/user.json | 3 - fittrackee_client/src/types/user.ts | 3 - 9 files changed, 21 insertions(+), 235 deletions(-) diff --git a/fittrackee/tests/users/test_auth_api.py b/fittrackee/tests/users/test_auth_api.py index bfddb843..5c9a4f5c 100644 --- a/fittrackee/tests/users/test_auth_api.py +++ b/fittrackee/tests/users/test_auth_api.py @@ -25,7 +25,6 @@ class TestUserRegistration(ApiTestCaseMixin): username='justatest', email='test@test.com', password='12345678', - password_conf='12345678', ) ), content_type='application/json', @@ -53,7 +52,6 @@ class TestUserRegistration(ApiTestCaseMixin): username=input_username, email='another_email@test.com', password='12345678', - password_conf='12345678', ) ), content_type='application/json', @@ -76,7 +74,6 @@ class TestUserRegistration(ApiTestCaseMixin): username='test', email='test@test.com', password='12345678', - password_conf='12345678', ) ), content_type='application/json', @@ -96,7 +93,6 @@ class TestUserRegistration(ApiTestCaseMixin): username='', email='test@test.com', password='12345678', - password_conf='12345678', ) ), content_type='application/json', @@ -123,7 +119,6 @@ class TestUserRegistration(ApiTestCaseMixin): username='a' * 31, email='test@test.com', password='12345678', - password_conf='12345678', ) ), content_type='application/json', @@ -150,7 +145,6 @@ class TestUserRegistration(ApiTestCaseMixin): username=input_username, email='test@test.com', password='12345678', - password_conf='12345678', ) ), content_type='application/json', @@ -172,7 +166,6 @@ class TestUserRegistration(ApiTestCaseMixin): username='test', email='test@test', password='12345678', - password_conf='12345678', ) ), content_type='application/json', @@ -192,7 +185,6 @@ class TestUserRegistration(ApiTestCaseMixin): username='test', email='test@test.com', password='1234567', - password_conf='1234567', ) ), content_type='application/json', @@ -200,27 +192,6 @@ class TestUserRegistration(ApiTestCaseMixin): self.assert_400(response, "password: 8 characters required\n") - def test_it_returns_error_if_passwords_mismatch(self, app: Flask) -> None: - client = app.test_client() - - response = client.post( - '/api/auth/register', - data=json.dumps( - dict( - username='test', - email='test@test.com', - password='12345678', - password_conf='87654321', - ) - ), - content_type='application/json', - ) - - self.assert_400( - response, - "password: password and password confirmation do not match\n", - ) - def test_it_returns_error_if_payload_is_invalid(self, app: Flask) -> None: client = app.test_client() response = client.post( @@ -242,7 +213,6 @@ class TestUserRegistration(ApiTestCaseMixin): dict( email='test@test.com', password='12345678', - password_conf='12345678', ) ), content_type='application/json', @@ -259,7 +229,6 @@ class TestUserRegistration(ApiTestCaseMixin): dict( username='test', password='12345678', - password_conf='12345678', ) ), content_type='application/json', @@ -276,23 +245,6 @@ class TestUserRegistration(ApiTestCaseMixin): dict( username='test', email='test@test.com', - password_conf='12345678', - ) - ), - content_type='application/json', - ) - - self.assert_400(response) - - def test_it_returns_error_if_password_confirmation_is_missing( - self, app: Flask - ) -> None: - client = app.test_client() - response = client.post( - '/api/auth/register', - data=json.dumps( - dict( - username='test', email='test@test.com', password='12345678' ) ), content_type='application/json', @@ -564,7 +516,6 @@ class TestUserProfileUpdate(ApiTestCaseMixin): bio='Nothing to tell', birth_date='1980-01-01', password='87654321', - password_conf='87654321', ) ), headers=dict(Authorization=f'Bearer {auth_token}'), @@ -672,63 +623,6 @@ class TestUserProfileUpdate(ApiTestCaseMixin): self.assert_400(response) - def test_it_returns_error_if_passwords_mismatch( - self, app: Flask, user_1: User - ) -> None: - client, auth_token = self.get_test_client_and_auth_token( - app, user_1.email - ) - - response = client.post( - '/api/auth/profile/edit', - content_type='application/json', - data=json.dumps( - dict( - first_name='John', - last_name='Doe', - location='Somewhere', - bio='just a random guy', - birth_date='1980-01-01', - password='87654321', - password_conf='876543210', - ) - ), - headers=dict(Authorization=f'Bearer {auth_token}'), - ) - - self.assert_400( - response, - 'password: password and password confirmation do not match\n', - ) - - def test_it_returns_error_if_password_confirmation_is_missing( - self, app: Flask, user_1: User - ) -> None: - client, auth_token = self.get_test_client_and_auth_token( - app, user_1.email - ) - - response = client.post( - '/api/auth/profile/edit', - content_type='application/json', - data=json.dumps( - dict( - first_name='John', - last_name='Doe', - location='Somewhere', - bio='just a random guy', - birth_date='1980-01-01', - password='87654321', - ) - ), - headers=dict(Authorization=f'Bearer {auth_token}'), - ) - - self.assert_400( - response, - 'password: password and password confirmation do not match\n', - ) - class TestUserPreferencesUpdate(ApiTestCaseMixin): def test_it_updates_user_preferences( @@ -1192,7 +1086,6 @@ class TestRegistrationConfiguration(ApiTestCaseMixin): username='user4', email='user4@test.com', password='12345678', - password_conf='12345678', ) ), content_type='application/json', @@ -1214,7 +1107,6 @@ class TestRegistrationConfiguration(ApiTestCaseMixin): username='sam', email='sam@test.com', password='12345678', - password_conf='12345678', ) ), content_type='application/json', @@ -1227,7 +1119,6 @@ class TestRegistrationConfiguration(ApiTestCaseMixin): username='new', email='new@test.com', password='12345678', - password_conf='12345678', ) ), content_type='application/json', @@ -1248,7 +1139,6 @@ class TestRegistrationConfiguration(ApiTestCaseMixin): username='sam', email='sam@test.com', password='12345678', - password_conf='12345678', ) ), content_type='application/json', @@ -1260,7 +1150,6 @@ class TestRegistrationConfiguration(ApiTestCaseMixin): username='new', email='new@test.com', password='12345678', - password_conf='12345678', ) ), content_type='application/json', @@ -1331,12 +1220,7 @@ class TestPasswordUpdate(ApiTestCaseMixin): response = client.post( '/api/auth/password/update', - data=json.dumps( - dict( - token='xxx', - password='1234567', - ) - ), + data=json.dumps(dict()), content_type='application/json', ) @@ -1350,7 +1234,6 @@ class TestPasswordUpdate(ApiTestCaseMixin): data=json.dumps( dict( password='12345678', - password_conf='12345678', ) ), content_type='application/json', @@ -1366,25 +1249,6 @@ class TestPasswordUpdate(ApiTestCaseMixin): data=json.dumps( dict( token='xxx', - password_conf='12345678', - ) - ), - content_type='application/json', - ) - - self.assert_400(response) - - def test_it_returns_error_if_password_confirmation_is_missing( - self, app: Flask - ) -> None: - client = app.test_client() - - response = client.post( - '/api/auth/password/update', - data=json.dumps( - dict( - token='xxx', - password='12345678', ) ), content_type='application/json', @@ -1424,7 +1288,6 @@ class TestPasswordUpdate(ApiTestCaseMixin): dict( token=token, password='12345678', - password_conf='12345678', ) ), content_type='application/json', @@ -1446,7 +1309,6 @@ class TestPasswordUpdate(ApiTestCaseMixin): dict( token=token, password='1234567', - password_conf='1234567', ) ), content_type='application/json', @@ -1454,7 +1316,7 @@ class TestPasswordUpdate(ApiTestCaseMixin): self.assert_400(response, 'password: 8 characters required\n') - def test_it_update_password(self, app: Flask, user_1: User) -> None: + def test_it_updates_password(self, app: Flask, user_1: User) -> None: token = get_user_token(user_1.id, password_reset=True) client = app.test_client() @@ -1464,7 +1326,6 @@ class TestPasswordUpdate(ApiTestCaseMixin): dict( token=token, password='12345678', - password_conf='12345678', ) ), content_type='application/json', diff --git a/fittrackee/tests/users/test_users_utils.py b/fittrackee/tests/users/test_users_utils.py index 30428508..82e6f8aa 100644 --- a/fittrackee/tests/users/test_users_utils.py +++ b/fittrackee/tests/users/test_users_utils.py @@ -7,7 +7,7 @@ from fittrackee.users.exceptions import UserNotFoundException from fittrackee.users.models import User from fittrackee.users.utils.admin import set_admin_rights from fittrackee.users.utils.controls import ( - check_passwords, + check_password, check_username, is_valid_email, register_controls, @@ -70,13 +70,6 @@ class TestIsValidEmail: class TestCheckPasswords: - def test_it_returns_error_message_string_if_passwords_do_not_match( - self, - ) -> None: - assert check_passwords('password', 'pasword') == ( - 'password: password and password confirmation do not match\n' - ) - @pytest.mark.parametrize( ('input_password_length',), [ @@ -89,7 +82,7 @@ class TestCheckPasswords: self, input_password_length: int ) -> None: password = random_string(input_password_length) - assert check_passwords(password, password) == ( + assert check_password(password) == ( 'password: 8 characters required\n' ) @@ -104,15 +97,7 @@ class TestCheckPasswords: self, input_password_length: int ) -> None: password = random_string(input_password_length) - assert check_passwords(password, password) == '' - - def test_it_returns_multiple_errors(self) -> None: - password = random_string(3) - password_conf = random_string(8) - assert check_passwords(password, password_conf) == ( - 'password: password and password confirmation do not match\n' - 'password: 8 characters required\n' - ) + assert check_password(password) == '' class TestIsUsernameValid: @@ -170,7 +155,7 @@ class TestRegisterControls: def test_it_calls_all_validators(self) -> None: with patch( - self.module_path + 'check_passwords' + self.module_path + 'check_password' ) as check_passwords_mock, patch( self.module_path + 'check_username' ) as check_username_mock, patch( @@ -180,12 +165,9 @@ class TestRegisterControls: self.valid_username, self.valid_email, self.valid_password, - self.valid_password, ) - check_passwords_mock.assert_called_once_with( - self.valid_password, self.valid_password - ) + check_passwords_mock.assert_called_once_with(self.valid_password) check_username_mock.assert_called_once_with(self.valid_username) is_valid_email_mock.assert_called_once_with(self.valid_email) @@ -195,7 +177,6 @@ class TestRegisterControls: self.valid_username, self.valid_email, self.valid_password, - self.valid_password, ) == '' ) @@ -206,9 +187,7 @@ class TestRegisterControls: username=invalid_username, email=invalid_username, password=random_string(8), - password_conf=random_string(8), ) == ( 'username: 3 to 30 characters required\n' 'email: valid email must be provided\n' - 'password: password and password confirmation do not match\n' ) diff --git a/fittrackee/users/auth.py b/fittrackee/users/auth.py index 389c6e28..b99f8656 100644 --- a/fittrackee/users/auth.py +++ b/fittrackee/users/auth.py @@ -27,7 +27,7 @@ from fittrackee.workouts.models import Sport from .decorators import authenticate from .models import User, UserSportPreference -from .utils.controls import check_passwords, register_controls +from .utils.controls import check_password, register_controls from .utils.token import decode_user_token auth_blueprint = Blueprint('auth', __name__) @@ -77,7 +77,6 @@ def register_user() -> Union[Tuple[Dict, int], HttpResponse]: : Union[Tuple[Dict, int], HttpResponse]: - username: only alphanumeric characters and the underscore character "_" allowed - email: valid email must be provided - - password: password and password confirmation don't match - password: 8 characters required :statuscode 403: error, registration is disabled @@ -106,16 +104,14 @@ def register_user() -> Union[Tuple[Dict, int], HttpResponse]: or post_data.get('username') is None or post_data.get('email') is None or post_data.get('password') is None - or post_data.get('password_conf') is None ): return InvalidPayloadErrorResponse() username = post_data.get('username') email = post_data.get('email') password = post_data.get('password') - password_conf = post_data.get('password_conf') try: - ret = register_controls(username, email, password, password_conf) + ret = register_controls(username, email, password) except TypeError as e: return handle_error_and_return_response(e, db=db) @@ -192,7 +188,7 @@ def login_user() -> Union[Dict, HttpResponse]: } : Union[Dict, HttpResponse]: : Union[Dict, HttpResponse]: birth_date = post_data.get('birth_date') location = post_data.get('location') password = post_data.get('password') - password_conf = post_data.get('password_conf') if password is not None and password != '': - message = check_passwords(password, password_conf) + message = check_password(password) if message != '': return InvalidPayloadErrorResponse(message) password = bcrypt.generate_password_hash( @@ -1068,7 +1061,6 @@ def update_password() -> Union[Dict, HttpResponse]: } : Union[Dict, HttpResponse]: if ( not post_data or post_data.get('password') is None - or post_data.get('password_conf') is None or post_data.get('token') is None ): return InvalidPayloadErrorResponse() password = post_data.get('password') - password_conf = post_data.get('password_conf') token = post_data.get('token') try: @@ -1094,7 +1084,7 @@ def update_password() -> Union[Dict, HttpResponse]: except (jwt.ExpiredSignatureError, jwt.InvalidTokenError): return UnauthorizedErrorResponse() - message = check_passwords(password, password_conf) + message = check_password(password) if message != '': return InvalidPayloadErrorResponse(message) diff --git a/fittrackee/users/utils/controls.py b/fittrackee/users/utils/controls.py index 1fffec9b..9c4e85ca 100644 --- a/fittrackee/users/utils/controls.py +++ b/fittrackee/users/utils/controls.py @@ -20,24 +20,20 @@ def is_valid_email(email: str) -> bool: return re.match(mail_pattern, email) is not None -def check_passwords(password: str, password_conf: str) -> str: +def check_password(password: str) -> str: """ - Verify if password and password confirmation are the same and have - more than 8 characters - - If not, it returns not empty string + Verify if password have more than 8 characters + If not, it returns error message """ - ret = '' - if password_conf != password: - ret = 'password: password and password confirmation do not match\n' if len(password) < 8: - ret += 'password: 8 characters required\n' - return ret + return 'password: 8 characters required\n' + return '' def check_username(username: str) -> str: """ Return if username is valid + If not, it returns error messages """ ret = '' if not (2 < len(username) < 31): @@ -50,18 +46,15 @@ def check_username(username: str) -> str: return ret -def register_controls( - username: str, email: str, password: str, password_conf: str -) -> str: +def register_controls(username: str, email: str, password: str) -> str: """ Verify if username, email and passwords are valid - - If not, it returns not empty string + If not, it returns error messages """ ret = check_username(username) if not is_valid_email(email): ret += 'email: valid email must be provided\n' - ret += check_passwords(password, password_conf) + ret += check_password(password) return ret diff --git a/fittrackee_client/src/components/User/ProfileEdition/UserInfosEdition.vue b/fittrackee_client/src/components/User/ProfileEdition/UserInfosEdition.vue index 9b4e95ea..fcd61937 100644 --- a/fittrackee_client/src/components/User/ProfileEdition/UserInfosEdition.vue +++ b/fittrackee_client/src/components/User/ProfileEdition/UserInfosEdition.vue @@ -27,15 +27,6 @@ :disabled="loading" /> -