blackduck-api
Version:
Bluck Duck API for Node
560 lines (495 loc) • 18.3 kB
JavaScript
import debug from 'debug';
import lodash from 'lodash';
const log = debug('index.js');
log('loading...');
import got from 'got';
export class BlackDuckAPI {
constructor(api, token) {
this._api = api;
this._token = token;
this._bearer = '';
}
async getBearer() {
try {
const result = await got.post(this._api + '/tokens/authenticate', {
headers: {
Authorization: 'token ' + this._token,
Accept: 'application/vnd.blackducksoftware.user-4+json'
},
https: {
rejectUnauthorized: false
}
});
const json = JSON.parse(result.body);
log('bearer', json);
this._bearer = json.bearerToken;
return json;
}
catch (error) {
console.log('error', error);
return null;
}
}
/*
* TOP NODES
*/
async getUsers(query, filter) {
try {
const result = await got.get(this._api + '/users?limit=9999&q=' + query + '&filter=' + filter, {
headers: {
Authorization: 'Bearer ' + this._bearer,
Accept: 'application/vnd.blackducksoftware.user-4+json'
},
https: {
rejectUnauthorized: false
}
});
const json = JSON.parse(result.body);
log('users', json.totalCount);
return json.items;
}
catch (error) {
console.log('error', error);
return null;
}
}
async getRoles(query, filter) {
try {
const result = await got.get(this._api + '/roles?limit=9999&q=' + query + '&filter=' + filter, {
headers: {
Authorization: 'Bearer ' + this._bearer,
Accept: 'application/vnd.blackducksoftware.user-4+json'
},
https: {
rejectUnauthorized: false
}
});
const json = JSON.parse(result.body);
log('roles', json.totalCount);
return json.items;
}
catch (error) {
console.log('error', error);
return null;
}
}
async getProjects(query, filter) {
let url = this._api + '/projects';
log('url', url);
try {
const result = await got.get(url + '?limit=9999&q=' + query + '&filter=' + filter, {
headers: {
Authorization: 'Bearer ' + this._bearer,
Accept: 'application/vnd.blackducksoftware.project-detail-4+json'
},
https: {
rejectUnauthorized: false
}
});
const json = JSON.parse(result.body);
if(json === undefined) {
log('projects', 0);
return [];
} else {
log('projects', json.totalCount);
return json.items;
}
}
catch (error) {
console.log('error', error);
return null;
}
}
/*
* PROJECT NODES
*/
async getVersions(project_object, query, filter) {
let url = lodash.filter(project_object._meta.links, x => x.rel == 'versions')[0].href;
log('url', url);
try {
const result = await got.get(url + '?limit=9999&q=' + query + '&filter=' + filter, {
headers: {
Authorization: 'Bearer ' + this._bearer,
Accept: 'application/vnd.blackducksoftware.project-detail-5+json'
},
https: {
rejectUnauthorized: false
}
});
const json = JSON.parse(result.body);
if(json === undefined) {
log('versions', 0);
return [];
} else {
log('versions', json.totalCount);
return json.items;
}
}
catch (error) {
console.log('error', error);
return null;
}
}
async getCustomFields(project_object, query, filter) {
try {
const result = await got.get(project_object._meta.href + '/custom-fields', {
headers: {
Authorization: 'Bearer ' + this._bearer,
Accept: 'application/vnd.blackducksoftware.project-detail-5+json'
},
https: {
rejectUnauthorized: false
}
});
const json = JSON.parse(result.body);
if(json === undefined) {
log('custom-fields', 0);
return [];
} else {
log('custom-fields', json.totalCount);
return json.items;
}
}
catch (error) {
console.log('error', error);
return null;
}
}
/*
* VERSION NODE
*/
async getScans(version_object, query, filter) {
let url = lodash.filter(version_object._meta.links, x => x.rel == 'codelocations')[0].href;
log('url', url);
try {
const result = await got.get(url + '?limit=9999&q=' + query + '&filter=' + filter, {
headers: {
Authorization: 'Bearer ' + this._bearer,
Accept: 'application/vnd.blackducksoftware.scan-4+json;charset=UTF-8'
},
https: {
rejectUnauthorized: false
}
});
const json = JSON.parse(result.body);
if(json === undefined) {
log('codelocations', 0);
return [];
} else {
log('codelocations', json.totalCount);
return json.items;
}
}
catch (error) {
console.log('error', error);
return null;
}
}
async getComponents(version_object, query, filter) {
let url = lodash.filter(version_object._meta.links, x => x.rel == 'components')[0].href;
log('url', url);
try {
const result = await got.get(url + '?limit=9999&q=' + query + '&filter=' + filter, {
headers: {
Authorization: 'Bearer ' + this._bearer,
Accept: 'application/vnd.blackducksoftware.bill-of-materials-6+json'
},
https: {
rejectUnauthorized: false
}
});
const json = JSON.parse(result.body);
if(json === undefined) {
log('components', 0);
return [];
} else {
log('components', json.totalCount);
return json.items;
}
}
catch (error) {
console.log('error', error);
return null;
}
}
async getBomComponents(version_object, query, filter) {
try {
const result = await got.get(version_object._meta.href + '/vulnerable-bom-components?limit=9999&q=' + query + '&filter=' + filter, {
headers: {
Authorization: 'Bearer ' + this._bearer,
Accept: 'application/vnd.blackducksoftware.bill-of-materials-6+json'
},
https: {
rejectUnauthorized: false
}
});
const json = JSON.parse(result.body);
if(json === undefined) {
log('bom', 0);
return [];
} else {
log('bom', json.totalCount);
return json.items;
}
}
catch (error) {
console.log('error', error);
return null;
}
}
/*
* COMPONENT NODES
*/
async getComments(component_object, query, filter) {
let url = lodash.filter(component_object._meta.links, x => x.rel == 'comments')[0].href;
log('url', url);
try {
const result = await got.get(url + '?limit=9999&q=' + query + '&filter=' + filter, {
headers: {
Authorization: 'Bearer ' + this._bearer,
Accept: 'application/vnd.blackducksoftware.bill-of-materials-6+json'
},
https: {
rejectUnauthorized: false
}
});
const json = JSON.parse(result.body);
if(json === undefined) {
log('comments', 0);
return [];
} else {
log('comments', json.totalCount);
return json.items;
}
}
catch (error) {
console.log('error', error);
return null;
}
}
/*
* OPERATIONS
*/
deleteProject(project_object) {
this.deleteObject(project_object);
}
deleteVersion(version_object) {
this.deleteObject(version_object);
}
deleteComponent(component_object) {
this.deleteObject(component_object);
}
async deleteObject(object) {
try {
const result = await got.delete(object._meta.href, {
headers: {
Authorization: 'Bearer ' + this._bearer,
},
https: {
rejectUnauthorized: false
}
});
log('delete', 'ok');
return true;
}
catch (error) {
console.log('error', error);
return null;
}
}
async createProject(name) {
try {
const result = await got.post(this._api + '/projects', {
json: {
name: '' + name,
description: 'Generated by https://www.npmjs.com/package/blackduck-api',
projectLevelAdjustments: true
},
headers: {
Authorization: 'Bearer ' + this._bearer,
Accept: 'application/vnd.blackducksoftware.project-detail-4+json'
},
https: {
rejectUnauthorized: false
}
});
return true;
}
catch (error) {
console.log('error', error);
return null;
}
}
async createVersion(project_object, name) {
try {
const result = await got.post(project_object._meta.href + '/versions', {
json: {
versionName: '' + name,
phase: 'PLANNING',
distribution: 'INTERNAL'
},
headers: {
Authorization: 'Bearer ' + this._bearer,
},
https: {
rejectUnauthorized: false
}
});
return true;
}
catch (error) {
console.log('error', error);
return null;
}
}
}
function format(str, length) {
if(str.length > length) {
return str.substring(0, length-3) + '...';
}
else {
return str.padEnd(length);
}
}
export class BlackDuckReports {
static usersReport(users) {
console.log(' =========================================================================================================================== ');
console.log(
'|', format('total:' + users.length, 9),
'|', format('USERNAME', 20),
'|', format('FIRSTNAME', 20),
'|', format('LASTNAME', 20),
'|', format('EMAIL', 40),
'|');
console.log('|---------------------------------------------------------------------------------------------------------------------------|');
users.forEach((user) => {
this.userReport(user);
});
console.log(' =========================================================================================================================== ');
}
static userReport(user) {
console.log(
'|', format('user', 9),
'|', format(user.userName, 20),
'|', format(user.firstName, 20),
'|', format(user.lastName, 20),
'|', format(user.email, 40),
'|');
}
static rolesReport(roles) {
console.log(' ===================================================================================================================== ');
console.log(
'|', format('total:' + roles.length, 9),
'|', format('NAME', 20),
'|', format('DESCRIPTION', 80),
'|');
console.log('|---------------------------------------------------------------------------------------------------------------------|');
roles.forEach((role) => {
this.roleReport(role);
});
console.log(' ===================================================================================================================== ');
}
static roleReport(role) {
console.log(
'|', format('role', 9),
'|', format(role.name, 20),
'|', format(role.description, 80),
'|');
}
static projectsReport(projects) {
console.log(' ======================================================================================================================= ');
console.log(
'|', format('total:' + projects.length, 9),
'|', format('NAME', 60),
'|', format('DATE', 24),
'|', format('USER', 15),
'|');
console.log('|-----------------------------------------------------------------------------------------------------------------------|');
projects.forEach((project) => {
this.projectReport(project);
});
console.log(' ======================================================================================================================= ');
}
static projectReport(project) {
console.log(
'|', format('project', 9),
'|', format(project.name, 60),
'|', format(project.createdAt, 24),
'|', format(project.createdBy, 15),
'|');
}
static versionsReport(versions) {
console.log(' ============================================================================================ ');
console.log(
'|', format('total:' + versions.length, 9),
'|', format('NAME', 15),
'|', format('DATE', 24),
'|', format('USER', 15),
'|', format('PHASE', 15),
'|');
console.log('|--------------------------------------------------------------------------------------------|');
versions.forEach((version) => {
this.versionReport(version);
});
console.log(' ============================================================================================ ');
}
static versionReport(version) {
console.log(
'|', format('version', 9),
'|', format(version.versionName, 15),
'|', format(version.createdAt, 24),
'|', format(version.createdBy, 15),
'|', format(version.phase, 15),
'|');
}
static componentsReport(components) {
console.log(' ======================================================================================================================== ');
console.log(
'|', format('total:' + components.length, 9),
'|', format('NAME', 40),
'|', format('VERSION', 20),
'|', format('LICENSE', 40),
'|');
console.log('|------------------------------------------------------------------------------------------------------------------------|');
components.forEach((component) => {
this.componentReport(component);
});
console.log(' ======================================================================================================================== ');
}
static componentReport(component) {
component.licenses.forEach((license) => {
console.log(
'|', format('component', 9),
'|', format(component.componentName, 40),
'|', format(component.componentVersionName, 20),
'|', format(license.licenseDisplay, 40),
'|');
});
}
static bomComponentsReport(components) {
console.log(' ======================================================================================================================= ');
console.log(
'|', format('total:' + components.length, 9),
'|', format('NAME', 40),
'|', format('VERSION', 25),
'|', format('VULNERABILITY', 15),
'|', format('SCORE', 5),
'|', format('SEVERITY', 8),
'|');
console.log(' ----------------------------------------------------------------------------------------------------------------------- ');
components.forEach((component) => {
this.bomComponentReport(component);
});
console.log(' ======================================================================================================================= ');
}
static bomComponentReport(component) {
console.log(
'|', format('bom', 9),
'|', format(component.componentName, 40),
'|', format(component.componentVersionName, 25),
'|', format(component.vulnerabilityWithRemediation.vulnerabilityName, 15),
'|', format('' + component.vulnerabilityWithRemediation.overallScore, 5),
'|', format(component.vulnerabilityWithRemediation.severity, 8),
'|');
}
}