forked from codedx/codedx-github-action
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcodedx.js
More file actions
124 lines (101 loc) · 4.2 KB
/
codedx.js
File metadata and controls
124 lines (101 loc) · 4.2 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
const axios = require('axios').default
const _ = require('underscore')
const AxiosLogger = require('axios-logger')
const https = require('https')
function parseError(e) {
if (axios.isAxiosError(e) && e.response) {
let msg = `${e.response.statusText} (HTTP ${e.response.status})`
if (e.response.data) {
if (e.response.data.error) {
msg += `: ${e.response.data.error}`
} else {
msg += `: received response ${JSON.stringify(e.response.data)}`
}
}
return new Error(msg)
} else {
return e
}
}
function rethrowError(err) {
throw parseError(err)
}
class CodeDxApiClient {
constructor(baseUrl, apiKey, caCert) {
const httpsAgent = caCert ? new https.Agent({ ca: caCert }) : undefined
const baseConfig = {
baseURL: baseUrl,
maxContentLength: Infinity,
maxBodyLength: Infinity,
httpsAgent
}
this.anonymousHttp = axios.create(baseConfig)
this.http = axios.create({
...baseConfig,
headers: {
'API-Key': apiKey
}
})
}
// WARNING: This logging will emit Header data, which contains the Code Dx API key. This should not be exposed and should only
// be used for internal testing.
useLogging() {
AxiosLogger.setGlobalConfig({
headers: true
})
this.anonymousHttp.interceptors.request.use(AxiosLogger.requestLogger, AxiosLogger.errorLogger)
this.http.interceptors.request.use(AxiosLogger.requestLogger, AxiosLogger.errorLogger)
this.anonymousHttp.interceptors.response.use(AxiosLogger.responseLogger, AxiosLogger.errorLogger)
this.http.interceptors.response.use(AxiosLogger.responseLogger, AxiosLogger.errorLogger)
}
async testConnection() {
const response = await this.anonymousHttp.get('/x/system-info').catch(e => {
if (axios.isAxiosError(e) && e.response) {
throw new Error(`Expected OK response, got ${e.response.status}. Is this a Code Dx instance?`)
} else {
throw e
}
})
if (typeof response.data != 'object') {
throw new Error(`Expected JSON Object response, got ${typeof response.data}. Is this a Code Dx instance?`)
}
const expectedFields = ['version', 'date']
const unexpectedFields = _.without(_.keys(response.data), ...expectedFields)
if (unexpectedFields.length > 0) {
throw new Error(`Received unexpected fields ${unexpectedFields.join(', ')}. Is this a Code Dx instance?`)
}
return response.data.version
}
async validatePermissions(projectId) {
const cleanNeededPermissions = [
'analysis:create'
]
const neededPermissions = cleanNeededPermissions.map(p => `${p}:${projectId}`)
const response = await this.http.post('/x/check-permissions', neededPermissions).catch(e => {
if (axios.isAxiosError(e) && e.response.status == 403) {
throw new Error("Permissions check responded with HTTP 403, is the API key valid?")
} else {
throw parseError(e)
}
})
const permissions = response.data
const missingPermissions = neededPermissions.filter(p => !permissions[p])
if (missingPermissions.length > 0) {
const cleanMissingPermissions = missingPermissions.map(p => {
const parts = p.split(':')
return parts.slice(0, -1).join(':')
})
const summary = cleanMissingPermissions.join(', ')
throw new Error("The following permissions were missing for the given API Key: " + summary)
}
}
async runAnalysis(projectId, formData) {
const response = await this.http.post(`/api/projects/${projectId}/analysis`, formData, { headers: formData.getHeaders() }).catch(rethrowError)
return response.data
}
async checkJobStatus(jobId) {
const response = await this.http.get('/api/jobs/' + jobId).catch(rethrowError)
return response.data.status
}
}
module.exports = CodeDxApiClient