Skip to content

Commit d9f3f97

Browse files
authored
Merge branch 'main' into demo-instruction-updates
2 parents 8b1b0be + ed3d739 commit d9f3f97

2 files changed

Lines changed: 137 additions & 0 deletions

File tree

aries_cloudagent/revocation/routes.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import json
44
import logging
5+
import os
6+
import shutil
57
from asyncio import shield
68
import re
79

@@ -146,6 +148,31 @@ def validate_fields(self, data, **kwargs):
146148
)
147149

148150

151+
class RevRegId(OpenAPISchema):
152+
"""Parameters and validators for delete tails file request."""
153+
154+
@validates_schema
155+
def validate_fields(self, data, **kwargs):
156+
"""Validate schema fields - must have either rr-id or cr-id."""
157+
158+
rev_reg_id = data.get("rev_reg_id")
159+
cred_def_id = data.get("cred_def_id")
160+
161+
if not (rev_reg_id or cred_def_id):
162+
raise ValidationError("Request must have either rev_reg_id or cred_def_id")
163+
164+
rev_reg_id = fields.Str(
165+
description="Revocation registry identifier",
166+
required=False,
167+
**INDY_REV_REG_ID,
168+
)
169+
cred_def_id = fields.Str(
170+
description="Credential definition identifier",
171+
required=False,
172+
**INDY_CRED_DEF_ID,
173+
)
174+
175+
149176
class RevokeRequestSchema(CredRevRecordQueryStringSchema):
150177
"""Parameters and validators for revocation request."""
151178

@@ -1467,6 +1494,51 @@ async def on_revocation_registry_endorsed_event(profile: Profile, event: Event):
14671494
)
14681495

14691496

1497+
@querystring_schema(RevRegId())
1498+
@docs(tags=["revocation"], summary="Delete the tail files")
1499+
async def delete_tails(request: web.BaseRequest) -> json:
1500+
"""Delete Tails Files."""
1501+
context: AdminRequestContext = request["context"]
1502+
rev_reg_id = request.query.get("rev_reg_id")
1503+
cred_def_id = request.query.get("cred_def_id")
1504+
revoc = IndyRevocation(context.profile)
1505+
session = revoc._profile.session()
1506+
if rev_reg_id:
1507+
rev_reg = await revoc.get_issuer_rev_reg_record(rev_reg_id)
1508+
tails_path = rev_reg.tails_local_path
1509+
main_dir_rev = os.path.dirname(tails_path)
1510+
try:
1511+
shutil.rmtree(main_dir_rev)
1512+
return web.json_response({"message": "All files deleted successfully"})
1513+
except Exception as e:
1514+
return web.json_response({"message": str(e)})
1515+
elif cred_def_id:
1516+
async with session:
1517+
cred_reg = sorted(
1518+
await IssuerRevRegRecord.query_by_cred_def_id(
1519+
session, cred_def_id, IssuerRevRegRecord.STATE_GENERATED
1520+
)
1521+
)[0]
1522+
tails_path = cred_reg.tails_local_path
1523+
main_dir_rev = os.path.dirname(tails_path)
1524+
main_dir_cred = os.path.dirname(main_dir_rev)
1525+
filenames = os.listdir(main_dir_cred)
1526+
try:
1527+
flag = 0
1528+
for i in filenames:
1529+
safe_cred_def_id = re.escape(cred_def_id)
1530+
if re.search(safe_cred_def_id, i):
1531+
shutil.rmtree(main_dir_cred + "/" + i)
1532+
flag = 1
1533+
if flag:
1534+
return web.json_response({"message": "All files deleted successfully"})
1535+
else:
1536+
return web.json_response({"message": "No such file or directory"})
1537+
1538+
except Exception as e:
1539+
return web.json_response({"message": str(e)})
1540+
1541+
14701542
async def register(app: web.Application):
14711543
"""Register routes."""
14721544
app.add_routes(
@@ -1524,6 +1596,7 @@ async def register(app: web.Application):
15241596
"/revocation/registry/{rev_reg_id}/fix-revocation-entry-state",
15251597
update_rev_reg_revoked_state,
15261598
),
1599+
web.delete("/revocation/registry/delete-tails-file", delete_tails),
15271600
]
15281601
)
15291602

aries_cloudagent/revocation/tests/test_routes.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
import os
2+
import shutil
3+
import unittest
4+
15
from aiohttp.web import HTTPBadRequest, HTTPNotFound
26
from asynctest import TestCase as AsyncTestCase
37
from asynctest import mock as async_mock
@@ -903,3 +907,63 @@ async def test_post_process_routes(self):
903907
]["get"]["responses"]["200"]["schema"] == {"type": "string", "format": "binary"}
904908

905909
assert "tags" in mock_app._state["swagger_dict"]
910+
911+
912+
class TestDeleteTails(unittest.TestCase):
913+
def setUp(self):
914+
self.rev_reg_id = "rev_reg_id_123"
915+
self.cred_def_id = "cred_def_id_456"
916+
917+
self.main_dir_rev = "path/to/main/dir/rev"
918+
self.tails_path = os.path.join(self.main_dir_rev, "tails")
919+
if not (os.path.exists(self.main_dir_rev)):
920+
os.makedirs(self.main_dir_rev)
921+
open(self.tails_path, "w").close()
922+
923+
async def test_delete_tails_by_rev_reg_id(self):
924+
# Setup
925+
rev_reg_id = self.rev_reg_id
926+
927+
# Test
928+
result = await test_module.delete_tails(
929+
{"context": None, "query": {"rev_reg_id": rev_reg_id}}
930+
)
931+
932+
# Assert
933+
self.assertEqual(result, {"message": "All files deleted successfully"})
934+
self.assertFalse(os.path.exists(self.tails_path))
935+
936+
async def test_delete_tails_by_cred_def_id(self):
937+
# Setup
938+
cred_def_id = self.cred_def_id
939+
main_dir_cred = "path/to/main/dir/cred"
940+
os.makedirs(main_dir_cred)
941+
cred_dir = os.path.join(main_dir_cred, cred_def_id)
942+
os.makedirs(cred_dir)
943+
944+
# Test
945+
result = await test_module.delete_tails(
946+
{"context": None, "query": {"cred_def_id": cred_def_id}}
947+
)
948+
949+
# Assert
950+
self.assertEqual(result, {"message": "All files deleted successfully"})
951+
self.assertFalse(os.path.exists(cred_dir))
952+
self.assertTrue(os.path.exists(main_dir_cred))
953+
954+
async def test_delete_tails_not_found(self):
955+
# Setup
956+
cred_def_id = "invalid_cred_def_id"
957+
958+
# Test
959+
result = await test_module.delete_tails(
960+
{"context": None, "query": {"cred_def_id": cred_def_id}}
961+
)
962+
963+
# Assert
964+
self.assertEqual(result, {"message": "No such file or directory"})
965+
self.assertTrue(os.path.exists(self.main_dir_rev))
966+
967+
async def tearDown(self):
968+
if os.path.exists(self.main_dir_rev):
969+
shutil.rmtree(self.main_dir_rev)

0 commit comments

Comments
 (0)