Skip to content

Commit 0d6983c

Browse files
esunejamshale
andauthored
feat: use DELETE for multitenancy subwallet removal (#4172)
* feat: use DELETE for multitenancy subwallet removal Replace POST /multitenancy/wallet/{wallet_id}/remove with DELETE /multitenancy/wallet/{wallet_id} for REST consistency. Updates docs and regenerated OpenAPI/Swagger specs. Signed-off-by: Emiliano Suñé <2395873+esune@users.noreply.github.com> * feat: keep deprecated POST subwallet remove endpoint Retain POST /multitenancy/wallet/{wallet_id}/remove as a deprecated alias of DELETE /multitenancy/wallet/{wallet_id} to avoid a breaking change. Marks the old route deprecated in the OpenAPI/Swagger specs and docs. Signed-off-by: Emiliano Suñé <2395873+esune@users.noreply.github.com> --------- Signed-off-by: Emiliano Suñé <2395873+esune@users.noreply.github.com> Co-authored-by: jamshale <31809382+jamshale@users.noreply.github.com>
1 parent 7cae153 commit 0d6983c

5 files changed

Lines changed: 110 additions & 2 deletions

File tree

acapy_agent/multitenant/admin/routes.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,23 @@ async def wallet_remove(request: web.BaseRequest):
677677
return web.json_response({})
678678

679679

680+
@docs(
681+
tags=["multitenancy"],
682+
summary="Remove a subwallet",
683+
deprecated=True,
684+
)
685+
@match_info_schema(WalletIdMatchInfoSchema())
686+
@request_schema(RemoveWalletRequestSchema)
687+
@response_schema(MultitenantModuleResponseSchema(), 200, description="")
688+
@admin_authentication
689+
async def wallet_remove_deprecated(request: web.BaseRequest):
690+
"""Deprecated alias for wallet_remove.
691+
692+
Use ``DELETE /multitenancy/wallet/{wallet_id}`` instead.
693+
"""
694+
return await wallet_remove(request)
695+
696+
680697
# MTODO: add wallet import route
681698
# MTODO: add wallet export route
682699
# MTODO: add rotate wallet key route
@@ -691,7 +708,8 @@ async def register(app: web.Application):
691708
web.get("/multitenancy/wallet/{wallet_id}", wallet_get, allow_head=False),
692709
web.put("/multitenancy/wallet/{wallet_id}", wallet_update),
693710
web.post("/multitenancy/wallet/{wallet_id}/token", wallet_create_token),
694-
web.post("/multitenancy/wallet/{wallet_id}/remove", wallet_remove),
711+
web.delete("/multitenancy/wallet/{wallet_id}", wallet_remove),
712+
web.post("/multitenancy/wallet/{wallet_id}/remove", wallet_remove_deprecated),
695713
]
696714
)
697715

acapy_agent/multitenant/admin/tests/test_routes.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -833,6 +833,27 @@ async def test_wallet_remove_managed(self):
833833
mock_response.assert_called_once_with({})
834834
assert result == mock_response.return_value
835835

836+
async def test_wallet_remove_deprecated_delegates(self):
837+
self.request.has_body = False
838+
self.request.match_info = {"wallet_id": "dummy"}
839+
mock_multitenant_mgr = mock.AsyncMock(BaseMultitenantManager, autospec=True)
840+
mock_multitenant_mgr.remove_wallet = mock.CoroutineMock()
841+
self.profile.context.injector.bind_instance(
842+
BaseMultitenantManager, mock_multitenant_mgr
843+
)
844+
845+
with (
846+
mock.patch.object(test_module.web, "json_response") as mock_response,
847+
mock.patch.object(
848+
test_module.WalletRecord, "retrieve_by_id", mock.CoroutineMock()
849+
),
850+
):
851+
result = await test_module.wallet_remove_deprecated(self.request)
852+
853+
mock_multitenant_mgr.remove_wallet.assert_called_once_with("dummy", None)
854+
mock_response.assert_called_once_with({})
855+
assert result == mock_response.return_value
856+
836857
async def test_wallet_remove_unmanaged(self):
837858
self.request.match_info = {"wallet_id": "dummy"}
838859
self.request.json = mock.CoroutineMock(return_value={"wallet_key": "dummy_key"})

