Skip to content

Commit 0c27905

Browse files
committed
Prevent unauthorized use of the self-hosted runners
Since we have to self-host the Windows/ARM64 build agents for now, let's cap the cost by disallowing random Pull Requests to use up our resources. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
1 parent 682e6fd commit 0c27905

3 files changed

Lines changed: 66 additions & 1 deletion

File tree

GitForWindowsHelper/check-runs.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,20 @@ const updateCheckRun = async (context, token, owner, repo, checkRunId, parameter
5959
)
6060
}
6161

62+
const cancelWorkflowRun = async (context, token, owner, repo, workflowRunId) => {
63+
const githubApiRequest = require('./github-api-request')
64+
65+
const answer = await githubApiRequest(
66+
context,
67+
token,
68+
'POST',
69+
`/repos/${owner}/${repo}/actions/runs/${workflowRunId}/cancel`
70+
)
71+
console.log(answer)
72+
}
73+
6274
module.exports = {
6375
queueCheckRun,
64-
updateCheckRun
76+
updateCheckRun,
77+
cancelWorkflowRun
6578
}

GitForWindowsHelper/index.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,19 @@ module.exports = async function (context, req) {
3131
return withStatus(500, undefined, e.toString('utf-8'))
3232
}
3333

34+
try {
35+
const selfHostedARM64Runners = require('./self-hosted-arm64-runners')
36+
if (req.headers['x-github-event'] === 'workflow_job'
37+
&& req.body.repository.full_name === 'git-for-windows/git-for-windows-automation'
38+
&& ['queued', 'completed'].includes(req.body.action)
39+
&& req.body.workflow_job.labels.length === 2
40+
&& req.body.workflow_job.labels[0] === 'Windows'
41+
&& req.body.workflow_job.labels[1] === 'ARM64') return ok(await selfHostedARM64Runners(context, req))
42+
} catch (e) {
43+
context.log(e)
44+
return withStatus(500, undefined, e.toString('utf-8'))
45+
}
46+
3447
context.log("Got headers")
3548
context.log(req.headers)
3649
context.log("Got body")
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
module.exports = async (context, req) => {
2+
const action = req.body.action
3+
const owner = req.body.repository.owner.login
4+
const repo = req.body.repository.name
5+
const sender = req.body.sender.login
6+
7+
const getToken = (() => {
8+
let token
9+
10+
const get = async () => {
11+
const getInstallationIdForRepo = require('./get-installation-id-for-repo')
12+
const installationId = await getInstallationIdForRepo(context, owner, repo)
13+
const getInstallationAccessToken = require('./get-installation-access-token')
14+
return await getInstallationAccessToken(context, installationId)
15+
}
16+
17+
return async () => token || (token = await get())
18+
})()
19+
20+
const isAllowed = async (login) => {
21+
const getCollaboratorPermissions = require('./get-collaborator-permissions')
22+
const token = await getToken()
23+
const permission = await getCollaboratorPermissions(context, token, owner, repo, login)
24+
return ['ADMIN', 'MAINTAIN', 'WRITE'].includes(permission.toString())
25+
}
26+
27+
if (!isAllowed(sender)) {
28+
if (action !== 'completed') {
29+
// Cancel workflow run
30+
const { cancelWorkflowRun } = require('./check-runs')
31+
const token = await getToken()
32+
const workflowRunId = req.body.workflow_job.run_id
33+
await cancelWorkflowRun(context, token, owner, repo, workflowRunId)
34+
}
35+
throw new Error(`${sender} is not allowed to do that`)
36+
}
37+
38+
return `Unhandled action: ${action}`
39+
}

0 commit comments

Comments
 (0)