-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy path__init__.py
More file actions
129 lines (109 loc) · 4.3 KB
/
__init__.py
File metadata and controls
129 lines (109 loc) · 4.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import os
from links.scitt import create_hashed_signed_statement, register_signed_statement
from fastapi import HTTPException
from lib.vcon_redis import VconRedis
from lib.logging_utils import init_logger
from starlette.status import HTTP_404_NOT_FOUND
logger = init_logger(__name__)
# Increment for any API/attribute changes
link_version = "0.3.0"
default_options = {
"scrapi_url": "http://scittles:8000",
"signing_key_path": "/etc/scitt/signing-key.pem",
"issuer": "conserver",
"key_id": "conserver-key-1",
"vcon_operation": "vcon_created",
"store_receipt": True,
}
def run(
vcon_uuid: str,
link_name: str,
opts: dict = default_options
) -> str:
"""
SCITT lifecycle registration link.
Creates a COSE Sign1 signed statement from the vCon hash and registers
it on a SCRAPI-compatible Transparency Service (SCITTLEs).
The vcon_operation option controls the lifecycle event type:
- "vcon_created": registered before transcription
- "vcon_enhanced": registered after transcription
Args:
vcon_uuid: UUID of the vCon to process.
link_name: Name of the link instance (for logging).
opts: Configuration options.
Returns:
The UUID of the processed vCon.
"""
module_name = __name__.split(".")[-1]
logger.info(f"Starting {module_name}: {link_name} for: {vcon_uuid}")
merged_opts = default_options.copy()
merged_opts.update(opts)
opts = merged_opts
# Get the vCon from Redis
vcon_redis = VconRedis()
vcon = vcon_redis.get_vcon(vcon_uuid)
if not vcon:
logger.info(f"{link_name}: vCon not found: {vcon_uuid}")
raise HTTPException(
status_code=HTTP_404_NOT_FOUND,
detail=f"vCon not found: {vcon_uuid}"
)
# Build per-participant SCITT registrations
payload = vcon.hash
operation = opts["vcon_operation"]
signing_key_path = opts["signing_key_path"]
signing_key = create_hashed_signed_statement.open_signing_key(signing_key_path)
# Collect tel URIs from parties (Party objects use attrs, dicts use keys)
party_tels = []
for party in (vcon.parties or []):
tel = party.get("tel") if isinstance(party, dict) else getattr(party, "tel", None)
if tel:
party_tels.append(tel)
else:
logger.warning(f"{link_name}: party without tel in {vcon_uuid}, skipping")
# Fall back to vcon:// subject if no parties have tel
if not party_tels:
party_tels = [None]
scrapi_url = opts["scrapi_url"]
receipts = []
for tel in party_tels:
if tel:
subject = f"tel:{tel}"
operation_payload = f"{payload}:{operation}:{tel}"
meta_map = {"vcon_operation": operation, "party_tel": tel}
else:
subject = f"vcon://{vcon_uuid}"
operation_payload = f"{payload}:{operation}"
meta_map = {"vcon_operation": operation}
signed_statement = create_hashed_signed_statement.create_hashed_signed_statement(
issuer=opts["issuer"],
signing_key=signing_key,
subject=subject,
kid=opts["key_id"].encode("utf-8"),
meta_map=meta_map,
payload=operation_payload.encode("utf-8"),
payload_hash_alg="SHA-256",
payload_location="",
pre_image_content_type="application/vcon+json",
)
logger.info(f"{link_name}: Created signed statement for {vcon_uuid} subject={subject} ({operation})")
result = register_signed_statement.register_statement(scrapi_url, signed_statement)
logger.info(f"{link_name}: Registered entry_id={result['entry_id']} subject={subject} for {vcon_uuid}")
receipts.append({
"entry_id": result["entry_id"],
"vcon_operation": operation,
"subject": subject,
"vcon_hash": payload,
"scrapi_url": scrapi_url,
})
# Store receipts as analysis entry on the vCon
if opts.get("store_receipt", True):
vcon.add_analysis(
type="scitt_receipt",
dialog=0,
vendor="scittles",
body=receipts if len(receipts) > 1 else receipts[0],
)
vcon_redis.store_vcon(vcon)
logger.info(f"{link_name}: Stored {len(receipts)} SCITT receipt(s) for {vcon_uuid}")
return vcon_uuid