Skip to content

Commit

Permalink
Adds basic providers api integration
Browse files Browse the repository at this point in the history
Adds filtering support on inputs

Improves types and adds getCurrentUser support

Updates getCurrentUser Fns

Adds GetReposFn for Azure

Reorganizes types and constants

Adds  providers service

Uses correct filter property for Bitbucket PRs

Switches to logged errors

Adds filter compatibility check

Adds paging and per-repo PR/Issue support

Uses PagedResult for paging

Updates dependencies

Updates dependency

Reorganizes and moves provider service logic to providerIntegration

Updates missing provider mappings, ProviderId usage

Updates provider api dependency

Adds enterprise domain passing and GLSH

Uses the correct base api urls

Updates dependency
  • Loading branch information
axosoft-ramint committed Nov 16, 2023
1 parent a338e59 commit c1d692d
Show file tree
Hide file tree
Showing 18 changed files with 2,157 additions and 214 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15761,6 +15761,7 @@
},
"dependencies": {
"@gitkraken/gitkraken-components": "10.2.5",
"@gitkraken/provider-apis": "0.10.0",
"@gitkraken/shared-web-components": "0.1.1-rc.15",
"@lit/react": "1.0.1",
"@microsoft/fast-element": "1.12.0",
Expand Down
8 changes: 6 additions & 2 deletions src/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ import { Commands, extensionPrefix } from './constants';
import { EventBus } from './eventBus';
import { GitFileSystemProvider } from './git/fsProvider';
import { GitProviderService } from './git/gitProviderService';
import { GitHubAuthenticationProvider } from './git/remotes/github';
import { GitLabAuthenticationProvider } from './git/remotes/gitlab';
import { RichRemoteProviderService } from './git/remotes/remoteProviderService';
import { LineHoverController } from './hovers/lineHoverController';
import type { RepositoryPathMappingProvider } from './pathMapping/repositoryPathMappingProvider';
Expand All @@ -26,6 +24,10 @@ import { FocusService } from './plus/focus/focusService';
import { AccountAuthenticationProvider } from './plus/gk/account/authenticationProvider';
import { SubscriptionService } from './plus/gk/account/subscriptionService';
import { ServerConnection } from './plus/gk/serverConnection';
import { AzureDevOpsAuthenticationProvider } from './plus/integrations/authentication/azureDevOps';
import { BitbucketAuthenticationProvider } from './plus/integrations/authentication/bitbucket';
import { GitHubAuthenticationProvider } from './plus/integrations/authentication/github';
import { GitLabAuthenticationProvider } from './plus/integrations/authentication/gitlab';
import { IntegrationAuthenticationService } from './plus/integrations/authentication/integrationAuthentication';
import { ProviderIntegrationService } from './plus/integrations/providers/providerIntegrationService';
import { RepositoryIdentityService } from './plus/repos/repositoryIdentityService';
Expand Down Expand Up @@ -564,6 +566,8 @@ export class Container {
// Register any integration authentication providers
new GitHubAuthenticationProvider(this),
new GitLabAuthenticationProvider(this),
new AzureDevOpsAuthenticationProvider(this),
new BitbucketAuthenticationProvider(this),
);
}

