mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-06-17 10:15:27 -04:00
Restrict provider discovery to admins
Require admin access before serving provider discovery data from GET /api/providers. This prevents normal authenticated users from triggering provider discovery or receiving cached provider host data. Keep GET /api/models available to normal users and leave the existing admin-only GET /api/discover behavior unchanged. Add a focused regression test to ensure unauthorized callers cannot trigger discovery and cannot receive cached provider data.
This commit is contained in:
committed by
GitHub
parent
7268c49992
commit
26483661da
@@ -890,8 +890,9 @@ def setup_model_routes(model_discovery):
|
|||||||
_PROVIDERS_CACHE_TTL = 30 # seconds
|
_PROVIDERS_CACHE_TTL = 30 # seconds
|
||||||
|
|
||||||
@router.get("/providers")
|
@router.get("/providers")
|
||||||
def providers(refresh: bool = False):
|
def providers(request: Request, refresh: bool = False):
|
||||||
"""Get all available providers (cached for 30s)."""
|
"""Get all available providers (cached for 30s)."""
|
||||||
|
require_admin(request)
|
||||||
now = _time.time()
|
now = _time.time()
|
||||||
if not refresh and _providers_cache["data"] is not None and (now - _providers_cache["time"]) < _PROVIDERS_CACHE_TTL:
|
if not refresh and _providers_cache["data"] is not None and (now - _providers_cache["time"]) < _PROVIDERS_CACHE_TTL:
|
||||||
return _providers_cache["data"]
|
return _providers_cache["data"]
|
||||||
|
|||||||
@@ -97,6 +97,42 @@ def _install_core_auth_stub(monkeypatch):
|
|||||||
return auth_mod
|
return auth_mod
|
||||||
|
|
||||||
|
|
||||||
|
def test_providers_requires_admin_before_discovery_and_cache(monkeypatch):
|
||||||
|
_install_model_route_import_stubs(monkeypatch)
|
||||||
|
import routes.model_routes as model_routes
|
||||||
|
|
||||||
|
class _Discovery:
|
||||||
|
def __init__(self):
|
||||||
|
self.calls = 0
|
||||||
|
|
||||||
|
def get_providers(self):
|
||||||
|
self.calls += 1
|
||||||
|
return {"providers": [{"host": "internal.example"}]}
|
||||||
|
|
||||||
|
discovery = _Discovery()
|
||||||
|
router = model_routes.setup_model_routes(discovery)
|
||||||
|
endpoint = next(
|
||||||
|
route.endpoint
|
||||||
|
for route in router.routes
|
||||||
|
if getattr(route, "path", "") == "/api/providers"
|
||||||
|
)
|
||||||
|
request = SimpleNamespace()
|
||||||
|
|
||||||
|
assert endpoint(request, refresh=True) == {"providers": [{"host": "internal.example"}]}
|
||||||
|
assert discovery.calls == 1
|
||||||
|
|
||||||
|
def deny_admin(_request):
|
||||||
|
raise PermissionError("admin required")
|
||||||
|
|
||||||
|
monkeypatch.setattr(model_routes, "require_admin", deny_admin)
|
||||||
|
|
||||||
|
with pytest.raises(PermissionError):
|
||||||
|
endpoint(request, refresh=True)
|
||||||
|
with pytest.raises(PermissionError):
|
||||||
|
endpoint(request, refresh=False)
|
||||||
|
assert discovery.calls == 1
|
||||||
|
|
||||||
|
|
||||||
def test_default_chat_does_not_auto_pick_shared_endpoint_for_fresh_user(monkeypatch):
|
def test_default_chat_does_not_auto_pick_shared_endpoint_for_fresh_user(monkeypatch):
|
||||||
_install_model_route_import_stubs(monkeypatch)
|
_install_model_route_import_stubs(monkeypatch)
|
||||||
import routes.model_routes as model_routes
|
import routes.model_routes as model_routes
|
||||||
|
|||||||
Reference in New Issue
Block a user