|
2 | 2 |
|
3 | 3 | import json |
4 | 4 | import logging |
| 5 | +import os |
| 6 | +import shutil |
5 | 7 | from asyncio import shield |
6 | 8 | import re |
7 | 9 |
|
@@ -146,6 +148,31 @@ def validate_fields(self, data, **kwargs): |
146 | 148 | ) |
147 | 149 |
|
148 | 150 |
|
| 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 | + |
149 | 176 | class RevokeRequestSchema(CredRevRecordQueryStringSchema): |
150 | 177 | """Parameters and validators for revocation request.""" |
151 | 178 |
|
@@ -1467,6 +1494,51 @@ async def on_revocation_registry_endorsed_event(profile: Profile, event: Event): |
1467 | 1494 | ) |
1468 | 1495 |
|
1469 | 1496 |
|
| 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 | + |
1470 | 1542 | async def register(app: web.Application): |
1471 | 1543 | """Register routes.""" |
1472 | 1544 | app.add_routes( |
@@ -1524,6 +1596,7 @@ async def register(app: web.Application): |
1524 | 1596 | "/revocation/registry/{rev_reg_id}/fix-revocation-entry-state", |
1525 | 1597 | update_rev_reg_revoked_state, |
1526 | 1598 | ), |
| 1599 | + web.delete("/revocation/registry/delete-tails-file", delete_tails), |
1527 | 1600 | ] |
1528 | 1601 | ) |
1529 | 1602 |
|
|
0 commit comments