Skip to content

Commit 4484109

Browse files
committed
fix
1 parent ece56eb commit 4484109

File tree

12 files changed

+238
-50
lines changed

12 files changed

+238
-50
lines changed

components/gitpod-protocol/go/gitpod-service.go

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ type APIInterface interface {
4242
GetWorkspaceOwner(ctx context.Context, workspaceID string) (res *UserInfo, err error)
4343
GetWorkspaceUsers(ctx context.Context, workspaceID string) (res []*WorkspaceInstanceUser, err error)
4444
GetFeaturedRepositories(ctx context.Context) (res []*WhitelistedRepository, err error)
45-
GetSuggestedContextURLs(ctx context.Context) (res []*string, err error)
4645
GetWorkspace(ctx context.Context, id string) (res *WorkspaceInfo, err error)
4746
GetIDEOptions(ctx context.Context) (res *IDEOptions, err error)
4847
IsWorkspaceOwner(ctx context.Context, workspaceID string) (res bool, err error)
@@ -147,8 +146,6 @@ const (
147146
FunctionGetWorkspaceUsers FunctionName = "getWorkspaceUsers"
148147
// FunctionGetFeaturedRepositories is the name of the getFeaturedRepositories function
149148
FunctionGetFeaturedRepositories FunctionName = "getFeaturedRepositories"
150-
// FunctionGetSuggestedContextURLs is the name of the getSuggestedContextURLs function
151-
FunctionGetSuggestedContextURLs FunctionName = "getSuggestedContextURLs"
152149
// FunctionGetWorkspace is the name of the getWorkspace function
153150
FunctionGetWorkspace FunctionName = "getWorkspace"
154151
// FunctionGetIDEOptions is the name of the getIDEOptions function
@@ -1057,24 +1054,6 @@ func (gp *APIoverJSONRPC) ClosePort(ctx context.Context, workspaceID string, por
10571054
return
10581055
}
10591056

1060-
// GetSuggestedContextURLs calls getSuggestedContextURLs on the server
1061-
func (gp *APIoverJSONRPC) GetSuggestedContextURLs(ctx context.Context) (res []*string, err error) {
1062-
if gp == nil {
1063-
err = errNotConnected
1064-
return
1065-
}
1066-
var _params []interface{}
1067-
1068-
var result []*string
1069-
err = gp.C.Call(ctx, "getSuggestedContextURLs", _params, &result)
1070-
if err != nil {
1071-
return
1072-
}
1073-
res = result
1074-
1075-
return
1076-
}
1077-
10781057
// UpdateGitStatus calls UpdateGitStatus on the server
10791058
func (gp *APIoverJSONRPC) UpdateGitStatus(ctx context.Context, workspaceID string, status *WorkspaceInstanceRepoStatus) (err error) {
10801059
if gp == nil {

components/gitpod-protocol/go/mock.go

Lines changed: 0 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

components/gitpod-protocol/src/analytics.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,7 @@
66

77
export const IAnalyticsWriter = Symbol("IAnalyticsWriter");
88

9-
type Identity =
10-
| { userId: string | number; anonymousId?: string | number }
11-
| { userId?: string | number; anonymousId: string | number };
9+
type Identity = { userId?: string | number; anonymousId?: string | number; subjectId?: string };
1210

1311
interface Message {
1412
messageId?: string;
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
/**
2+
* Copyright (c) 2023 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+
import { AuthProviderType } from "@gitpod/public-api/lib/gitpod/v1/authprovider_pb";
8+
9+
export namespace GitLabScope {
10+
export const READ_USER = "read_user";
11+
export const API = "api";
12+
export const READ_REPO = "read_repository";
13+
14+
export const ALL = [READ_USER, API, READ_REPO];
15+
/**
16+
* Minimal required permission.
17+
* GitLab API usage requires the permission of a user.
18+
*/
19+
export const DEFAULT = [READ_USER, API];
20+
export const REPO = [API, READ_REPO];
21+
}
22+
23+
export namespace GitHubScope {
24+
export const EMAIL = "user:email";
25+
export const READ_USER = "read:user";
26+
export const PUBLIC = "public_repo";
27+
export const PRIVATE = "repo";
28+
export const ORGS = "read:org";
29+
export const WORKFLOW = "workflow";
30+
31+
export const ALL = [EMAIL, READ_USER, PUBLIC, PRIVATE, ORGS, WORKFLOW];
32+
export const DEFAULT = ALL;
33+
export const PUBLIC_REPO = ALL;
34+
export const PRIVATE_REPO = ALL;
35+
}
36+
37+
export namespace BitbucketOAuthScopes {
38+
// https://confluence.atlassian.com/bitbucket/oauth-on-bitbucket-cloud-238027431.html
39+
40+
/** Read user info like name, e-mail adresses etc. */
41+
export const ACCOUNT_READ = "account";
42+
/** Access repo info, clone repo over https, read and write issues */
43+
export const REPOSITORY_READ = "repository";
44+
/** Push over https, fork repo */
45+
export const REPOSITORY_WRITE = "repository:write";
46+
/** Lists and read pull requests */
47+
export const PULL_REQUEST_READ = "pullrequest";
48+
/** Create, comment and merge pull requests */
49+
export const PULL_REQUEST_WRITE = "pullrequest:write";
50+
/** Create, list web hooks */
51+
export const WEBHOOK = "webhook";
52+
53+
export const ALL = [
54+
ACCOUNT_READ,
55+
REPOSITORY_READ,
56+
REPOSITORY_WRITE,
57+
PULL_REQUEST_READ,
58+
PULL_REQUEST_WRITE,
59+
WEBHOOK,
60+
];
61+
62+
export const DEFAULT = ALL;
63+
}
64+
65+
export namespace BitbucketServerOAuthScopes {
66+
// https://confluence.atlassian.com/bitbucketserver/bitbucket-oauth-2-0-provider-api-1108483661.html#BitbucketOAuth2.0providerAPI-scopesScopes
67+
68+
/** View projects and repositories that are publicly accessible, including pulling code and cloning repositories. */
69+
export const PUBLIC_REPOS = "PUBLIC_REPOS";
70+
/** View projects and repositories the user account can view, including pulling code, cloning, and forking repositories. Create and comment on pull requests. */
71+
export const REPO_READ = "REPO_READ";
72+
/** Push over https, fork repo */
73+
export const REPO_WRITE = "REPO_WRITE";
74+
75+
export const REPO_ADMIN = "REPO_ADMIN";
76+
export const PROJECT_ADMIN = "PROJECT_ADMIN";
77+
78+
export const ALL = [PUBLIC_REPOS, REPO_READ, REPO_WRITE, REPO_ADMIN, PROJECT_ADMIN];
79+
80+
export const DEFAULT = ALL;
81+
}
82+
83+
export function getScopesForAuthProviderType(type: AuthProviderType | string) {
84+
switch (type) {
85+
case AuthProviderType.GITHUB:
86+
case "GitHub":
87+
return GitHubScope.ALL;
88+
case AuthProviderType.GITLAB:
89+
case "GitLab":
90+
return GitLabScope.ALL;
91+
case AuthProviderType.BITBUCKET:
92+
case "Bitbucket":
93+
return BitbucketOAuthScopes.ALL;
94+
case AuthProviderType.BITBUCKET_SERVER:
95+
case "BitbucketServer":
96+
return BitbucketServerOAuthScopes.ALL;
97+
}
98+
}
99+
100+
export function getRequiredScopes(type: AuthProviderType | string) {
101+
switch (type) {
102+
case AuthProviderType.GITHUB:
103+
case "GitHub":
104+
return {
105+
default: GitHubScope.DEFAULT,
106+
publicRepo: GitHubScope.PUBLIC_REPO,
107+
privateRepo: GitHubScope.PRIVATE_REPO,
108+
};
109+
case AuthProviderType.GITLAB:
110+
case "GitLab":
111+
return {
112+
default: GitLabScope.DEFAULT,
113+
publicRepo: GitLabScope.DEFAULT,
114+
privateRepo: GitLabScope.REPO,
115+
};
116+
case AuthProviderType.BITBUCKET:
117+
case "Bitbucket":
118+
return {
119+
default: BitbucketOAuthScopes.DEFAULT,
120+
publicRepo: BitbucketOAuthScopes.DEFAULT,
121+
privateRepo: BitbucketOAuthScopes.DEFAULT,
122+
};
123+
case AuthProviderType.BITBUCKET_SERVER:
124+
case "BitbucketServer":
125+
return {
126+
default: BitbucketServerOAuthScopes.DEFAULT,
127+
publicRepo: BitbucketServerOAuthScopes.DEFAULT,
128+
privateRepo: BitbucketServerOAuthScopes.DEFAULT,
129+
};
130+
}
131+
}

components/gitpod-protocol/src/gitpod-service.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,6 @@ export interface GitpodServer extends JsonRpcServer<GitpodClient>, AdminServer,
110110
getWorkspaceOwner(workspaceId: string): Promise<UserInfo | undefined>;
111111
getWorkspaceUsers(workspaceId: string): Promise<WorkspaceInstanceUser[]>;
112112
getFeaturedRepositories(): Promise<WhitelistedRepository[]>;
113-
getSuggestedContextURLs(): Promise<string[]>;
114113
getSuggestedRepositories(organizationId: string): Promise<SuggestedRepository[]>;
115114
searchRepositories(params: SearchRepositoriesParams): Promise<SuggestedRepository[]>;
116115
/**
@@ -188,6 +187,7 @@ export interface GitpodServer extends JsonRpcServer<GitpodClient>, AdminServer,
188187
getOnboardingState(): Promise<GitpodServer.OnboardingState>;
189188

190189
// Projects
190+
/** @deprecated no-op */
191191
getProviderRepositoriesForUser(
192192
params: GetProviderRepositoriesParams,
193193
cancellationToken?: CancellationToken,
@@ -212,7 +212,9 @@ export interface GitpodServer extends JsonRpcServer<GitpodClient>, AdminServer,
212212
deleteGitpodToken(tokenHash: string): Promise<void>;
213213

214214
// misc
215+
/** @deprecated always returns false */
215216
isGitHubAppEnabled(): Promise<boolean>;
217+
/** @deprecated this is a no-op */
216218
registerGithubApp(installationId: string): Promise<void>;
217219

218220
/**

components/gitpod-protocol/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ export * from "./teams-projects-protocol";
1818
export * from "./snapshot-url";
1919
export * from "./webhook-event";
2020
export * from "./redis";
21+
export * from "./auth-providers";

components/gitpod-protocol/src/messaging/error.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ export const ErrorCodes = {
6565
// 404 Not Found
6666
NOT_FOUND: 404 as const,
6767

68+
// 408 Request Timeout
69+
REQUEST_TIMEOUT: 408 as const,
70+
6871
// 409 Conflict (e.g. already existing)
6972
CONFLICT: 409 as const,
7073

components/gitpod-protocol/src/public-api-converter.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,7 @@ describe("PublicAPIConverter", () => {
666666
expect(result.organizationId).to.equal(project.teamId);
667667
expect(result.name).to.equal(project.name);
668668
expect(result.cloneUrl).to.equal(project.cloneUrl);
669+
expect(result.creationTime).to.deep.equal(Timestamp.fromDate(new Date(project.creationTime)));
669670
expect(result.workspaceSettings).to.deep.equal(
670671
new WorkspaceSettings({
671672
workspaceClass: project.settings?.workspaceClasses?.regular,

components/gitpod-protocol/src/public-api-converter.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,9 @@ export class PublicAPIConverter {
201201
if (reason.code === ErrorCodes.INTERNAL_SERVER_ERROR) {
202202
return new ConnectError(reason.message, Code.Internal, metadata, undefined, reason);
203203
}
204+
if (reason.code === ErrorCodes.REQUEST_TIMEOUT) {
205+
return new ConnectError(reason.message, Code.Canceled, metadata, undefined, reason);
206+
}
204207
return new ConnectError(reason.message, Code.InvalidArgument, metadata, undefined, reason);
205208
}
206209
return ConnectError.from(reason, Code.Internal);
@@ -403,6 +406,7 @@ export class PublicAPIConverter {
403406
result.organizationId = project.teamId;
404407
result.name = project.name;
405408
result.cloneUrl = project.cloneUrl;
409+
result.creationTime = Timestamp.fromDate(new Date(project.creationTime));
406410
result.workspaceSettings = this.toWorkspaceSettings(project.settings?.workspaceClasses?.regular);
407411
result.prebuildSettings = this.toPrebuildSettings(project.settings?.prebuilds);
408412
return result;
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/* eslint-disable @typescript-eslint/no-unsafe-argument */
2+
/**
3+
* Copyright (c) 2023 Gitpod GmbH. All rights reserved.
4+
* Licensed under the GNU Affero General Public License (AGPL).
5+
* See License.AGPL.txt in the project root for license information.
6+
*/
7+
8+
import { expect } from "chai";
9+
import { parsePagination } from "./public-api-pagination";
10+
11+
describe("PublicAPIConverter", () => {
12+
describe("parsePagination", () => {
13+
it("Happy path", () => {
14+
// first path is { page: 0 }
15+
const result = parsePagination({ page: 1, pageSize: 50 }, 50);
16+
expect(result.limit).to.equal(50);
17+
expect(result.offset).to.equal(50);
18+
});
19+
20+
it("Default is more than max, limit to max", () => {
21+
const result = parsePagination({ page: 2 }, 5000);
22+
expect(result.limit).to.equal(100); // MAX_PAGE_SIZE
23+
expect(result.offset).to.equal(200);
24+
});
25+
26+
it("All undefined", () => {
27+
const result = parsePagination({}, 20);
28+
expect(result.limit).to.equal(20);
29+
expect(result.offset).to.equal(0);
30+
});
31+
32+
it("All undefined, default undefined, go to default 50", () => {
33+
const result = parsePagination({});
34+
expect(result.limit).to.equal(50); // DEFAULT_PAGE_SIZE
35+
expect(result.offset).to.equal(0);
36+
});
37+
38+
it("Page less than zero, should go to zero", () => {
39+
const result = parsePagination({ page: -100, pageSize: 50 });
40+
expect(result.limit).to.equal(50);
41+
expect(result.offset).to.equal(0);
42+
});
43+
44+
it("Not integer page to zero", () => {
45+
const result = parsePagination({ page: 0.1, pageSize: 20 });
46+
expect(result.limit).to.equal(20);
47+
expect(result.offset).to.equal(0);
48+
});
49+
50+
it("Not integer pageSize to default", () => {
51+
const result = parsePagination({ page: 1, pageSize: 0.1 });
52+
expect(result.limit).to.equal(50);
53+
expect(result.offset).to.equal(50);
54+
});
55+
});
56+
});
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* Copyright (c) 2023 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+
import { PaginationRequest } from "@gitpod/public-api/lib/gitpod/v1/pagination_pb";
8+
9+
export interface ParsedPagination {
10+
offset: number;
11+
limit: number;
12+
}
13+
14+
const MAX_PAGE_SIZE = 100;
15+
const DEFAULT_PAGE_SIZE = 50;
16+
export function parsePagination(
17+
pagination: Partial<PaginationRequest> | undefined,
18+
defaultPageSize = DEFAULT_PAGE_SIZE,
19+
): ParsedPagination {
20+
let pageSize = pagination?.pageSize ?? defaultPageSize;
21+
if (!Number.isInteger(pageSize)) {
22+
pageSize = defaultPageSize;
23+
}
24+
if (pageSize < 0) {
25+
pageSize = defaultPageSize;
26+
} else if (pageSize > MAX_PAGE_SIZE) {
27+
pageSize = MAX_PAGE_SIZE;
28+
}
29+
let page = pagination?.page ?? 0;
30+
if (!Number.isInteger(page) || (page ?? 0) < 0) {
31+
page = 0;
32+
}
33+
return {
34+
offset: page * pageSize,
35+
limit: pageSize,
36+
};
37+
}

0 commit comments

Comments
 (0)