Skip to content

Commit bf69bc0

Browse files
committed
create oidc token provider to pass down token to exhort-javascript-api
1 parent 354d4d0 commit bf69bc0

18 files changed

+114
-58
lines changed

src/dependencyAnalysis/analysis.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
* ------------------------------------------------------------------------------------------ */
55
'use strict';
66

7-
import exhort from '@trustification/exhort-javascript-api';
7+
8+
import exhort, { Options } from '@trustification/exhort-javascript-api';
89
import { AnalysisReport } from '@trustification/exhort-api-spec/model/v4/AnalysisReport';
910

1011
import { globalConfig } from '../config';
@@ -15,6 +16,7 @@ import { notifications, outputChannelDep } from '../extension';
1516
import { Source } from '@trustification/exhort-api-spec/model/v4/Source';
1617
import { DependencyReport } from '@trustification/exhort-api-spec/model/v4/DependencyReport';
1718
import { Issue } from '@trustification/exhort-api-spec/model/v4/Issue';
19+
import { TokenProvider } from '../tokenProvider';
1820

1921
/**
2022
* Represents a source object with an ID and dependencies array.
@@ -146,11 +148,12 @@ class AnalysisResponse implements IAnalysisResponse {
146148
* @param provider - The dependency provider of the corresponding ecosystem.
147149
* @returns A Promise resolving to an AnalysisResponse object.
148150
*/
149-
async function executeComponentAnalysis(diagnosticFilePath: Uri, provider: IDependencyProvider): Promise<AnalysisResponse> {
151+
async function executeComponentAnalysis(tokenProvider: TokenProvider, diagnosticFilePath: Uri, provider: IDependencyProvider): Promise<AnalysisResponse> {
150152

151153
// Define configuration options for the component analysis request
152-
const options = {
153-
'RHDA_TOKEN': globalConfig.telemetryId,
154+
const options: Options = {
155+
'RHDA_TOKEN': await tokenProvider.getToken() ?? '',
156+
'RHDA_TELEMETRY_ID': globalConfig.telemetryId,
154157
'RHDA_SOURCE': globalConfig.utmSource,
155158
'MATCH_MANIFEST_VERSIONS': globalConfig.matchManifestVersions,
156159
'EXHORT_PROXY_URL': globalConfig.exhortProxyUrl,

src/dependencyAnalysis/diagnostics.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { AbstractDiagnosticsPipeline } from '../diagnosticsPipeline';
1515
import { Diagnostic, DiagnosticSeverity, Uri } from 'vscode';
1616
import { notifications, outputChannelDep } from '../extension';
1717
import { globalConfig } from '../config';
18+
import { TokenProvider } from '../tokenProvider';
1819

1920
/**
2021
* Implementation of DiagnosticsPipeline interface.
@@ -95,7 +96,7 @@ class DiagnosticsPipeline extends AbstractDiagnosticsPipeline<DependencyData> {
9596
* @param provider - The dependency provider of the corresponding ecosystem.
9697
* @returns A Promise that resolves when diagnostics are completed.
9798
*/
98-
async function performDiagnostics(diagnosticFilePath: Uri, contents: string, provider: IDependencyProvider) {
99+
async function performDiagnostics(tokenProvider: TokenProvider, diagnosticFilePath: Uri, contents: string, provider: IDependencyProvider) {
99100
try {
100101
const dependencies = provider.collect(contents);
101102
const ecosystem = provider.getEcosystem();
@@ -104,7 +105,7 @@ async function performDiagnostics(diagnosticFilePath: Uri, contents: string, pro
104105
const diagnosticsPipeline = new DiagnosticsPipeline(dependencyMap, diagnosticFilePath);
105106
diagnosticsPipeline.clearDiagnostics();
106107

107-
const response = await executeComponentAnalysis(diagnosticFilePath, provider);
108+
const response = await executeComponentAnalysis(tokenProvider, diagnosticFilePath, provider);
108109

109110
clearCodeActionsMap(diagnosticFilePath);
110111

src/exhortServices.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ function parseImageReference(image: IImageRef, options: IOptions): ImageRef {
5050
* @param source The source for which the token is being validated.
5151
* @returns A promise resolving after validating the token.
5252
*/
53-
async function tokenValidationService(options: { [key: string]: string }, source: string): Promise<string | undefined> {
53+
async function tokenValidationService(options: Options, source: string): Promise<string | undefined> {
5454
try {
5555
// Get token validation status code
5656
const response = await exhort.validateToken(options);

src/extension.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,13 @@ import { LLMAnalysisReportPanel } from './llmAnalysisReportPanel';
2222
import CliTable3 = require('cli-table3');
2323
import { Language, Parser, Query } from 'web-tree-sitter';
2424
import { getValidAccessToken, performOIDCAuthorizationFlow } from './oidcAuthentication';
25+
import { TokenProvider, VSCodeTokenProvider } from './tokenProvider';
2526

2627
export let outputChannelDep: DepOutputChannel;
2728

2829
export const notifications = new EventEmitter();
2930

30-
31-
32-
async function enableExtensionFeatures(context: vscode.ExtensionContext): Promise<void> {
31+
async function enableExtensionFeatures(context: vscode.ExtensionContext, tokenProvider: TokenProvider): Promise<void> {
3332
outputChannelDep.info('Initializing RHDA analysis features');
3433

3534
context.subscriptions.push(vscode.languages.registerCodeActionsProvider('*', new class implements vscode.CodeActionProvider {
@@ -38,7 +37,7 @@ async function enableExtensionFeatures(context: vscode.ExtensionContext): Promis
3837
}
3938
}()));
4039

41-
const fileHandler = new AnalysisMatcher();
40+
const fileHandler = new AnalysisMatcher(tokenProvider);
4241
context.subscriptions.push(vscode.workspace.onDidSaveTextDocument((doc) => fileHandler.handle(doc, outputChannelDep)));
4342
// Anecdotaly, some extension(s) may cause did-open events for files that aren't actually open in the editor,
4443
// so this will trigger CA for files not actually open.
@@ -254,7 +253,7 @@ async function enableExtensionFeatures(context: vscode.ExtensionContext): Promis
254253
record(context, TelemetryActions.componentAnalysisVulnerabilityReportQuickfixOption, { manifest: fileName, fileName: fileName });
255254
}
256255
try {
257-
await generateRHDAReport(context, fspath, outputChannelDep);
256+
await generateRHDAReport(context, tokenProvider, fspath, outputChannelDep);
258257
record(context, TelemetryActions.vulnerabilityReportDone, { manifest: fileName, fileName: fileName });
259258
} catch (error) {
260259
// TODO: dont show raw message
@@ -291,7 +290,7 @@ async function enableExtensionFeatures(context: vscode.ExtensionContext): Promis
291290
}
292291
);
293292

294-
registerStackAnalysisCommands(context);
293+
registerStackAnalysisCommands(context, tokenProvider);
295294

296295
const showVulnerabilityFoundPrompt = async (msg: string, filePath: vscode.Uri) => {
297296
const fileName = path.basename(filePath.fsPath);
@@ -348,14 +347,16 @@ async function enableExtensionFeatures(context: vscode.ExtensionContext): Promis
348347
/**
349348
* Main activation function - checks authentication and conditionally enables features
350349
*/
351-
export async function activate(context: vscode.ExtensionContext) {
350+
export async function activate(context: vscode.ExtensionContext): Promise<vscode.ExtensionContext> {
352351
outputChannelDep = new DepOutputChannel();
353352
outputChannelDep.info(`starting RHDA extension ${context.extension.packageJSON['version']}`);
354353

355354
globalConfig.linkToSecretStorage(context);
356355

357356
initTelemetry(context);
358357

358+
const tokenProvider = new VSCodeTokenProvider(context);
359+
359360
// Register authentication command (always available)
360361
const authenticateCommand = vscode.commands.registerCommand('rhda.authenticate', async () => {
361362
const existingToken = await getValidAccessToken(context);
@@ -400,7 +401,9 @@ export async function activate(context: vscode.ExtensionContext) {
400401
});
401402
}
402403

403-
await enableExtensionFeatures(context);
404+
await enableExtensionFeatures(context, tokenProvider);
405+
406+
return context;
404407
}
405408

406409
/**
@@ -461,12 +464,12 @@ function showRHRepositoryRecommendationNotification() {
461464
* Registers stack analysis commands to track RHDA report generations.
462465
* @param context - The extension context.
463466
*/
464-
function registerStackAnalysisCommands(context: vscode.ExtensionContext) {
467+
function registerStackAnalysisCommands(context: vscode.ExtensionContext, tokenProvider: TokenProvider) {
465468

466469
const invokeFullStackReport = async (filePath: string) => {
467470
const fileName = path.basename(filePath);
468471
try {
469-
await generateRHDAReport(context, filePath, outputChannelDep);
472+
await generateRHDAReport(context, tokenProvider, filePath, outputChannelDep);
470473
record(context, TelemetryActions.vulnerabilityReportDone, { manifest: fileName, fileName: fileName });
471474
} catch (error) {
472475
const message = applySettingNameMappings((error as Error).message);

src/fileHandler.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,37 +10,44 @@ import { DependencyProvider as BuildGradle } from './providers/build.gradle';
1010
import { ImageProvider as Docker } from './providers/docker';
1111
import { globalConfig } from './config';
1212
import { DepOutputChannel } from './depOutputChannel';
13+
import { TokenProvider } from './tokenProvider';
1314

1415
export class AnalysisMatcher {
16+
tokenProvider: TokenProvider;
17+
18+
constructor(tokenProvider: TokenProvider) {
19+
this.tokenProvider = tokenProvider;
20+
}
21+
1522
matchers: Array<{ scheme: string, pattern: RegExp, callback: (path: Uri, contents: string) => Promise<void> }> = [
1623
{
1724
scheme: 'file', pattern: new RegExp('^package\\.json$'), callback: (path: Uri, contents: string) => {
18-
return dependencyDiagnostics.performDiagnostics(path, contents, new PackageJson());
25+
return dependencyDiagnostics.performDiagnostics(this.tokenProvider, path, contents, new PackageJson());
1926
}
2027
},
2128
{
2229
scheme: 'file', pattern: new RegExp('^pom\\.xml$'), callback: (path: Uri, contents: string) => {
23-
return dependencyDiagnostics.performDiagnostics(path, contents, new PomXml());
30+
return dependencyDiagnostics.performDiagnostics(this.tokenProvider, path, contents, new PomXml());
2431
}
2532
},
2633
{
2734
scheme: 'file', pattern: new RegExp('^go\\.mod$'), callback: (path: Uri, contents: string) => {
28-
return dependencyDiagnostics.performDiagnostics(path, contents, new GoMod());
35+
return dependencyDiagnostics.performDiagnostics(this.tokenProvider, path, contents, new GoMod());
2936
}
3037
},
3138
{
3239
scheme: 'file', pattern: new RegExp('^requirements\\.txt$'), callback: (path: Uri, contents: string) => {
33-
return dependencyDiagnostics.performDiagnostics(path, contents, new RequirementsTxt());
40+
return dependencyDiagnostics.performDiagnostics(this.tokenProvider, path, contents, new RequirementsTxt());
3441
}
3542
},
3643
{
3744
scheme: 'file', pattern: new RegExp('^build\\.gradle$'), callback: (path: Uri, contents: string) => {
38-
return dependencyDiagnostics.performDiagnostics(path, contents, new BuildGradle());
45+
return dependencyDiagnostics.performDiagnostics(this.tokenProvider, path, contents, new BuildGradle());
3946
}
4047
},
4148
{
4249
scheme: 'file', pattern: new RegExp('^(Dockerfile|Containerfile)$'), callback: (path: Uri, contents: string) => {
43-
return imageDiagnostics.performDiagnostics(path, contents, new Docker());
50+
return imageDiagnostics.performDiagnostics(this.tokenProvider, path, contents, new Docker());
4451
}
4552
}
4653
];

src/imageAnalysis.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,14 @@ import { Options } from '@trustification/exhort-javascript-api';
1010
import { updateCurrentWebviewPanel } from './rhda';
1111
import { buildLogErrorMessage } from './utils';
1212
import { DepOutputChannel } from './depOutputChannel';
13+
import { TokenProvider } from './tokenProvider';
1314

1415
/**
1516
* Represents options for image analysis.
1617
*/
1718
interface IOptions extends Options {
1819
RHDA_TOKEN: string;
20+
RHDA_TELEMETRY_ID: string;
1921
RHDA_SOURCE: string;
2022
EXHORT_SYFT_PATH: string;
2123
EXHORT_SYFT_CONFIG_PATH: string;
@@ -155,15 +157,16 @@ class DockerImageAnalysis {
155157
/**
156158
* Runs the image analysis process.
157159
*/
158-
public async runImageAnalysis() {
160+
public async runImageAnalysis(tokenProvider: TokenProvider) {
159161
return await vscode.window.withProgress({ location: vscode.ProgressLocation.Window, title: Titles.EXT_TITLE }, async p => {
160162
p.report({ message: StatusMessages.WIN_ANALYZING_DEPENDENCIES });
161163

162164
try {
163165
this.outputChannel.info(`generating image analysis report for "${this.filePath}"`);
164166

165167
const options: IOptions = {
166-
'RHDA_TOKEN': globalConfig.telemetryId ?? '',
168+
'RHDA_TOKEN': await tokenProvider.getToken() ?? '',
169+
'RHDA_TELEMETRY_ID': globalConfig.telemetryId ?? '',
167170
'RHDA_SOURCE': globalConfig.utmSource,
168171
'EXHORT_SYFT_PATH': globalConfig.exhortSyftPath,
169172
'EXHORT_SYFT_CONFIG_PATH': globalConfig.exhortSyftConfigPath,
@@ -204,9 +207,9 @@ class DockerImageAnalysis {
204207
* @param filePath - The path to the image file to analyze.
205208
* @returns A Promise resolving to an Analysis Report HTML.
206209
*/
207-
async function executeDockerImageAnalysis(filePath: string, outputChannel: DepOutputChannel): Promise<string> {
210+
async function executeDockerImageAnalysis(tokenProvider: TokenProvider, filePath: string, outputChannel: DepOutputChannel): Promise<string> {
208211
const dockerImageAnalysis = new DockerImageAnalysis(filePath, outputChannel);
209-
await dockerImageAnalysis.runImageAnalysis();
212+
await dockerImageAnalysis.runImageAnalysis(tokenProvider);
210213
return dockerImageAnalysis.imageAnalysisReportHtml;
211214
}
212215

src/imageAnalysis/diagnostics.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { Diagnostic, DiagnosticSeverity, Uri } from 'vscode';
1414
import { notifications, outputChannelDep } from '../extension';
1515
import { globalConfig } from '../config';
1616
import { type IOptions } from '../imageAnalysis';
17+
import { TokenProvider } from '../tokenProvider';
1718

1819
/**
1920
* Implementation of DiagnosticsPipeline interface.
@@ -88,10 +89,11 @@ class DiagnosticsPipeline extends AbstractDiagnosticsPipeline<ImageData> {
8889
* @param provider - The image provider of the corresponding ecosystem.
8990
* @returns A Promise that resolves when diagnostics are completed.
9091
*/
91-
async function performDiagnostics(diagnosticFilePath: Uri, contents: string, provider: IImageProvider) {
92+
async function performDiagnostics(tokenProvider: TokenProvider, diagnosticFilePath: Uri, contents: string, provider: IImageProvider) {
9293
try {
9394
const options: IOptions = {
94-
'RHDA_TOKEN': globalConfig.telemetryId ?? '',
95+
'RHDA_TOKEN': await tokenProvider.getToken() ?? '',
96+
'RHDA_TELEMETRY_ID': globalConfig.telemetryId ?? '',
9597
'RHDA_SOURCE': globalConfig.utmSource,
9698
'EXHORT_SYFT_PATH': globalConfig.exhortSyftPath,
9799
'EXHORT_SYFT_CONFIG_PATH': globalConfig.exhortSyftConfigPath,

src/oidcAuthentication.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { outputChannelDep } from './extension';
55
import { record, TelemetryActions } from './redhatTelemetry';
66
import { caStatusBarProvider } from './caStatusBarProvider';
77

8-
98
// OIDC flow state storage
109
interface OIDCFlowState {
1110
codeVerifier: string;

src/rhda.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { DependencyReportPanel } from './dependencyReportPanel';
99
import { globalConfig } from './config';
1010
import { executeDockerImageAnalysis } from './imageAnalysis';
1111
import { DepOutputChannel } from './depOutputChannel';
12+
import { TokenProvider } from './tokenProvider';
1213

1314
/**
1415
* Represents supported file types for analysis.
@@ -97,15 +98,15 @@ async function writeReportToFile(data: string) {
9798
* @param filePath The path of the file for analysis.
9899
* @returns A promise that resolves once the report generation is complete.
99100
*/
100-
async function generateRHDAReport(context: vscode.ExtensionContext, filePath: string, outputChannel: DepOutputChannel) {
101+
async function generateRHDAReport(context: vscode.ExtensionContext, tokenProvider: TokenProvider, filePath: string, outputChannel: DepOutputChannel) {
101102
const fileType = getFileType(filePath);
102103
if (fileType) {
103104
await triggerWebviewPanel(context);
104105
let resp: string;
105106
if (fileType === 'docker') {
106-
resp = await executeDockerImageAnalysis(filePath, outputChannel);
107+
resp = await executeDockerImageAnalysis(tokenProvider, filePath, outputChannel);
107108
} else {
108-
resp = await executeStackAnalysis(filePath, outputChannel);
109+
resp = await executeStackAnalysis(tokenProvider, filePath, outputChannel);
109110
}
110111
/* istanbul ignore else */
111112
if (DependencyReportPanel.currentPanel) {

src/stackAnalysis.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,21 @@ import { updateCurrentWebviewPanel } from './rhda';
99
import { buildLogErrorMessage } from './utils';
1010
import { DepOutputChannel } from './depOutputChannel';
1111
import { Options } from '@trustification/exhort-javascript-api';
12+
import { TokenProvider } from './tokenProvider';
1213

1314
/**
1415
* Executes the RHDA stack analysis process.
1516
* @param manifestFilePath The file path to the manifest file for analysis.
1617
* @returns The stack analysis response string.
1718
*/
18-
export async function executeStackAnalysis(manifestFilePath: string, outputChannel: DepOutputChannel): Promise<string> {
19+
export async function executeStackAnalysis(tokenProvider: TokenProvider, manifestFilePath: string, outputChannel: DepOutputChannel): Promise<string> {
1920
return await vscode.window.withProgress({ location: vscode.ProgressLocation.Window, title: Titles.EXT_TITLE }, async p => {
2021
p.report({ message: StatusMessages.WIN_ANALYZING_DEPENDENCIES });
2122

2223
// set up configuration options for the stack analysis request
2324
const options: Options = {
24-
'RHDA_TOKEN': globalConfig.telemetryId,
25+
'RHDA_TOKEN': await tokenProvider.getToken() ?? '',
26+
'RHDA_TELEMETRY_ID': globalConfig.telemetryId,
2527
'RHDA_SOURCE': globalConfig.utmSource,
2628
'MATCH_MANIFEST_VERSIONS': globalConfig.matchManifestVersions,
2729
'EXHORT_PYTHON_VIRTUAL_ENV': globalConfig.usePythonVirtualEnvironment,

0 commit comments

Comments
 (0)