Skip to content

Commit 0428a9d

Browse files
Merge pull request #16029 from openshift-cherrypick-robot/cherry-pick-15978-to-release-4.20
[release-4.20] OCPBUGS-76951: “Import from Git” should not force HTTPS/443 for Git providers (GitHub/GitLab/Bitbucket)
2 parents c5c94d5 + 411841a commit 0428a9d

9 files changed

Lines changed: 354 additions & 17 deletions

File tree

frontend/packages/git-service/src/services/__tests__/bitbucket-service.spec.ts

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,4 +294,87 @@ describe('Bitbucket Service', () => {
294294
nockDone();
295295
});
296296
});
297+
298+
it('should preserve scheme and port for Bitbucket Server API calls', async () => {
299+
const gitSource: GitSource = {
300+
url: 'http://bb.example.com:7990/scm/PROJ/repo.git',
301+
};
302+
const gitService = new BitbucketService(gitSource);
303+
304+
const scope = nock('http://bb.example.com:7990')
305+
.get('/rest/api/1.0/projects/PROJ/repos/repo')
306+
.reply(200, { slug: 'repo' });
307+
308+
const status = await gitService.isRepoReachable();
309+
expect(status).toEqual(RepoStatus.Reachable);
310+
scope.done();
311+
});
312+
313+
describe('getRepoMetadata - Protocol and Port Handling', () => {
314+
it('should use HTTPS protocol for standard Bitbucket URL', () => {
315+
const gitSource: GitSource = { url: 'https://bitbucket.org/owner/repo' };
316+
const gitService = new BitbucketService(gitSource);
317+
const metadata = gitService.getRepoMetadata();
318+
319+
expect(metadata.host).toBe('https://bitbucket.org');
320+
});
321+
322+
it('should preserve HTTP protocol', () => {
323+
const gitSource: GitSource = { url: 'http://bitbucket.example.com/owner/repo' };
324+
const gitService = new BitbucketService(gitSource);
325+
const metadata = gitService.getRepoMetadata();
326+
327+
expect(metadata.host).toBe('http://bitbucket.example.com');
328+
});
329+
330+
it('should preserve custom port with HTTPS', () => {
331+
const gitSource: GitSource = { url: 'https://bitbucket.example.com:8443/owner/repo' };
332+
const gitService = new BitbucketService(gitSource);
333+
const metadata = gitService.getRepoMetadata();
334+
335+
expect(metadata.host).toBe('https://bitbucket.example.com:8443');
336+
});
337+
338+
it('should preserve custom port with HTTP', () => {
339+
const gitSource: GitSource = { url: 'http://bitbucket.example.com:8080/owner/repo' };
340+
const gitService = new BitbucketService(gitSource);
341+
const metadata = gitService.getRepoMetadata();
342+
343+
expect(metadata.host).toBe('http://bitbucket.example.com:8080');
344+
});
345+
346+
it('should default to HTTPS for SSH URLs and preserve port', () => {
347+
const gitSource: GitSource = { url: 'git@bitbucket.example.com:2222/owner/repo.git' };
348+
const gitService = new BitbucketService(gitSource);
349+
const metadata = gitService.getRepoMetadata();
350+
351+
expect(metadata.host).toBe('https://bitbucket.example.com:2222');
352+
});
353+
354+
it('should default to HTTPS for git:// protocol URLs', () => {
355+
const gitSource: GitSource = { url: 'git://bitbucket.example.com/owner/repo.git' };
356+
const gitService = new BitbucketService(gitSource);
357+
const metadata = gitService.getRepoMetadata();
358+
359+
expect(metadata.host).toBe('https://bitbucket.example.com');
360+
});
361+
362+
it('should preserve non-standard port regardless of original protocol', () => {
363+
const gitSource: GitSource = { url: 'ssh://git@bitbucket.example.com:9999/owner/repo.git' };
364+
const gitService = new BitbucketService(gitSource);
365+
const metadata = gitService.getRepoMetadata();
366+
367+
expect(metadata.host).toBe('https://bitbucket.example.com:9999');
368+
});
369+
370+
it('should handle Bitbucket Server URL with custom port', () => {
371+
const gitSource: GitSource = {
372+
url: 'http://bb.example.com:7990/scm/proj/repo.git',
373+
};
374+
const gitService = new BitbucketService(gitSource);
375+
const metadata = gitService.getRepoMetadata();
376+
377+
expect(metadata.host).toBe('http://bb.example.com:7990');
378+
});
379+
});
297380
});

