Skip to content

Commit 77d45b3

Browse files
committed
✨ Refactor login module: replace legacy repository with confirmation service and clean up related tests
1 parent e3a498c commit 77d45b3

File tree

8 files changed

+15
-96
lines changed

8 files changed

+15
-96
lines changed

packages/pytest-simcore/src/pytest_simcore/helpers/webserver_login.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55

66
from aiohttp.test_utils import TestClient
77
from servicelib.aiohttp import status
8-
from simcore_service_webserver.login._invitations_service import create_invitation_token
9-
from simcore_service_webserver.login._login_repository_legacy import (
10-
get_plugin_storage,
8+
from simcore_service_webserver.login._controller.rest._rest_dependencies import (
9+
get_confirmation_service,
1110
)
11+
from simcore_service_webserver.login._invitations_service import create_invitation_token
1212
from simcore_service_webserver.login.constants import MSG_LOGGED_IN
1313
from simcore_service_webserver.security import security_service
1414
from yarl import URL
@@ -132,15 +132,15 @@ def __init__(
132132
self.confirmation = None
133133
self.trial_days = trial_days
134134
self.extra_credits_in_usd = extra_credits_in_usd
135-
self.db = get_plugin_storage(self.app)
135+
self.confirmation_service = get_confirmation_service(client.app)
136136

137137
async def __aenter__(self) -> "NewInvitation":
138138
# creates host user
139139
assert self.client.app
140140
self.user = await super().__aenter__()
141141

142142
self.confirmation = await create_invitation_token(
143-
self.db,
143+
self.client.app,
144144
user_id=self.user["id"],
145145
user_email=self.user["email"],
146146
tag=self.tag,
@@ -150,5 +150,11 @@ async def __aenter__(self) -> "NewInvitation":
150150
return self
151151

152152
async def __aexit__(self, *args):
153-
if await self.db.get_confirmation(self.confirmation):
154-
await self.db.delete_confirmation(self.confirmation)
153+
if self.confirmation:
154+
# Try to get confirmation by filter and delete if it exists
155+
confirmation = await self.confirmation_service.get_confirmation(
156+
filter_dict={"code": self.confirmation["code"]}
157+
)
158+
if confirmation:
159+
await self.confirmation_service.delete_confirmation(confirmation)
160+
return await super().__aexit__(*args)

services/web/server/src/simcore_service_webserver/garbage_collector/plugin.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
from servicelib.logging_utils import set_parent_module_log_level
66

77
from ..application_settings import get_application_settings
8-
from ..login.plugin import setup_login_storage
98
from ..products.plugin import setup_products
109
from ..projects._projects_repository_legacy import setup_projects_db
1110
from ..redis import setup_redis
@@ -34,8 +33,6 @@ def setup_garbage_collector(app: web.Application) -> None:
3433

3534
# - project needs access to socketio via notify_project_state_update
3635
setup_socketio(app)
37-
# - project needs access to user-api that is connected to login plugin
38-
setup_login_storage(app)
3936

4037
settings = get_plugin_settings(app)
4138

services/web/server/src/simcore_service_webserver/login/login_repository_legacy.py

Lines changed: 0 additions & 8 deletions
This file was deleted.

services/web/server/src/simcore_service_webserver/login/plugin.py

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
import asyncio
21
import logging
32

4-
import asyncpg
53
from aiohttp import web
64
from pydantic import ValidationError
75
from servicelib.aiohttp.application_setup import (
@@ -10,15 +8,13 @@
108
ensure_single_setup,
119
)
1210
from settings_library.email import SMTPSettings
13-
from settings_library.postgres import PostgresSettings
1411

1512
from ..constants import (
1613
APP_PUBLIC_CONFIG_PER_PRODUCT,
1714
APP_SETTINGS_KEY,
1815
INDEX_RESOURCE_NAME,
1916
)
2017
from ..db.plugin import setup_db
21-
from ..db.settings import get_plugin_settings as get_db_plugin_settings
2218
from ..email.plugin import setup_email
2319
from ..email.settings import get_plugin_settings as get_email_plugin_settings
2420
from ..invitations.plugin import setup_invitations
@@ -36,7 +32,6 @@
3632
registration,
3733
twofa,
3834
)
39-
from ._login_repository_legacy import APP_LOGIN_STORAGE_KEY, AsyncpgStorage
4035
from .constants import APP_LOGIN_SETTINGS_PER_PRODUCT_KEY
4136
from .settings import (
4237
APP_LOGIN_OPTIONS_KEY,
@@ -51,27 +46,6 @@
5146
MAX_TIME_TO_CLOSE_POOL_SECS = 5
5247

5348

54-
async def _setup_login_storage_ctx(app: web.Application):
55-
assert APP_LOGIN_STORAGE_KEY not in app # nosec
56-
settings: PostgresSettings = get_db_plugin_settings(app)
57-
58-
async with asyncpg.create_pool(
59-
dsn=settings.dsn_with_query,
60-
min_size=settings.POSTGRES_MINSIZE,
61-
max_size=settings.POSTGRES_MAXSIZE,
62-
loop=asyncio.get_event_loop(),
63-
) as pool:
64-
app[APP_LOGIN_STORAGE_KEY] = AsyncpgStorage(pool)
65-
66-
yield # ----------------
67-
68-
69-
@ensure_single_setup(f"{__name__}.storage", logger=log)
70-
def setup_login_storage(app: web.Application):
71-
if _setup_login_storage_ctx not in app.cleanup_ctx:
72-
app.cleanup_ctx.append(_setup_login_storage_ctx)
73-
74-
7549
@ensure_single_setup(f"{__name__}.login_options", logger=log)
7650
def _setup_login_options(app: web.Application):
7751
settings: SMTPSettings = get_email_plugin_settings(app)
@@ -155,7 +129,6 @@ def setup_login(app: web.Application):
155129
app.router.add_routes(twofa.routes)
156130

157131
_setup_login_options(app)
158-
setup_login_storage(app)
159132

160133
app.on_startup.append(_resolve_login_settings_per_product)
161134

services/web/server/tests/unit/with_dbs/01/test_db.py

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
from pathlib import Path
77

88
import aiopg.sa
9-
import asyncpg
109
import sqlalchemy as sa
1110
import yaml
1211
from aiohttp.test_utils import TestServer
@@ -19,10 +18,6 @@
1918
is_service_enabled,
2019
is_service_responsive,
2120
)
22-
from simcore_service_webserver.login._login_repository_legacy import (
23-
AsyncpgStorage,
24-
get_plugin_storage,
25-
)
2621
from sqlalchemy.ext.asyncio import AsyncEngine
2722

2823

@@ -44,29 +39,18 @@ async def test_all_pg_engines_in_app(web_server: TestServer):
4439
assert asyncpg_engine
4540
assert isinstance(asyncpg_engine, AsyncEngine)
4641

47-
# (3) low-level asyncpg Pool (deprecated)
48-
# Will be replaced by (2)
49-
login_storage: AsyncpgStorage = get_plugin_storage(app)
50-
assert login_storage.pool
51-
assert isinstance(login_storage.pool, asyncpg.Pool)
52-
5342
# they ALL point to the SAME database
5443
assert aiopg_engine.dsn
5544
assert asyncpg_engine.url
5645

5746
query = sa.text('SELECT "version_num" FROM "alembic_version"')
58-
async with login_storage.pool.acquire() as conn:
59-
result_pool = await conn.fetchval(str(query))
6047

6148
async with asyncpg_engine.connect() as conn:
6249
result_asyncpg = (await conn.execute(query)).scalar_one_or_none()
6350

6451
async with aiopg_engine.acquire() as conn:
6552
result_aiopg = await (await conn.execute(query)).scalar()
6653

67-
assert result_pool == result_asyncpg
68-
assert result_pool == result_aiopg
69-
7054

7155
def test_uses_same_postgres_version(
7256
docker_compose_file: Path, osparc_simcore_root_dir: Path

services/web/server/tests/unit/with_dbs/03/login/conftest.py

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,6 @@
2121
ConfirmationRepository,
2222
)
2323
from simcore_service_webserver.login._confirmation_service import ConfirmationService
24-
from simcore_service_webserver.login._login_repository_legacy import (
25-
AsyncpgStorage,
26-
get_plugin_storage,
27-
)
2824
from simcore_service_webserver.login.settings import LoginOptions, get_plugin_options
2925

3026

@@ -87,15 +83,6 @@ def fake_weak_password(faker: Faker) -> str:
8783
)
8884

8985

90-
@pytest.fixture
91-
def db_storage_deprecated(client: TestClient) -> AsyncpgStorage:
92-
"""login database repository instance"""
93-
assert client.app
94-
db: AsyncpgStorage = get_plugin_storage(client.app)
95-
assert db
96-
return db
97-
98-
9986
@pytest.fixture
10087
def confirmation_repository(client: TestClient) -> ConfirmationRepository:
10188
"""Modern confirmation repository instance"""

services/web/server/tests/unit/with_dbs/03/login/test_login_registration.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
ConfirmationRepository,
2525
)
2626
from simcore_service_webserver.login._confirmation_web import _url_for_confirmation
27-
from simcore_service_webserver.login._login_repository_legacy import AsyncpgStorage
2827
from simcore_service_webserver.login.constants import (
2928
MSG_EMAIL_ALREADY_REGISTERED,
3029
MSG_LOGGED_IN,
@@ -243,7 +242,6 @@ async def test_registration_with_weak_password_fails(
243242
async def test_registration_with_invalid_confirmation_code(
244243
client: TestClient,
245244
login_options: LoginOptions,
246-
db_storage_deprecated: AsyncpgStorage,
247245
mocker: MockerFixture,
248246
cleanup_db_tables: None,
249247
):

services/web/server/tests/unit/with_dbs/03/login/test_login_reset_password.py

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@
44
# pylint: disable=too-many-arguments
55

66

7-
import contextlib
8-
from collections.abc import AsyncIterator, Callable
7+
from collections.abc import Callable
98

109
import pytest
1110
from aiohttp.test_utils import TestClient, TestServer
@@ -16,12 +15,8 @@
1615
from servicelib.aiohttp import status
1716
from servicelib.rest_constants import X_PRODUCT_NAME_HEADER
1817
from servicelib.utils_secrets import generate_password
19-
from simcore_service_webserver.db.models import ConfirmationAction, UserStatus
18+
from simcore_service_webserver.db.models import UserStatus
2019
from simcore_service_webserver.groups import api as groups_service
21-
from simcore_service_webserver.login._login_repository_legacy import (
22-
AsyncpgStorage,
23-
ConfirmationTokenDict,
24-
)
2520
from simcore_service_webserver.login.constants import (
2621
MSG_ACTIVATION_REQUIRED,
2722
MSG_EMAIL_SENT,
@@ -295,16 +290,3 @@ async def test_unregistered_product(
295290
message.startswith("Password reset initiated")
296291
for message in logged_warnings
297292
), f"Missing warning in {logged_warnings}"
298-
299-
300-
@contextlib.asynccontextmanager
301-
async def confirmation_ctx(
302-
db: AsyncpgStorage, user
303-
) -> AsyncIterator[ConfirmationTokenDict]:
304-
confirmation = await db.create_confirmation(
305-
user["id"], ConfirmationAction.RESET_PASSWORD.name
306-
)
307-
308-
yield confirmation
309-
310-
await db.delete_confirmation(confirmation)

0 commit comments

Comments
 (0)