Skip to content

Commit 3bc60bb

Browse files
committed
drafted invitation generation
1 parent f94412e commit 3bc60bb

File tree

3 files changed

+63
-10
lines changed

3 files changed

+63
-10
lines changed

services/web/server/src/simcore_service_webserver/users/_users_repository.py

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,7 @@ async def review_user_pre_registration(
694694
pre_registration_id: int,
695695
reviewed_by: UserID,
696696
new_status: AccountRequestStatus,
697+
invitation_extras: dict[str, Any] | None = None,
697698
) -> None:
698699
"""Updates the account request status of a pre-registered user.
699700
@@ -703,19 +704,44 @@ async def review_user_pre_registration(
703704
pre_registration_id: ID of the pre-registration record
704705
reviewed_by: ID of the user who reviewed the request
705706
new_status: New status (APPROVED or REJECTED)
707+
invitation_extras: Optional invitation data to store in extras field
706708
"""
707709
if new_status not in (AccountRequestStatus.APPROVED, AccountRequestStatus.REJECTED):
708710
msg = f"Invalid status for review: {new_status}. Must be APPROVED or REJECTED."
709711
raise ValueError(msg)
710712

711713
async with transaction_context(engine, connection) as conn:
714+
# Base update values
715+
update_values = {
716+
"account_request_status": new_status,
717+
"account_request_reviewed_by": reviewed_by,
718+
"account_request_reviewed_at": sa.func.now(),
719+
}
720+
721+
# Add invitation extras to the existing extras if provided
722+
if invitation_extras is not None:
723+
assert list(invitation_extras.keys()) == "invitation" # nosec
724+
725+
# Get the current extras first
726+
current_extras_result = await conn.execute(
727+
sa.select(users_pre_registration_details.c.extras).where(
728+
users_pre_registration_details.c.id == pre_registration_id
729+
)
730+
)
731+
current_extras_row = current_extras_result.one_or_none()
732+
current_extras = (
733+
current_extras_row.extras
734+
if current_extras_row and current_extras_row.extras
735+
else {}
736+
)
737+
738+
# Merge with invitation extras
739+
merged_extras = {**current_extras, **invitation_extras}
740+
update_values["extras"] = merged_extras
741+
712742
await conn.execute(
713743
users_pre_registration_details.update()
714-
.values(
715-
account_request_status=new_status,
716-
account_request_reviewed_by=reviewed_by,
717-
account_request_reviewed_at=sa.func.now(),
718-
)
744+
.values(**update_values)
719745
.where(users_pre_registration_details.c.id == pre_registration_id)
720746
)
721747

services/web/server/src/simcore_service_webserver/users/_users_rest.py

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from aiohttp import web
66
from common_library.user_messages import user_message
77
from common_library.users_enums import AccountRequestStatus
8+
from models_library.api_schemas_invitations.invitations import ApiInvitationInputs
89
from models_library.api_schemas_webserver.users import (
910
MyProfileGet,
1011
MyProfilePatch,
@@ -34,6 +35,7 @@
3435
)
3536
from ..groups import api as groups_api
3637
from ..groups.exceptions import GroupNotFoundError
38+
from ..invitations import api as invitations_service
3739
from ..login.decorators import login_required
3840
from ..products import products_web
3941
from ..products.models import Product
@@ -298,23 +300,46 @@ async def approve_user_account(request: web.Request) -> web.Response:
298300

299301
approval_data = await parse_request_body_as(UserAccountApprove, request)
300302

303+
invitation_extras = None
301304
if approval_data.invitation:
302305
_logger.debug(
303-
"TODO: User is being approved with invitation %s: \n"
304-
"1. Approve user account\n"
305-
"2. Generate invitation\n"
306-
"3. Store invitation in extras\n"
307-
"4. Send invitation to user %s\n",
306+
"User is being approved with invitation %s for user %s",
308307
approval_data.invitation.model_dump_json(indent=1),
309308
approval_data.email,
310309
)
311310

311+
# Generate invitation
312+
invitation_params = ApiInvitationInputs(
313+
issuer=str(req_ctx.user_id),
314+
guest=approval_data.email,
315+
trial_account_days=approval_data.invitation.trial_account_days,
316+
extra_credits_in_usd=approval_data.invitation.extra_credits_in_usd,
317+
)
318+
319+
invitation_result = await invitations_service.generate_invitation(
320+
request.app, params=invitation_params
321+
)
322+
323+
assert ( # nosec
324+
invitation_result.extra_credits_in_usd
325+
== approval_data.invitation.extra_credits_in_usd
326+
)
327+
assert ( # nosec
328+
invitation_result.trial_account_days
329+
== approval_data.invitation.trial_account_days
330+
)
331+
assert invitation_result.guest == approval_data.email # nosec
332+
333+
# Store invitation data in extras
334+
invitation_extras = {"invitation": invitation_result.model_dump(mode="json")}
335+
312336
# Approve the user account, passing the current user's ID as the reviewer
313337
pre_registration_id = await _users_service.approve_user_account(
314338
request.app,
315339
pre_registration_email=approval_data.email,
316340
product_name=req_ctx.product_name,
317341
reviewer_id=req_ctx.user_id,
342+
invitation_extras=invitation_extras,
318343
)
319344
assert pre_registration_id # nosec
320345

services/web/server/src/simcore_service_webserver/users/_users_service.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,7 @@ async def approve_user_account(
477477
pre_registration_email: LowerCaseEmailStr,
478478
product_name: ProductName,
479479
reviewer_id: UserID,
480+
invitation_extras: dict[str, Any] | None = None,
480481
) -> int:
481482
"""Approve a user account based on their pre-registration email.
482483
@@ -517,6 +518,7 @@ async def approve_user_account(
517518
pre_registration_id=pre_registration_id,
518519
reviewed_by=reviewer_id,
519520
new_status=AccountRequestStatus.APPROVED,
521+
invitation_extras=invitation_extras,
520522
)
521523

522524
return pre_registration_id

0 commit comments

Comments
 (0)