frontend/packages/git-service/src/services/__tests__/gitea-service.spec.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,4 +281,62 @@ describe('Gitea Service', () => {
281281
nockDone();
282282
});
283283
});
284+
285+
describe('getRepoMetadata - Protocol and Port Handling', () => {
286+
it('should use HTTPS protocol for standard Gitea URL', () => {
287+
const gitSource: GitSource = { url: 'https://gitea.com/owner/repo' };
288+
const gitService = new GiteaService(gitSource);
289+
const metadata = gitService.getRepoMetadata();
290+
291+
expect(metadata.host).toBe('https://gitea.com');
292+
});
293+
294+
it('should preserve HTTP protocol', () => {
295+
const gitSource: GitSource = { url: 'http://gitea.example.com/owner/repo' };
296+
const gitService = new GiteaService(gitSource);
297+
const metadata = gitService.getRepoMetadata();
298+
299+
expect(metadata.host).toBe('http://gitea.example.com');
300+
});
301+
302+
it('should preserve custom port with HTTPS', () => {
303+
const gitSource: GitSource = { url: 'https://gitea.example.com:8443/owner/repo' };
304+
const gitService = new GiteaService(gitSource);
305+
const metadata = gitService.getRepoMetadata();
306+
307+
expect(metadata.host).toBe('https://gitea.example.com:8443');
308+
});
309+
310+
it('should preserve custom port with HTTP', () => {
311+
const gitSource: GitSource = { url: 'http://gitea.example.com:8080/owner/repo' };
312+
const gitService = new GiteaService(gitSource);
313+
const metadata = gitService.getRepoMetadata();
314+
315+
expect(metadata.host).toBe('http://gitea.example.com:8080');
316+
});
317+
318+
it('should default to HTTPS for SSH URLs and preserve port', () => {
319+
const gitSource: GitSource = { url: 'git@gitea.example.com:2222/owner/repo.git' };
320+
const gitService = new GiteaService(gitSource);
321+
const metadata = gitService.getRepoMetadata();
322+
323+
expect(metadata.host).toBe('https://gitea.example.com:2222');
324+
});
325+
326+
it('should default to HTTPS for git:// protocol URLs', () => {
327+
const gitSource: GitSource = { url: 'git://gitea.example.com/owner/repo.git' };
328+
const gitService = new GiteaService(gitSource);
329+
const metadata = gitService.getRepoMetadata();
330+
331+
expect(metadata.host).toBe('https://gitea.example.com');
332+
});
333+
334+
it('should preserve non-standard port regardless of original protocol', () => {
335+
const gitSource: GitSource = { url: 'ssh://git@gitea.example.com:9999/owner/repo.git' };
336+
const gitService = new GiteaService(gitSource);
337+
const metadata = gitService.getRepoMetadata();
338+
339+
expect(metadata.host).toBe('https://gitea.example.com:9999');
340+
});
341+
});
284342
});

frontend/packages/git-service/src/services/__tests__/github-service.spec.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,17 @@ describe('Github Service', () => {
265265
scope.done();
266266
});
267267

