-
Notifications
You must be signed in to change notification settings - Fork 284
Expand file tree
/
Copy pathreplicate.js
More file actions
220 lines (217 loc) · 8.6 KB
/
replicate.js
File metadata and controls
220 lines (217 loc) · 8.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.isFirstSubmission = exports.createInternalIssue = exports.generateInternalIssueContentFromPayload = exports.BOUNTY_LABELS = void 0;
const core = __importStar(require("@actions/core"));
const github = __importStar(require("@actions/github"));
const issues_1 = require("./issues");
exports.BOUNTY_LABELS = ['All For One', 'The Bug Slayer'];
const COMMENT_TASK_LIST_AFO = `## Task List
- [ ] Initial assessment - Please record your decision in the comment below
- [ ] CodeQL
- [ ] Security Lab
- [ ] CodeQL: Generate result set and post the URL in the comment
- [ ] Security Lab assessment:
- [ ] Assess the Vulnerability Impact, the Vulnerability Scope, and the False Positive ratio based on the provided CodeQL result set
- [ ] Provide feedback to the author in the PR
- [ ] CodeQL assessment:
- [ ] Assess the Code Maturity and the Documentation
- [ ] Provide feedback to the author in the PR
- [ ] Merge the PR into the experimental folder
- [ ] Score - Both teams fill the score table according to the version of the PR merged into the repository
- [ ] Bounty Payment
`;
const COMMENT_TASK_LIST_BS = `## Task List
- [ ] Initial assessment from Security Lab
- [ ] Security Lab assessment:
- [ ] Confirm the CVE
- [ ] Assess the Vulnerability Impact, the Vulnerability Scope
- [ ] Get the CodeQL scores (False Positive ratio, Code Maturity and the Documentation) from the previous query rating
- [ ] PR is merged? Finalize the score
- [ ] Bounty Payment`;
const COMMENT_TASK_LIST = {
'All For One': COMMENT_TASK_LIST_AFO,
'The Bug Slayer': COMMENT_TASK_LIST_BS
};
const COMMENT_SCORING = `## Scoring
| Criterion | Score|
|--- | --- |
| Vulnerability Impact | |
| Vulnerability Scope | |
| False Positive | |
| Code Maturity | |
| Documentation | |
- [ ] Reject
- [ ] Reject with thank you reward
- [ ] Reject with encouragement swag (Decision: Dev Advocacy)
- [ ] Accept
`;
const COMMENT_FIRST_SUBMISSION = `## :tada: First submission for this user :tada:`;
exports.generateInternalIssueContentFromPayload = async (payload) => {
const issue = payload.issue;
let result = { title: 'none', body: 'none', labels: [], bountyType: 'All For One' };
let bountyIssue = false;
let bountyType = '';
if (!issue || !issue.user || !issue.html_url) {
core.debug("Invalid issue payload");
return undefined;
}
issue.labels.forEach((element) => {
result.labels.push(element.name);
if (!bountyIssue) {
bountyIssue = exports.BOUNTY_LABELS.includes(element.name);
if (bountyIssue) {
bountyType = element.name;
}
}
});
if (!bountyIssue) {
core.debug("Not a bounty");
return undefined;
}
result.title = `[${bountyType}] ${issue.title}`,
// In order to differentiate immediately the issues from others in the repo
// And with the current situation, the robot with Read access cannot add labels to the issue
result.body = `Original external [issue](${issue.html_url})
Sumitted by [${issue.user.login}](${issue.user.html_url})
${issue.body ? issue.body : ""}`;
return result;
};
exports.createInternalIssue = async (payload, issue) => {
const internalRepoAccessToken = process.env['INT_REPO_TOKEN'];
const token = process.env['GITHUB_TOKEN'];
let internal_ref = undefined;
if (!internalRepoAccessToken) {
core.debug("No valid token for creating issues on the internal repo");
return;
}
try {
const octokit = new github.GitHub(internalRepoAccessToken);
const internalRepo = core.getInput('internal_repo') || '/';
const [owner, repo] = internalRepo.split('/');
const issueResponse = await octokit.issues.create({
owner,
repo,
title: issue.title,
body: issue.body,
labels: issue.labels
});
internal_ref = issueResponse.data.number;
core.debug(`issue created: ${internal_ref}`);
const issueCommentResponse1 = await octokit.issues.createComment({
owner,
repo,
issue_number: internal_ref,
body: COMMENT_TASK_LIST[issue.bountyType],
});
core.debug(`comment created ${issueCommentResponse1.data.url}`);
const issueCommentResponse2 = await octokit.issues.createComment({
owner,
repo,
issue_number: internal_ref,
body: COMMENT_SCORING,
});
core.debug(`comment created ${issueCommentResponse2.data.url}`);
if (await exports.isFirstSubmission(payload, token)) {
const issueCommentResponse3 = await octokit.issues.createComment({
owner,
repo,
issue_number: internal_ref,
body: COMMENT_FIRST_SUBMISSION,
});
core.debug(`comment created ${issueCommentResponse3.data.url}`);
}
}
catch (error) {
core.debug(error.message);
}
return internal_ref;
};
const commentOriginalIssue = async (payload, internal_issue) => {
const repository = payload.repository;
const external_issue = payload.issue ? payload.issue.number : 0;
const token = process.env['GITHUB_TOKEN'];
if (!token) {
core.debug("No valid token for this repo");
return;
}
if (!repository || external_issue <= 0) {
core.debug("Invalid payload");
return;
}
try {
const octokit = new github.GitHub(token);
const issueCommentResponseOriginal = await octokit.issues.createComment({
owner: repository.owner.login,
repo: repository.name,
issue_number: external_issue,
body: `Thanks for submitting this bounty :heart:!
Your submission is tracked internally with the issue reference ${internal_issue}.`,
});
core.debug(`comment created ${issueCommentResponseOriginal.data.url}`);
}
catch (error) {
core.debug(error.message);
}
};
const checkDuplicates = async (payload) => {
var _a;
const internalRepoAccessToken = process.env['INT_REPO_TOKEN'];
const internalRepo = core.getInput('internal_repo') || '/';
const [owner, repo] = internalRepo.split('/');
const internalIssues = await issues_1.getIssueList(owner, repo, internalRepoAccessToken, false, false);
if (!internalIssues) {
core.debug('Internal error. Cannot check for duplicates. Aborting');
return true;
}
else {
const ref = issues_1.internalIssueAlreadyCreated((_a = payload.issue) === null || _a === void 0 ? void 0 : _a.html_url, internalIssues);
if (ref) {
core.debug(`This issue has already been duplicated with reference ${ref}`);
return true;
}
}
return false;
};
exports.isFirstSubmission = async (payload, token) => {
var _a;
const repository = payload.repository;
if (!repository)
return false;
const allSubmissions = await issues_1.getIssueList(repository.owner.login, repository.name, token, false, true);
return !issues_1.isUserAlreadyParticipant((_a = payload.issue) === null || _a === void 0 ? void 0 : _a.user.login, allSubmissions);
};
const run = async () => {
const internalIssue = await exports.generateInternalIssueContentFromPayload(github.context.payload);
if (!internalIssue)
return;
const existingIssue = core.getInput('existingIssue') || true;
if (existingIssue && await checkDuplicates(github.context.payload))
return;
const internal_ref = await exports.createInternalIssue(github.context.payload, internalIssue);
if (!internal_ref)
return;
if (!existingIssue) {
commentOriginalIssue(github.context.payload, internal_ref);
}
};
run();
//# sourceMappingURL=replicate.js.map