diff --git a/src/helpers/checkers.ts b/src/helpers/checkers.ts index 58ba65cb..42758638 100644 --- a/src/helpers/checkers.ts +++ b/src/helpers/checkers.ts @@ -41,9 +41,27 @@ export function nonAssigneeApprovedReviews(data: Readonly) { return false; } +/* + * Returns true if a given user has admin permission in the specific repo, otherwise checks for admin / billing manager + * within the parent organization. + */ export async function isAdmin(username: string, context: ContextPlugin): Promise { const octokit = context.octokit; try { + const permissionLevel = await octokit.rest.repos.getCollaboratorPermissionLevel({ + username, + owner: context.payload.repository.owner.login, + repo: context.payload.repository.name, + }); + context.logger.debug(`Retrieved collaborator permission level for ${username}.`, { + username, + owner: context.payload.repository.owner.login, + repo: context.payload.repository.name, + isAdmin: permissionLevel.data.user?.permissions?.admin, + }); + if (permissionLevel.data.user?.permissions?.admin) { + return true; + } const userPerms = await octokit.rest.orgs.getMembershipForUser({ org: context.payload.repository.owner.login, username: username, diff --git a/tests/issue.http b/tests/issue.http index 5b596a30..445a6393 100644 --- a/tests/issue.http +++ b/tests/issue.http @@ -1,4 +1,4 @@ -POST http://localhost:3000 +POST http://localhost:4000 Content-Type: application/json { @@ -7,6 +7,7 @@ Content-Type: application/json "signature": "", "eventName": "issues.closed", "action": "closed", + "command": null, "settings": { "evmPrivateEncrypted": "YfEnpznMNbSPhCQzWy1Uevi4xQC25SqJrHd87CjjS1gsu92QrCReSgvl8Z_pVI1ZM57PNC1mZSgHbNgX9ITmOJc6qaOJ_mRe_sP_8jBcNimusDCQcWEkcPIW7Md-QGDPnwuN8FIavS7I0uiOIRYK6h0NK02-3uzPqhM", "incentives": { @@ -25,55 +26,55 @@ Content-Type: application/json "eventPayload": { "issue": { "state_reason": "completed", - "url": "https://api.github.com/repos/{{OWNER_REPO}}/issues/1", - "repository_url": "https://api.github.com/repos/{{OWNER_REPO}}", - "labels_url": "https://api.github.com/repos/{{OWNER_REPO}}/issues/1/labels{/name}", - "comments_url": "https://api.github.com/repos/{{OWNER_REPO}}/issues/1/comments", - "events_url": "https://api.github.com/repos/{{OWNER_REPO}}/issues/1/events", - "html_url": "https://github.com/{{OWNER_REPO}}/issues/1", + "url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/issues/{{ISSUE_ID}}", + "repository_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}", + "labels_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/issues/{{ISSUE_ID}}/labels{/name}", + "comments_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/issues/{{ISSUE_ID}}/comments", + "events_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/issues/{{ISSUE_ID}}/events", + "html_url": "https://github.com/{{OWNER}}/{{REPO}}/issues/{{ISSUE_ID}}", "id": 1, "node_id": "MDU6SXNzdWUx", "number": 1, "title": "Found a bug", "user": { - "login": "meniole", + "login": "{{OWNER}}", "id": 1, "node_id": "MDQ6VXNlcjE=", - "avatar_url": "https://github.com/images/error/meniole_happy.gif", + "avatar_url": "https://github.com/images/error/{{OWNER}}_happy.gif", "gravatar_id": "", - "url": "https://api.github.com/users/meniole", - "html_url": "https://github.com/meniole", - "followers_url": "https://api.github.com/users/meniole/followers", - "following_url": "https://api.github.com/users/meniole/following{/other_user}", - "gists_url": "https://api.github.com/users/meniole/gists{/gist_id}", - "starred_url": "https://api.github.com/users/meniole/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/meniole/subscriptions", - "organizations_url": "https://api.github.com/users/meniole/orgs", - "repos_url": "https://api.github.com/users/meniole/repos", - "events_url": "https://api.github.com/users/meniole/events{/privacy}", - "received_events_url": "https://api.github.com/users/meniole/received_events", + "url": "https://api.github.com/users/{{OWNER}}", + "html_url": "https://github.com/{{OWNER}}", + "followers_url": "https://api.github.com/users/{{OWNER}}/followers", + "following_url": "https://api.github.com/users/{{OWNER}}/following{/other_user}", + "gists_url": "https://api.github.com/users/{{OWNER}}/gists{/gist_id}", + "starred_url": "https://api.github.com/users/{{OWNER}}/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/{{OWNER}}/subscriptions", + "organizations_url": "https://api.github.com/users/{{OWNER}}/orgs", + "repos_url": "https://api.github.com/users/{{OWNER}}/repos", + "events_url": "https://api.github.com/users/{{OWNER}}/events{/privacy}", + "received_events_url": "https://api.github.com/users/{{OWNER}}/received_events", "type": "User", "site_admin": false }, "state": "closed", "locked": false, "assignee": { - "login": "meniole", + "login": "{{OWNER}}", "id": 1, "node_id": "MDQ6VXNlcjE=", - "avatar_url": "https://github.com/images/error/meniole_happy.gif", + "avatar_url": "https://github.com/images/error/{{OWNER}}_happy.gif", "gravatar_id": "", - "url": "https://api.github.com/users/meniole", - "html_url": "https://github.com/meniole", - "followers_url": "https://api.github.com/users/meniole/followers", - "following_url": "https://api.github.com/users/meniole/following{/other_user}", - "gists_url": "https://api.github.com/users/meniole/gists{/gist_id}", - "starred_url": "https://api.github.com/users/meniole/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/meniole/subscriptions", - "organizations_url": "https://api.github.com/users/meniole/orgs", - "repos_url": "https://api.github.com/users/meniole/repos", - "events_url": "https://api.github.com/users/meniole/events{/privacy}", - "received_events_url": "https://api.github.com/users/meniole/received_events", + "url": "https://api.github.com/users/{{OWNER}}", + "html_url": "https://github.com/{{OWNER}}", + "followers_url": "https://api.github.com/users/{{OWNER}}/followers", + "following_url": "https://api.github.com/users/{{OWNER}}/following{/other_user}", + "gists_url": "https://api.github.com/users/{{OWNER}}/gists{/gist_id}", + "starred_url": "https://api.github.com/users/{{OWNER}}/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/{{OWNER}}/subscriptions", + "organizations_url": "https://api.github.com/users/{{OWNER}}/orgs", + "repos_url": "https://api.github.com/users/{{OWNER}}/repos", + "events_url": "https://api.github.com/users/{{OWNER}}/events{/privacy}", + "received_events_url": "https://api.github.com/users/{{OWNER}}/received_events", "type": "User", "site_admin": false }, @@ -81,7 +82,7 @@ Content-Type: application/json { "id": 208045946, "node_id": "MDU6TGFiZWwyMDgwNDU5NDY=", - "url": "https://api.github.com/repos/{{OWNER_REPO}}/labels/bug", + "url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/labels/bug", "name": "bug", "description": "Something isn't working", "color": "f29513", @@ -98,69 +99,69 @@ Content-Type: application/json "repository": { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", - "name": "conversation-rewards", - "full_name": "meniole/conversation-rewards", + "name": "{{REPO}}", + "full_name": "{{OWNER}}/{{REPO}}", "owner": { - "login": "meniole", + "login": "{{OWNER}}", "id": 159901852, "node_id": "MDQ6VXNlcjE=", - "avatar_url": "https://github.com/images/error/meniole_happy.gif", + "avatar_url": "https://github.com/images/error/{{OWNER}}_happy.gif", "gravatar_id": "", - "url": "https://api.github.com/users/meniole", - "html_url": "https://github.com/meniole", - "followers_url": "https://api.github.com/users/meniole/followers", - "following_url": "https://api.github.com/users/meniole/following{/other_user}", - "gists_url": "https://api.github.com/users/meniole/gists{/gist_id}", - "starred_url": "https://api.github.com/users/meniole/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/meniole/subscriptions", - "organizations_url": "https://api.github.com/users/meniole/orgs", - "repos_url": "https://api.github.com/users/meniole/repos", - "events_url": "https://api.github.com/users/meniole/events{/privacy}", - "received_events_url": "https://api.github.com/users/meniole/received_events", + "url": "https://api.github.com/users/{{OWNER}}", + "html_url": "https://github.com/{{OWNER}}", + "followers_url": "https://api.github.com/users/{{OWNER}}/followers", + "following_url": "https://api.github.com/users/{{OWNER}}/following{/other_user}", + "gists_url": "https://api.github.com/users/{{OWNER}}/gists{/gist_id}", + "starred_url": "https://api.github.com/users/{{OWNER}}/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/{{OWNER}}/subscriptions", + "organizations_url": "https://api.github.com/users/{{OWNER}}/orgs", + "repos_url": "https://api.github.com/users/{{OWNER}}/repos", + "events_url": "https://api.github.com/users/{{OWNER}}/events{/privacy}", + "received_events_url": "https://api.github.com/users/{{OWNER}}/received_events", "type": "User", "site_admin": false }, "private": false, - "html_url": "https://github.com/meniole/conversation-rewards", + "html_url": "https://github.com/{{OWNER}}/{{REPO}}", "description": "This your first repo!", "fork": false, - "url": "https://api.github.com/repos/meniole/conversation-rewards", - "archive_url": "https://api.github.com/repos/meniole/conversation-rewards/{archive_format}{/ref}", - "assignees_url": "https://api.github.com/repos/meniole/conversation-rewards/assignees{/user}", - "blobs_url": "https://api.github.com/repos/meniole/conversation-rewards/git/blobs{/sha}", - "branches_url": "https://api.github.com/repos/meniole/conversation-rewards/branches{/branch}", - "collaborators_url": "https://api.github.com/repos/meniole/conversation-rewards/collaborators{/collaborator}", - "comments_url": "https://api.github.com/repos/meniole/conversation-rewards/comments{/number}", - "commits_url": "https://api.github.com/repos/meniole/conversation-rewards/commits{/sha}", - "compare_url": "https://api.github.com/repos/meniole/conversation-rewards/compare/{base}...{head}", - "contents_url": "https://api.github.com/repos/meniole/conversation-rewards/contents/{+path}", - "contributors_url": "https://api.github.com/repos/meniole/conversation-rewards/contributors", - "deployments_url": "https://api.github.com/repos/meniole/conversation-rewards/deployments", - "downloads_url": "https://api.github.com/repos/meniole/conversation-rewards/downloads", - "events_url": "https://api.github.com/repos/meniole/conversation-rewards/events", - "forks_url": "https://api.github.com/repos/meniole/conversation-rewards/forks", - "git_commits_url": "https://api.github.com/repos/meniole/conversation-rewards/git/commits{/sha}", - "git_refs_url": "https://api.github.com/repos/meniole/conversation-rewards/git/refs{/sha}", - "git_tags_url": "https://api.github.com/repos/meniole/conversation-rewards/git/tags{/sha}", - "git_url": "git:github.com/meniole/conversation-rewards.git", - "issue_comment_url": "https://api.github.com/repos/meniole/conversation-rewards/issues/comments{/number}", - "issue_events_url": "https://api.github.com/repos/meniole/conversation-rewards/issues/events{/number}", - "issues_url": "https://api.github.com/repos/meniole/conversation-rewards/issues{/number}", - "keys_url": "https://api.github.com/repos/meniole/conversation-rewards/keys{/key_id}", - "labels_url": "https://api.github.com/repos/meniole/conversation-rewards/labels{/name}", - "languages_url": "https://api.github.com/repos/meniole/conversation-rewards/languages", - "merges_url": "https://api.github.com/repos/meniole/conversation-rewards/merges", - "milestones_url": "https://api.github.com/repos/meniole/conversation-rewards/milestones{/number}", - "notifications_url": "https://api.github.com/repos/meniole/conversation-rewards/notifications{?since,all,participating}", - "pulls_url": "https://api.github.com/repos/meniole/conversation-rewards/pulls{/number}", - "releases_url": "https://api.github.com/repos/meniole/conversation-rewards/releases{/id}", - "stargazers_url": "https://api.github.com/repos/meniole/conversation-rewards/stargazers", - "statuses_url": "https://api.github.com/repos/meniole/conversation-rewards/statuses/{sha}", - "subscribers_url": "https://api.github.com/repos/meniole/conversation-rewards/subscribers", - "subscription_url": "https://api.github.com/repos/meniole/conversation-rewards/subscription", - "tags_url": "https://api.github.com/repos/meniole/conversation-rewards/tags", - "teams_url": "https://api.github.com/repos/meniole/conversation-rewards/teams", - "trees_url": "https://api.github.com/repos/meniole/conversation-rewards/git/trees{/sha}", + "url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}", + "archive_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/{archive_format}{/ref}", + "assignees_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/assignees{/user}", + "blobs_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/branches{/branch}", + "collaborators_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/comments{/number}", + "commits_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/commits{/sha}", + "compare_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/contents/{+path}", + "contributors_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/contributors", + "deployments_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/deployments", + "downloads_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/downloads", + "events_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/events", + "forks_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/forks", + "git_commits_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/git/tags{/sha}", + "git_url": "git:github.com/{{OWNER}}/{{REPO}}.git", + "issue_comment_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/issues/events{/number}", + "issues_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/issues{/number}", + "keys_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/keys{/key_id}", + "labels_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/labels{/name}", + "languages_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/languages", + "merges_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/merges", + "milestones_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/milestones{/number}", + "notifications_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/notifications{?since,all,participating}", + "pulls_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/pulls{/number}", + "releases_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/releases{/id}", + "stargazers_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/stargazers", + "statuses_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/subscribers", + "subscription_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/subscription", + "tags_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/tags", + "teams_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/teams", + "trees_url": "https://api.github.com/repos/{{OWNER}}/{{REPO}}/git/trees{/sha}", "homepage": "https://github.com", "language": null, "forks_count": 9, @@ -199,22 +200,22 @@ Content-Type: application/json "network_count": 0 }, "sender": { - "login": "meniole", + "login": "{{OWNER}}", "id": 159901852, "node_id": "MDQ6VXNlcjE=", - "avatar_url": "https://github.com/images/error/meniole_happy.gif", + "avatar_url": "https://github.com/images/error/{{OWNER}}_happy.gif", "gravatar_id": "", - "url": "https://api.github.com/users/meniole", - "html_url": "https://github.com/meniole", - "followers_url": "https://api.github.com/users/meniole/followers", - "following_url": "https://api.github.com/users/meniole/following{/other_user}", - "gists_url": "https://api.github.com/users/meniole/gists{/gist_id}", - "starred_url": "https://api.github.com/users/meniole/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/meniole/subscriptions", - "organizations_url": "https://api.github.com/users/meniole/orgs", - "repos_url": "https://api.github.com/users/meniole/repos", - "events_url": "https://api.github.com/users/meniole/events{/privacy}", - "received_events_url": "https://api.github.com/users/meniole/received_events", + "url": "https://api.github.com/users/{{OWNER}}", + "html_url": "https://github.com/{{OWNER}}", + "followers_url": "https://api.github.com/users/{{OWNER}}/followers", + "following_url": "https://api.github.com/users/{{OWNER}}/following{/other_user}", + "gists_url": "https://api.github.com/users/{{OWNER}}/gists{/gist_id}", + "starred_url": "https://api.github.com/users/{{OWNER}}/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/{{OWNER}}/subscriptions", + "organizations_url": "https://api.github.com/users/{{OWNER}}/orgs", + "repos_url": "https://api.github.com/users/{{OWNER}}/repos", + "events_url": "https://api.github.com/users/{{OWNER}}/events{/privacy}", + "received_events_url": "https://api.github.com/users/{{OWNER}}/received_events", "type": "User", "site_admin": false }