From 78abcab6d590da1ed1683ecf983fb9ebd393bd13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Espino?= Date: Tue, 3 Jan 2017 19:40:36 +0100 Subject: [PATCH] Fix #4841: Use the plugins login for invitations --- taiga/auth/api.py | 50 ++++++------------------------ taiga/auth/services.py | 15 ++------- taiga/auth/validators.py | 8 +---- tests/integration/test_auth_api.py | 16 +++++----- 4 files changed, 20 insertions(+), 69 deletions(-) diff --git a/taiga/auth/api.py b/taiga/auth/api.py index df077b52..52892bb1 100644 --- a/taiga/auth/api.py +++ b/taiga/auth/api.py @@ -30,14 +30,13 @@ from taiga.base import exceptions as exc from taiga.base import response from .validators import PublicRegisterValidator -from .validators import PrivateRegisterForExistingUserValidator -from .validators import PrivateRegisterForNewUserValidator +from .validators import PrivateRegisterValidator -from .services import private_register_for_existing_user from .services import private_register_for_new_user from .services import public_register from .services import make_auth_response_data from .services import get_auth_plugins +from .services import accept_invitation_by_existing_user from .permissions import AuthPermission @@ -61,37 +60,8 @@ def _parse_data(data:dict, *, cls): # Parse public register data parse_public_register_data = partial(_parse_data, cls=PublicRegisterValidator) -# Parse private register data for existing user -parse_private_register_for_existing_user_data = \ - partial(_parse_data, cls=PrivateRegisterForExistingUserValidator) - # Parse private register data for new user -parse_private_register_for_new_user_data = \ - partial(_parse_data, cls=PrivateRegisterForNewUserValidator) - - -class RegisterTypeEnum(Enum): - new_user = 1 - existing_user = 2 - - -def parse_register_type(userdata:dict) -> str: - """ - Parses user data and detects that register type is. - It returns RegisterTypeEnum value. - """ - # Create adhoc inner serializer for avoid parse - # manually the user data. - class _validator(validators.Validator): - existing = serializers.BooleanField() - - instance = _validator(data=userdata) - if not instance.is_valid(): - raise exc.RequestValidationError(instance.errors) - - if instance.data["existing"]: - return RegisterTypeEnum.existing_user - return RegisterTypeEnum.new_user +parse_private_register_data = partial(_parse_data, cls=PrivateRegisterValidator) class AuthViewSet(viewsets.ViewSet): @@ -111,14 +81,8 @@ class AuthViewSet(viewsets.ViewSet): return response.Created(data) def _private_register(self, request): - register_type = parse_register_type(request.DATA) - - if register_type is RegisterTypeEnum.existing_user: - data = parse_private_register_for_existing_user_data(request.DATA) - user = private_register_for_existing_user(**data) - else: - data = parse_private_register_for_new_user_data(request.DATA) - user = private_register_for_new_user(**data) + data = parse_private_register_data(request.DATA) + user = private_register_for_new_user(**data) data = make_auth_response_data(user) return response.Created(data) @@ -140,9 +104,13 @@ class AuthViewSet(viewsets.ViewSet): auth_plugins = get_auth_plugins() login_type = request.DATA.get("type", None) + invitation_token = request.DATA.get("invitation_token", None) if login_type in auth_plugins: data = auth_plugins[login_type]['login_func'](request) + if invitation_token: + accept_invitation_by_existing_user(invitation_token, data['id']) return response.Ok(data) + raise exc.BadRequest(_("invalid login type")) diff --git a/taiga/auth/services.py b/taiga/auth/services.py index a76c350f..f4c02296 100644 --- a/taiga/auth/services.py +++ b/taiga/auth/services.py @@ -128,16 +128,9 @@ def public_register(username:str, password:str, email:str, full_name:str): @tx.atomic -def private_register_for_existing_user(token:str, username:str, password:str): - """ - Register works not only for register users, also serves for accept - inviatations for projects as existing user. - - Given a invitation token with parsed parameters, accept inviation - as existing user. - """ - - user = get_and_validate_user(username=username, password=password) +def accept_invitation_by_existing_user(token:str, user_id:int): + user_model = get_user_model() + user = user_model.objects.get(id=user_id) membership = get_membership_by_token(token) try: @@ -145,8 +138,6 @@ def private_register_for_existing_user(token:str, username:str, password:str): membership.save(update_fields=["user"]) except IntegrityError: raise exc.IntegrityError(_("This user is already a member of the project.")) - - send_register_email(user) return user diff --git a/taiga/auth/validators.py b/taiga/auth/validators.py index a18dc4bc..fdfb4009 100644 --- a/taiga/auth/validators.py +++ b/taiga/auth/validators.py @@ -48,11 +48,5 @@ class PublicRegisterValidator(BaseRegisterValidator): pass -class PrivateRegisterForNewUserValidator(BaseRegisterValidator): - token = serializers.CharField(max_length=255, required=True) - - -class PrivateRegisterForExistingUserValidator(validators.Validator): - username = serializers.CharField(max_length=255) - password = serializers.CharField(min_length=4) +class PrivateRegisterValidator(BaseRegisterValidator): token = serializers.CharField(max_length=255, required=True) diff --git a/tests/integration/test_auth_api.py b/tests/integration/test_auth_api.py index 0504881b..1add6615 100644 --- a/tests/integration/test_auth_api.py +++ b/tests/integration/test_auth_api.py @@ -62,23 +62,21 @@ def test_respond_201_when_the_email_domain_is_in_allowed_domains(client, setting assert response.status_code == 201 -def test_respond_201_with_invitation_without_public_registration(client, register_form, settings): +def test_respond_201_with_invitation_login(client, settings): settings.PUBLIC_REGISTER_ENABLED = False user = factories.UserFactory() membership = factories.MembershipFactory(user=user) - register_form.update({ - "type": "private", - "existing": "1", - "token": membership.token, + auth_data = { + "type": "normal", + "invitation_token": membership.token, "username": user.username, - "email": user.email, "password": user.username, - }) + } - response = client.post(reverse("auth-register"), register_form) + response = client.post(reverse("auth-list"), auth_data) - assert response.status_code == 201, response.data + assert response.status_code == 200, response.data def test_response_200_in_public_registration(client, settings):