mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-22 01:29:04 +01:00
GitHub - update authentication flow for branch protection (#181924)
* GitHub - tweak authentication request * Add tracing messages
This commit is contained in:
@@ -10,6 +10,8 @@ import { Octokit } from '@octokit/rest';
|
||||
import { httpsOverHttp } from 'tunnel';
|
||||
import { URL } from 'url';
|
||||
|
||||
export class AuthenticationError extends Error { }
|
||||
|
||||
function getAgent(url: string | undefined = process.env.HTTPS_PROXY): Agent {
|
||||
if (!url) {
|
||||
return globalAgent;
|
||||
@@ -57,25 +59,30 @@ export function getOctokit(): Promise<Octokit> {
|
||||
|
||||
let _octokitGraphql: Promise<graphql> | undefined;
|
||||
|
||||
export function getOctokitGraphql(): Promise<graphql> {
|
||||
export async function getOctokitGraphql(): Promise<graphql> {
|
||||
if (!_octokitGraphql) {
|
||||
_octokitGraphql = getSession()
|
||||
.then(async session => {
|
||||
const token = session.accessToken;
|
||||
const { graphql } = await import('@octokit/graphql');
|
||||
try {
|
||||
const session = await authentication.getSession('github', scopes, { createIfNone: false });
|
||||
|
||||
return graphql.defaults({
|
||||
headers: {
|
||||
authorization: `token ${token}`
|
||||
},
|
||||
request: {
|
||||
agent: getAgent()
|
||||
}
|
||||
});
|
||||
}).then(null, async err => {
|
||||
_octokitGraphql = undefined;
|
||||
throw err;
|
||||
if (!session) {
|
||||
throw new AuthenticationError('No GitHub authentication session available.');
|
||||
}
|
||||
|
||||
const token = session.accessToken;
|
||||
const { graphql } = await import('@octokit/graphql');
|
||||
|
||||
return graphql.defaults({
|
||||
headers: {
|
||||
authorization: `token ${token}`
|
||||
},
|
||||
request: {
|
||||
agent: getAgent()
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
_octokitGraphql = undefined;
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
return _octokitGraphql;
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { EventEmitter, LogOutputChannel, Memento, Uri, workspace } from 'vscode';
|
||||
import { authentication, EventEmitter, LogOutputChannel, Memento, Uri, workspace } from 'vscode';
|
||||
import { Repository as GitHubRepository, RepositoryRuleset } from '@octokit/graphql-schema';
|
||||
import { getOctokitGraphql } from './auth';
|
||||
import { AuthenticationError, getOctokitGraphql } from './auth';
|
||||
import { API, BranchProtection, BranchProtectionProvider, BranchProtectionRule, Repository } from './typings/git';
|
||||
import { DisposableStore, getRepositoryFromUrl } from './util';
|
||||
|
||||
@@ -163,10 +163,12 @@ export class GithubBranchProtectionProvider implements BranchProtectionProvider
|
||||
}
|
||||
|
||||
// Repository details
|
||||
this.logger.trace(`Fetching repository details for "${repository.owner}/${repository.repo}".`);
|
||||
const repositoryDetails = await this.getRepositoryDetails(repository.owner, repository.repo);
|
||||
|
||||
// Check repository write permission
|
||||
if (repositoryDetails.viewerPermission !== 'ADMIN' && repositoryDetails.viewerPermission !== 'MAINTAIN' && repositoryDetails.viewerPermission !== 'WRITE') {
|
||||
this.logger.trace(`Skipping branch protection for "${repository.owner}/${repository.repo}" due to missing repository write permission.`);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -189,8 +191,20 @@ export class GithubBranchProtectionProvider implements BranchProtectionProvider
|
||||
|
||||
// Save branch protection to global state
|
||||
await this.globalState.update(this.globalStateKey, branchProtection);
|
||||
this.logger.trace(`Branch protection for "${this.repository.rootUri.toString()}": ${JSON.stringify(branchProtection)}.`);
|
||||
} catch (err) {
|
||||
// noop
|
||||
if (err instanceof AuthenticationError) {
|
||||
// Since there is no GitHub authentication session available we need to wait
|
||||
// until the user signs in with their GitHub account so that we can query the
|
||||
// repository rulesets
|
||||
const disposable = authentication.onDidChangeSessions(e => {
|
||||
if (e.provider.id === 'github') {
|
||||
disposable.dispose();
|
||||
this.updateRepositoryBranchProtection();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.logger.warn(`Failed to update repository branch protection: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user