feat: require auth for registry endpoints and track asset ownership

- Add authentication to /registry endpoint
- Add authentication to /registry/record-run endpoint
- Extract register logic to _register_asset_impl helper
- Store owner username in registered assets
- Use authenticated user for ActivityPub actor ID in activities

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
gilesb
2026-01-07 17:25:15 +00:00
parent d4ae129b3a
commit 9a0e77a852

View File

@@ -889,9 +889,8 @@ async def get_asset(name: str):
return registry["assets"][name]
@app.post("/registry")
async def register_asset(req: RegisterRequest):
"""Register a new asset and create ownership activity."""
def _register_asset_impl(req: RegisterRequest, owner: str):
"""Internal implementation for registering an asset."""
registry = load_registry()
# Check if name exists
@@ -908,6 +907,7 @@ async def register_asset(req: RegisterRequest):
"metadata": req.metadata,
"url": req.url,
"provenance": req.provenance,
"owner": owner,
"created_at": now
}
@@ -921,7 +921,7 @@ async def register_asset(req: RegisterRequest):
activity = {
"activity_id": str(uuid.uuid4()),
"activity_type": "Create",
"actor_id": f"https://{DOMAIN}/users/{USERNAME}",
"actor_id": f"https://{DOMAIN}/users/{owner}",
"object_data": {
"type": req.asset_type.capitalize(),
"name": req.name,
@@ -930,7 +930,7 @@ async def register_asset(req: RegisterRequest):
"algorithm": "sha3-256",
"value": req.content_hash
},
"attributedTo": f"https://{DOMAIN}/users/{USERNAME}"
"attributedTo": f"https://{DOMAIN}/users/{owner}"
},
"published": now
}
@@ -946,9 +946,15 @@ async def register_asset(req: RegisterRequest):
return {"asset": asset, "activity": activity}
@app.post("/registry")
async def register_asset(req: RegisterRequest, user: User = Depends(get_required_user)):
"""Register a new asset and create ownership activity. Requires authentication."""
return _register_asset_impl(req, user.username)
@app.post("/registry/record-run")
async def record_run(req: RecordRunRequest):
"""Record an L1 run and register the output."""
async def record_run(req: RecordRunRequest, user: User = Depends(get_required_user)):
"""Record an L1 run and register the output. Requires authentication."""
# Fetch run from L1 server
try:
resp = requests.get(f"{L1_SERVER}/runs/{req.run_id}")
@@ -972,15 +978,15 @@ async def record_run(req: RecordRunRequest):
"rendered_at": run.get("completed_at")
}
# Register the output
return await register_asset(RegisterRequest(
# Register the output under the authenticated user
return _register_asset_impl(RegisterRequest(
name=req.output_name,
content_hash=output_hash,
asset_type="video", # Could be smarter about this
tags=["rendered", "l1"],
metadata={"l1_run_id": req.run_id},
provenance=provenance
))
), user.username)
# ============ Activities Endpoints ============