Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@
"dependencies": {
"@fabric8-analytics/fabric8-analytics-lsp-server": "^0.9.4-ea.28",
"@redhat-developer/vscode-redhat-telemetry": "^0.8.0",
"@trustification/exhort-javascript-api": "^0.1.1-ea.54",
"@trustification/exhort-javascript-api": "^0.1.1-ea.62",
"fs": "^0.0.1-security",
"path": "^0.12.7",
"vscode-languageclient": "^8.1.0"
Expand Down
3 changes: 1 addition & 2 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ class Config {
* Authorizes the RHDA (Red Hat Dependency Analytics) service.
* @param context The extension context for authorization.
*/
async authorizeRHDA(context): Promise<void> {
async authorizeRHDA(context: vscode.ExtensionContext): Promise<void> {
this.telemetryId = await getTelemetryId(context);
await this.setProcessEnv();
}
Expand Down Expand Up @@ -214,7 +214,6 @@ class Config {
} else {
console.error(errorMsg);
}

}
}
}
Expand Down
81 changes: 28 additions & 53 deletions src/exhortServices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,36 +12,29 @@ import { IImageRef, IOptions } from './imageAnalysis';
* @param options - The options for running image analysis.
* @returns A Promise resolving to the analysis response in HTML format.
*/
function imageAnalysisService(images: IImageRef[], options: IOptions): Promise<any> {
return new Promise<any>(async (resolve, reject) => {
const jarPath = `${__dirname}/../javaApiAdapter/exhort-java-api-adapter-1.0-SNAPSHOT-jar-with-dependencies.jar`;
const reportType = 'html';
let parameters = '';
let properties = '';
async function imageAnalysisService(images: IImageRef[], options: IOptions): Promise<any> {
const jarPath = `${__dirname}/../javaApiAdapter/exhort-java-api-adapter-1.0-SNAPSHOT-jar-with-dependencies.jar`;
const reportType = 'html';
let parameters = '';
let properties = '';

images.forEach(image => {
if (image.platform) {
parameters += ` ${image.image}^^${image.platform}`;
} else {
parameters += ` ${image.image}`;
}
});

for (const setting in options) {
if (options[setting]) {
properties += ` -D${setting}=${options[setting]}`;
}
images.forEach(image => {
if (image.platform) {
parameters += ` ${image.image}^^${image.platform}`;
} else {
parameters += ` ${image.image}`;
}
});

try {
const result = execSync(`java${properties} -jar ${jarPath} ${reportType}${parameters}`, {
maxBuffer: 1000 * 1000 * 10, // 10 MB
});
resolve(result.toString());
} catch (error) {
reject(error);
for (const setting in options) {
if (options[setting]) {
properties += ` -D${setting}=${options[setting]}`;
}
});
}

return execSync(`java${properties} -jar ${jarPath} ${reportType}${parameters}`, {
maxBuffer: 1000 * 1000 * 10, // 10 MB
}).toString();
}

/**
Expand All @@ -50,16 +43,9 @@ function imageAnalysisService(images: IImageRef[], options: IOptions): Promise<a
* @param options Additional options for the analysis.
* @returns A promise resolving to the stack analysis report in HTML format.
*/
function stackAnalysisService(pathToManifest: string, options: object): Promise<any> {
return new Promise<any>(async (resolve, reject) => {
try {
// Get stack analysis in HTML format
const stackAnalysisReportHtml = await exhort.stackAnalysis(pathToManifest, true, options);
resolve(stackAnalysisReportHtml);
} catch (error) {
reject(error);
}
});
async function stackAnalysisService(pathToManifest: string, options: object): Promise<string> {
// Get stack analysis in HTML format
return await exhort.stackAnalysis(pathToManifest, true, options);
}

/**
Expand All @@ -68,32 +54,21 @@ function stackAnalysisService(pathToManifest: string, options: object): Promise<
* @param source The source for which the token is being validated.
* @returns A promise resolving after validating the token.
*/
async function tokenValidationService(options, source): Promise<string> {
async function tokenValidationService(options: object, source: string): Promise<string | undefined> {
try {

// Get token validation status code
const tokenValidationStatus = await exhort.validateToken(options);

if (
tokenValidationStatus === 200
) {
if (tokenValidationStatus === 200) {
vscode.window.showInformationMessage(`${source} token validated successfully`);
return;
} else if (
tokenValidationStatus === 400
) {
} else if (tokenValidationStatus === 400) {
return `Missing token. Please provide a valid ${source} Token in the extension workspace settings. Status: ${tokenValidationStatus}`;
} else if (
tokenValidationStatus === 401
) {
} else if (tokenValidationStatus === 401) {
return `Invalid token. Please provide a valid ${source} Token in the extension workspace settings. Status: ${tokenValidationStatus}`;
} else if (
tokenValidationStatus === 403
) {
} else if (tokenValidationStatus === 403) {
return `Forbidden. The token does not have permissions. Please provide a valid ${source} Token in the extension workspace settings. Status: ${tokenValidationStatus}`;
} else if (
tokenValidationStatus === 429
) {
} else if (tokenValidationStatus === 429) {
return `Too many requests. Rate limit exceeded. Please try again in a little while. Status: ${tokenValidationStatus}`;
} else {
return `Failed to validate token. Status: ${tokenValidationStatus}`;
Expand Down
45 changes: 7 additions & 38 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,26 +81,6 @@ export function activate(context: vscode.ExtensionContext) {
}
);

// const disposableSetSnykToken = vscode.commands.registerCommand(
// commands.SET_SNYK_TOKEN_COMMAND,
// async () => {
// const token = await vscode.window.showInputBox({
// prompt: 'Please enter your Snyk Token:',
// placeHolder: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
// password: true,
// validateInput: validateSnykToken
// });

// if (token === undefined) {
// return;
// } else if (token === '') {
// await globalConfig.clearSnykToken(true);
// } else {
// await globalConfig.setSnykToken(token);
// }
// }
// );

registerStackAnalysisCommands(context);

globalConfig.authorizeRHDA(context)
Expand Down Expand Up @@ -157,8 +137,7 @@ export function activate(context: vscode.ExtensionContext) {
if (selection === PromptText.FULL_STACK_PROMPT_TEXT) {
record(context, TelemetryActions.vulnerabilityReportPopupOpened, { manifest: fileName, fileName: fileName });
vscode.commands.executeCommand(commands.STACK_ANALYSIS_COMMAND, filePath);
}
else {
} else {
record(context, TelemetryActions.vulnerabilityReportPopupIgnored, { manifest: fileName, fileName: fileName });
}
};
Expand Down Expand Up @@ -194,30 +173,20 @@ export function activate(context: vscode.ExtensionContext) {
})
.catch(error => {
vscode.window.showErrorMessage(`Failed to Authorize Red Hat Dependency Analytics extension: ${error.message}`);
throw (error);
throw error;
});

vscode.workspace.onDidChangeConfiguration(() => {
globalConfig.loadData();
});

// context.secrets.onDidChange(async (e) => {
// if (e.key === SNYK_TOKEN_KEY) {
// const token = await globalConfig.getSnykToken();
// lspClient.sendNotification('snykTokenModified', token);
// }
// });
}

/**
* Deactivates the extension.
* @returns A `Thenable` for void.
*/
export function deactivate(): Thenable<void> {
if (!lspClient) {
return undefined;
}
return lspClient.stop();
return lspClient?.stop();
}

/**
Expand Down Expand Up @@ -263,10 +232,10 @@ function redirectToRedHatCatalog() {
* Shows a notification regarding Red Hat Dependency Analytics recommendations.
*/
function showRHRepositoryRecommendationNotification() {
const msg = `Important: If you apply Red Hat Dependency Analytics recommendations,
make sure the Red Hat GA Repository (${REDHAT_MAVEN_REPOSITORY}) has been added to your project configuration.
This ensures that the applied dependencies work correctly.
Learn how to add the repository: [Click here](${REDHAT_MAVEN_REPOSITORY_DOCUMENTATION_URL})`;
const msg = 'Important: If you apply Red Hat Dependency Analytics recommendations, ' +
`make sure the Red Hat GA Repository (${REDHAT_MAVEN_REPOSITORY}) has been added to your project configuration. ` +
'This ensures that the applied dependencies work correctly. ' +
`Learn how to add the repository: [Click here](${REDHAT_MAVEN_REPOSITORY_DOCUMENTATION_URL})`;
vscode.window.showWarningMessage(msg);
}

Expand Down
77 changes: 29 additions & 48 deletions src/imageAnalysis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ class DockerImageAnalysis implements IImageAnalysis {
args: Map<string, string> = new Map<string, string>();
images: IImageRef[] = [];
imageAnalysisReportHtml: string = '';
filePath: string;

/**
* Regular expression for matching 'FROM' statements.
Expand All @@ -101,20 +102,18 @@ class DockerImageAnalysis implements IImageAnalysis {

constructor(filePath: string) {
const lines = this.parseTxtDoc(filePath);

this.filePath = filePath;
this.images = this.collectImages(lines);
}

parseTxtDoc(filePath: string): string[] {
try {
const contentBuffer = fs.readFileSync(filePath);

const contentString = contentBuffer.toString('utf-8');

return contentString.split('\n');
} catch (err) {
updateCurrentWebviewPanel('error');
throw (err);
throw err;
}
}

Expand Down Expand Up @@ -179,43 +178,29 @@ class DockerImageAnalysis implements IImageAnalysis {
}

async runImageAnalysis() {
try {
return await vscode.window.withProgress({ location: vscode.ProgressLocation.Window, title: Titles.EXT_TITLE }, async p => {
return new Promise<void>(async (resolve, reject) => {
p.report({
message: StatusMessages.WIN_ANALYZING_DEPENDENCIES
});

// execute image analysis
await imageAnalysisService(this.images, this.options)
.then(async (resp) => {
p.report({
message: StatusMessages.WIN_GENERATING_DEPENDENCIES
});

updateCurrentWebviewPanel(resp);

p.report({
message: StatusMessages.WIN_SUCCESS_DEPENDENCY_ANALYSIS
});

this.imageAnalysisReportHtml = resp;

resolve();
})
.catch(err => {
p.report({
message: StatusMessages.WIN_FAILURE_DEPENDENCY_ANALYSIS
});

reject(err);
});
});
});
} catch (err) {
updateCurrentWebviewPanel('error');
throw (err);
}
return await vscode.window.withProgress({ location: vscode.ProgressLocation.Window, title: Titles.EXT_TITLE }, async p => {
p.report({ message: StatusMessages.WIN_ANALYZING_DEPENDENCIES });

try {

// execute image analysis
const promise = imageAnalysisService(this.images, this.options);
p.report({ message: StatusMessages.WIN_GENERATING_DEPENDENCIES });

const resp = await promise;
updateCurrentWebviewPanel(resp);

p.report({ message: StatusMessages.WIN_SUCCESS_DEPENDENCY_ANALYSIS });

this.imageAnalysisReportHtml = resp;
} catch (error) {
p.report({ message: StatusMessages.WIN_FAILURE_DEPENDENCY_ANALYSIS });

updateCurrentWebviewPanel('error');

throw error;
}
});
}
}

Expand All @@ -225,13 +210,9 @@ class DockerImageAnalysis implements IImageAnalysis {
* @returns A Promise resolving to an Analysis Report HTML.
*/
async function executeDockerImageAnalysis(filePath: string): Promise<string> {
try {
const dockerImageAnalysis = new DockerImageAnalysis(filePath);
await dockerImageAnalysis.runImageAnalysis();
return dockerImageAnalysis.imageAnalysisReportHtml;
} catch (error) {
throw (error);
}
const dockerImageAnalysis = new DockerImageAnalysis(filePath);
await dockerImageAnalysis.runImageAnalysis();
return dockerImageAnalysis.imageAnalysisReportHtml;
}

export { executeDockerImageAnalysis, IImageRef, IOptions };
2 changes: 1 addition & 1 deletion src/redhatTelemetry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ async function startUp(context: vscode.ExtensionContext) {
* @param context The extension context.
* @returns A promise resolving to the telemetry ID.
*/
async function getTelemetryId(context) {
async function getTelemetryId(context: vscode.ExtensionContext) {
const redhatService = await getRedHatService(context);
const redhatIdProvider = await redhatService.getIdProvider();
const telemetryId = await redhatIdProvider.getRedHatUUID();
Expand Down
Loading
Loading