mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-09-10 18:22:20 +02:00
fix(companion): preserve models with auth disabled (#5797)
* fix(companion): preserve models with auth disabled * test(companion): guard auth-disabled model scoping
This commit is contained in:
+10
-4
@@ -23,7 +23,7 @@ from fastapi import APIRouter, HTTPException, Request
|
|||||||
from fastapi.responses import HTMLResponse
|
from fastapi.responses import HTMLResponse
|
||||||
|
|
||||||
from core.middleware import require_admin
|
from core.middleware import require_admin
|
||||||
from src.auth_helpers import get_current_user
|
from src.auth_helpers import _auth_disabled, get_current_user
|
||||||
|
|
||||||
from companion import pairing as _pairing
|
from companion import pairing as _pairing
|
||||||
|
|
||||||
@@ -113,8 +113,9 @@ def setup_companion_routes() -> APIRouter:
|
|||||||
The stock /api/models route scopes to get_current_user, which for a
|
The stock /api/models route scopes to get_current_user, which for a
|
||||||
bearer token is the sandboxed pseudo-user "api" (owns nothing). Here we
|
bearer token is the sandboxed pseudo-user "api" (owns nothing). Here we
|
||||||
scope to the token's real owner instead, plus legacy null-owner shared
|
scope to the token's real owner instead, plus legacy null-owner shared
|
||||||
rows -- the same rule as owner_filter. Read-only; never returns api_key
|
rows -- the same rule as owner_filter. Explicit auth-disabled mode keeps
|
||||||
material.
|
the stock route's single-user all-endpoints view. Read-only; never
|
||||||
|
returns api_key material.
|
||||||
"""
|
"""
|
||||||
require_models_scope(request)
|
require_models_scope(request)
|
||||||
import json as _json
|
import json as _json
|
||||||
@@ -123,6 +124,11 @@ def setup_companion_routes() -> APIRouter:
|
|||||||
from src.endpoint_resolver import build_chat_url
|
from src.endpoint_resolver import build_chat_url
|
||||||
|
|
||||||
owner = token_owner(request)
|
owner = token_owner(request)
|
||||||
|
single_user_mode = (
|
||||||
|
owner is None
|
||||||
|
and not getattr(request.state, "api_token", False)
|
||||||
|
and _auth_disabled()
|
||||||
|
)
|
||||||
out = []
|
out = []
|
||||||
db = SessionLocal()
|
db = SessionLocal()
|
||||||
try:
|
try:
|
||||||
@@ -133,7 +139,7 @@ def setup_companion_routes() -> APIRouter:
|
|||||||
if owner:
|
if owner:
|
||||||
q = q.filter((ModelEndpoint.owner == owner) | (ModelEndpoint.owner == None)) # noqa: E711
|
q = q.filter((ModelEndpoint.owner == owner) | (ModelEndpoint.owner == None)) # noqa: E711
|
||||||
for ep in q.all():
|
for ep in q.all():
|
||||||
if not owner_can_see(ep.owner, owner):
|
if not single_user_mode and not owner_can_see(ep.owner, owner):
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
model_ids = _json.loads(ep.cached_models) if ep.cached_models else []
|
model_ids = _json.loads(ep.cached_models) if ep.cached_models else []
|
||||||
|
|||||||
@@ -257,6 +257,7 @@ def test_models_route_rejects_api_token_without_chat_scope(monkeypatch):
|
|||||||
|
|
||||||
|
|
||||||
def test_models_route_unresolved_owner_returns_only_shared_rows(monkeypatch):
|
def test_models_route_unresolved_owner_returns_only_shared_rows(monkeypatch):
|
||||||
|
monkeypatch.setenv("AUTH_ENABLED", "true")
|
||||||
rows = [
|
rows = [
|
||||||
_ep(1, "alice-endpoint", "alice"),
|
_ep(1, "alice-endpoint", "alice"),
|
||||||
_ep(2, "shared-endpoint", None),
|
_ep(2, "shared-endpoint", None),
|
||||||
@@ -278,6 +279,87 @@ def test_models_route_unresolved_owner_returns_only_shared_rows(monkeypatch):
|
|||||||
assert _endpoint_names(endpoints) == ["shared-endpoint"]
|
assert _endpoint_names(endpoints) == ["shared-endpoint"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_models_route_auth_disabled_does_not_widen_ownerless_api_token(monkeypatch):
|
||||||
|
monkeypatch.setenv("AUTH_ENABLED", "false")
|
||||||
|
rows = [
|
||||||
|
_ep(1, "alice-endpoint", "alice"),
|
||||||
|
_ep(2, "shared-endpoint", None),
|
||||||
|
_ep(3, "bob-endpoint", "bob"),
|
||||||
|
]
|
||||||
|
monkeypatch.setattr(companion_routes, "get_current_user", lambda request: None)
|
||||||
|
|
||||||
|
endpoints = _call_models_route(
|
||||||
|
monkeypatch,
|
||||||
|
rows,
|
||||||
|
_request(
|
||||||
|
api_token=True,
|
||||||
|
api_token_owner=None,
|
||||||
|
api_token_scopes=["chat"],
|
||||||
|
current_user="api",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
assert _endpoint_names(endpoints) == ["shared-endpoint"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_models_route_auth_disabled_keeps_cookie_owner_scoped(monkeypatch):
|
||||||
|
monkeypatch.setenv("AUTH_ENABLED", "false")
|
||||||
|
rows = [
|
||||||
|
_ep(1, "alice-endpoint", "alice"),
|
||||||
|
_ep(2, "shared-endpoint", None),
|
||||||
|
_ep(3, "bob-endpoint", "bob"),
|
||||||
|
]
|
||||||
|
monkeypatch.setattr(companion_routes, "get_current_user", lambda request: "alice")
|
||||||
|
|
||||||
|
endpoints = _call_models_route(
|
||||||
|
monkeypatch,
|
||||||
|
rows,
|
||||||
|
_request(api_token=False, current_user="alice"),
|
||||||
|
)
|
||||||
|
|
||||||
|
assert _endpoint_names(endpoints) == ["alice-endpoint", "shared-endpoint"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_models_route_auth_enabled_anonymous_returns_only_shared_rows(monkeypatch):
|
||||||
|
monkeypatch.setenv("AUTH_ENABLED", "true")
|
||||||
|
rows = [
|
||||||
|
_ep(1, "alice-endpoint", "alice"),
|
||||||
|
_ep(2, "shared-endpoint", None),
|
||||||
|
_ep(3, "bob-endpoint", "bob"),
|
||||||
|
]
|
||||||
|
monkeypatch.setattr(companion_routes, "get_current_user", lambda request: None)
|
||||||
|
|
||||||
|
endpoints = _call_models_route(
|
||||||
|
monkeypatch,
|
||||||
|
rows,
|
||||||
|
_request(api_token=False, current_user=None),
|
||||||
|
)
|
||||||
|
|
||||||
|
assert _endpoint_names(endpoints) == ["shared-endpoint"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_models_route_auth_disabled_returns_all_enabled_rows(monkeypatch):
|
||||||
|
monkeypatch.setenv("AUTH_ENABLED", "false")
|
||||||
|
rows = [
|
||||||
|
_ep(1, "alice-endpoint", "alice"),
|
||||||
|
_ep(2, "shared-endpoint", None),
|
||||||
|
_ep(3, "bob-endpoint", "bob"),
|
||||||
|
]
|
||||||
|
monkeypatch.setattr(companion_routes, "get_current_user", lambda request: None)
|
||||||
|
|
||||||
|
endpoints = _call_models_route(
|
||||||
|
monkeypatch,
|
||||||
|
rows,
|
||||||
|
_request(api_token=False, current_user=None),
|
||||||
|
)
|
||||||
|
|
||||||
|
assert _endpoint_names(endpoints) == [
|
||||||
|
"alice-endpoint",
|
||||||
|
"shared-endpoint",
|
||||||
|
"bob-endpoint",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def test_models_route_filters_hidden_models_and_secret_fields(monkeypatch):
|
def test_models_route_filters_hidden_models_and_secret_fields(monkeypatch):
|
||||||
rows = [
|
rows = [
|
||||||
_ep(
|
_ep(
|
||||||
|
|||||||
Reference in New Issue
Block a user