feat(robomp): improved authorization and login normalization

- Implemented case-insensitive normalization for bot logins to handle mention handles and `[bot]` suffixes consistently.
- Added support for `ROBOMP_MAINTAINER_LOGINS` to allow authorized non-owner users to execute implementations.
- Refined authorization logic to distinguish between personal repository owners and organizational accounts.
- Updated documentation and added comprehensive tests to verify authorization handling across tasks, workers, and directive processing.
This commit is contained in:
can1357
2026-06-21 19:14:13 +02:00
parent 4b9f7cd8fa
commit 4b2e4085e0
11 changed files with 453 additions and 20 deletions
+37
View File
@@ -1536,6 +1536,43 @@ def test_webhook_directive_on_unknown_issue_is_queued_with_metadata(env) -> None
assert directive == {"body": "please refactor X", "author": "can1357", "pragmas": [], "authorizes_impl": True}
def test_webhook_directive_authorizes_deployed_app_login_without_author_association(
monkeypatch: pytest.MonkeyPatch, env
) -> None:
monkeypatch.setenv("ROBOMP_BOT_LOGIN", "@roboomp[bot]")
monkeypatch.setenv("ROBOMP_REPO_ALLOWLIST", "can1357/widget")
reset_settings_cache()
cfg = Settings() # type: ignore[call-arg]
cfg.ensure_paths()
app = create_app(cfg)
payload = {
"action": "created",
"comment": {
"user": {"login": "can1357"},
"body": "@roboomp go ahead",
},
"issue": {"number": 3196},
"repository": {
"full_name": "can1357/widget",
"owner": {"login": "can1357", "type": "User"},
},
}
raw = json.dumps(payload).encode()
with TestClient(app) as client:
resp = client.post(
"/webhook/github",
content=raw,
headers=_signed_headers("test-webhook-secret", raw, event="issue_comment", delivery="dir-app-login"),
)
assert resp.status_code == 202
assert resp.json()["state"] == "queued"
row = get_database(cfg.sqlite_path).get_event("dir-app-login")
close_database()
assert row is not None
directive = row.payload.get("_robomp_directive")
assert directive == {"body": "go ahead", "author": "can1357", "pragmas": [], "authorizes_impl": True}
def test_webhook_maintainer_bypasses_rate_limit(
rate_limited_settings: Settings,
monkeypatch: pytest.MonkeyPatch,