mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-06-17 18:25:26 -04:00
fix(auth): case-insensitive skill owner match on rename (#3614)
SKILL.md files written with mixed-case owner (e.g. 'owner: Alice') were skipped because the regex had no IGNORECASE flag. _usage.json keys like 'Alice::skill-name' were missed by the startswith prefix check for the same reason. Both comparisons now match the same way the deep_research and memory blocks do — case-insensitively against old_username. Fixes #3611
This commit is contained in:
@@ -391,7 +391,8 @@ def setup_auth_routes(auth_manager: AuthManager) -> APIRouter:
|
|||||||
skills_root = Path(SKILLS_DIR)
|
skills_root = Path(SKILLS_DIR)
|
||||||
if skills_root.is_dir():
|
if skills_root.is_dir():
|
||||||
_owner_re = re.compile(
|
_owner_re = re.compile(
|
||||||
r'(?m)^(owner:\s*)' + re.escape(old_username) + r'\s*$'
|
r'(?m)^(owner:\s*)' + re.escape(old_username) + r'\s*$',
|
||||||
|
re.IGNORECASE,
|
||||||
)
|
)
|
||||||
for p in skills_root.rglob("SKILL.md"):
|
for p in skills_root.rglob("SKILL.md"):
|
||||||
try:
|
try:
|
||||||
@@ -406,12 +407,12 @@ def setup_auth_routes(auth_manager: AuthManager) -> APIRouter:
|
|||||||
try:
|
try:
|
||||||
usage = json.loads(usage_path.read_text(encoding="utf-8"))
|
usage = json.loads(usage_path.read_text(encoding="utf-8"))
|
||||||
if isinstance(usage, dict):
|
if isinstance(usage, dict):
|
||||||
prefix = old_username + "::"
|
|
||||||
new_usage = {}
|
new_usage = {}
|
||||||
changed = False
|
changed = False
|
||||||
for k, v in usage.items():
|
for k, v in usage.items():
|
||||||
if k.startswith(prefix):
|
owner_part, sep, skill_part = k.partition("::")
|
||||||
new_usage[new_username + "::" + k[len(prefix):]] = v
|
if sep and owner_part.lower() == old_username:
|
||||||
|
new_usage[new_username + "::" + skill_part] = v
|
||||||
changed = True
|
changed = True
|
||||||
else:
|
else:
|
||||||
new_usage[k] = v
|
new_usage[k] = v
|
||||||
|
|||||||
@@ -333,6 +333,37 @@ def test_rename_no_skills_dir_does_not_crash(rename_endpoint):
|
|||||||
assert res["ok"] is True
|
assert res["ok"] is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_rename_skill_md_owner_case_insensitive(rename_endpoint):
|
||||||
|
"""SKILL.md written with owner: Alice (mixed case) must be updated when
|
||||||
|
renaming alice — the regex was missing re.IGNORECASE."""
|
||||||
|
endpoint, _am, tmp_path = rename_endpoint
|
||||||
|
|
||||||
|
skill_dir = tmp_path / "skills" / "general" / "s"
|
||||||
|
skill_dir.mkdir(parents=True)
|
||||||
|
(skill_dir / "SKILL.md").write_text(_SKILL_MD.format(owner="Alice"), encoding="utf-8")
|
||||||
|
|
||||||
|
asyncio.run(endpoint("alice", SimpleNamespace(username="alice2"), _request(tmp_path)))
|
||||||
|
|
||||||
|
assert "owner: alice2" in (skill_dir / "SKILL.md").read_text(encoding="utf-8")
|
||||||
|
|
||||||
|
|
||||||
|
def test_rename_usage_keys_case_insensitive(rename_endpoint):
|
||||||
|
"""_usage.json keys stored as Alice::skill-name must be migrated when
|
||||||
|
renaming alice — the old startswith check was not lowercasing."""
|
||||||
|
endpoint, _am, tmp_path = rename_endpoint
|
||||||
|
|
||||||
|
skills_root = tmp_path / "skills"
|
||||||
|
skills_root.mkdir(parents=True)
|
||||||
|
usage = {"Alice::my-skill": {"uses": 5, "last_used": 999}}
|
||||||
|
(skills_root / "_usage.json").write_text(json.dumps(usage), encoding="utf-8")
|
||||||
|
|
||||||
|
asyncio.run(endpoint("alice", SimpleNamespace(username="alice2"), _request(tmp_path)))
|
||||||
|
|
||||||
|
updated = json.loads((skills_root / "_usage.json").read_text(encoding="utf-8"))
|
||||||
|
assert "alice2::my-skill" in updated
|
||||||
|
assert "Alice::my-skill" not in updated
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# 5. P1 regression: rejected auth rename must not mutate file-backed stores
|
# 5. P1 regression: rejected auth rename must not mutate file-backed stores
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user