268+
it('should preserve scheme and port when making API call to specified hostname', async () => {
269+
const gitSource: GitSource = { url: 'http://example.com:3000/test/repo' };
270+
const gitService = new GithubService(gitSource);
271+
272+
const scope = nock('http://example.com:3000/api/v3').get('/repos/test/repo').reply(200);
273+
274+
const status = await gitService.isRepoReachable();
275+
expect(status).toEqual(RepoStatus.Reachable);
276+
scope.done();
277+
});
278+
268279
it('should detect .tekton folder', () => {
269280
const gitSource = {
270281
url: 'https://github.com/Lucifergene/oc-pipe',
@@ -324,4 +335,62 @@ describe('Github Service', () => {
324335
nockDone();
325336
});
326337
});
338+
339+
describe('getRepoMetadata - Protocol and Port Handling', () => {
340+
it('should use HTTPS protocol for standard GitHub URL', () => {
341+
const gitSource: GitSource = { url: 'https://github.com/owner/repo' };
342+
const gitService = new GithubService(gitSource);
343+
const metadata = gitService.getRepoMetadata();
344+
345+
expect(metadata.host).toBe('https://github.com');
346+
});
347+
348+
it('should preserve HTTP protocol', () => {
349+
const gitSource: GitSource = { url: 'http://github.example.com/owner/repo' };
350+
const gitService = new GithubService(gitSource);
351+
const metadata = gitService.getRepoMetadata();
352+
353+
expect(metadata.host).toBe('http://github.example.com');
354+
});
355+
356+
it('should preserve custom port with HTTPS', () => {
357+
const gitSource: GitSource = { url: 'https://github.example.com:8443/owner/repo' };
358+
const gitService = new GithubService(gitSource);
359+
const metadata = gitService.getRepoMetadata();
360+
361+
expect(metadata.host).toBe('https://github.example.com:8443');
362+
});
363+
364+
it('should preserve custom port with HTTP', () => {
365+
const gitSource: GitSource = { url: 'http://github.example.com:8080/owner/repo' };
366+
const gitService = new GithubService(gitSource);
367+
const metadata = gitService.getRepoMetadata();
368+
369+
expect(metadata.host).toBe('http://github.example.com:8080');
370+
});
371+
372+
it('should default to HTTPS for SSH URLs and preserve port', () => {
373+
const gitSource: GitSource = { url: 'git@github.example.com:2222/owner/repo.git' };
374+
const gitService = new GithubService(gitSource);
375+
const metadata = gitService.getRepoMetadata();
376+
377+
expect(metadata.host).toBe('https://github.example.com:2222');
378+
});
379+
380+
it('should default to HTTPS for git:// protocol URLs', () => {
381+
const gitSource: GitSource = { url: 'git://github.example.com/owner/repo.git' };
382+
const gitService = new GithubService(gitSource);
383+
const metadata = gitService.getRepoMetadata();
384+
385+
expect(metadata.host).toBe('https://github.example.com');
386+
});
387+
388+
it('should preserve non-standard port regardless of original protocol', () => {
389+
const gitSource: GitSource = { url: 'ssh://git@github.example.com:9999/owner/repo.git' };
390+
const gitService = new GithubService(gitSource);
391+
const metadata = gitService.getRepoMetadata();
392+
393+
expect(metadata.host).toBe('https://github.example.com:9999');
394+
});
395+
});
327396
});

frontend/packages/git-service/src/services/__tests__/gitlab-service.spec.ts

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,4 +316,84 @@ describe('Gitlab Service', () => {
316316
expect(status).toEqual(RepoStatus.Reachable);
317317
scope.done();
318318
});
319+
320+
it('should preserve scheme and port when making API call to specified hostname', async () => {
321+
const gitSource: GitSource = { url: 'http://example.com:3000/test/repo' };
322+
const gitService = new GitlabService(gitSource);
323+
324+
const scope = nock('http://example.com:3000/api/v4')
325+
.get('/projects/test%2Frepo')
326+
// eslint-disable-next-line @typescript-eslint/naming-convention
327+
.reply(200, { path_with_namespace: 'test/repo' });
328+
329+
const status = await gitService.isRepoReachable();
330+
expect(status).toEqual(RepoStatus.Reachable);
331+
scope.done();
332+
});
333+
334+
describe('getRepoMetadata - Protocol and Port Handling', () => {
335+
it('should use HTTPS protocol for standard GitLab URL', () => {
336+
const gitSource: GitSource = { url: 'https://gitlab.com/owner/repo' };
337+
const gitService = new GitlabService(gitSource);
338+
const metadata = gitService.getRepoMetadata();
339+
340+
expect(metadata.host).toBe('https://gitlab.com');
341+
});
342+
343+
it('should preserve HTTP protocol', () => {
344+
const gitSource: GitSource = { url: 'http://gitlab.example.com/owner/repo' };
345+
const gitService = new GitlabService(gitSource);
346+
const metadata = gitService.getRepoMetadata();
347+
348+
expect(metadata.host).toBe('http://gitlab.example.com');
349+
});
350+
351+
it('should preserve custom port with HTTPS', () => {
352+
const gitSource: GitSource = { url: 'https://gitlab.example.com:8443/owner/repo' };
353+
const gitService = new GitlabService(gitSource);
354+
const metadata = gitService.getRepoMetadata();
355+
356+
expect(metadata.host).toBe('https://gitlab.example.com:8443');
357+
});
358+
359+
it('should preserve custom port with HTTP', () => {
360+
const gitSource: GitSource = { url: 'http://gitlab.example.com:8080/owner/repo' };
361+
const gitService = new GitlabService(gitSource);
362+
const metadata = gitService.getRepoMetadata();
363+
364+
expect(metadata.host).toBe('http://gitlab.example.com:8080');
365+
});
366+
367+
it('should default to HTTPS for SSH URLs and preserve port', () => {
368+
const gitSource: GitSource = { url: 'git@gitlab.example.com:2222/owner/repo.git' };
369+
const gitService = new GitlabService(gitSource);
370+
const metadata = gitService.getRepoMetadata();
371+
372+
expect(metadata.host).toBe('https://gitlab.example.com:2222');
373+
});
374+
375+
it('should default to HTTPS for git:// protocol URLs', () => {
376+
const gitSource: GitSource = { url: 'git://gitlab.example.com/owner/repo.git' };
377+
const gitService = new GitlabService(gitSource);
378+
const metadata = gitService.getRepoMetadata();
379+
380+
expect(metadata.host).toBe('https://gitlab.example.com');
381+
});
382+
383+
it('should preserve non-standard port regardless of original protocol', () => {
384+
const gitSource: GitSource = { url: 'ssh://git@gitlab.example.com:9999/owner/repo.git' };
385+
const gitService = new GitlabService(gitSource);
386+
const metadata = gitService.getRepoMetadata();
387+
388+
expect(metadata.host).toBe('https://gitlab.example.com:9999');
389+
});
390+
391+
it('should handle subdomains with custom port', () => {
392+
const gitSource: GitSource = { url: 'https://version.helsinki.fi:3000/owner/repo' };
393+
const gitService = new GitlabService(gitSource);
394+
const metadata = gitService.getRepoMetadata();
395+
396+
expect(metadata.host).toBe('https://version.helsinki.fi:3000');
397+
});
398+
});
319399
});

