50 lines
2.3 KiB
Python
50 lines
2.3 KiB
Python
"""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'
|