@backstage-community/plugin-blackduck-backend 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/README.md +169 -0
- package/dist/index.cjs.js +279 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/package.json +61 -0
package/CHANGELOG.md
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# blackduck
|
|
2
|
+
|
|
3
|
+
Welcome to the blackduck backend plugin!
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
This plugin needs to be added to an existing backstage instance.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# From your Backstage root directory
|
|
11
|
+
yarn --cwd packages/backend add @backstage-community/plugin-blackduck-backend
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
### New Backend System
|
|
15
|
+
|
|
16
|
+
This backend plugin has support for the [new backend system](https://backstage.io/docs/backend-system/), here's how you can set that up:
|
|
17
|
+
|
|
18
|
+
In your `packages/backend/src/index.ts` make the following changes:
|
|
19
|
+
|
|
20
|
+
```diff
|
|
21
|
+
import { createBackend } from '@backstage/backend-defaults';
|
|
22
|
+
|
|
23
|
+
const backend = createBackend();
|
|
24
|
+
|
|
25
|
+
// ... other feature additions
|
|
26
|
+
|
|
27
|
+
+backend.add(import('@backstage-community/plugin-blackduck-backend'));
|
|
28
|
+
|
|
29
|
+
// ...
|
|
30
|
+
|
|
31
|
+
backend.start();
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Legacy Backend System
|
|
35
|
+
|
|
36
|
+
Create a file called blackduck.ts inside `packages/backend/src/plugins/` and add the following:
|
|
37
|
+
|
|
38
|
+
### blackduck.ts
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
import { createRouter } from '@backstage-community/plugin-blackduck-backend';
|
|
42
|
+
import { Router } from 'express';
|
|
43
|
+
import { PluginEnvironment } from '../types';
|
|
44
|
+
|
|
45
|
+
export default async function createPlugin(
|
|
46
|
+
env: PluginEnvironment,
|
|
47
|
+
): Promise<Router> {
|
|
48
|
+
return await createRouter({
|
|
49
|
+
logger: env.logger,
|
|
50
|
+
config: env.config,
|
|
51
|
+
permissions: env.permissions,
|
|
52
|
+
discovery: env.discovery,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
And import the plugin to `packages/backend/src/index.ts`.
|
|
58
|
+
|
|
59
|
+
### src/index.ts
|
|
60
|
+
|
|
61
|
+
```diff
|
|
62
|
+
diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts
|
|
63
|
+
index c4736a5..5822302 100644
|
|
64
|
+
--- a/packages/backend/src/index.ts
|
|
65
|
+
+++ b/packages/backend/src/index.ts
|
|
66
|
+
@@ -28,6 +28,7 @@ import scaffolder from './plugins/scaffolder';
|
|
67
|
+
import proxy from './plugins/proxy';
|
|
68
|
+
import techdocs from './plugins/techdocs';
|
|
69
|
+
import search from './plugins/search';
|
|
70
|
+
+import blackduck from './plugins/blackduck';
|
|
71
|
+
import { PluginEnvironment } from './types';
|
|
72
|
+
import { ServerPermissionClient } from '@backstage/plugin-permission-node';
|
|
73
|
+
import { DefaultIdentityClient } from '@backstage/plugin-auth-node';
|
|
74
|
+
@@ -85,6 +86,7 @@ async function main() {
|
|
75
|
+
const techdocsEnv = useHotMemoize(module, () => createEnv('techdocs'));
|
|
76
|
+
const searchEnv = useHotMemoize(module, () => createEnv('search'));
|
|
77
|
+
const appEnv = useHotMemoize(module, () => createEnv('app'));
|
|
78
|
+
+ const blackduckEnv = useHotMemoize(module, () => createEnv('blackduck'));
|
|
79
|
+
|
|
80
|
+
const apiRouter = Router();
|
|
81
|
+
apiRouter.use('/catalog', await catalog(catalogEnv));
|
|
82
|
+
@@ -93,6 +95,7 @@ async function main() {
|
|
83
|
+
apiRouter.use('/techdocs', await techdocs(techdocsEnv));
|
|
84
|
+
apiRouter.use('/proxy', await proxy(proxyEnv));
|
|
85
|
+
apiRouter.use('/search', await search(searchEnv));
|
|
86
|
+
+ apiRouter.use('/blackduck', await blackduck(blackduckEnv));
|
|
87
|
+
|
|
88
|
+
// Add backends ABOVE this line; this 404 handler is the catch-all fallback
|
|
89
|
+
apiRouter.use(notFoundHandler());
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Configuration
|
|
94
|
+
|
|
95
|
+
### Integrate Permission Framework
|
|
96
|
+
|
|
97
|
+
BlackDuck plugin supports permission framework.
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
# From your Backstage root directory
|
|
101
|
+
yarn --cwd packages/backend add @backstage-community/plugin-blackduck-common
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
In your `packages/backend/src/index.ts` make the following changes:
|
|
105
|
+
|
|
106
|
+
```diff
|
|
107
|
+
import { createBackend } from '@backstage/backend-defaults';
|
|
108
|
+
const backend = createBackend();
|
|
109
|
+
// ... other feature additions
|
|
110
|
+
+backend.add(import('@backstage-community/plugin-blackduck-common'));
|
|
111
|
+
// ...
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Configure Permission
|
|
115
|
+
|
|
116
|
+
To apply the permission rules add the following in `packages/backend/src/plugins/permissions.ts`
|
|
117
|
+
|
|
118
|
+
```diff
|
|
119
|
+
...
|
|
120
|
+
+ import {
|
|
121
|
+
+ blackduckRiskProfileReadPermission
|
|
122
|
+
+ blackduckVulnerabilitiesReadPermission } from '@backstage-community/plugin-blackduck-common';
|
|
123
|
+
...
|
|
124
|
+
async handle(
|
|
125
|
+
request: PolicyQuery,
|
|
126
|
+
user?: BackstageIdentityResponse,
|
|
127
|
+
): Promise<PolicyDecision> {
|
|
128
|
+
+ if ( isPermission(request.permission, blackduckRiskProfileReadPermission) ||
|
|
129
|
+
+ isPermission(request.permission, blackduckVulnerabilitiesReadPermission)) {
|
|
130
|
+
+ return createCatalogConditionalDecision(
|
|
131
|
+
+ request.permission,
|
|
132
|
+
+ catalogConditions.isEntityOwner({
|
|
133
|
+
+ claims: user?.identity.ownershipEntityRefs ?? [],
|
|
134
|
+
+ }),
|
|
135
|
+
+ );
|
|
136
|
+
+ }
|
|
137
|
+
...
|
|
138
|
+
return {
|
|
139
|
+
result: AuthorizeResult.ALLOW,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Continue with Frontend Plugin
|
|
145
|
+
|
|
146
|
+
Follow the Docs from [README.md](https://github.com/backstage/community-plugins/blob/main/workspaces/blackduck/plugins/blackduck/README.md)
|
|
147
|
+
|
|
148
|
+
### Global Config
|
|
149
|
+
|
|
150
|
+
Add the following into your `app-config.yaml`
|
|
151
|
+
|
|
152
|
+
```yaml
|
|
153
|
+
blackduck:
|
|
154
|
+
host: https://blackduck.yourcompany.com/api
|
|
155
|
+
token: YOUR_API_TOKEN
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Catalog
|
|
159
|
+
|
|
160
|
+
Add the following into your catalog
|
|
161
|
+
|
|
162
|
+
```yaml
|
|
163
|
+
apiVersion: backstage.io/v1alpha1
|
|
164
|
+
kind: Component
|
|
165
|
+
metadata:
|
|
166
|
+
name: backstage
|
|
167
|
+
annotations:
|
|
168
|
+
blackduck/project: YOUR_PROJECT_NAME/YOUR_PROJECT_VERSION
|
|
169
|
+
```
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var rootHttpRouter = require('@backstage/backend-defaults/rootHttpRouter');
|
|
6
|
+
var express = require('express');
|
|
7
|
+
var Router = require('express-promise-router');
|
|
8
|
+
var pluginPermissionNode = require('@backstage/plugin-permission-node');
|
|
9
|
+
var errors = require('@backstage/errors');
|
|
10
|
+
var pluginPermissionCommon = require('@backstage/plugin-permission-common');
|
|
11
|
+
var backendCommon = require('@backstage/backend-common');
|
|
12
|
+
var pluginBlackduckCommon = require('@backstage-community/plugin-blackduck-common');
|
|
13
|
+
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
14
|
+
|
|
15
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
16
|
+
|
|
17
|
+
var express__default = /*#__PURE__*/_interopDefaultCompat(express);
|
|
18
|
+
var Router__default = /*#__PURE__*/_interopDefaultCompat(Router);
|
|
19
|
+
|
|
20
|
+
class BlackDuckRestApi {
|
|
21
|
+
constructor(logger, host, token) {
|
|
22
|
+
this.logger = logger;
|
|
23
|
+
this.host = host;
|
|
24
|
+
this.token = token;
|
|
25
|
+
this._bearer = "";
|
|
26
|
+
this._limit = 1e3;
|
|
27
|
+
}
|
|
28
|
+
_bearer;
|
|
29
|
+
_limit;
|
|
30
|
+
async auth() {
|
|
31
|
+
try {
|
|
32
|
+
const auth = await fetch(`${this.host}/tokens/authenticate`, {
|
|
33
|
+
method: "POST",
|
|
34
|
+
headers: {
|
|
35
|
+
Authorization: `token ${this.token}`,
|
|
36
|
+
Accept: "application/vnd.blackducksoftware.user-4+json",
|
|
37
|
+
"Content-Type": "application/json"
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
const token = await auth.json();
|
|
41
|
+
this.logger.info("Auth Successfull");
|
|
42
|
+
this._bearer = token.bearerToken;
|
|
43
|
+
return token.bearerToken;
|
|
44
|
+
} catch (error) {
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
async getProjects(name) {
|
|
49
|
+
const projects = await fetch(
|
|
50
|
+
`${this.host}/projects?limit=999&q=name:${name}`,
|
|
51
|
+
{
|
|
52
|
+
method: "GET",
|
|
53
|
+
headers: {
|
|
54
|
+
Authorization: `Bearer ${this._bearer}`,
|
|
55
|
+
Accept: "application/vnd.blackducksoftware.project-detail-4+json",
|
|
56
|
+
"Content-Type": "application/json"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
);
|
|
60
|
+
this.logger.debug("Retrived Projects!!");
|
|
61
|
+
return projects.json();
|
|
62
|
+
}
|
|
63
|
+
async getVersions(projectUrl, versionName) {
|
|
64
|
+
const versions = await fetch(
|
|
65
|
+
`${projectUrl}/versions?limit=999&q=versionName:${versionName}`,
|
|
66
|
+
{
|
|
67
|
+
method: "GET",
|
|
68
|
+
headers: {
|
|
69
|
+
Authorization: `Bearer ${this._bearer}`,
|
|
70
|
+
Accept: "application/vnd.blackducksoftware.project-detail-5+json",
|
|
71
|
+
"Content-Type": "application/json"
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
);
|
|
75
|
+
this.logger.debug("Retrived Versions!!");
|
|
76
|
+
return versions.json();
|
|
77
|
+
}
|
|
78
|
+
async getProjectVersionDetails(projectName, projectVersion) {
|
|
79
|
+
let projectDetail;
|
|
80
|
+
let versionDetail;
|
|
81
|
+
const projects = await this.getProjects(
|
|
82
|
+
projectName
|
|
83
|
+
);
|
|
84
|
+
projects.items.forEach((item) => {
|
|
85
|
+
if (item.name === projectName) {
|
|
86
|
+
projectDetail = item;
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
if (projectDetail === void 0) {
|
|
90
|
+
this.logger.error("Provide full project name");
|
|
91
|
+
}
|
|
92
|
+
this.logger.debug(`Fetched Project : ${projectName} details`);
|
|
93
|
+
const versions = await this.getVersions(
|
|
94
|
+
projectDetail._meta.href,
|
|
95
|
+
projectVersion
|
|
96
|
+
);
|
|
97
|
+
versions.items.forEach((item) => {
|
|
98
|
+
if (item.versionName === projectVersion) {
|
|
99
|
+
versionDetail = item;
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
if (versionDetail === void 0) {
|
|
103
|
+
this.logger.error("Provide full version name");
|
|
104
|
+
}
|
|
105
|
+
this.logger.debug(
|
|
106
|
+
`Fetched Project : ${projectName}, Version: ${projectVersion} details`
|
|
107
|
+
);
|
|
108
|
+
return versionDetail;
|
|
109
|
+
}
|
|
110
|
+
async getVulnerableComponents(projectName, projectVersion) {
|
|
111
|
+
const versionDetail = await this.getProjectVersionDetails(
|
|
112
|
+
projectName,
|
|
113
|
+
projectVersion
|
|
114
|
+
);
|
|
115
|
+
const vuln_url = `${versionDetail._meta.href}/vulnerable-bom-components?limit=${this._limit}`;
|
|
116
|
+
const vulns = await fetch(vuln_url, {
|
|
117
|
+
method: "GET",
|
|
118
|
+
headers: {
|
|
119
|
+
Authorization: `Bearer ${this._bearer}`,
|
|
120
|
+
Accept: "application/vnd.blackducksoftware.bill-of-materials-6+json",
|
|
121
|
+
"Content-Type": "application/json"
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
this.logger.debug(
|
|
125
|
+
`Fetched Project : ${projectName}, Version: ${projectVersion} Vulnerable Components`
|
|
126
|
+
);
|
|
127
|
+
return vulns.json();
|
|
128
|
+
}
|
|
129
|
+
async getRiskProfile(projectName, projectVersion) {
|
|
130
|
+
const versionDetail = await this.getProjectVersionDetails(
|
|
131
|
+
projectName,
|
|
132
|
+
projectVersion
|
|
133
|
+
);
|
|
134
|
+
const risk_profile_url = `${versionDetail._meta.href}/risk-profile`;
|
|
135
|
+
const risk_profile = await fetch(risk_profile_url, {
|
|
136
|
+
method: "GET",
|
|
137
|
+
headers: {
|
|
138
|
+
Authorization: `Bearer ${this._bearer}`,
|
|
139
|
+
// Accept: 'application/vnd.blackducksoftware.component-detail-5+json',
|
|
140
|
+
"Content-Type": "application/json"
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
this.logger.debug(
|
|
144
|
+
`Fetched Project : ${projectName}, Version: ${projectVersion} risk profile`
|
|
145
|
+
);
|
|
146
|
+
return risk_profile.json();
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
async function createRouter(options) {
|
|
151
|
+
const { logger, config, permissions } = options;
|
|
152
|
+
const { httpAuth } = backendCommon.createLegacyAuthAdapters(options);
|
|
153
|
+
const permissionIntegrationRouter = pluginPermissionNode.createPermissionIntegrationRouter({
|
|
154
|
+
permissions: pluginBlackduckCommon.blackduckPermissions
|
|
155
|
+
});
|
|
156
|
+
const bdConfig = config.getConfig("blackduck");
|
|
157
|
+
const bdHost = bdConfig.getString("host");
|
|
158
|
+
const bdToken = bdConfig.getString("token");
|
|
159
|
+
const router = Router__default.default();
|
|
160
|
+
router.use(express__default.default.json());
|
|
161
|
+
router.use(permissionIntegrationRouter);
|
|
162
|
+
router.get("/health", (_, response) => {
|
|
163
|
+
logger.info("PONG!");
|
|
164
|
+
response.json({ status: "ok" });
|
|
165
|
+
});
|
|
166
|
+
const middleware = rootHttpRouter.MiddlewareFactory.create({ logger, config });
|
|
167
|
+
router.post(
|
|
168
|
+
"/risk-profile/:projectName/:projectVersion",
|
|
169
|
+
async (_request, response) => {
|
|
170
|
+
logger.debug("getting vulnarabilities..");
|
|
171
|
+
const { projectName, projectVersion } = _request.params;
|
|
172
|
+
const blackDuck = new BlackDuckRestApi(logger, bdHost, bdToken);
|
|
173
|
+
const credentials = await httpAuth.credentials(_request);
|
|
174
|
+
const entityRef = _request.body.entityRef;
|
|
175
|
+
logger.info("getting risk profile for project: ", entityRef);
|
|
176
|
+
if (typeof entityRef !== "string") {
|
|
177
|
+
throw new errors.InputError("Invalid entityRef, not a string");
|
|
178
|
+
}
|
|
179
|
+
const decision = (await permissions.authorize(
|
|
180
|
+
[
|
|
181
|
+
{
|
|
182
|
+
permission: pluginBlackduckCommon.blackduckRiskProfileReadPermission,
|
|
183
|
+
resourceRef: entityRef
|
|
184
|
+
}
|
|
185
|
+
],
|
|
186
|
+
{
|
|
187
|
+
credentials
|
|
188
|
+
}
|
|
189
|
+
))[0];
|
|
190
|
+
if (decision.result !== pluginPermissionCommon.AuthorizeResult.ALLOW) {
|
|
191
|
+
throw new errors.NotAllowedError("Unauthorized");
|
|
192
|
+
}
|
|
193
|
+
await blackDuck.auth();
|
|
194
|
+
const risk_profile = await blackDuck.getRiskProfile(
|
|
195
|
+
projectName,
|
|
196
|
+
projectVersion
|
|
197
|
+
);
|
|
198
|
+
response.json(risk_profile);
|
|
199
|
+
}
|
|
200
|
+
);
|
|
201
|
+
router.post(
|
|
202
|
+
"/vulns/:projectName/:projectVersion",
|
|
203
|
+
async (_request, response) => {
|
|
204
|
+
const { projectName, projectVersion } = _request.params;
|
|
205
|
+
const blackDuck = new BlackDuckRestApi(logger, bdHost, bdToken);
|
|
206
|
+
const credentials = await httpAuth.credentials(_request);
|
|
207
|
+
const entityRef = _request.body.entityRef;
|
|
208
|
+
logger.info("getting vulnarabilities for project: ", entityRef);
|
|
209
|
+
if (typeof entityRef !== "string") {
|
|
210
|
+
throw new errors.InputError("Invalid entityRef, not a string");
|
|
211
|
+
}
|
|
212
|
+
const decision = (await permissions.authorize(
|
|
213
|
+
[
|
|
214
|
+
{
|
|
215
|
+
permission: pluginBlackduckCommon.blackduckVulnerabilitiesReadPermission,
|
|
216
|
+
resourceRef: entityRef
|
|
217
|
+
}
|
|
218
|
+
],
|
|
219
|
+
{
|
|
220
|
+
credentials
|
|
221
|
+
}
|
|
222
|
+
))[0];
|
|
223
|
+
logger.info("decision", decision);
|
|
224
|
+
if (decision.result !== pluginPermissionCommon.AuthorizeResult.ALLOW) {
|
|
225
|
+
throw new errors.NotAllowedError("Unauthorized");
|
|
226
|
+
}
|
|
227
|
+
await blackDuck.auth();
|
|
228
|
+
const vulns = await blackDuck.getVulnerableComponents(
|
|
229
|
+
projectName,
|
|
230
|
+
projectVersion
|
|
231
|
+
);
|
|
232
|
+
response.json(vulns);
|
|
233
|
+
}
|
|
234
|
+
);
|
|
235
|
+
router.use(middleware.error());
|
|
236
|
+
return router;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
const blackduckPlugin = backendPluginApi.createBackendPlugin({
|
|
240
|
+
pluginId: "blackduck",
|
|
241
|
+
register(env) {
|
|
242
|
+
env.registerInit({
|
|
243
|
+
deps: {
|
|
244
|
+
httpRouter: backendPluginApi.coreServices.httpRouter,
|
|
245
|
+
logger: backendPluginApi.coreServices.logger,
|
|
246
|
+
config: backendPluginApi.coreServices.rootConfig,
|
|
247
|
+
permissions: backendPluginApi.coreServices.permissions,
|
|
248
|
+
discovery: backendPluginApi.coreServices.discovery,
|
|
249
|
+
httpAuth: backendPluginApi.coreServices.httpAuth
|
|
250
|
+
},
|
|
251
|
+
async init({
|
|
252
|
+
httpRouter,
|
|
253
|
+
logger,
|
|
254
|
+
config,
|
|
255
|
+
permissions,
|
|
256
|
+
discovery,
|
|
257
|
+
httpAuth
|
|
258
|
+
}) {
|
|
259
|
+
httpRouter.use(
|
|
260
|
+
await createRouter({
|
|
261
|
+
logger,
|
|
262
|
+
config,
|
|
263
|
+
permissions,
|
|
264
|
+
discovery,
|
|
265
|
+
httpAuth
|
|
266
|
+
})
|
|
267
|
+
);
|
|
268
|
+
httpRouter.addAuthPolicy({
|
|
269
|
+
path: "/health",
|
|
270
|
+
allow: "unauthenticated"
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
exports.createRouter = createRouter;
|
|
278
|
+
exports.default = blackduckPlugin;
|
|
279
|
+
//# sourceMappingURL=index.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../src/api/BlackDuckRestApi.ts","../src/service/router.ts","../src/plugin.ts"],"sourcesContent":["import { LoggerService } from '@backstage/backend-plugin-api';\nimport {\n BD_REST_API_RESPONSE,\n BD_PROJECT_DETAIL,\n BD_VERISON_DETAIL,\n BD_VERSIONS_API_RESPONSE,\n BD_PROJECTS_API_RESPONSE,\n} from '@backstage-community/plugin-blackduck-common';\n\nexport class BlackDuckRestApi {\n private _bearer: string;\n private _limit: number;\n public constructor(\n private readonly logger: LoggerService,\n private readonly host: string,\n private readonly token: string,\n ) {\n this._bearer = '';\n this._limit = 1000;\n }\n\n public async auth() {\n try {\n const auth = await fetch(`${this.host}/tokens/authenticate`, {\n method: 'POST',\n headers: {\n Authorization: `token ${this.token}`,\n Accept: 'application/vnd.blackducksoftware.user-4+json',\n 'Content-Type': 'application/json',\n },\n });\n const token = await auth.json();\n this.logger.info('Auth Successfull');\n this._bearer = token.bearerToken;\n return token.bearerToken;\n } catch (error) {\n throw error;\n }\n }\n public async getProjects(name: string): Promise<BD_REST_API_RESPONSE> {\n const projects = await fetch(\n `${this.host}/projects?limit=999&q=name:${name}`,\n {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${this._bearer}`,\n Accept: 'application/vnd.blackducksoftware.project-detail-4+json',\n 'Content-Type': 'application/json',\n },\n },\n );\n this.logger.debug('Retrived Projects!!');\n return projects.json();\n }\n\n public async getVersions(\n projectUrl: string,\n versionName: string,\n ): Promise<BD_VERSIONS_API_RESPONSE> {\n const versions = await fetch(\n `${projectUrl}/versions?limit=999&q=versionName:${versionName}`,\n {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${this._bearer}`,\n Accept: 'application/vnd.blackducksoftware.project-detail-5+json',\n 'Content-Type': 'application/json',\n },\n },\n );\n this.logger.debug('Retrived Versions!!');\n return versions.json();\n }\n\n public async getProjectVersionDetails(\n projectName: string,\n projectVersion: string,\n ) {\n let projectDetail: BD_PROJECT_DETAIL | any;\n let versionDetail: BD_VERISON_DETAIL | any;\n const projects: BD_PROJECTS_API_RESPONSE = await this.getProjects(\n projectName,\n );\n projects.items.forEach((item: any) => {\n if (item.name === projectName) {\n projectDetail = item;\n }\n });\n if (projectDetail === undefined) {\n this.logger.error('Provide full project name');\n }\n this.logger.debug(`Fetched Project : ${projectName} details`);\n const versions: BD_VERSIONS_API_RESPONSE = await this.getVersions(\n projectDetail._meta.href,\n projectVersion,\n );\n versions.items.forEach((item: any) => {\n if (item.versionName === projectVersion) {\n versionDetail = item;\n }\n });\n if (versionDetail === undefined) {\n this.logger.error('Provide full version name');\n }\n this.logger.debug(\n `Fetched Project : ${projectName}, Version: ${projectVersion} details`,\n );\n\n return versionDetail;\n }\n\n public async getVulnerableComponents(\n projectName: string,\n projectVersion: string,\n ) {\n const versionDetail = await this.getProjectVersionDetails(\n projectName,\n projectVersion,\n );\n const vuln_url = `${versionDetail._meta.href}/vulnerable-bom-components?limit=${this._limit}`;\n const vulns: any = await fetch(vuln_url, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${this._bearer}`,\n Accept: 'application/vnd.blackducksoftware.bill-of-materials-6+json',\n 'Content-Type': 'application/json',\n },\n });\n this.logger.debug(\n `Fetched Project : ${projectName}, Version: ${projectVersion} Vulnerable Components`,\n );\n return vulns.json();\n }\n\n public async getRiskProfile(projectName: string, projectVersion: string) {\n const versionDetail = await this.getProjectVersionDetails(\n projectName,\n projectVersion,\n );\n const risk_profile_url = `${versionDetail._meta.href}/risk-profile`;\n const risk_profile: any = await fetch(risk_profile_url, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${this._bearer}`,\n // Accept: 'application/vnd.blackducksoftware.component-detail-5+json',\n 'Content-Type': 'application/json',\n },\n });\n this.logger.debug(\n `Fetched Project : ${projectName}, Version: ${projectVersion} risk profile`,\n );\n return risk_profile.json();\n }\n}\n","import { MiddlewareFactory } from '@backstage/backend-defaults/rootHttpRouter';\nimport {\n DiscoveryService,\n HttpAuthService,\n LoggerService,\n PermissionsService,\n} from '@backstage/backend-plugin-api';\nimport { Config } from '@backstage/config';\nimport express from 'express';\nimport Router from 'express-promise-router';\nimport { createPermissionIntegrationRouter } from '@backstage/plugin-permission-node';\nimport { InputError, NotAllowedError } from '@backstage/errors';\nimport { AuthorizeResult } from '@backstage/plugin-permission-common';\nimport { createLegacyAuthAdapters } from '@backstage/backend-common';\nimport {\n blackduckPermissions,\n blackduckRiskProfileReadPermission,\n blackduckVulnerabilitiesReadPermission,\n} from '@backstage-community/plugin-blackduck-common';\nimport { BlackDuckRestApi } from '../api/BlackDuckRestApi';\n\n/** @public */\nexport interface RouterOptions {\n logger: LoggerService;\n config: Config;\n permissions: PermissionsService;\n discovery: DiscoveryService;\n httpAuth?: HttpAuthService;\n}\n\n/** @public */\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const { logger, config, permissions } = options;\n const { httpAuth } = createLegacyAuthAdapters(options);\n const permissionIntegrationRouter = createPermissionIntegrationRouter({\n permissions: blackduckPermissions,\n });\n\n const bdConfig = config.getConfig('blackduck');\n const bdHost = bdConfig.getString('host');\n const bdToken = bdConfig.getString('token');\n\n const router = Router();\n router.use(express.json());\n router.use(permissionIntegrationRouter);\n\n router.get('/health', (_, response) => {\n logger.info('PONG!');\n response.json({ status: 'ok' });\n });\n\n const middleware = MiddlewareFactory.create({ logger, config });\n\n router.post(\n '/risk-profile/:projectName/:projectVersion',\n async (_request, response) => {\n logger.debug('getting vulnarabilities..');\n const { projectName, projectVersion } = _request.params;\n const blackDuck = new BlackDuckRestApi(logger, bdHost, bdToken);\n const credentials = await httpAuth.credentials(_request);\n const entityRef = _request.body.entityRef;\n logger.info('getting risk profile for project: ', entityRef);\n if (typeof entityRef !== 'string') {\n throw new InputError('Invalid entityRef, not a string');\n }\n\n const decision = (\n await permissions.authorize(\n [\n {\n permission: blackduckRiskProfileReadPermission,\n resourceRef: entityRef,\n },\n ],\n {\n credentials,\n },\n )\n )[0];\n\n if (decision.result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('Unauthorized');\n }\n\n await blackDuck.auth();\n const risk_profile = await blackDuck.getRiskProfile(\n projectName,\n projectVersion,\n );\n response.json(risk_profile);\n },\n );\n\n router.post(\n '/vulns/:projectName/:projectVersion',\n async (_request, response) => {\n const { projectName, projectVersion } = _request.params;\n const blackDuck = new BlackDuckRestApi(logger, bdHost, bdToken);\n const credentials = await httpAuth.credentials(_request);\n const entityRef = _request.body.entityRef;\n logger.info('getting vulnarabilities for project: ', entityRef);\n if (typeof entityRef !== 'string') {\n throw new InputError('Invalid entityRef, not a string');\n }\n\n const decision = (\n await permissions.authorize(\n [\n {\n permission: blackduckVulnerabilitiesReadPermission,\n resourceRef: entityRef,\n },\n ],\n {\n credentials,\n },\n )\n )[0];\n logger.info('decision', decision);\n if (decision.result !== AuthorizeResult.ALLOW) {\n throw new NotAllowedError('Unauthorized');\n }\n\n await blackDuck.auth();\n const vulns = await blackDuck.getVulnerableComponents(\n projectName,\n projectVersion,\n );\n response.json(vulns);\n },\n );\n\n router.use(middleware.error());\n return router;\n}\n","import {\n coreServices,\n createBackendPlugin,\n} from '@backstage/backend-plugin-api';\nimport { createRouter } from './service/router';\n\n/**\n * blackduckPlugin backend plugin\n *\n * @public\n */\nexport const blackduckPlugin = createBackendPlugin({\n pluginId: 'blackduck',\n register(env) {\n env.registerInit({\n deps: {\n httpRouter: coreServices.httpRouter,\n logger: coreServices.logger,\n config: coreServices.rootConfig,\n permissions: coreServices.permissions,\n discovery: coreServices.discovery,\n httpAuth: coreServices.httpAuth,\n },\n async init({\n httpRouter,\n logger,\n config,\n permissions,\n discovery,\n httpAuth,\n }) {\n httpRouter.use(\n await createRouter({\n logger,\n config,\n permissions,\n discovery,\n httpAuth,\n }),\n );\n httpRouter.addAuthPolicy({\n path: '/health',\n allow: 'unauthenticated',\n });\n },\n });\n },\n});\n"],"names":["createLegacyAuthAdapters","createPermissionIntegrationRouter","blackduckPermissions","Router","express","MiddlewareFactory","InputError","blackduckRiskProfileReadPermission","AuthorizeResult","NotAllowedError","blackduckVulnerabilitiesReadPermission","createBackendPlugin","coreServices"],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as _backstage_backend_plugin_api from '@backstage/backend-plugin-api';
|
|
2
|
+
import { LoggerService, PermissionsService, DiscoveryService, HttpAuthService } from '@backstage/backend-plugin-api';
|
|
3
|
+
import { Config } from '@backstage/config';
|
|
4
|
+
import express from 'express';
|
|
5
|
+
|
|
6
|
+
/** @public */
|
|
7
|
+
interface RouterOptions {
|
|
8
|
+
logger: LoggerService;
|
|
9
|
+
config: Config;
|
|
10
|
+
permissions: PermissionsService;
|
|
11
|
+
discovery: DiscoveryService;
|
|
12
|
+
httpAuth?: HttpAuthService;
|
|
13
|
+
}
|
|
14
|
+
/** @public */
|
|
15
|
+
declare function createRouter(options: RouterOptions): Promise<express.Router>;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* blackduckPlugin backend plugin
|
|
19
|
+
*
|
|
20
|
+
* @public
|
|
21
|
+
*/
|
|
22
|
+
declare const blackduckPlugin: _backstage_backend_plugin_api.BackendFeatureCompat;
|
|
23
|
+
|
|
24
|
+
export { type RouterOptions, createRouter, blackduckPlugin as default };
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@backstage-community/plugin-blackduck-backend",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"main": "dist/index.cjs.js",
|
|
5
|
+
"types": "dist/index.d.ts",
|
|
6
|
+
"license": "Apache-2.0",
|
|
7
|
+
"publishConfig": {
|
|
8
|
+
"access": "public",
|
|
9
|
+
"main": "dist/index.cjs.js",
|
|
10
|
+
"types": "dist/index.d.ts"
|
|
11
|
+
},
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "https://github.com/backstage/community-plugins",
|
|
15
|
+
"directory": "workspaces/blackduck/plugins/blackduck-backend"
|
|
16
|
+
},
|
|
17
|
+
"backstage": {
|
|
18
|
+
"role": "backend-plugin",
|
|
19
|
+
"pluginId": "blackduck",
|
|
20
|
+
"pluginPackages": [
|
|
21
|
+
"@backstage-community/plugin-blackduck",
|
|
22
|
+
"@backstage-community/plugin-blackduck-backend",
|
|
23
|
+
"@backstage-community/plugin-blackduck-common"
|
|
24
|
+
]
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"start": "backstage-cli package start",
|
|
28
|
+
"build": "backstage-cli package build",
|
|
29
|
+
"lint": "backstage-cli package lint",
|
|
30
|
+
"test": "backstage-cli package test",
|
|
31
|
+
"clean": "backstage-cli package clean",
|
|
32
|
+
"prepack": "backstage-cli package prepack",
|
|
33
|
+
"postpack": "backstage-cli package postpack"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@backstage-community/plugin-blackduck-common": "^0.0.1",
|
|
37
|
+
"@backstage/backend-common": "^0.23.3",
|
|
38
|
+
"@backstage/backend-defaults": "^0.4.0",
|
|
39
|
+
"@backstage/backend-plugin-api": "^0.7.0",
|
|
40
|
+
"@backstage/config": "^1.2.0",
|
|
41
|
+
"@backstage/errors": "^1.2.4",
|
|
42
|
+
"@backstage/plugin-permission-common": "^0.8.0",
|
|
43
|
+
"@backstage/plugin-permission-node": "^0.8.0",
|
|
44
|
+
"express": "^4.17.1",
|
|
45
|
+
"express-promise-router": "^4.1.0",
|
|
46
|
+
"node-fetch": "^2.6.7"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@backstage/backend-test-utils": "^0.4.4",
|
|
50
|
+
"@backstage/cli": "^0.26.11",
|
|
51
|
+
"@backstage/plugin-auth-backend": "^0.22.9",
|
|
52
|
+
"@backstage/plugin-auth-backend-module-guest-provider": "^0.1.8",
|
|
53
|
+
"@types/express": "*",
|
|
54
|
+
"@types/supertest": "^2.0.12",
|
|
55
|
+
"msw": "^2.3.1",
|
|
56
|
+
"supertest": "^6.2.4"
|
|
57
|
+
},
|
|
58
|
+
"files": [
|
|
59
|
+
"dist"
|
|
60
|
+
]
|
|
61
|
+
}
|