frontend/packages/git-service/src/services/bitbucket-service.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
import * as GitUrlParse from 'git-url-parse';
12
import { Base64 } from 'js-base64';
2-
import * as ParseBitbucketUrl from 'parse-bitbucket-url';
33
import { consoleFetchJSON } from '@console/dynamic-plugin-sdk/src/lib-core';
44
import { DevConsoleEndpointResponse } from '@console/shared/src';
55
import {
@@ -41,8 +41,8 @@ export class BitbucketService extends BaseService {
4141
constructor(gitsource: GitSource) {
4242
super(gitsource);
4343
this.metadata = this.getRepoMetadata();
44-
if (this.metadata.host !== 'bitbucket.org') {
45-
this.baseURL = `https://${this.metadata.host}/rest/api/1.0`;
44+
if (!this.metadata.host.includes('bitbucket.org')) {
45+
this.baseURL = `${this.metadata.host}/rest/api/1.0`;
4646
this.isServer = true;
4747
}
4848
}
@@ -88,8 +88,14 @@ export class BitbucketService extends BaseService {
8888
};
8989

9090
getRepoMetadata = (): RepoMetadata => {
91-
const { name, owner, host } = ParseBitbucketUrl(this.gitsource.url);
91+
const { name, owner, resource, protocols, port } = GitUrlParse(this.gitsource.url);
9292
const contextDir = this.gitsource.contextDir?.replace(/\/$/, '') || '';
93+
const rawProtocol = protocols?.[0];
94+
const isHttpProtocol = rawProtocol === 'http' || rawProtocol === 'https';
95+
const protocol = isHttpProtocol ? rawProtocol : 'https';
96+
97+
const host = port ? `${protocol}://${resource}:${port}` : `${protocol}://${resource}`;
98+
9399
return {
94100
repoName: name,
95101
owner,

frontend/packages/git-service/src/services/gitea-service.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,16 @@ export class GiteaService extends BaseService {
6262
};
6363

6464
getRepoMetadata = (): RepoMetadata => {
65-
const { name, owner, resource, full_name: fullName } = GitUrlParse(this.gitsource.url);
65+
const { name, owner, resource, protocols, port, full_name: fullName } = GitUrlParse(
66+
this.gitsource.url,
67+
);
6668
const contextDir = this.gitsource.contextDir?.replace(/\/$/, '') || '';
67-
const host = `https://${resource}`;
69+
const rawProtocol = protocols?.[0];
70+
const isHttpProtocol = rawProtocol === 'http' || rawProtocol === 'https';
71+
const protocol = isHttpProtocol ? rawProtocol : 'https';
72+
73+
const host = port ? `${protocol}://${resource}:${port}` : `${protocol}://${resource}`;
74+
6875
return {
6976
repoName: name,
7077
owner,

0 commit comments

Comments
 (0)