GitHub Enterprise Auth improvements (#165082)

1. Namespace secrets based on the value of github-enterprise.uri to support "multiple separate GHES instances"
2. If the setting value disappears, continue using last set value. Fixes https://github.com/microsoft/vscode-pull-request-github/issues/3992
3. Mark github-enterprise.uri as requires trust
3. Refactoring like:
  * UriHandler is handled in extension.ts and passed down everywhere since we can only have 1 instance of it
  * misc style (`private` usage, better `disposable` handling)
This commit is contained in:
Tyler James Leonhardt
2022-10-31 12:18:54 -07:00
committed by GitHub
parent c60980ca7a
commit 9b3e147d6d
4 changed files with 88 additions and 63 deletions

View File

@@ -28,27 +28,49 @@ export enum AuthProviderType {
githubEnterprise = 'github-enterprise'
}
export class UriEventHandler extends vscode.EventEmitter<vscode.Uri> implements vscode.UriHandler {
public handleUri(uri: vscode.Uri) {
this.fire(uri);
}
}
export class GitHubAuthenticationProvider implements vscode.AuthenticationProvider, vscode.Disposable {
private _sessionChangeEmitter = new vscode.EventEmitter<vscode.AuthenticationProviderAuthenticationSessionsChangeEvent>();
private _logger = new Log(this.type);
private _githubServer: IGitHubServer;
private _telemetryReporter: ExperimentationTelemetry;
private readonly _sessionChangeEmitter = new vscode.EventEmitter<vscode.AuthenticationProviderAuthenticationSessionsChangeEvent>();
private readonly _logger: Log;
private readonly _githubServer: IGitHubServer;
private readonly _telemetryReporter: ExperimentationTelemetry;
private readonly _keychain: Keychain;
private readonly _accountsSeen = new Set<string>();
private readonly _disposable: vscode.Disposable | undefined;
private _keychain: Keychain = new Keychain(this.context, `${this.type}.auth`, this._logger);
private _sessionsPromise: Promise<vscode.AuthenticationSession[]>;
private _accountsSeen = new Set<string>();
private _disposable: vscode.Disposable;
constructor(private readonly context: vscode.ExtensionContext, private readonly type: AuthProviderType) {
constructor(
private readonly context: vscode.ExtensionContext,
uriHandler: UriEventHandler,
ghesUri?: vscode.Uri
) {
const { name, version, aiKey } = context.extension.packageJSON as { name: string; version: string; aiKey: string };
this._telemetryReporter = new ExperimentationTelemetry(context, new TelemetryReporter(name, version, aiKey));
const type = ghesUri ? AuthProviderType.githubEnterprise : AuthProviderType.github;
this._logger = new Log(type);
this._keychain = new Keychain(
this.context,
type === AuthProviderType.github
? `${type}.auth`
: `${ghesUri?.authority}${ghesUri?.path}.ghes.auth`,
this._logger);
this._githubServer = new GitHubServer(
this.type,
this._logger,
this._telemetryReporter,
uriHandler,
// We only can use the Device Code flow when we have a full node environment because of CORS.
context.extension.extensionKind === vscode.ExtensionKind.Workspace || vscode.env.uiKind === vscode.UIKind.Desktop,
this._logger,
this._telemetryReporter);
ghesUri);
// Contains the current state of the sessions we have available.
this._sessionsPromise = this.readSessions().then((sessions) => {
@@ -59,14 +81,13 @@ export class GitHubAuthenticationProvider implements vscode.AuthenticationProvid
this._disposable = vscode.Disposable.from(
this._telemetryReporter,
this._githubServer,
vscode.authentication.registerAuthenticationProvider(type, this._githubServer.friendlyName, this, { supportsMultipleAccounts: false }),
this.context.secrets.onDidChange(() => this.checkForUpdates())
);
}
dispose() {
this._disposable.dispose();
this._disposable?.dispose();
}
get onDidChangeSessions() {