Expand Down
96 changes: 4 additions & 92 deletions src/git/remotes/github.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
import type { AuthenticationSession, Disposable, QuickInputButton, Range } from 'vscode';
import { env, ThemeIcon, Uri, window } from 'vscode';
import type { AuthenticationSession, Range } from 'vscode';
import { Uri } from 'vscode';
import type { Autolink, DynamicAutolinkReference, MaybeEnrichedAutolink } from '../../annotations/autolinks';
import type { AutolinkReference } from '../../config';
import { GlyphChars } from '../../constants';
import type { Container } from '../../container';
import type { GkProviderId } from '../../gk/models/repositoryIdentities';
import type {
IntegrationAuthenticationProvider,
IntegrationAuthenticationSessionDescriptor,
} from '../../plus/integrations/authentication/integrationAuthentication';
import type { GitHubRepositoryDescriptor } from '../../plus/integrations/providers/github';
import { ProviderId } from '../../plus/integrations/providers/models';
import type { ProviderIntegration, RepositoryDescriptor } from '../../plus/integrations/providers/providerIntegration';
import type { Brand, Unbrand } from '../../system/brand';
import { fromNow } from '../../system/date';
import { log } from '../../system/decorators/log';
import { memoize } from '../../system/decorators/memoize';
import { encodeUrl } from '../../system/encoding';
import { equalsIgnoreCase, escapeMarkdown, unescapeMarkdown } from '../../system/string';
import { supportedInVSCodeVersion } from '../../system/utils';
import type { Account } from '../models/author';
import type { DefaultBranch } from '../models/defaultBranch';
import type { IssueOrPullRequest, SearchedIssue } from '../models/issue';
Expand Down Expand Up @@ -59,7 +55,7 @@ export class GitHubRemote extends RichRemoteProvider<GitHubRepositoryDescriptor>
) {
super(container, domain, path, protocol, name, custom);

this._provider = container.providers.get(custom ? 'github-enterprise' : 'github', domain);
this._provider = container.providers.get(custom ? ProviderId.GitHubEnterprise : ProviderId.GitHub, domain);
}

get apiBaseUrl() {
Expand Down Expand Up @@ -533,87 +529,3 @@ export function getGitHubNoReplyAddressParts(
const [, userId, login, authority] = match;
return { userId: userId, login: login, authority: authority };
}

export class GitHubAuthenticationProvider implements Disposable, IntegrationAuthenticationProvider {
private readonly _disposable: Disposable;

constructor(container: Container) {
this._disposable = container.integrationAuthentication.registerProvider('github-enterprise', this);
}

dispose() {
this._disposable.dispose();
}

getSessionId(descriptor?: IntegrationAuthenticationSessionDescriptor): string {
return descriptor?.domain ?? '';
}

async createSession(
descriptor?: IntegrationAuthenticationSessionDescriptor,
): Promise<AuthenticationSession | undefined> {
const input = window.createInputBox();
input.ignoreFocusOut = true;

const disposables: Disposable[] = [];

let token;
try {
const infoButton: QuickInputButton = {
iconPath: new ThemeIcon(`link-external`),
tooltip: 'Open the GitHub Access Tokens Page',
};

token = await new Promise<string | undefined>(resolve => {
disposables.push(
input.onDidHide(() => resolve(undefined)),
input.onDidChangeValue(() => (input.validationMessage = undefined)),
input.onDidAccept(() => {
const value = input.value.trim();
if (!value) {
input.validationMessage = 'A personal access token is required';
return;
}

resolve(value);
}),
input.onDidTriggerButton(e => {
if (e === infoButton) {
void env.openExternal(
Uri.parse(`https://${descriptor?.domain ?? 'github.com'}/settings/tokens`),
);
}
}),
);

input.password = true;
input.title = `GitHub Authentication${descriptor?.domain ? ` \u2022 ${descriptor.domain}` : ''}`;
input.placeholder = `Requires ${descriptor?.scopes.join(', ') ?? 'all'} scopes`;
input.prompt = supportedInVSCodeVersion('input-prompt-links')
? `Paste your [GitHub Personal Access Token](https://${
descriptor?.domain ?? 'github.com'
}/settings/tokens "Get your GitHub Access Token")`
: 'Paste your GitHub Personal Access Token';

input.buttons = [infoButton];

input.show();
});
} finally {
input.dispose();
disposables.forEach(d => void d.dispose());
}

if (!token) return undefined;

return {
id: this.getSessionId(descriptor),
accessToken: token,
scopes: [],
account: {
id: '',
label: '',
},
};
}
}
93 changes: 1 addition & 92 deletions src/git/remotes/gitlab.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
import type { AuthenticationSession, Disposable, QuickInputButton, Range } from 'vscode';
import { env, ThemeIcon, Uri, window } from 'vscode';
import type { AuthenticationSession, Range, Uri } from 'vscode';
import type { Autolink, DynamicAutolinkReference, MaybeEnrichedAutolink } from '../../annotations/autolinks';
import type { AutolinkReference } from '../../config';
import { GlyphChars } from '../../constants';
import type { Container } from '../../container';
import type { GkProviderId } from '../../gk/models/repositoryIdentities';
import type {
IntegrationAuthenticationProvider,
IntegrationAuthenticationSessionDescriptor,
} from '../../plus/integrations/authentication/integrationAuthentication';
import type { Brand, Unbrand } from '../../system/brand';
import { fromNow } from '../../system/date';
import { log } from '../../system/decorators/log';
import { encodeUrl } from '../../system/encoding';
import { equalsIgnoreCase, escapeMarkdown, unescapeMarkdown } from '../../system/string';
import { supportedInVSCodeVersion } from '../../system/utils';
import type { Account } from '../models/author';
import type { DefaultBranch } from '../models/defaultBranch';
import type { IssueOrPullRequest, SearchedIssue } from '../models/issue';
Expand Down Expand Up @@ -508,88 +502,3 @@ export class GitLabRemote extends RichRemoteProvider<GitLabRepositoryDescriptor>
return Promise.resolve(undefined);
}
}

