🐾 feat(library): per-app managed_by replaces hardcoded Daedalus badge
Libraries created through the API are now stamped with the name of the UserToken that created them (Library.managed_by), on both the workspace and plain create endpoints; web-session creates stay null/unmanaged. The idempotent workspace re-POST lazily backfills null managed_by, and a one-off backfill_managed_by command labels pre-existing rows (workspace inference: kairos-mail-* → Kairos, else Daedalus; Spelunker via ingest job provenance). UI badges and warnings now render "Managed by <app>" via managed_by_display (inference fallback keeps legacy rows accurate before backfill). The list scope filter becomes all/managed/unmanaged with the old daedalus/global values aliased for bookmarks. The plain create endpoint also gains an explicit 409 name_conflict (previously a raw UniqueProperty 500) reporting the existing library's uid and manager. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -105,6 +105,44 @@ class UserTokenAuthenticationTest(TestCase):
|
||||
resp = self._get(f"Bearer {self.plaintext} extra")
|
||||
self.assertEqual(resp.status_code, status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
def test_request_token_label_reads_token_name(self):
|
||||
from types import SimpleNamespace
|
||||
|
||||
from mcp_server.drf_auth import request_token_label
|
||||
|
||||
token = UserToken(name=" Spelunker ")
|
||||
self.assertEqual(
|
||||
request_token_label(SimpleNamespace(auth=token)), "Spelunker"
|
||||
)
|
||||
|
||||
def test_request_token_label_none_for_session(self):
|
||||
from types import SimpleNamespace
|
||||
|
||||
from mcp_server.drf_auth import request_token_label
|
||||
|
||||
self.assertIsNone(request_token_label(SimpleNamespace(auth=None)))
|
||||
# A request object with no auth attribute at all (plain Django).
|
||||
self.assertIsNone(request_token_label(SimpleNamespace()))
|
||||
|
||||
def test_request_token_label_none_for_blank_name(self):
|
||||
from types import SimpleNamespace
|
||||
|
||||
from mcp_server.drf_auth import request_token_label
|
||||
|
||||
self.assertIsNone(
|
||||
request_token_label(SimpleNamespace(auth=UserToken(name=" ")))
|
||||
)
|
||||
|
||||
def test_request_token_label_none_for_foreign_auth_object(self):
|
||||
from types import SimpleNamespace
|
||||
|
||||
from mcp_server.drf_auth import request_token_label
|
||||
|
||||
# e.g. a JWT dict from another auth class — not a UserToken.
|
||||
self.assertIsNone(
|
||||
request_token_label(SimpleNamespace(auth={"iss": "daedalus"}))
|
||||
)
|
||||
|
||||
def test_request_auth_stashes_token(self):
|
||||
# The auth class returns (user, token); DRF places the token on
|
||||
# request.auth. Re-use a UserToken-aware endpoint to verify.
|
||||
|
||||
Reference in New Issue
Block a user