Skip to content

Commit 5d42cbc

Browse files
committed
Also use credentials in non-canary mode
We want users to be able to download databases from private/internal repositories without using canary mode. This will change the prompt to ask for credentials in non-canary mode as well.
1 parent 636f8f1 commit 5d42cbc

3 files changed

Lines changed: 154 additions & 133 deletions

File tree

extensions/ql-vscode/src/databases/github-database-module.ts

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
1+
import { window } from "vscode";
12
import { DisposableObject } from "../common/disposable-object";
23
import { App } from "../common/app";
34
import { findGitHubRepositoryForWorkspace } from "./github-repository-finder";
45
import { redactableError } from "../common/errors";
56
import { asError, getErrorMessage } from "../common/helpers-pure";
67
import {
8+
askForGitHubDatabaseDownload,
79
CodeqlDatabase,
810
findGitHubDatabasesForRepository,
9-
promptGitHubDatabaseDownload,
11+
downloadDatabaseFromGitHub,
1012
} from "./github-database-prompt";
11-
import {
12-
GitHubDatabaseConfig,
13-
GitHubDatabaseConfigListener,
14-
isCanary,
15-
} from "../config";
16-
import { AppOctokit } from "../common/octokit";
13+
import { GitHubDatabaseConfig, GitHubDatabaseConfigListener } from "../config";
1714
import { DatabaseManager } from "./local-databases";
1815
import { CodeQLCliServer } from "../codeql-cli/cli";
16+
import { showNeverAskAgainDialog } from "../common/vscode/dialog";
1917

2018
export class GithubDatabaseModule extends DisposableObject {
2119
private readonly config: GitHubDatabaseConfig;
@@ -93,11 +91,31 @@ export class GithubDatabaseModule extends DisposableObject {
9391
return;
9492
}
9593

96-
const credentials = isCanary() ? this.app.credentials : undefined;
94+
const credentials = this.app.credentials;
95+
96+
const hasAccessToken = !!(await credentials.getExistingAccessToken());
97+
98+
// If the user does not have an access token, ask whether they want to connect.
99+
if (!hasAccessToken) {
100+
const answer = await showNeverAskAgainDialog(
101+
"This repository has an origin (GitHub) that may have one or more CodeQL databases. Connect to GitHub and download any existing databases?",
102+
false,
103+
"Connect",
104+
"Not now",
105+
"Never",
106+
);
107+
108+
if (answer === "Not now" || answer === undefined) {
109+
return;
110+
}
97111

98-
const octokit = credentials
99-
? await credentials.getOctokit()
100-
: new AppOctokit();
112+
if (answer === "Never") {
113+
await this.config.setDownload("never");
114+
return;
115+
}
116+
}
117+
118+
const octokit = await credentials.getOctokit();
101119

102120
let databases: CodeqlDatabase[];
103121
try {
@@ -121,15 +139,29 @@ export class GithubDatabaseModule extends DisposableObject {
121139
}
122140

123141
if (databases.length === 0) {
142+
// If the user didn't have an access token, they have already been prompted,
143+
// so we should give feedback.
144+
if (!hasAccessToken) {
145+
void window.showInformationMessage(
146+
"The GitHub repository does not have any CodeQL databases.",
147+
);
148+
}
149+
124150
return;
125151
}
126152

127-
void promptGitHubDatabaseDownload(
153+
// If the user already had an access token, first ask if they even want to download the DB.
154+
if (hasAccessToken) {
155+
if (!(await askForGitHubDatabaseDownload(databases, this.config))) {
156+
return;
157+
}
158+
}
159+
160+
await downloadDatabaseFromGitHub(
128161
octokit,
129162
githubRepository.owner,
130163
githubRepository.name,
131164
databases,
132-
this.config,
133165
this.databaseManager,
134166
this.databaseStoragePath,
135167
this.cliServer,

extensions/ql-vscode/src/databases/github-database-prompt.ts

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,13 @@ export async function findGitHubDatabasesForRepository(
3030
}
3131

3232
/**
33-
* Prompt the user to download a database from GitHub. This is a blocking method, so this should
34-
* almost never be called with `await`.
33+
* Ask whether the user wants to download a database from GitHub.
34+
* @return true if the user wants to download a database, false otherwise.
3535
*/
36-
export async function promptGitHubDatabaseDownload(
37-
octokit: Octokit,
38-
owner: string,
39-
repo: string,
36+
export async function askForGitHubDatabaseDownload(
4037
databases: CodeqlDatabase[],
4138
config: GitHubDatabaseConfig,
42-
databaseManager: DatabaseManager,
43-
storagePath: string,
44-
cliServer: CodeQLCliServer,
45-
commandManager: AppCommandManager,
46-
): Promise<void> {
39+
): Promise<boolean> {
4740
const languages = databases.map((database) => database.language);
4841

4942
const databasesMessage =
@@ -57,26 +50,45 @@ export async function promptGitHubDatabaseDownload(
5750

5851
const connectMessage =
5952
databases.length === 1
60-
? `Connect to GitHub and download the existing database?`
61-
: `Connect to GitHub and download any existing databases?`;
53+
? `Download the existing database from GitHub?`
54+
: `Download any existing databases from GitHub?`;
6255

6356
const answer = await showNeverAskAgainDialog(
6457
`${databasesMessage} ${connectMessage}`,
6558
false,
66-
"Connect",
59+
"Download",
6760
"Not now",
6861
"Never",
6962
);
7063

7164
if (answer === "Not now" || answer === undefined) {
72-
return;
65+
return false;
7366
}
7467

7568
if (answer === "Never") {
7669
await config.setDownload("never");
77-
return;
70+
return false;
7871
}
7972

73+
return true;
74+
}
75+
76+
/**
77+
* Download a database from GitHub by asking the user for a language and then
78+
* downloading the database for that language.
79+
*/
80+
export async function downloadDatabaseFromGitHub(
81+
octokit: Octokit,
82+
owner: string,
83+
repo: string,
84+
databases: CodeqlDatabase[],
85+
databaseManager: DatabaseManager,
86+
storagePath: string,
87+
cliServer: CodeQLCliServer,
88+
commandManager: AppCommandManager,
89+
): Promise<void> {
90+
const languages = databases.map((database) => database.language);
91+
8092
const language = await promptForLanguage(languages, undefined);
8193
if (!language) {
8294
return;

0 commit comments

Comments
 (0)