export class GitLabAuthenticationProvider implements Disposable, IntegrationAuthenticationProvider {
private readonly _disposable: Disposable;

constructor(container: Container) {
this._disposable = container.integrationAuthentication.registerProvider('gitlab', this);
}

dispose() {
this._disposable.dispose();
}

getSessionId(descriptor?: IntegrationAuthenticationSessionDescriptor): string {
return descriptor?.domain ?? '';
}

async createSession(
descriptor?: IntegrationAuthenticationSessionDescriptor,
): Promise<AuthenticationSession | undefined> {
const input = window.createInputBox();
input.ignoreFocusOut = true;

const disposables: Disposable[] = [];

let token;
try {
const infoButton: QuickInputButton = {
iconPath: new ThemeIcon(`link-external`),
tooltip: 'Open the GitLab Access Tokens Page',
};

token = await new Promise<string | undefined>(resolve => {
disposables.push(
input.onDidHide(() => resolve(undefined)),
input.onDidChangeValue(() => (input.validationMessage = undefined)),
input.onDidAccept(() => {
const value = input.value.trim();
if (!value) {
input.validationMessage = 'A personal access token is required';
return;
}

resolve(value);
}),
input.onDidTriggerButton(e => {
if (e === infoButton) {
void env.openExternal(
Uri.parse(
`https://${descriptor?.domain ?? 'gitlab.com'}/-/profile/personal_access_tokens`,
),
);
}
}),
);

input.password = true;
input.title = `GitLab Authentication${descriptor?.domain ? ` \u2022 ${descriptor.domain}` : ''}`;
input.placeholder = `Requires ${descriptor?.scopes.join(', ') ?? 'all'} scopes`;
input.prompt = input.prompt = supportedInVSCodeVersion('input-prompt-links')
? `Paste your [GitLab Personal Access Token](https://${
descriptor?.domain ?? 'gitlab.com'
}/-/profile/personal_access_tokens "Get your GitLab Access Token")`
: 'Paste your GitLab Personal Access Token';
input.buttons = [infoButton];

input.show();
});
} finally {
input.dispose();
disposables.forEach(d => void d.dispose());
}

if (!token) return undefined;

return {
id: this.getSessionId(descriptor),
accessToken: token,
scopes: [],
account: {
id: '',
label: '',
},
};
}
}
Loading

0 comments on commit c1d692d

Please sign in to comment.