docs/features/Multitenancy.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ The following information is required to delete a tenant:
367367
Example
368368

369369
```sh
370-
curl -X POST "${ACAPY_ADMIN_URL}/multitenancy/wallet/{wallet_id}/remove" \
370+
curl -X DELETE "${ACAPY_ADMIN_URL}/multitenancy/wallet/{wallet_id}" \
371371
-H "Content-Type: application/json" \
372372
-H "x-api-key: $ACAPY_ADMIN_URL_API_KEY" \
373373
-d '{ "wallet_key": "example-encryption-key-02" }'
@@ -379,6 +379,10 @@ curl -X POST "${ACAPY_ADMIN_URL}/multitenancy/wallet/{wallet_id}/remove" \
379379
{}
380380
```
381381

382+
> The `POST /multitenancy/wallet/{wallet_id}/remove` endpoint is deprecated and
383+
> will be removed in a future release. Use `DELETE /multitenancy/wallet/{wallet_id}`
384+
> instead.
385+
382386
### Per tenant settings
383387

384388
To allow the configuring of ACA-Py startup parameters/environment variables at a tenant/subwallet level. [PR#2233](https://github.com/openwallet-foundation/acapy/pull/2233) will provide the ability to update the following subset of settings when creating or updating the subwallet:

open-api/openapi.json

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3932,10 +3932,47 @@
39323932
"summary" : "Update a subwallet",
39333933
"tags" : [ "multitenancy" ],
39343934
"x-codegen-request-body-name" : "body"
3935+
},
3936+
"delete" : {
3937+
"parameters" : [ {
3938+
"description" : "Subwallet identifier",
3939+
"in" : "path",
3940+
"name" : "wallet_id",
3941+
"required" : true,
3942+
"schema" : {
3943+
"type" : "string"
3944+
}
3945+
} ],
3946+
"requestBody" : {
3947+
"content" : {
3948+
"*/*" : {
3949+
"schema" : {
3950+
"$ref" : "#/components/schemas/RemoveWalletRequest"
3951+
}
3952+
}
3953+
},
3954+
"required" : false
3955+
},
3956+
"responses" : {
3957+
"200" : {
3958+
"content" : {
3959+
"application/json" : {
3960+
"schema" : {
3961+
"$ref" : "#/components/schemas/MultitenantModuleResponse"
3962+
}
3963+
}
3964+
},
3965+
"description" : ""
3966+
}
3967+
},
3968+
"summary" : "Remove a subwallet",
3969+
"tags" : [ "multitenancy" ],
3970+
"x-codegen-request-body-name" : "body"
39353971
}
39363972
},
39373973
"/multitenancy/wallet/{wallet_id}/remove" : {
39383974
"post" : {
3975+
"deprecated" : true,
39393976
"parameters" : [ {
39403977
"description" : "Subwallet identifier",
39413978
"in" : "path",

open-api/swagger.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3244,12 +3244,40 @@
32443244
}
32453245
}
32463246
}
3247+
},
3248+
"delete" : {
3249+
"tags" : [ "multitenancy" ],
3250+
"summary" : "Remove a subwallet",
3251+
"produces" : [ "application/json" ],
3252+
"parameters" : [ {
3253+
"in" : "body",
3254+
"name" : "body",
3255+
"required" : false,
3256+
"schema" : {
3257+
"$ref" : "#/definitions/RemoveWalletRequest"
3258+
}
3259+
}, {
3260+
"name" : "wallet_id",
3261+
"in" : "path",
3262+
"description" : "Subwallet identifier",
3263+
"required" : true,
3264+
"type" : "string"
3265+
} ],
3266+
"responses" : {
3267+
"200" : {
3268+
"description" : "",
3269+
"schema" : {
3270+
"$ref" : "#/definitions/MultitenantModuleResponse"
3271+
}
3272+
}
3273+
}
32473274
}
32483275
},
32493276
"/multitenancy/wallet/{wallet_id}/remove" : {
32503277
"post" : {
32513278
"tags" : [ "multitenancy" ],
32523279
"summary" : "Remove a subwallet",
3280+
"deprecated" : true,
32533281
"produces" : [ "application/json" ],
32543282
"parameters" : [ {
32553283
"in" : "body",

0 commit comments

Comments
 (0)