-
Notifications
You must be signed in to change notification settings - Fork 0
/
ScanAttestation.gs
235 lines (219 loc) · 5.8 KB
/
ScanAttestation.gs
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
221
222
223
224
225
226
227
228
229
230
231
232
233
/*
* Create a scan attestation report from BoostSecurity
*
* IMPORTANT
* Assumes the Google Sheet it is sending information to is named "Scan Attestation", has 2 frozen rows at the top, and has a start date and and end date in cells B1 and D1 respectively as is shown in line 202
* See a sample at https://docs.google.com/spreadsheets/d/e/2PACX-1vT5obGg7P4ckbnfvgZ8n_Bn3gkBNfFRTgTvjfCKztB0s0oZYAkEtOWg_B3Z1e1eTOGmGDjn2T52ZEwo/pubhtml?gid=950015480&single=true
*/
// Constants
const SHEET_NAME = "Scan Attestation";
const API_URL = "https://api.boostsecurity.io/analysis-history/graphql";
const API_KEY = PropertiesService.getScriptProperties().getProperty("apiKey");
const DATE_FORMAT = "yyyy-MM-dd";
const AUTHORIZATION_HEADER = "ApiKey " + API_KEY;
const COLUMNS = ["Timestamp", "Repo", "Scanner", "Successful"];
/**
* Get scan history from BoostSecurity
*/
function getScanHistory() {
// Get date range
const {startDate, endDate} = getDateRange();
// Call the API
const arrayOfFindingsDetails = callBoostSecurityAPI(startDate, endDate);
// Display the findings
displayFindingsInSpreadsheet(arrayOfFindingsDetails);
}
/**
* Retrieves the start and end date from the Google Sheet
* @returns {Object} An object containing the start and end dates
*/
function getDateRange() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME);
const startDate = Utilities.formatDate(sheet.getRange("B1").getValue(), "GMT", DATE_FORMAT);
const endDate = Utilities.formatDate(sheet.getRange("D1").getValue(), "GMT", DATE_FORMAT);
return {startDate, endDate};
}
/**
* Makes a call to the BoostSecurity API and retrieves the scan findings
* @param {Date} startDate - The start date for the data retrieval
* @param {Date} endDate - The end date for the data retrieval
* @returns {Array} An array of scan findings
*/
function callBoostSecurityAPI(startDate, endDate) {
// Prepare the query
let graphql = JSON.stringify({
/* Findings Details */
query: `query (
$first: Int,
$after: String,
$last: Int,
$page: Int,
$before: String,
$assets: [String!]
$assetTypes: [AssetTypeNameSchema!]
$analyzers: [String!]
$statuses: [StatusNameSchema!]
$assetIds: [String!]
$orderBy: [AnalysesOrder!]
$fromDate: Date
$toDate: Date
) {
analyses(
first: $first
after: $after
last: $last
before: $before
page: $page
filters: {
assets: $assets
assetTypes:$assetTypes
analyzers:$analyzers
statuses:$statuses
assetIds:$assetIds
}
orderBy: $orderBy
fromDate: $fromDate
toDate: $toDate
) {
filters {
assets {
value
display
count
}
assetTypes {
count
value
}
analyzers {
count
displayValue
value
}
statuses {
count
value
}
}
totalCount
edges {
node {
analysisId
accountId
timestamp
durationSeconds
findingCount
violationCount
analyzerType
analyzer {
analyzerName
}
asset {
__typename
... on ScmOrganization {
assetType
scmProvider
baseUrl
organizationName
}
... on ScmRepository {
assetType
scmProvider
baseUrl
organizationName
repositoryName
}
... on ScmRepositoryCode {
assetType
scmProvider
baseUrl
organizationName
repositoryName
branchName
commitId
label
}
... on ScmRepositoryCodeChange {
assetType
scmProvider
baseUrl
organizationName
repositoryName
branchName
commitId
pullRequestId
label
}
}
status {
...on Success {
statusName
}
...on Error {
messages
statusName
}
...on Timeout {
timeoutSeconds
statusName
}
...on BrokenInstallation {
message
statusName
}
}
}
cursor
}
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
}
}`,
/*
* Filter results
*/
variables: {
"fromDate": startDate,
"toDate": endDate
},
});
let params = {
method: "POST",
payload: graphql,
headers: {
"Content-Type": "application/json",
Authorization: AUTHORIZATION_HEADER,
},
};
// Error handling for API call
try {
var responseText = UrlFetchApp.fetch(API_URL, params).getContentText();
} catch (error) {
console.error("Error fetching data from BoostSecurity API: ", error);
return [];
}
// Process the response
var arrayOfFindings = JSON.parse(responseText).data.analyses.edges.map(f => f.node);
return arrayOfFindings.map(f => Object.values({
timestamp: Utilities.formatDate(new Date(f.timestamp), "GMT", DATE_FORMAT),
repository: (f.asset.scmProvider +"."+ f.asset.organizationName +"."+ f.asset.repositoryName),
scanner: f.analyzer.analyzerName,
status: f.status.statusName
}));
}
/**
* Displays the scan findings in the Google Sheet
* @param {Array} boostSecurityFindings - An array of findings from the BoostSecurity API
* @returns {void}
*/
function displayFindingsInSpreadsheet(boostSecurityFindings) {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME);
// Clear current contents
sheet.getRange(3, 1, sheet.getMaxRows(), COLUMNS.length).clear();
// Add values
sheet.getRange(3, 1, boostSecurityFindings.length, COLUMNS.length).setValues(boostSecurityFindings);
}