Skip to content

Commit

Permalink
✨ Implement temporary endpoint to patch wallets with old group_id (#750)
Browse files Browse the repository at this point in the history
* 🐛 Fix None is not iterable

* 🎨 define UpdateWalletRequestWithGroupId

* ✨ Implement route to patch wallets with old group_id pattern
  • Loading branch information
ff137 authored Apr 10, 2024
1 parent 8f60665 commit 79f6e8b
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 2 deletions.
8 changes: 7 additions & 1 deletion app/models/tenants.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import re
from typing import Dict, List, Literal, Optional

from aries_cloudcontroller import CreateWalletRequest
from aries_cloudcontroller import CreateWalletRequest, UpdateWalletRequest
from pydantic import BaseModel, Field, field_validator

from app.models.trust_registry import TrustRegistryRole
Expand Down Expand Up @@ -138,6 +138,12 @@ def validate_wallet_label(cls, v):
return v


class UpdateWalletRequestWithGroupId(UpdateWalletRequest):
"""Adds group_id to the default UpdateWalletRequest body"""

group_id: Optional[str] = Field(default=None, examples=["some_group_id"])


class Tenant(BaseModel):
wallet_id: str = Field(..., examples=["545135a4-ecbc-4400-8594-bdb74c51c88d"])
wallet_label: str = Field(..., examples=["Alice"])
Expand Down
96 changes: 96 additions & 0 deletions app/routes/admin/tenants.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
Tenant,
TenantAuth,
UpdateTenantRequest,
UpdateWalletRequestWithGroupId,
)
from app.models.trust_registry import Actor
from app.services.onboarding.tenants import handle_tenant_update, onboard_tenant
Expand Down Expand Up @@ -329,3 +330,98 @@ async def get_tenants(
response = [tenant_from_wallet_record(record) for record in wallets_list]
bound_logger.info("Successfully fetched wallets.")
return response


@router.put("/patch/wallets", include_in_schema=False, response_model=str)
async def patch_wallets(
dry_run: bool = True,
admin_auth: AcaPyAuthVerified = Depends(acapy_auth_tenant_admin),
) -> str:
logger.info("PUT request received: Patch old wallets to use new group_id pattern ")

async with get_tenant_admin_controller(admin_auth) as admin_controller:
wallets = await handle_acapy_call(
logger=logger,
acapy_call=admin_controller.multitenancy.get_wallets,
)
wallet_list = wallets.results

# Filter wallet list to only wallets without the correct way to store group_id
wallets_without_updated_group_id = [
wallet
for wallet in wallet_list
if wallet.settings.get("wallet.group_id") is None
]

num_records_to_change = len(wallets_without_updated_group_id)
logger.info(
"Patching wallet group_id: {} records to be updated",
num_records_to_change,
)

records_changed = 0
for wallet in wallets_without_updated_group_id:
wallet_id = wallet.wallet_id

# Read the old way of storing group_id attribute:
old_group_id = wallet.group_id

if not old_group_id:
logger.warning(
"Patching wallet group_id: wallet with id {} has no old group",
wallet_id,
)
continue

update_request_body = UpdateWalletRequestWithGroupId(group_id=old_group_id)

if not dry_run:
updated_wallet = await handle_acapy_call(
logger=logger,
acapy_call=admin_controller.multitenancy.update_wallet,
wallet_id=wallet_id,
body=update_request_body,
)

new_group_id = updated_wallet.settings.get("wallet.group_id")

if old_group_id == new_group_id:
records_changed += 1
logger.info(
"Successfully updated wallet_id {} to group {}",
wallet_id,
old_group_id,
)
else:
logger.warning(
"Wallet {} did not update to expected group {}, got {} instead",
wallet_id,
old_group_id,
new_group_id,
)

else:
logger.info(
(
"Patch wallets dry run:\n"
"We will update wallet record: {}\n"
"To be updated to group: {}"
),
wallet,
old_group_id,
)

if not dry_run:
if records_changed == num_records_to_change:
response = "Wallet group_id patching applied successfully."
logger.info(response)
else:
response = (
f"Only patched {records_changed} of {num_records_to_change} wallets."
)
logger.warning(response)
else:
response = f"Wallet patching dry run complete, {records_changed} to be updated."
logger.info(response)

return response
2 changes: 1 addition & 1 deletion app/services/onboarding/tenants.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ async def handle_tenant_update(
bound_logger = logger.bind(body={"wallet_id": wallet_id})
bound_logger.bind(body=update_request).info("Handling tenant update")

new_roles = update_request.roles
new_roles = update_request.roles or []
new_label = update_request.wallet_label

# See if this wallet belongs to an actor
Expand Down

0 comments on commit 79f6e8b

Please sign in to comment.