mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-06-17 02:05:22 -04:00
fix(auth): per-user allowed-models checklist ignores cache, [None] doesn't block (#3355)
Three issues combined to make the per-user 'Allowed models' checklist unreliable (#3032): 1. admin.js _loadModelsForUser fetched /api/models, which is backed by cached_models — endpoints that haven't been probed yet (e.g. a freshly-added DeepSeek API endpoint) simply didn't show up in the checklist. Switched to /api/model-endpoints, which always reflects every configured endpoint regardless of cache state. 2. _saveModels sent allowed_models: [] both when the admin clicked [All] (no restriction) and [None] (block everything) — the backend had no way to distinguish the two. 3. _enforce_chat_privileges treated an empty allowed_models list as 'no restriction' (falsy -> skip the check), so [None] had no effect. Added an explicit block_all_models privilege flag (defaulting to False, and forced to False for admins) that admin.js now sets when zero models are checked. _enforce_chat_privileges checks it first and 403s regardless of allowed_models contents.
This commit is contained in:
@@ -69,6 +69,64 @@ def test_allowed_models_nonempty_list_still_restricts_without_new_flag(monkeypat
|
||||
)
|
||||
|
||||
|
||||
def test_no_restriction_allows_any_model(monkeypatch):
|
||||
monkeypatch.setattr("routes.chat_helpers.get_current_user", lambda request: "alice")
|
||||
|
||||
privs = {"allowed_models": [], "block_all_models": False, "max_messages_per_day": 0}
|
||||
_enforce_chat_privileges(_Request(privs), _Session("provider/model-a"))
|
||||
_enforce_chat_privileges(_Request(privs), _Session("provider/model-z"))
|
||||
|
||||
|
||||
def test_specific_allowlist_blocks_models_outside_it(monkeypatch):
|
||||
monkeypatch.setattr("routes.chat_helpers.get_current_user", lambda request: "alice")
|
||||
|
||||
privs = {
|
||||
"allowed_models": ["gpt-4"],
|
||||
"block_all_models": False,
|
||||
"max_messages_per_day": 0,
|
||||
}
|
||||
_enforce_chat_privileges(_Request(privs), _Session("gpt-4"))
|
||||
with pytest.raises(HTTPException) as exc:
|
||||
_enforce_chat_privileges(_Request(privs), _Session("gpt-3.5"))
|
||||
assert exc.value.status_code == 403
|
||||
|
||||
|
||||
def test_block_all_models_blocks_regardless_of_allowed_models_contents(monkeypatch):
|
||||
monkeypatch.setattr("routes.chat_helpers.get_current_user", lambda request: "alice")
|
||||
|
||||
# Even if allowed_models contains entries, block_all_models wins.
|
||||
privs = {
|
||||
"allowed_models": ["gpt-4", "gpt-3.5"],
|
||||
"block_all_models": True,
|
||||
"max_messages_per_day": 0,
|
||||
}
|
||||
with pytest.raises(HTTPException) as exc:
|
||||
_enforce_chat_privileges(_Request(privs), _Session("gpt-4"))
|
||||
assert exc.value.status_code == 403
|
||||
|
||||
with pytest.raises(HTTPException):
|
||||
_enforce_chat_privileges(_Request(privs), _Session("anything-else"))
|
||||
|
||||
|
||||
def test_admin_user_is_never_blocked(monkeypatch):
|
||||
from core.auth import ADMIN_PRIVILEGES
|
||||
|
||||
monkeypatch.setattr("routes.chat_helpers.get_current_user", lambda request: "admin")
|
||||
|
||||
class _AdminAuthManager:
|
||||
def get_privileges(self, username):
|
||||
assert username == "admin"
|
||||
return dict(ADMIN_PRIVILEGES)
|
||||
|
||||
class _AdminRequest:
|
||||
def __init__(self):
|
||||
self.app = type("App", (), {})()
|
||||
self.app.state = type("State", (), {"auth_manager": _AdminAuthManager()})()
|
||||
|
||||
_enforce_chat_privileges(_AdminRequest(), _Session("provider/model-a"))
|
||||
_enforce_chat_privileges(_AdminRequest(), _Session("anything-else"))
|
||||
|
||||
|
||||
class _FakeSession:
|
||||
def __init__(self, model="selected-model"):
|
||||
self.model = model
|
||||
|
||||
Reference in New Issue
Block a user