feat: provision private Hermes assistants for authenticated Hope accounts

This commit is contained in:
snowspeeder committed 2026-10-01 13:30:18 -04:00
1 parent da65da68b3
commit 2aedea84b5
33 files changed
+3063 -1743

No files matched your search

+49
View File
@@ -0,0 +1,49 @@
"""Offline bootstrap authorization: no anonymous or client-selected routing."""
import importlib.util
import json
from pathlib import Path
from unittest.mock import patch
import httpx
from fastapi.testclient import TestClient
spec = importlib.util.spec_from_file_location('hope_token', Path(__file__).parents[2] / 'web/token_server.py')
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
def test_anonymous_and_cookie_origin_denied():
with patch.multiple(module, CONTROL_SECRET='x'*32, API_KEY='key', API_SECRET='secret'):
client = TestClient(module.app)
assert client.post('/token').status_code == 401
assert client.post('/token', headers={'Cookie':'hope_session='+'y'*40,'Origin':'https://evil.invalid'}).status_code == 403
def test_authenticated_route_is_server_derived():
seen=[]
uid='a'*32
def handler(request):
body=json.loads(request.content)
seen.append((request.url.path,body))
assert request.headers['X-Control-Secret']=='x'*32
if request.url.path.endswith('resolve-session'):
return httpx.Response(200,json={'user':{'id':uid,'display_name':'John Doe'},'hermes_url':'http://127.0.0.1:1234','hermes_api_key':'private'})
assert body['session_token']=='y'*40
assert body['user_id']==uid
assert body['room_name'].startswith('voice-'+uid+'-')
return httpx.Response(201,json={})
original=httpx.AsyncClient
def factory(**kwargs):
return original(transport=httpx.MockTransport(handler),**kwargs)
with patch.multiple(module,CONTROL_SECRET='x'*32,API_KEY='key',API_SECRET='secret'),patch.object(module.httpx,'AsyncClient',factory):
response=TestClient(module.app).post('/token',headers={'Authorization':'Bearer '+'y'*40},json={'user_id':'victim','room':'victim'})
assert response.status_code==200
body=response.json()
assert body['user']['id']==uid
assert 'hermes_api_key' not in body
import base64
claims=json.loads(base64.urlsafe_b64decode(body['token'].split('.')[1]+'=='))
assert claims['sub']=='user:'+uid
assert claims['video']['canPublishSources']==['microphone']
assert claims['exp']-claims['nbf']==305
assert response.headers['Cache-Control']=='no-store'