Skip to content

Commit 03993f3

Browse files
Add credentials to App
1 parent 13389fd commit 03993f3

34 files changed

+256
-259
lines changed

extensions/ql-vscode/src/authentication.ts

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as vscode from "vscode";
22
import * as Octokit from "@octokit/rest";
33
import { retry } from "@octokit/plugin-retry";
4+
import { Credentials } from "./common/authentication";
45

56
const GITHUB_AUTH_PROVIDER_ID = "github";
67

@@ -13,41 +14,12 @@ const SCOPES = ["repo", "gist", "read:packages"];
1314
/**
1415
* Handles authentication to GitHub, using the VS Code [authentication API](https://code.visualstudio.com/api/references/vscode-api#authentication).
1516
*/
16-
export class Credentials {
17+
export class VSCodeCredentials implements Credentials {
1718
/**
1819
* A specific octokit to return, otherwise a new authenticated octokit will be created when needed.
1920
*/
2021
private octokit: Octokit.Octokit | undefined;
2122

22-
// Explicitly make the constructor private, so that we can't accidentally call the constructor from outside the class
23-
// without also initializing the class.
24-
private constructor(octokit?: Octokit.Octokit) {
25-
this.octokit = octokit;
26-
}
27-
28-
/**
29-
* Initializes a Credentials instance. This will generate octokit instances
30-
* authenticated as the user. If there is not already an authenticated GitHub
31-
* session available then the user will be prompted to log in.
32-
*
33-
* @returns An instance of credentials.
34-
*/
35-
static async initialize(): Promise<Credentials> {
36-
return new Credentials();
37-
}
38-
39-
/**
40-
* Initializes an instance of credentials with an octokit instance using
41-
* a specific known token. This method is meant to be used in
42-
* non-interactive environments such as tests.
43-
*
44-
* @param overrideToken The GitHub token to use for authentication.
45-
* @returns An instance of credentials.
46-
*/
47-
static async initializeWithToken(overrideToken: string) {
48-
return new Credentials(new Octokit.Octokit({ auth: overrideToken, retry }));
49-
}
50-
5123
/**
5224
* Creates or returns an instance of Octokit.
5325
*

extensions/ql-vscode/src/cli.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import { Logger, ProgressReporter } from "./common";
2727
import { CompilationMessage } from "./pure/legacy-messages";
2828
import { sarifParser } from "./sarif-parser";
2929
import { dbSchemeToLanguage, walkDirectory } from "./helpers";
30-
import { Credentials } from "./authentication";
30+
import { App } from "./common/app";
3131

3232
/**
3333
* The version of the SARIF format that we are using.
@@ -197,6 +197,7 @@ export class CodeQLCliServer implements Disposable {
197197
public quiet = false;
198198

199199
constructor(
200+
private readonly app: App,
200201
private distributionProvider: DistributionProvider,
201202
private cliConfig: CliConfig,
202203
private logger: Logger,
@@ -618,9 +619,7 @@ export class CodeQLCliServer implements Disposable {
618619
addFormat = true,
619620
progressReporter?: ProgressReporter,
620621
): Promise<OutputType> {
621-
const credentials = await Credentials.initialize();
622-
623-
const accessToken = await credentials.getExistingAccessToken();
622+
const accessToken = await this.app.credentials.getExistingAccessToken();
624623

625624
const extraArgs = accessToken ? ["--github-auth-stdin"] : [];
626625

@@ -633,7 +632,7 @@ export class CodeQLCliServer implements Disposable {
633632
async (line) => {
634633
if (line.startsWith("Enter value for --github-auth-stdin")) {
635634
try {
636-
return await credentials.getAccessToken();
635+
return await this.app.credentials.getAccessToken();
637636
} catch (e) {
638637
// If the user cancels the authentication prompt, we still need to give a value to the CLI.
639638
// By giving a potentially invalid value, the user will just get a 401/403 when they try to access a

extensions/ql-vscode/src/common/app.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { Credentials } from "./authentication";
12
import { Disposable } from "../pure/disposable-object";
23
import { AppEventEmitter } from "./events";
34
import { Logger } from "./logging";
@@ -13,6 +14,7 @@ export interface App {
1314
readonly globalStoragePath: string;
1415
readonly workspaceStoragePath?: string;
1516
readonly workspaceState: Memento;
17+
readonly credentials: Credentials;
1618
}
1719

1820
export enum AppMode {
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import * as Octokit from "@octokit/rest";
2+
3+
export interface Credentials {
4+
/**
5+
* Creates or returns an instance of Octokit.
6+
*
7+
* @returns An instance of Octokit.
8+
*/
9+
getOctokit(): Promise<Octokit.Octokit>;
10+
11+
getAccessToken(): Promise<string>;
12+
13+
getExistingAccessToken(): Promise<string | undefined>;
14+
}

extensions/ql-vscode/src/common/vscode/vscode-app.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as vscode from "vscode";
2+
import { VSCodeCredentials } from "../../authentication";
23
import { Disposable } from "../../pure/disposable-object";
34
import { App, AppMode } from "../app";
45
import { AppEventEmitter } from "../events";
@@ -7,9 +8,13 @@ import { Memento } from "../memento";
78
import { VSCodeAppEventEmitter } from "./events";
89

910
export class ExtensionApp implements App {
11+
public readonly credentials: VSCodeCredentials;
12+
1013
public constructor(
1114
public readonly extensionContext: vscode.ExtensionContext,
12-
) {}
15+
) {
16+
this.credentials = new VSCodeCredentials();
17+
}
1318

1419
public get extensionPath(): string {
1520
return this.extensionContext.extensionPath;

extensions/ql-vscode/src/databaseFetcher.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@ import { DatabaseManager, DatabaseItem } from "./databases";
2020
import { showAndLogInformationMessage, tmpDir } from "./helpers";
2121
import { reportStreamProgress, ProgressCallback } from "./commandRunner";
2222
import { extLogger } from "./common";
23-
import { Credentials } from "./authentication";
2423
import { getErrorMessage } from "./pure/helpers-pure";
2524
import {
2625
getNwoFromGitHubUrl,
2726
isValidGitHubNwo,
2827
} from "./common/github-url-identifier-helper";
28+
import { Credentials } from "./common/authentication";
2929

3030
/**
3131
* Prompts a user to fetch a database from a remote location. Database is assumed to be an archive file.

extensions/ql-vscode/src/databases-ui.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,10 @@ import {
3535
promptImportInternetDatabase,
3636
} from "./databaseFetcher";
3737
import { asyncFilter, getErrorMessage } from "./pure/helpers-pure";
38-
import { Credentials } from "./authentication";
3938
import { QueryRunner } from "./queryRunner";
4039
import { isCanary } from "./config";
40+
import { App } from "./common/app";
41+
import { Credentials } from "./common/authentication";
4142

4243
type ThemableIconPath = { light: string; dark: string } | string;
4344

@@ -220,11 +221,11 @@ export class DatabaseUI extends DisposableObject {
220221
private treeDataProvider: DatabaseTreeDataProvider;
221222

222223
public constructor(
224+
private app: App,
223225
private databaseManager: DatabaseManager,
224226
private readonly queryServer: QueryRunner | undefined,
225227
private readonly storagePath: string,
226228
readonly extensionPath: string,
227-
private readonly getCredentials: () => Promise<Credentials>,
228229
) {
229230
super();
230231

@@ -297,9 +298,7 @@ export class DatabaseUI extends DisposableObject {
297298
commandRunnerWithProgress(
298299
"codeQLDatabases.chooseDatabaseGithub",
299300
async (progress: ProgressCallback, token: CancellationToken) => {
300-
const credentials = isCanary()
301-
? await this.getCredentials()
302-
: undefined;
301+
const credentials = isCanary() ? this.app.credentials : undefined;
303302
await this.handleChooseDatabaseGithub(credentials, progress, token);
304303
},
305304
{

extensions/ql-vscode/src/extension.ts

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@ import {
102102
} from "./commandRunner";
103103
import { CodeQlStatusBarHandler } from "./status-bar";
104104

105-
import { Credentials } from "./authentication";
106105
import { RemoteQueriesManager } from "./remote-queries/remote-queries-manager";
107106
import { RemoteQueryResult } from "./remote-queries/remote-query-result";
108107
import { URLSearchParams } from "url";
@@ -546,6 +545,8 @@ async function activateWithInstalledDistribution(
546545
// of activation.
547546
errorStubs.forEach((stub) => stub.dispose());
548547

548+
const app = new ExtensionApp(ctx);
549+
549550
void extLogger.log("Initializing configuration listener...");
550551
const qlConfigurationListener =
551552
await QueryServerConfigListener.createQueryServerConfigListener(
@@ -555,6 +556,7 @@ async function activateWithInstalledDistribution(
555556

556557
void extLogger.log("Initializing CodeQL cli server...");
557558
const cliServer = new CodeQLCliServer(
559+
app,
558560
distributionManager,
559561
new CliConfigListener(),
560562
extLogger,
@@ -587,11 +589,11 @@ async function activateWithInstalledDistribution(
587589
ctx.subscriptions.push(dbm);
588590
void extLogger.log("Initializing database panel.");
589591
const databaseUI = new DatabaseUI(
592+
app,
590593
dbm,
591594
qs,
592595
getContextStoragePath(ctx),
593596
ctx.extensionPath,
594-
() => Credentials.initialize(),
595597
);
596598
databaseUI.init();
597599
ctx.subscriptions.push(databaseUI);
@@ -623,8 +625,6 @@ async function activateWithInstalledDistribution(
623625

624626
void extLogger.log("Initializing variant analysis manager.");
625627

626-
const app = new ExtensionApp(ctx);
627-
628628
const dbModule = await DbModule.initialize(app);
629629

630630
const variantAnalysisStorageDir = join(
@@ -633,12 +633,14 @@ async function activateWithInstalledDistribution(
633633
);
634634
await ensureDir(variantAnalysisStorageDir);
635635
const variantAnalysisResultsManager = new VariantAnalysisResultsManager(
636+
app.credentials,
636637
cliServer,
637638
extLogger,
638639
);
639640

640641
const variantAnalysisManager = new VariantAnalysisManager(
641642
ctx,
643+
app,
642644
cliServer,
643645
variantAnalysisStorageDir,
644646
variantAnalysisResultsManager,
@@ -656,6 +658,7 @@ async function activateWithInstalledDistribution(
656658
void extLogger.log("Initializing remote queries manager.");
657659
const rqm = new RemoteQueriesManager(
658660
ctx,
661+
app,
659662
cliServer,
660663
queryStorageDir,
661664
extLogger,
@@ -664,6 +667,7 @@ async function activateWithInstalledDistribution(
664667

665668
void extLogger.log("Initializing query history.");
666669
const qhm = new QueryHistoryManager(
670+
app,
667671
qs,
668672
dbm,
669673
localQueryResultsView,
@@ -1245,7 +1249,7 @@ async function activateWithInstalledDistribution(
12451249
commandRunner(
12461250
"codeQL.exportRemoteQueryResults",
12471251
async (queryId: string) => {
1248-
await exportRemoteQueryResults(qhm, rqm, queryId);
1252+
await exportRemoteQueryResults(qhm, rqm, queryId, app.credentials);
12491253
},
12501254
),
12511255
);
@@ -1263,6 +1267,7 @@ async function activateWithInstalledDistribution(
12631267
variantAnalysisManager,
12641268
variantAnalysisId,
12651269
filterSort,
1270+
app.credentials,
12661271
progress,
12671272
token,
12681273
);
@@ -1363,9 +1368,7 @@ async function activateWithInstalledDistribution(
13631368
commandRunnerWithProgress(
13641369
"codeQL.chooseDatabaseGithub",
13651370
async (progress: ProgressCallback, token: CancellationToken) => {
1366-
const credentials = isCanary()
1367-
? await Credentials.initialize()
1368-
: undefined;
1371+
const credentials = isCanary() ? app.credentials : undefined;
13691372
await databaseUI.handleChooseDatabaseGithub(
13701373
credentials,
13711374
progress,
@@ -1419,8 +1422,7 @@ async function activateWithInstalledDistribution(
14191422
* Credentials for authenticating to GitHub.
14201423
* These are used when making API calls.
14211424
*/
1422-
const credentials = await Credentials.initialize();
1423-
const octokit = await credentials.getOctokit();
1425+
const octokit = await app.credentials.getOctokit();
14241426
const userInfo = await octokit.users.getAuthenticated();
14251427
void showAndLogInformationMessage(
14261428
`Authenticated to GitHub as user: ${userInfo.data.login}`,

extensions/ql-vscode/src/query-history.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ import {
5555
import { pathExists } from "fs-extra";
5656
import { CliVersionConstraint } from "./cli";
5757
import { HistoryItemLabelProvider } from "./history-item-label-provider";
58-
import { Credentials } from "./authentication";
5958
import { cancelRemoteQuery } from "./remote-queries/gh-api/gh-actions-api-client";
6059
import { RemoteQueriesManager } from "./remote-queries/remote-queries-manager";
6160
import { RemoteQueryHistoryItem } from "./remote-queries/remote-query-history-item";
@@ -69,6 +68,7 @@ import { QueryRunner } from "./queryRunner";
6968
import { VariantAnalysisManager } from "./remote-queries/variant-analysis-manager";
7069
import { VariantAnalysisHistoryItem } from "./remote-queries/variant-analysis-history-item";
7170
import { getTotalResultCount } from "./remote-queries/shared/variant-analysis";
71+
import { App } from "./common/app";
7272

7373
/**
7474
* query-history.ts
@@ -394,6 +394,7 @@ export class QueryHistoryManager extends DisposableObject {
394394
readonly onDidCompleteQuery = this._onDidCompleteQuery.event;
395395

396396
constructor(
397+
private readonly app: App,
397398
private readonly qs: QueryRunner,
398399
private readonly dbm: DatabaseManager,
399400
private readonly localQueriesResultsView: ResultsView,
@@ -636,10 +637,6 @@ export class QueryHistoryManager extends DisposableObject {
636637
this._onDidCompleteQuery.fire(info);
637638
}
638639

639-
private getCredentials() {
640-
return Credentials.initialize();
641-
}
642-
643640
/**
644641
* Register and create the history scrubber.
645642
*/
@@ -1346,8 +1343,7 @@ export class QueryHistoryManager extends DisposableObject {
13461343
void showAndLogInformationMessage(
13471344
"Cancelling variant analysis. This may take a while.",
13481345
);
1349-
const credentials = await this.getCredentials();
1350-
await cancelRemoteQuery(credentials, item.remoteQuery);
1346+
await cancelRemoteQuery(this.app.credentials, item.remoteQuery);
13511347
} else if (item.t === "variant-analysis") {
13521348
await commands.executeCommand(
13531349
"codeQL.cancelVariantAnalysis",

0 commit comments

Comments
 (0)