|
3 | 3 | # pylint: disable=unused-variable
|
4 | 4 |
|
5 | 5 | import asyncio
|
| 6 | +import logging |
6 | 7 | from contextlib import AsyncExitStack
|
7 | 8 | from unittest.mock import Mock
|
8 | 9 |
|
|
12 | 13 | from aiohttp.test_utils import TestClient, make_mocked_request
|
13 | 14 | from faker import Faker
|
14 | 15 | from pytest import CaptureFixture, MonkeyPatch
|
| 16 | +from pytest_mock import MockerFixture |
15 | 17 | from pytest_simcore.helpers.utils_assert import assert_status
|
16 | 18 | from pytest_simcore.helpers.utils_envs import EnvVarsDict, setenvs_from_dict
|
17 | 19 | from pytest_simcore.helpers.utils_login import NewUser, parse_link, parse_test_marks
|
|
27 | 29 | get_redis_validation_code_client,
|
28 | 30 | send_email_code,
|
29 | 31 | )
|
| 32 | +from simcore_service_webserver.login._constants import MSG_2FA_UNAVAILABLE_OEC |
30 | 33 | from simcore_service_webserver.login.storage import AsyncpgStorage
|
31 | 34 | from simcore_service_webserver.products.plugin import get_current_product
|
| 35 | +from twilio.base.exceptions import TwilioRestException |
32 | 36 |
|
33 | 37 |
|
34 | 38 | @pytest.fixture
|
@@ -65,7 +69,7 @@ def postgres_db(postgres_db: sa.engine.Engine):
|
65 | 69 |
|
66 | 70 |
|
67 | 71 | @pytest.fixture
|
68 |
| -def mocked_twilio_service(mocker) -> dict[str, Mock]: |
| 72 | +def mocked_twilio_service(mocker: MockerFixture) -> dict[str, Mock]: |
69 | 73 | return {
|
70 | 74 | "send_sms_code_for_registration": mocker.patch(
|
71 | 75 | "simcore_service_webserver.login.handlers_registration.send_sms_code",
|
@@ -322,3 +326,56 @@ async def test_send_email_code(
|
322 | 326 | assert parsed_context["code"] == f"{code}"
|
323 | 327 | assert parsed_context["name"] == user_name.capitalize()
|
324 | 328 | assert parsed_context["support_email"] == support_email
|
| 329 | + |
| 330 | + |
| 331 | +async def test_2fa_sms_failure_during_login( |
| 332 | + client: TestClient, |
| 333 | + fake_user_email: str, |
| 334 | + fake_user_password: str, |
| 335 | + fake_user_phone_number: str, |
| 336 | + caplog: pytest.LogCaptureFixture, |
| 337 | + mocker: MockerFixture, |
| 338 | +): |
| 339 | + assert client.app |
| 340 | + |
| 341 | + # Mocks error in graylog https://monitoring.osparc.io/graylog/search/649e7619ce6e0838a96e9bf1?q=%222FA%22&rangetype=relative&from=172800 |
| 342 | + mocker.patch( |
| 343 | + "simcore_service_webserver.login.handlers_auth.send_sms_code", |
| 344 | + autospec=True, |
| 345 | + side_effect=TwilioRestException( |
| 346 | + status=400, |
| 347 | + uri="https://www.twilio.com/doc", |
| 348 | + msg="Unable to create record: A 'From' phone number is required", |
| 349 | + ), |
| 350 | + ) |
| 351 | + |
| 352 | + # A registered user ... |
| 353 | + async with NewUser( |
| 354 | + params={ |
| 355 | + "email": fake_user_email, |
| 356 | + "password": fake_user_password, |
| 357 | + "phone": fake_user_phone_number, |
| 358 | + }, |
| 359 | + app=client.app, |
| 360 | + ): |
| 361 | + # ... logs in, but fails to send SMS ! |
| 362 | + with caplog.at_level(logging.ERROR): |
| 363 | + url = client.app.router["auth_login"].url_for() |
| 364 | + response = await client.post( |
| 365 | + f"{url}", |
| 366 | + json={ |
| 367 | + "email": fake_user_email, |
| 368 | + "password": fake_user_password, |
| 369 | + }, |
| 370 | + ) |
| 371 | + |
| 372 | + # Expects failure: |
| 373 | + # HTTPServiceUnavailable: Currently we cannot use 2FA, please try again later (OEC:140558738809344) |
| 374 | + data, error = await assert_status(response, web.HTTPServiceUnavailable) |
| 375 | + assert not data |
| 376 | + assert error["errors"][0]["message"].startswith( |
| 377 | + MSG_2FA_UNAVAILABLE_OEC[:10] |
| 378 | + ) |
| 379 | + |
| 380 | + # Expects logs like 'Failed while setting up 2FA code and sending SMS to 157XXXXXXXX3 [OEC:140392495277888]' |
| 381 | + assert f"{fake_user_phone_number[:3]}" in caplog.text |
0 commit comments