Skip to content

Commit fe5f1c4

Browse files
committed
Remove authentication requirement for download GitHub databases
This makes authentication for download GitHub CodeQL databases optional. If you are already authenticated, your token will be used. If you are not authenticated, an anonymous request will be made. If the canary flag is enabled, you will be prompted for credentials when downloading a database and you are not yet logged in.
1 parent 95438bb commit fe5f1c4

File tree

2 files changed

+24
-15
lines changed

2 files changed

+24
-15
lines changed

extensions/ql-vscode/src/authentication.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,16 +76,27 @@ export class Credentials {
7676
}));
7777
}
7878

79-
async getOctokit(): Promise<Octokit.Octokit> {
79+
/**
80+
* Creates or returns an instance of Octokit.
81+
*
82+
* @param requireAuthentication Whether the Octokit instance needs to be authentication as user.
83+
* @returns An instance of Octokit.
84+
*/
85+
async getOctokit(requireAuthentication = true): Promise<Octokit.Octokit> {
8086
if (this.octokit) {
8187
return this.octokit;
8288
}
8389

84-
this.octokit = await this.createOctokit(true);
85-
// octokit shouldn't be undefined, since we've set "createIfNone: true".
86-
// The following block is mainly here to prevent a compiler error.
90+
this.octokit = await this.createOctokit(requireAuthentication);
91+
8792
if (!this.octokit) {
88-
throw new Error('Did not initialize Octokit.');
93+
if (requireAuthentication) {
94+
throw new Error('Did not initialize Octokit.');
95+
}
96+
97+
// We don't want to set this in this.octokit because that would prevent
98+
// authenticating when requireCredentials is true.
99+
return new Octokit.Octokit({ retry });
89100
}
90101
return this.octokit;
91102
}

extensions/ql-vscode/src/databaseFetcher.ts

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
import { CodeQLCliServer } from './cli';
1111
import * as fs from 'fs-extra';
1212
import * as path from 'path';
13+
import * as Octokit from '@octokit/rest';
1314

1415
import { DatabaseManager, DatabaseItem } from './databases';
1516
import {
@@ -23,6 +24,7 @@ import { logger } from './logging';
2324
import { tmpDir } from './helpers';
2425
import { Credentials } from './authentication';
2526
import { REPO_REGEX, getErrorMessage } from './pure/helpers-pure';
27+
import { isCanary } from './config';
2628

2729
/**
2830
* Prompts a user to fetch a database from a remote location. Database is assumed to be an archive file.
@@ -99,14 +101,16 @@ export async function promptImportGithubDatabase(
99101
throw new Error(`Invalid GitHub repository: ${githubRepo}`);
100102
}
101103

102-
const result = await convertGithubNwoToDatabaseUrl(githubRepo, credentials, progress);
104+
// Only require authentication if we are running with the canary flag enabled
105+
const octokit = await credentials.getOctokit(isCanary());
106+
107+
const result = await convertGithubNwoToDatabaseUrl(githubRepo, octokit, progress);
103108
if (!result) {
104109
return;
105110
}
106111

107112
const { databaseUrl, name, owner } = result;
108113

109-
const octokit = await credentials.getOctokit();
110114
/**
111115
* The 'token' property of the token object returned by `octokit.auth()`.
112116
* The object is undocumented, but looks something like this:
@@ -118,14 +122,9 @@ export async function promptImportGithubDatabase(
118122
* We only need the actual token string.
119123
*/
120124
const octokitToken = (await octokit.auth() as { token: string })?.token;
121-
if (!octokitToken) {
122-
// Just print a generic error message for now. Ideally we could show more debugging info, like the
123-
// octokit object, but that would expose a user token.
124-
throw new Error('Unable to get GitHub token.');
125-
}
126125
const item = await databaseArchiveFetcher(
127126
databaseUrl,
128-
{ 'Accept': 'application/zip', 'Authorization': `Bearer ${octokitToken}` },
127+
{ 'Accept': 'application/zip', 'Authorization': octokitToken ? `Bearer ${octokitToken}` : '' },
129128
databaseManager,
130129
storagePath,
131130
`${owner}/${name}`,
@@ -523,7 +522,7 @@ function convertGitHubUrlToNwo(githubUrl: string): string | undefined {
523522

524523
export async function convertGithubNwoToDatabaseUrl(
525524
githubRepo: string,
526-
credentials: Credentials,
525+
octokit: Octokit.Octokit,
527526
progress: ProgressCallback): Promise<{
528527
databaseUrl: string,
529528
owner: string,
@@ -533,7 +532,6 @@ export async function convertGithubNwoToDatabaseUrl(
533532
const nwo = convertGitHubUrlToNwo(githubRepo) || githubRepo;
534533
const [owner, repo] = nwo.split('/');
535534

536-
const octokit = await credentials.getOctokit();
537535
const response = await octokit.request('GET /repos/:owner/:repo/code-scanning/codeql/databases', { owner, repo });
538536

539537
const languages = response.data.map((db: any) => db.language);

0 commit comments

Comments
 (0)