Skip to content

Commit ad66981

Browse files
committed
wip
1 parent 1cfbf1a commit ad66981

7 files changed

+274
-182
lines changed

components/server/src/bitbucket-server/bitbucket-api-factory.ts

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
*/
66

77
import { User, Token } from "@gitpod/gitpod-protocol";
8-
import { APIClient, Bitbucket } from "bitbucket";
98
import { inject, injectable } from "inversify";
109
import { AuthProviderParams } from "../auth/auth-provider";
1110
import { BitbucketTokenHelper } from "../bitbucket/bitbucket-token-handler";
11+
import * as BitbucketServer from "@atlassian/bitbucket-server";
1212

1313
@injectable()
1414
export class BitbucketServerApiFactory {
@@ -20,35 +20,40 @@ export class BitbucketServerApiFactory {
2020
* Returns a Bitbucket API client for the given user.
2121
* @param user The user the API client should be created for.
2222
*/
23-
public async create(user: User): Promise<APIClient> {
23+
public async create(user: User): Promise<BitbucketServer> {
2424
const token = await this.tokenHelper.getTokenWithScopes(user, []);
2525
return this.createBitbucket(this.baseUrl, token);
2626
}
2727

28-
protected createBitbucket(baseUrl: string, token: Token): APIClient {
29-
return new Bitbucket({
28+
protected createBitbucket(baseUrl: string, token: Token): BitbucketServer {
29+
const options = {
3030
baseUrl,
31-
auth: {
32-
token: token.value
33-
}
34-
});
31+
};
32+
const client = new BitbucketServer(options);
33+
client.authenticate({
34+
type: "token",
35+
token: token.value
36+
})
37+
return client;
3538
}
3639

3740
protected get baseUrl(): string {
38-
return `https://api.${this.config.host}/2.0`;
41+
return `https://${this.config.host}/rest/api/1.0`;
3942
}
4043
}
4144

4245
@injectable()
4346
export class BasicAuthBitbucketServerApiFactory extends BitbucketServerApiFactory {
44-
protected createBitbucket(baseUrl: string, token: Token): APIClient {
45-
46-
return new Bitbucket({
47+
protected createBitbucket(baseUrl: string, token: Token): BitbucketServer {
48+
const options = {
4749
baseUrl,
48-
auth: {
49-
username: token.username!,
50-
password: token.value
51-
}
52-
});
50+
};
51+
const client = new BitbucketServer(options);
52+
client.authenticate({
53+
type: "basic",
54+
username: token.username || "nobody",
55+
password: token.value
56+
})
57+
return client;
5358
}
5459
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/**
2+
* Copyright (c) 2022 Gitpod GmbH. All rights reserved.
3+
* Licensed under the GNU Affero General Public License (AGPL).
4+
* See License-AGPL.txt in the project root for license information.
5+
*/
6+
7+
8+
declare namespace BitbucketServer {
9+
10+
export namespace Schema {
11+
export interface Repository {
12+
id: number;
13+
slug: string;
14+
name: string;
15+
public: boolean;
16+
links: {
17+
clone: {
18+
href: string;
19+
name: string;
20+
}[]
21+
}
22+
project: Project;
23+
}
24+
25+
export interface Project {
26+
key: string;
27+
id: number;
28+
name: string;
29+
public: boolean;
30+
}
31+
}
32+
}
33+
34+
35+
// {
36+
// "slug": "test123",
37+
// "id": 3,
38+
// "name": "test123",
39+
// "hierarchyId": "670d2b6499d312c9deb8",
40+
// "scmId": "git",
41+
// "state": "AVAILABLE",
42+
// "statusMessage": "Available",
43+
// "forkable": true,
44+
// "project": {
45+
// "key": "JLDEC",
46+
// "id": 2,
47+
// "name": "jldec-project",
48+
// "public": false,
49+
// "type": "NORMAL",
50+
// "links": {
51+
// "self": ...
52+
// }
53+
// },
54+
// "public": false,
55+
// "links": {
56+
// "clone": [
57+
// ...,
58+
// {
59+
// "href": "https://bitbucket.gitpod-self-hosted.com/scm/jldec/test123.git",
60+
// "name": "http"
61+
// }
62+
// ],
63+
// "self": ...
64+
// }
65+
// }
66+
67+
68+
69+
// {
70+
// "name": "roboquat",
71+
// "emailAddress": "[email protected]",
72+
// "id": 102,
73+
// "displayName": "Robot Kumquat",
74+
// "active": true,
75+
// "slug": "roboquat",
76+
// "type": "NORMAL",
77+
// "links": {
78+
// "self": [
79+
// {
80+
// "href": "https://bitbucket.gitpod-self-hosted.com/users/roboquat"
81+
// }
82+
// ]
83+
// }
84+
// }

components/server/src/bitbucket-server/bitbucket-server-auth-provider.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright (c) 2021 Gitpod GmbH. All rights reserved.
2+
* Copyright (c) 2022 Gitpod GmbH. All rights reserved.
33
* Licensed under the GNU Affero General Public License (AGPL).
44
* See License-AGPL.txt in the project root for license information.
55
*/
@@ -12,7 +12,7 @@ import fetch from "node-fetch";
1212
import { AuthUserSetup } from "../auth/auth-provider";
1313
import { GenericAuthProvider } from "../auth/generic-auth-provider";
1414
import { BitbucketServerOAuthScopes } from "./bitbucket-server-oauth-scopes";
15-
import BitbucketServer = require("@atlassian/bitbucket-server")
15+
import * as BitbucketServer from "@atlassian/bitbucket-server";
1616

1717
@injectable()
1818
export class BitbucketServerAuthProvider extends GenericAuthProvider {
@@ -94,7 +94,7 @@ export class BitbucketServerAuthProvider extends GenericAuthProvider {
9494
return <AuthUserSetup>{
9595
authUser: {
9696
authId: `${user.id!}`,
97-
authName: user.name!,
97+
authName: user.slug!,
9898
primaryEmail: user.emailAddress!,
9999
name: user.displayName!,
100100
// avatarUrl: user.links!.avatar!.href // TODO

components/server/src/bitbucket-server/bitbucket-server-context-parser.ts

Lines changed: 59 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import { NavigatorContext, Repository, User, WorkspaceContext } from "@gitpod/gitpod-protocol";
88
import { log } from "@gitpod/gitpod-protocol/lib/util/logging";
99
import { TraceContext } from "@gitpod/gitpod-protocol/lib/util/tracing";
10-
import { Schema } from "bitbucket";
10+
import { Schema } from "@atlassian/bitbucket-server";
1111
import { inject, injectable } from "inversify";
1212
import { BitbucketTokenHelper } from "../bitbucket/bitbucket-token-handler";
1313
import { NotFoundError } from "../errors";
@@ -47,34 +47,36 @@ export class BitbucketServerContextParser extends AbstractContextParser implemen
4747
return undefined;
4848
}
4949

50-
protected async isValidCommitHash(user: User, owner: string, repoName: string, potentialCommitHash: string) {
51-
if (potentialCommitHash.length !== 40) {
52-
return false;
53-
}
50+
// protected async isValidCommitHash(user: User, owner: string, repoName: string, potentialCommitHash: string) {
51+
// if (potentialCommitHash.length !== 40) {
52+
// return false;
53+
// }
54+
// try {
55+
// const api = await this.api(user);
56+
// const result = (await api.repositories.getCommit({ workspace: owner, repo_slug: repoName, commit: potentialCommitHash }));
57+
// return result.data.hash === potentialCommitHash;
58+
// } catch {
59+
// return false;
60+
// }
61+
// }
62+
63+
// protected async isTag(user: User, owner: string, repoName: string, potentialTag: string) {
64+
// try {
65+
// const api = await this.api(user);
66+
// const result = (await api.repositories.getTag({ workspace: owner, repo_slug: repoName, name: potentialTag }));
67+
// return result.data.name === potentialTag;
68+
// } catch {
69+
// return false;
70+
// }
71+
// }
72+
73+
protected async handleNavigatorContext(ctx: TraceContext, user: User, host: string, owner: string, repoName: string, more: Partial<NavigatorContext> = {}): Promise<NavigatorContext> {
74+
const span = TraceContext.startSpan("BitbucketServerContextParser.handleNavigatorContext", ctx);
5475
try {
5576
const api = await this.api(user);
56-
const result = (await api.repositories.getCommit({ workspace: owner, repo_slug: repoName, commit: potentialCommitHash }));
57-
return result.data.hash === potentialCommitHash;
58-
} catch {
59-
return false;
60-
}
61-
}
6277

63-
protected async isTag(user: User, owner: string, repoName: string, potentialTag: string) {
64-
try {
65-
const api = await this.api(user);
66-
const result = (await api.repositories.getTag({ workspace: owner, repo_slug: repoName, name: potentialTag }));
67-
return result.data.name === potentialTag;
68-
} catch {
69-
return false;
70-
}
71-
}
78+
const repo = (await api.repos.getRepository({projectKey: owner, repositorySlug: repoName})).data;
7279

73-
protected async handleNavigatorContext(ctx: TraceContext, user: User, host: string, owner: string, repoName: string, more: Partial<NavigatorContext> = {}, givenRepo?: Schema.Repository): Promise<NavigatorContext> {
74-
const span = TraceContext.startSpan("BitbucketServerContextParser.handleNavigatorContext", ctx);
75-
try {
76-
const api = await this.api(user);
77-
const repo = givenRepo || (await api.repositories.get({ workspace: owner, repo_slug: repoName })).data;
7880
const repository = await this.toRepository(user, host, repo);
7981
span.log({ "request.finished": "" });
8082

@@ -87,24 +89,24 @@ export class BitbucketServerContextParser extends AbstractContextParser implemen
8789
}
8890
more.refType = more.refType || "branch";
8991

90-
if (!more.revision) {
91-
const commits = (await api.repositories.listCommitsAt({ workspace: owner, repo_slug: repoName, revision: more.ref!, pagelen: 1 })).data;
92-
more.revision = commits.values && commits.values.length > 0 ? commits.values[0].hash : "";
93-
if ((!commits.values || commits.values.length === 0) && more.ref === repository.defaultBranch) {
94-
// empty repo
95-
more.ref = undefined;
96-
more.revision = "";
97-
more.refType = undefined;
98-
}
99-
}
100-
101-
if (!more.path) {
102-
more.isFile = false;
103-
more.path = "";
104-
} else if (more.isFile === undefined) {
105-
const fileMeta = (await api.repositories.readSrc({ workspace: owner, repo_slug: repoName, format: "meta", commit: more.revision!, path: more.path!, pagelen: 1 })).data;
106-
more.isFile = (fileMeta as any).type === "commit_file";
107-
}
92+
// if (!more.revision) {
93+
// const commits = (await api.repositories.listCommitsAt({ workspace: owner, repo_slug: repoName, revision: more.ref!, pagelen: 1 })).data;
94+
// more.revision = commits.values && commits.values.length > 0 ? commits.values[0].hash : "";
95+
// if ((!commits.values || commits.values.length === 0) && more.ref === repository.defaultBranch) {
96+
// // empty repo
97+
// more.ref = undefined;
98+
// more.revision = "";
99+
// more.refType = undefined;
100+
// }
101+
// }
102+
103+
// if (!more.path) {
104+
// more.isFile = false;
105+
// more.path = "";
106+
// } else if (more.isFile === undefined) {
107+
// const fileMeta = (await api.repositories.readSrc({ workspace: owner, repo_slug: repoName, format: "meta", commit: more.revision!, path: more.path!, pagelen: 1 })).data;
108+
// more.isFile = (fileMeta as any).type === "commit_file";
109+
// }
108110

109111
return {
110112
...more,
@@ -125,27 +127,26 @@ export class BitbucketServerContextParser extends AbstractContextParser implemen
125127
if (!repo) {
126128
throw new Error('Unknown repository.');
127129
}
128-
// full_name: string
129-
// The concatenation of the repository owner's username and the slugified name, e.g. "evzijst/interruptingcow". This is the same string used in Bitbucket URLs.
130-
const fullName = repo.full_name!.split("/");
131-
const owner = fullName[0];
132-
const name = fullName[1];
130+
131+
const owner = repo.project.key;
132+
const name = repo.name;
133+
const cloneUrl = repo.links.clone.find(u => u.name === "http")?.href!;
133134

134135
const result: Repository = {
135-
cloneUrl: `https://${host}/${repo.full_name}.git`,
136+
cloneUrl,
136137
host,
137138
name,
138139
owner,
139-
private: !!repo.isPrivate,
140-
defaultBranch: repo.mainbranch ? repo.mainbranch.name : DEFAULT_BRANCH,
141-
}
142-
if (!!repo.parent && !!repo.parent.full_name) {
143-
const api = await this.api(user);
144-
const parentRepo = (await api.repositories.get({ workspace: repo.parent!.full_name!.split("/")[0], repo_slug: repo.parent!.full_name!.split("/")[1] })).data;
145-
result.fork = {
146-
parent: await this.toRepository(user, host, parentRepo)
147-
};
140+
private: !repo.public,
141+
defaultBranch: DEFAULT_BRANCH,
148142
}
143+
// if (!!repo.parent && !!repo.parent.full_name) {
144+
// const api = await this.api(user);
145+
// const parentRepo = (await api.repositories.get({ workspace: repo.parent!.full_name!.split("/")[0], repo_slug: repo.parent!.full_name!.split("/")[1] })).data;
146+
// result.fork = {
147+
// parent: await this.toRepository(user, host, parentRepo)
148+
// };
149+
// }
149150

150151
return result;
151152
}

0 commit comments

Comments
 (0)