Esempio n. 1
0
def test_create_user_exception(mocker):
    """
    Test that create_user_with_generated_username does not reattempt if an exception was raised that
    does not indicate a username collision
    """
    patched_save = mocker.patch.object(UserSerializer,
                                       "save",
                                       side_effect=ValueError("idk"))
    with pytest.raises(ValueError):
        api.create_user_with_generated_username(UserSerializer(data={}),
                                                "testuser")
    patched_save.assert_called_once()
Esempio n. 2
0
def test_create_user_reattempt(mocker):
    """
    Test that create_user_with_generated_username reattempts User creation multiple times when
    username collisions are experienced repeatedly
    """
    username = "******"
    fake_user = UserFactory.build()
    patched_find_username = mocker.patch(
        "authentication.api.find_available_username",
        side_effect=["testuser1", "testuser2", "testuser3"],
    )
    patched_save = mocker.patch.object(
        UserSerializer,
        "save",
        side_effect=[
            IntegrityError("(username)=(testuser) already exists"),
            IntegrityError("(username)=(testuser1) already exists"),
            IntegrityError("(username)=(testuser2) already exists"),
            fake_user,
        ],
    )

    created_user = api.create_user_with_generated_username(
        UserSerializer(data={}), username)
    assert patched_save.call_count == 4
    patched_save.assert_any_call(username="******")
    patched_save.assert_any_call(username="******")
    patched_save.assert_any_call(username="******")
    patched_save.assert_any_call(username="******")
    # `find_available_username` should be called as many times as serializer.save() failed
    # with a duplicate username error
    assert patched_find_username.call_count == 3
    patched_find_username.assert_called_with(username)
    assert created_user == fake_user
Esempio n. 3
0
def test_create_user_with_generated_username(mocker, valid_address_dict):
    """
    Integration test to assert that create_user_with_generated_username tries to find an available
    username and try again to save a User if there was a username collision
    """
    username = "******"
    # Create a user with the desired username before calling the function so we get a collision
    UserFactory.create(username=username)
    data = {
        "username": username,
        "email": "*****@*****.**",
        "name": "Test User",
        "legal_address": valid_address_dict,
        "password": "******",
    }
    serializer = UserSerializer(data=data)
    serializer.is_valid()
    patched_find_username = mocker.patch(
        "authentication.api.find_available_username", return_value="testuser1")

    created_user = api.create_user_with_generated_username(
        serializer, username)
    patched_find_username.assert_called_once_with(username)
    assert created_user is not None
    assert created_user.username == patched_find_username.return_value
Esempio n. 4
0
def create_user_via_email(
    strategy, backend, user=None, flow=None, current_partial=None, *args, **kwargs
):  # pylint: disable=too-many-arguments,unused-argument
    """
    Creates a new user if needed and sets the password and name.
    Args:
        strategy (social_django.strategy.DjangoStrategy): the strategy used to authenticate
        backend (social_core.backends.base.BaseAuth): the backend being used to authenticate
        user (User): the current user
        details (dict): Dict of user details
        flow (str): the type of flow (login or register)
        current_partial (Partial): the partial for the step in the pipeline

    Raises:
        RequirePasswordAndPersonalInfoException: if the user hasn't set password or name
    """
    if backend.name != EmailAuth.name or flow != SocialAuthState.FLOW_REGISTER:
        return {}

    if user is not None:
        raise UnexpectedExistingUserException(backend, current_partial)

    context = {}
    data = strategy.request_data().copy()
    if "name" not in data or "password" not in data:
        raise RequirePasswordAndPersonalInfoException(backend, current_partial)
    if len(data.get("name", 0)) < NAME_MIN_LENGTH:
        raise RequirePasswordAndPersonalInfoException(
            backend,
            current_partial,
            errors=["Full name must be at least 2 characters long."],
        )

    data["email"] = kwargs.get("email", kwargs.get("details", {}).get("email"))
    username = usernameify(data["name"], email=data["email"])
    data["username"] = username

    affiliate_id = get_affiliate_id_from_request(strategy.request)
    if affiliate_id is not None:
        context["affiliate_id"] = affiliate_id

    serializer = UserSerializer(data=data, context=context)

    if not serializer.is_valid():
        raise RequirePasswordAndPersonalInfoException(
            backend, current_partial, errors=serializer.errors
        )

    try:
        created_user = create_user_with_generated_username(serializer, username)
        if created_user is None:
            raise IntegrityError(
                "Failed to create User with generated username ({})".format(username)
            )
    except Exception as exc:
        raise UserCreationFailedException(backend, current_partial) from exc

    return {"is_new": True, "user": created_user, "username": created_user.username}
Esempio n. 5
0
def test_create_user_too_many_attempts(mocker):
    """
    Test that create_user_with_generated_username exits if there are too many attempts
    """
    attempt_limit = 2
    mocker.patch("authentication.api.USERNAME_COLLISION_ATTEMPTS",
                 attempt_limit)
    patched_save = mocker.patch.object(
        UserSerializer,
        "save",
        side_effect=(IntegrityError("(username)=(testuser) already exists")),
    )
    patched_find_username = mocker.patch(
        "authentication.api.find_available_username", return_value=None)
    created_user = api.create_user_with_generated_username(
        UserSerializer(data={}), "testuser")
    assert created_user is None
    assert patched_save.call_count == attempt_limit
    assert patched_find_username.call_count == attempt_limit