diff --git a/components/dashboard/src/user-settings/Integrations.tsx b/components/dashboard/src/user-settings/Integrations.tsx
index aaadd3e9c9b720..415606cbab470c 100644
--- a/components/dashboard/src/user-settings/Integrations.tsx
+++ b/components/dashboard/src/user-settings/Integrations.tsx
@@ -4,10 +4,10 @@
* See License.AGPL.txt in the project root for license information.
*/
-import { getScopesForAuthProviderType } from "@gitpod/public-api-common/lib/auth-providers";
+import { getRequiredScopes, getScopesForAuthProviderType } from "@gitpod/public-api-common/lib/auth-providers";
import { SelectAccountPayload } from "@gitpod/gitpod-protocol/lib/auth";
import { useQuery } from "@tanstack/react-query";
-import React, { useCallback, useContext, useEffect, useMemo, useState } from "react";
+import { useCallback, useContext, useEffect, useMemo, useState } from "react";
import Alert from "../components/Alert";
import { CheckboxInputField, CheckboxListField } from "../components/forms/CheckboxInputField";
import ConfirmationModal from "../components/ConfirmationModal";
@@ -54,6 +54,46 @@ export default function Integrations() {
);
}
+const getDescriptionForScope = (scope: string) => {
+ switch (scope) {
+ // GitHub
+ case "user:email":
+ return "Read-only access to your email addresses";
+ case "read:user":
+ return "Read-only access to your profile information";
+ case "public_repo":
+ return "Write access to code in public repositories and organizations";
+ case "repo":
+ return "Read/write access to code in private repositories and organizations";
+ case "read:org":
+ return "Read-only access to organizations (used to suggest organizations when forking a repository)";
+ case "workflow":
+ return "Allow updating GitHub Actions workflow files";
+ // GitLab
+ case "read_user":
+ return "Read-only access to your email addresses";
+ case "api":
+ return "Allow making API calls (used to set up a webhook when enabling prebuilds for a repository)";
+ case "read_repository":
+ return "Read/write access to your repositories";
+ // Bitbucket
+ case "account":
+ return "Read-only access to your account information";
+ case "repository":
+ return "Read-only access to your repositories (note: Bitbucket doesn't support revoking scopes)";
+ case "repository:write":
+ return "Read/write access to your repositories (note: Bitbucket doesn't support revoking scopes)";
+ case "pullrequest":
+ return "Read access to pull requests and ability to collaborate via comments, tasks, and approvals (note: Bitbucket doesn't support revoking scopes)";
+ case "pullrequest:write":
+ return "Allow creating, merging and declining pull requests (note: Bitbucket doesn't support revoking scopes)";
+ case "webhook":
+ return "Allow installing webhooks (used when enabling prebuilds for a repository, note: Bitbucket doesn't support revoking scopes)";
+ default:
+ return "";
+ }
+};
+
function GitProviders() {
const { user, setUser } = useContext(UserContext);
@@ -250,45 +290,6 @@ function GitProviders() {
setEditModal({ ...editModal, nextScopes });
};
- const getDescriptionForScope = (scope: string) => {
- switch (scope) {
- case "user:email":
- return "Read-only access to your email addresses";
- case "read:user":
- return "Read-only access to your profile information";
- case "public_repo":
- return "Write access to code in public repositories and organizations";
- case "repo":
- return "Read/write access to code in private repositories and organizations";
- case "read:org":
- return "Read-only access to organizations (used to suggest organizations when forking a repository)";
- case "workflow":
- return "Allow updating GitHub Actions workflow files";
- // GitLab
- case "read_user":
- return "Read-only access to your email addresses";
- case "api":
- return "Allow making API calls (used to set up a webhook when enabling prebuilds for a repository)";
- case "read_repository":
- return "Read/write access to your repositories";
- // Bitbucket
- case "account":
- return "Read-only access to your account information";
- case "repository":
- return "Read-only access to your repositories (note: Bitbucket doesn't support revoking scopes)";
- case "repository:write":
- return "Read/write access to your repositories (note: Bitbucket doesn't support revoking scopes)";
- case "pullrequest":
- return "Read access to pull requests and ability to collaborate via comments, tasks, and approvals (note: Bitbucket doesn't support revoking scopes)";
- case "pullrequest:write":
- return "Allow creating, merging and declining pull requests (note: Bitbucket doesn't support revoking scopes)";
- case "webhook":
- return "Allow installing webhooks (used when enabling prebuilds for a repository, note: Bitbucket doesn't support revoking scopes)";
- default:
- return "";
- }
- };
-
return (
{selectAccountModal && (
@@ -325,18 +326,22 @@ function GitProviders() {
Edit Permissions
- {(getScopesForAuthProviderType(editModal.provider.type) || []).map((scope) => (
- onChangeScopeHandler(checked, scope)}
- />
- ))}
+ {(getScopesForAuthProviderType(editModal.provider.type) || []).map((scope) => {
+ const isRequired = getRequiredScopes(editModal.provider.type)?.default.includes(scope);
+
+ return (
+ onChangeScopeHandler(checked, scope)}
+ />
+ );
+ })}
diff --git a/components/gitpod-db/src/typeorm/user-db-impl.ts b/components/gitpod-db/src/typeorm/user-db-impl.ts
index 1ad4d5de466815..a59feac01eb4cf 100644
--- a/components/gitpod-db/src/typeorm/user-db-impl.ts
+++ b/components/gitpod-db/src/typeorm/user-db-impl.ts
@@ -571,7 +571,7 @@ export class TypeORMUserDBImpl extends TransactionalDBImpl implements Us
accessTokenExpiresAt: expiry,
client,
user,
- scopes: scopes,
+ scopes,
};
}
async issueRefreshToken(accessToken: OAuthToken): Promise {
diff --git a/components/public-api/typescript-common/src/auth-providers.ts b/components/public-api/typescript-common/src/auth-providers.ts
index 61d05d348dd7c0..1c573e17c00c2e 100644
--- a/components/public-api/typescript-common/src/auth-providers.ts
+++ b/components/public-api/typescript-common/src/auth-providers.ts
@@ -6,21 +6,25 @@
import { AuthProviderType } from "@gitpod/public-api/lib/gitpod/v1/authprovider_pb";
-export namespace GitLabScope {
+export namespace GitLabOAuthScopes {
export const READ_USER = "read_user";
export const API = "api";
export const READ_REPO = "read_repository";
export const ALL = [READ_USER, API, READ_REPO];
- /**
- * Minimal required permission.
- * GitLab API usage requires the permission of a user.
- */
- export const DEFAULT = [READ_USER, API];
- export const REPO = [API, READ_REPO];
+
+ export const Requirements = {
+ /**
+ * Minimal required permission.
+ * GitLab API usage requires the permission of a user.
+ */
+ DEFAULT: [READ_USER, API],
+
+ REPO: [API, READ_REPO],
+ };
}
-export namespace GitHubScope {
+export namespace GitHubOAuthScopes {
export const EMAIL = "user:email";
export const READ_USER = "read:user";
export const PUBLIC = "public_repo";
@@ -29,9 +33,17 @@ export namespace GitHubScope {
export const WORKFLOW = "workflow";
export const ALL = [EMAIL, READ_USER, PUBLIC, PRIVATE, ORGS, WORKFLOW];
- export const DEFAULT = ALL;
- export const PUBLIC_REPO = ALL;
- export const PRIVATE_REPO = ALL;
+
+ export const Requirements = {
+ /**
+ * Minimal required permission.
+ * GitHub's API is not restricted any further.
+ */
+ DEFAULT: [EMAIL],
+
+ PUBLIC_REPO: [PUBLIC],
+ PRIVATE_REPO: [PRIVATE],
+ };
}
export namespace BitbucketOAuthScopes {
@@ -48,15 +60,14 @@ export namespace BitbucketOAuthScopes {
/** Create, comment and merge pull requests */
export const PULL_REQUEST_WRITE = "pullrequest:write";
- export const ALL = [
- ACCOUNT_READ,
- REPOSITORY_READ,
- REPOSITORY_WRITE,
- PULL_REQUEST_READ,
- PULL_REQUEST_WRITE,
- ];
+ export const ALL = [ACCOUNT_READ, REPOSITORY_READ, REPOSITORY_WRITE, PULL_REQUEST_READ, PULL_REQUEST_WRITE];
- export const DEFAULT = ALL;
+ export const Requirements = {
+ /**
+ * Minimal required permission.
+ */
+ DEFAULT: ALL,
+ };
}
export namespace BitbucketServerOAuthScopes {
@@ -74,17 +85,22 @@ export namespace BitbucketServerOAuthScopes {
export const ALL = [PUBLIC_REPOS, REPO_READ, REPO_WRITE, REPO_ADMIN, PROJECT_ADMIN];
- export const DEFAULT = ALL;
+ export const Requirements = {
+ /**
+ * Minimal required permission.
+ */
+ DEFAULT: [PUBLIC_REPOS, REPO_READ, REPO_WRITE],
+ };
}
export function getScopesForAuthProviderType(type: AuthProviderType | string) {
switch (type) {
case AuthProviderType.GITHUB:
case "GitHub":
- return GitHubScope.ALL;
+ return GitHubOAuthScopes.ALL;
case AuthProviderType.GITLAB:
case "GitLab":
- return GitLabScope.ALL;
+ return GitLabOAuthScopes.ALL;
case AuthProviderType.BITBUCKET:
case "Bitbucket":
return BitbucketOAuthScopes.ALL;
@@ -99,30 +115,30 @@ export function getRequiredScopes(type: AuthProviderType | string) {
case AuthProviderType.GITHUB:
case "GitHub":
return {
- default: GitHubScope.DEFAULT,
- publicRepo: GitHubScope.PUBLIC_REPO,
- privateRepo: GitHubScope.PRIVATE_REPO,
+ default: GitHubOAuthScopes.Requirements.DEFAULT,
+ publicRepo: GitHubOAuthScopes.Requirements.PUBLIC_REPO,
+ privateRepo: GitHubOAuthScopes.Requirements.PRIVATE_REPO,
};
case AuthProviderType.GITLAB:
case "GitLab":
return {
- default: GitLabScope.DEFAULT,
- publicRepo: GitLabScope.DEFAULT,
- privateRepo: GitLabScope.REPO,
+ default: GitLabOAuthScopes.Requirements.DEFAULT,
+ publicRepo: GitLabOAuthScopes.Requirements.DEFAULT,
+ privateRepo: GitLabOAuthScopes.Requirements.REPO,
};
case AuthProviderType.BITBUCKET:
case "Bitbucket":
return {
- default: BitbucketOAuthScopes.DEFAULT,
- publicRepo: BitbucketOAuthScopes.DEFAULT,
- privateRepo: BitbucketOAuthScopes.DEFAULT,
+ default: BitbucketOAuthScopes.Requirements.DEFAULT,
+ publicRepo: BitbucketOAuthScopes.Requirements.DEFAULT,
+ privateRepo: BitbucketOAuthScopes.Requirements.DEFAULT,
};
case AuthProviderType.BITBUCKET_SERVER:
case "BitbucketServer":
return {
- default: BitbucketServerOAuthScopes.DEFAULT,
- publicRepo: BitbucketServerOAuthScopes.DEFAULT,
- privateRepo: BitbucketServerOAuthScopes.DEFAULT,
+ default: BitbucketServerOAuthScopes.Requirements.DEFAULT,
+ publicRepo: BitbucketServerOAuthScopes.Requirements.DEFAULT,
+ privateRepo: BitbucketServerOAuthScopes.Requirements.DEFAULT,
};
}
}
diff --git a/components/server/src/auth/auth-provider-scopes.ts b/components/server/src/auth/auth-provider-scopes.ts
deleted file mode 100644
index 95534e67717534..00000000000000
--- a/components/server/src/auth/auth-provider-scopes.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * Copyright (c) 2023 Gitpod GmbH. All rights reserved.
- * Licensed under the GNU Affero General Public License (AGPL).
- * See License.AGPL.txt in the project root for license information.
- */
-
-import { GitHubScope } from "../github/scopes";
-import { GitLabScope } from "../gitlab/scopes";
-import { BitbucketOAuthScopes } from "../bitbucket/bitbucket-oauth-scopes";
-import { BitbucketServerOAuthScopes } from "../bitbucket-server/bitbucket-server-oauth-scopes";
-
-export function getRequiredScopes(entry: { type: string }) {
- switch (entry.type) {
- case "GitHub":
- return {
- default: GitHubScope.Requirements.DEFAULT,
- publicRepo: GitHubScope.Requirements.PUBLIC_REPO,
- privateRepo: GitHubScope.Requirements.PRIVATE_REPO,
- };
- case "GitLab":
- return {
- default: GitLabScope.Requirements.DEFAULT,
- publicRepo: GitLabScope.Requirements.DEFAULT,
- privateRepo: GitLabScope.Requirements.REPO,
- };
- case "Bitbucket":
- return {
- default: BitbucketOAuthScopes.Requirements.DEFAULT,
- publicRepo: BitbucketOAuthScopes.Requirements.DEFAULT,
- privateRepo: BitbucketOAuthScopes.Requirements.DEFAULT,
- };
- case "BitbucketServer":
- return {
- default: BitbucketServerOAuthScopes.Requirements.DEFAULT,
- publicRepo: BitbucketServerOAuthScopes.Requirements.DEFAULT,
- privateRepo: BitbucketServerOAuthScopes.Requirements.DEFAULT,
- };
- }
-}
-export function getScopesOfProvider(entry: { type: string }) {
- switch (entry.type) {
- case "GitHub":
- return GitHubScope.All;
- case "GitLab":
- return GitLabScope.All;
- case "Bitbucket":
- return BitbucketOAuthScopes.ALL;
- case "BitbucketServer":
- return BitbucketServerOAuthScopes.ALL;
- }
-}
diff --git a/components/server/src/auth/auth-provider-service.ts b/components/server/src/auth/auth-provider-service.ts
index 293e0ead3557c1..3d8f2c3a7a1902 100644
--- a/components/server/src/auth/auth-provider-service.ts
+++ b/components/server/src/auth/auth-provider-service.ts
@@ -18,7 +18,7 @@ import { log } from "@gitpod/gitpod-protocol/lib/util/logging";
import fetch from "node-fetch";
import { Authorizer } from "../authorization/authorizer";
import { ApplicationError, ErrorCodes } from "@gitpod/gitpod-protocol/lib/messaging/error";
-import { getRequiredScopes, getScopesOfProvider } from "./auth-provider-scopes";
+import { getRequiredScopes, getScopesForAuthProviderType } from "@gitpod/public-api-common/lib/auth-providers";
@injectable()
export class AuthProviderService {
@@ -106,8 +106,8 @@ export class AuthProviderService {
hiddenOnDashboard: ap.hiddenOnDashboard,
disallowLogin: ap.disallowLogin,
description: ap.description,
- scopes: getScopesOfProvider(ap),
- requirements: getRequiredScopes(ap),
+ scopes: getScopesForAuthProviderType(ap.type),
+ requirements: getRequiredScopes(ap.type),
};
}
diff --git a/components/server/src/auth/resource-access.ts b/components/server/src/auth/resource-access.ts
index ba4c7ba60adc6c..526686e7d0fe46 100644
--- a/components/server/src/auth/resource-access.ts
+++ b/components/server/src/auth/resource-access.ts
@@ -23,8 +23,8 @@ import { UnauthorizedError } from "../errors";
import { RepoURL } from "../repohost";
import { HostContextProvider } from "./host-context-provider";
import { reportGuardAccessCheck } from "../prometheus-metrics";
-import { getRequiredScopes } from "./auth-provider-scopes";
import { FunctionAccessGuard } from "./function-access";
+import { getRequiredScopes } from "@gitpod/public-api-common/lib/auth-providers";
declare let resourceInstance: GuardedResource;
export type GuardedResourceKind = typeof resourceInstance.kind;
@@ -585,7 +585,7 @@ export class RepositoryResourceGuard implements ResourceAccessGuard {
const identity = User.getIdentity(this.user, authProvider.authProviderId);
if (!identity) {
const providerType = authProvider.info.authProviderType;
- const requiredScopes = getRequiredScopes({ type: providerType })?.default;
+ const requiredScopes = getRequiredScopes(providerType)?.default;
throw UnauthorizedError.create({
host: repoUrl.host,
repoName: repoUrl.repo,
diff --git a/components/server/src/bitbucket-server/bitbucket-server-auth-provider.ts b/components/server/src/bitbucket-server/bitbucket-server-auth-provider.ts
index c5cc61f60710ed..e1e759feb7e74a 100644
--- a/components/server/src/bitbucket-server/bitbucket-server-auth-provider.ts
+++ b/components/server/src/bitbucket-server/bitbucket-server-auth-provider.ts
@@ -10,8 +10,8 @@ import express from "express";
import { inject, injectable } from "inversify";
import { AuthUserSetup } from "../auth/auth-provider";
import { GenericAuthProvider } from "../auth/generic-auth-provider";
-import { BitbucketServerOAuthScopes } from "./bitbucket-server-oauth-scopes";
import { BitbucketServerApi } from "./bitbucket-server-api";
+import { BitbucketServerOAuthScopes } from "@gitpod/public-api-common/lib/auth-providers";
@injectable()
export class BitbucketServerAuthProvider extends GenericAuthProvider {
diff --git a/components/server/src/bitbucket-server/bitbucket-server-oauth-scopes.ts b/components/server/src/bitbucket-server/bitbucket-server-oauth-scopes.ts
deleted file mode 100644
index 529f25d56289ca..00000000000000
--- a/components/server/src/bitbucket-server/bitbucket-server-oauth-scopes.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-/**
- * Copyright (c) 2021 Gitpod GmbH. All rights reserved.
- * Licensed under the GNU Affero General Public License (AGPL).
- * See License.AGPL.txt in the project root for license information.
- */
-
-// https://confluence.atlassian.com/bitbucketserver/bitbucket-oauth-2-0-provider-api-1108483661.html#BitbucketOAuth2.0providerAPI-scopesScopes
-
-export namespace BitbucketServerOAuthScopes {
- /** View projects and repositories that are publicly accessible, including pulling code and cloning repositories. */
- export const PUBLIC_REPOS = "PUBLIC_REPOS";
- /** View projects and repositories the user account can view, including pulling code, cloning, and forking repositories. Create and comment on pull requests. */
- export const REPO_READ = "REPO_READ";
- /** Push over https, fork repo */
- export const REPO_WRITE = "REPO_WRITE";
-
- export const REPO_ADMIN = "REPO_ADMIN";
- export const PROJECT_ADMIN = "PROJECT_ADMIN";
-
- export const ALL = [PUBLIC_REPOS, REPO_READ, REPO_WRITE, REPO_ADMIN, PROJECT_ADMIN];
-
- export const Requirements = {
- /**
- * Minimal required permission.
- */
- DEFAULT: [PUBLIC_REPOS, REPO_READ, REPO_WRITE],
- };
-}
diff --git a/components/server/src/bitbucket-server/bitbucket-server-token-handler.ts b/components/server/src/bitbucket-server/bitbucket-server-token-handler.ts
index bb1f728c9bb5e6..0cfd3857632a26 100644
--- a/components/server/src/bitbucket-server/bitbucket-server-token-handler.ts
+++ b/components/server/src/bitbucket-server/bitbucket-server-token-handler.ts
@@ -9,7 +9,7 @@ import { inject, injectable } from "inversify";
import { AuthProviderParams } from "../auth/auth-provider";
import { UnauthorizedError } from "../errors";
import { TokenProvider } from "../user/token-provider";
-import { BitbucketServerOAuthScopes } from "./bitbucket-server-oauth-scopes";
+import { BitbucketServerOAuthScopes } from "@gitpod/public-api-common/lib/auth-providers";
@injectable()
export class BitbucketServerTokenHelper {
diff --git a/components/server/src/bitbucket/bitbucket-auth-provider.ts b/components/server/src/bitbucket/bitbucket-auth-provider.ts
index 937f801773f1c3..450f2fe3a19214 100644
--- a/components/server/src/bitbucket/bitbucket-auth-provider.ts
+++ b/components/server/src/bitbucket/bitbucket-auth-provider.ts
@@ -11,7 +11,7 @@ import express from "express";
import { injectable } from "inversify";
import { AuthUserSetup } from "../auth/auth-provider";
import { GenericAuthProvider } from "../auth/generic-auth-provider";
-import { BitbucketOAuthScopes } from "./bitbucket-oauth-scopes";
+import { BitbucketOAuthScopes } from "@gitpod/public-api-common/lib/auth-providers";
@injectable()
export class BitbucketAuthProvider extends GenericAuthProvider {
diff --git a/components/server/src/bitbucket/bitbucket-oauth-scopes.ts b/components/server/src/bitbucket/bitbucket-oauth-scopes.ts
deleted file mode 100644
index b8795f2f120b44..00000000000000
--- a/components/server/src/bitbucket/bitbucket-oauth-scopes.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * Copyright (c) 2020 Gitpod GmbH. All rights reserved.
- * Licensed under the GNU Affero General Public License (AGPL).
- * See License.AGPL.txt in the project root for license information.
- */
-
-// https://confluence.atlassian.com/bitbucket/oauth-on-bitbucket-cloud-238027431.html
-
-export namespace BitbucketOAuthScopes {
- /** Read user info like name, e-mail addresses etc. */
- export const ACCOUNT_READ = "account";
- /** Access repo info, clone repo over https, read and write issues */
- export const REPOSITORY_READ = "repository";
- /** Push over https, fork repo */
- export const REPOSITORY_WRITE = "repository:write";
- /** Lists and read pull requests */
- export const PULL_REQUEST_READ = "pullrequest";
- /** Create, comment and merge pull requests */
- export const PULL_REQUEST_WRITE = "pullrequest:write";
-
- export const ALL = [ACCOUNT_READ, REPOSITORY_READ, REPOSITORY_WRITE, PULL_REQUEST_READ, PULL_REQUEST_WRITE];
-
- export const Requirements = {
- /**
- * Minimal required permission.
- */
- DEFAULT: ALL,
- };
-}
diff --git a/components/server/src/bitbucket/bitbucket-token-handler.ts b/components/server/src/bitbucket/bitbucket-token-handler.ts
index fdf9389eb79d73..533eac7979f769 100644
--- a/components/server/src/bitbucket/bitbucket-token-handler.ts
+++ b/components/server/src/bitbucket/bitbucket-token-handler.ts
@@ -9,7 +9,7 @@ import { inject, injectable } from "inversify";
import { AuthProviderParams } from "../auth/auth-provider";
import { UnauthorizedError } from "../errors";
import { TokenProvider } from "../user/token-provider";
-import { BitbucketOAuthScopes } from "./bitbucket-oauth-scopes";
+import { BitbucketOAuthScopes } from "@gitpod/public-api-common/lib/auth-providers";
@injectable()
export class BitbucketTokenHelper {
diff --git a/components/server/src/dev/dev-data.ts b/components/server/src/dev/dev-data.ts
index 95360a56a14762..271b94684d6b37 100644
--- a/components/server/src/dev/dev-data.ts
+++ b/components/server/src/dev/dev-data.ts
@@ -5,8 +5,7 @@
*/
import { IssueContext, User, PullRequestContext, Repository, Token } from "@gitpod/gitpod-protocol";
-import { GitHubScope } from "../github/scopes";
-import { GitLabScope } from "../gitlab/scopes";
+import { GitHubOAuthScopes, GitLabOAuthScopes } from "@gitpod/public-api-common/lib/auth-providers";
export namespace DevData {
export function createTestUser(): User {
@@ -41,7 +40,7 @@ export namespace DevData {
export function createGitHubTestToken(): Token {
return {
...getTokenFromEnv("GITPOD_TEST_TOKEN_GITHUB"),
- scopes: [GitHubScope.EMAIL, GitHubScope.PUBLIC, GitHubScope.PRIVATE],
+ scopes: [GitHubOAuthScopes.EMAIL, GitHubOAuthScopes.PUBLIC, GitHubOAuthScopes.PRIVATE],
};
}
@@ -61,7 +60,7 @@ export namespace DevData {
export function createGitlabTestToken(): Token {
return {
...getTokenFromEnv("GITPOD_TEST_TOKEN_GITLAB"),
- scopes: [GitLabScope.READ_USER, GitLabScope.API],
+ scopes: [GitLabOAuthScopes.READ_USER, GitLabOAuthScopes.API],
};
}
diff --git a/components/server/src/github/api.ts b/components/server/src/github/api.ts
index 7899c9a119dc60..c7593a1d6a6ff5 100644
--- a/components/server/src/github/api.ts
+++ b/components/server/src/github/api.ts
@@ -13,12 +13,12 @@ import { Branch, CommitInfo, User } from "@gitpod/gitpod-protocol";
import { GarbageCollectedCache } from "@gitpod/gitpod-protocol/lib/util/garbage-collected-cache";
import { injectable, inject } from "inversify";
import { log } from "@gitpod/gitpod-protocol/lib/util/logging";
-import { GitHubScope } from "./scopes";
import { AuthProviderParams } from "../auth/auth-provider";
import { GitHubTokenHelper } from "./github-token-helper";
import { Deferred } from "@gitpod/gitpod-protocol/lib/util/deferred";
import { URL } from "url";
+import { GitHubOAuthScopes } from "@gitpod/public-api-common/lib/auth-providers";
export class GitHubApiError extends Error {
readonly code: number;
@@ -149,7 +149,7 @@ export class GitHubRestApi {
} else {
const githubToken = await this.tokenHelper.getTokenWithScopes(
userOrToken,
- GitHubScope.Requirements.DEFAULT,
+ GitHubOAuthScopes.Requirements.DEFAULT,
);
token = githubToken.value;
}
diff --git a/components/server/src/github/github-auth-provider.ts b/components/server/src/github/github-auth-provider.ts
index 2c810abff0a73d..03eaa82eb620d6 100644
--- a/components/server/src/github/github-auth-provider.ts
+++ b/components/server/src/github/github-auth-provider.ts
@@ -8,23 +8,23 @@ import { injectable } from "inversify";
import express from "express";
import { AuthProviderInfo } from "@gitpod/gitpod-protocol";
import { log } from "@gitpod/gitpod-protocol/lib/util/logging";
-import { GitHubScope } from "./scopes";
import { AuthUserSetup } from "../auth/auth-provider";
import { Octokit } from "@octokit/rest";
import { GitHubApiError } from "./api";
import { GenericAuthProvider } from "../auth/generic-auth-provider";
import { oauthUrls } from "./github-urls";
+import { GitHubOAuthScopes } from "@gitpod/public-api-common/lib/auth-providers";
@injectable()
export class GitHubAuthProvider extends GenericAuthProvider {
get info(): AuthProviderInfo {
return {
...this.defaultInfo(),
- scopes: GitHubScope.All,
+ scopes: GitHubOAuthScopes.ALL,
requirements: {
- default: GitHubScope.Requirements.DEFAULT,
- publicRepo: GitHubScope.Requirements.PUBLIC_REPO,
- privateRepo: GitHubScope.Requirements.PRIVATE_REPO,
+ default: GitHubOAuthScopes.Requirements.DEFAULT,
+ publicRepo: GitHubOAuthScopes.Requirements.PUBLIC_REPO,
+ privateRepo: GitHubOAuthScopes.Requirements.PRIVATE_REPO,
},
};
}
@@ -40,7 +40,7 @@ export class GitHubAuthProvider extends GenericAuthProvider {
...oauth!,
authorizationUrl: oauth.authorizationUrl || defaultUrls.authorizationUrl,
tokenUrl: oauth.tokenUrl || defaultUrls.tokenUrl,
- scope: GitHubScope.All.join(scopeSeparator),
+ scope: GitHubOAuthScopes.ALL.join(scopeSeparator),
scopeSeparator,
};
}
@@ -52,7 +52,7 @@ export class GitHubAuthProvider extends GenericAuthProvider {
state: string,
scope?: string[],
) {
- super.authorize(req, res, next, state, scope ? scope : GitHubScope.Requirements.DEFAULT);
+ super.authorize(req, res, next, state, scope ? scope : GitHubOAuthScopes.Requirements.DEFAULT);
}
/**
diff --git a/components/server/src/github/github-context-parser.ts b/components/server/src/github/github-context-parser.ts
index ee067825459526..fc5c33d89e7d13 100644
--- a/components/server/src/github/github-context-parser.ts
+++ b/components/server/src/github/github-context-parser.ts
@@ -19,12 +19,12 @@ import { GitHubGraphQlEndpoint, QueryResult } from "./api";
import { NotFoundError, UnauthorizedError } from "../errors";
import { log, LogContext, LogPayload } from "@gitpod/gitpod-protocol/lib/util/logging";
import { IContextParser, IssueContexts, AbstractContextParser } from "../workspace/context-parser";
-import { GitHubScope } from "./scopes";
import { GitHubTokenHelper } from "./github-token-helper";
import { TraceContext } from "@gitpod/gitpod-protocol/lib/util/tracing";
import { RepoURL } from "../repohost";
import { containsScopes } from "../prebuilds/token-scopes-inclusion";
import { TrustedValue } from "@gitpod/gitpod-protocol/lib/util/scrubbing";
+import { GitHubOAuthScopes } from "@gitpod/public-api-common/lib/auth-providers";
@injectable()
export class GithubContextParser extends AbstractContextParser implements IContextParser {
@@ -95,10 +95,10 @@ export class GithubContextParser extends AbstractContextParser implements IConte
throw UnauthorizedError.create({
host: this.config.host,
providerType: "GitHub",
- requiredScopes: GitHubScope.Requirements.PUBLIC_REPO,
+ requiredScopes: GitHubOAuthScopes.Requirements.PUBLIC_REPO,
repoName: RepoURL.parseRepoUrl(contextUrl)?.repo,
providerIsConnected: !!token,
- isMissingScopes: containsScopes(token?.scopes, GitHubScope.Requirements.PUBLIC_REPO),
+ isMissingScopes: containsScopes(token?.scopes, GitHubOAuthScopes.Requirements.PUBLIC_REPO),
});
}
throw error;
diff --git a/components/server/src/github/github-token-helper.ts b/components/server/src/github/github-token-helper.ts
index a7f4ed8d14c96d..3b1302e3294f77 100644
--- a/components/server/src/github/github-token-helper.ts
+++ b/components/server/src/github/github-token-helper.ts
@@ -8,8 +8,8 @@ import { injectable, inject } from "inversify";
import { AuthProviderParams } from "../auth/auth-provider";
import { User, Token } from "@gitpod/gitpod-protocol";
import { UnauthorizedError } from "../errors";
-import { GitHubScope } from "./scopes";
import { TokenProvider } from "../user/token-provider";
+import { GitHubOAuthScopes } from "@gitpod/public-api-common/lib/auth-providers";
@injectable()
export class GitHubTokenHelper {
@@ -37,12 +37,12 @@ export class GitHubTokenHelper {
// no token
}
if (requiredScopes.length === 0) {
- requiredScopes = GitHubScope.Requirements.DEFAULT;
+ requiredScopes = GitHubOAuthScopes.Requirements.DEFAULT;
}
throw UnauthorizedError.create({
host,
providerType: "GitHub",
- requiredScopes: GitHubScope.Requirements.DEFAULT,
+ requiredScopes: GitHubOAuthScopes.Requirements.DEFAULT,
providerIsConnected: false,
isMissingScopes: true,
});
@@ -50,8 +50,8 @@ export class GitHubTokenHelper {
protected containsScopes(token: Token, wantedScopes: string[] | undefined): boolean {
const wantedSet = new Set(wantedScopes);
const currentScopes = [...token.scopes];
- if (currentScopes.some((s) => s === GitHubScope.PRIVATE)) {
- currentScopes.push(GitHubScope.PUBLIC); // normalize private_repo, which includes public_repo
+ if (currentScopes.some((s) => s === GitHubOAuthScopes.PRIVATE)) {
+ currentScopes.push(GitHubOAuthScopes.PUBLIC); // normalize private_repo, which includes public_repo
}
currentScopes.forEach((s) => wantedSet.delete(s));
return wantedSet.size === 0;
diff --git a/components/server/src/github/scopes.ts b/components/server/src/github/scopes.ts
deleted file mode 100644
index 64575aa36215eb..00000000000000
--- a/components/server/src/github/scopes.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-/**
- * Copyright (c) 2020 Gitpod GmbH. All rights reserved.
- * Licensed under the GNU Affero General Public License (AGPL).
- * See License.AGPL.txt in the project root for license information.
- */
-
-export namespace GitHubScope {
- export const EMAIL = "user:email";
- export const READ_USER = "read:user";
- export const PUBLIC = "public_repo";
- export const PRIVATE = "repo";
- export const ORGS = "read:org";
- export const WORKFLOW = "workflow";
-
- export const All = [EMAIL, READ_USER, PUBLIC, PRIVATE, ORGS, WORKFLOW];
- export const Requirements = {
- /**
- * Minimal required permission.
- * GitHub's API is not restricted any further.
- */
- DEFAULT: [EMAIL],
-
- PUBLIC_REPO: [PUBLIC],
- PRIVATE_REPO: [PRIVATE],
- };
-}
diff --git a/components/server/src/gitlab/api.ts b/components/server/src/gitlab/api.ts
index 635f361f4a66c2..301a8918ca1dc2 100644
--- a/components/server/src/gitlab/api.ts
+++ b/components/server/src/gitlab/api.ts
@@ -26,9 +26,9 @@ import {
SimpleProjectSchema,
} from "@gitbeaker/core";
import { log } from "@gitpod/gitpod-protocol/lib/util/logging";
-import { GitLabScope } from "./scopes";
import { AuthProviderParams } from "../auth/auth-provider";
import { GitLabTokenHelper } from "./gitlab-token-helper";
+import { GitLabOAuthScopes } from "@gitpod/public-api-common/lib/auth-providers";
@injectable()
export class GitLabApi {
@@ -42,7 +42,7 @@ export class GitLabApi {
} else {
const gitlabToken = await this.tokenHelper.getTokenWithScopes(
userOrToken,
- GitLabScope.Requirements.DEFAULT,
+ GitLabOAuthScopes.Requirements.DEFAULT,
);
oauthToken = gitlabToken.value;
}
diff --git a/components/server/src/gitlab/gitlab-auth-provider.ts b/components/server/src/gitlab/gitlab-auth-provider.ts
index 9ee945da460b3f..e9475c0f69b3ca 100644
--- a/components/server/src/gitlab/gitlab-auth-provider.ts
+++ b/components/server/src/gitlab/gitlab-auth-provider.ts
@@ -8,23 +8,23 @@ import express from "express";
import { injectable } from "inversify";
import { log } from "@gitpod/gitpod-protocol/lib/util/logging";
import { AuthProviderInfo } from "@gitpod/gitpod-protocol";
-import { GitLabScope } from "./scopes";
import { UnconfirmedUserException } from "../auth/errors";
import { GitLab } from "./api";
import { GenericAuthProvider } from "../auth/generic-auth-provider";
import { AuthUserSetup } from "../auth/auth-provider";
import { oauthUrls } from "./gitlab-urls";
+import { GitLabOAuthScopes } from "@gitpod/public-api-common/lib/auth-providers";
@injectable()
export class GitLabAuthProvider extends GenericAuthProvider {
get info(): AuthProviderInfo {
return {
...this.defaultInfo(),
- scopes: GitLabScope.All,
+ scopes: GitLabOAuthScopes.ALL,
requirements: {
- default: GitLabScope.Requirements.DEFAULT,
- publicRepo: GitLabScope.Requirements.REPO,
- privateRepo: GitLabScope.Requirements.REPO,
+ default: GitLabOAuthScopes.Requirements.DEFAULT,
+ publicRepo: GitLabOAuthScopes.Requirements.REPO,
+ privateRepo: GitLabOAuthScopes.Requirements.REPO,
},
};
}
@@ -41,7 +41,7 @@ export class GitLabAuthProvider extends GenericAuthProvider {
authorizationUrl: oauth.authorizationUrl || defaultUrls.authorizationUrl,
tokenUrl: oauth.tokenUrl || defaultUrls.tokenUrl,
settingsUrl: oauth.settingsUrl || defaultUrls.settingsUrl,
- scope: GitLabScope.All.join(scopeSeparator),
+ scope: GitLabOAuthScopes.ALL.join(scopeSeparator),
scopeSeparator,
};
}
@@ -53,7 +53,7 @@ export class GitLabAuthProvider extends GenericAuthProvider {
state: string,
scope?: string[],
) {
- super.authorize(req, res, next, state, scope ? scope : GitLabScope.Requirements.DEFAULT);
+ super.authorize(req, res, next, state, scope ? scope : GitLabOAuthScopes.Requirements.DEFAULT);
}
protected get baseURL() {
diff --git a/components/server/src/gitlab/gitlab-context-parser.ts b/components/server/src/gitlab/gitlab-context-parser.ts
index 44b47ffac1ab9b..17ac2e539485e9 100644
--- a/components/server/src/gitlab/gitlab-context-parser.ts
+++ b/components/server/src/gitlab/gitlab-context-parser.ts
@@ -17,7 +17,7 @@ import {
} from "@gitpod/gitpod-protocol";
import { GitLabApi, GitLab } from "./api";
import { UnauthorizedError, NotFoundError } from "../errors";
-import { GitLabScope } from "./scopes";
+import { GitLabOAuthScopes } from "@gitpod/public-api-common/lib/auth-providers";
import { IContextParser, IssueContexts, AbstractContextParser, URLParts } from "../workspace/context-parser";
import { log } from "@gitpod/gitpod-protocol/lib/util/logging";
import { GitLabTokenHelper } from "./gitlab-token-helper";
@@ -74,10 +74,10 @@ export class GitlabContextParser extends AbstractContextParser implements IConte
throw UnauthorizedError.create({
host: this.config.host,
providerType: "Gitlab",
- requiredScopes: GitLabScope.Requirements.DEFAULT,
+ requiredScopes: GitLabOAuthScopes.Requirements.DEFAULT,
repoName: RepoURL.parseRepoUrl(contextUrl)?.repo,
providerIsConnected: !!token,
- isMissingScopes: containsScopes(token?.scopes, GitLabScope.Requirements.DEFAULT),
+ isMissingScopes: containsScopes(token?.scopes, GitLabOAuthScopes.Requirements.DEFAULT),
});
}
throw error;
diff --git a/components/server/src/gitlab/gitlab-token-helper.ts b/components/server/src/gitlab/gitlab-token-helper.ts
index 724cc60ff972d2..1d7905146f8410 100644
--- a/components/server/src/gitlab/gitlab-token-helper.ts
+++ b/components/server/src/gitlab/gitlab-token-helper.ts
@@ -8,8 +8,8 @@ import { User, Token } from "@gitpod/gitpod-protocol";
import { UnauthorizedError } from "../errors";
import { AuthProviderParams } from "../auth/auth-provider";
import { injectable, inject } from "inversify";
-import { GitLabScope } from "./scopes";
import { TokenProvider } from "../user/token-provider";
+import { GitLabOAuthScopes } from "@gitpod/public-api-common/lib/auth-providers";
@injectable()
export class GitLabTokenHelper {
@@ -37,12 +37,12 @@ export class GitLabTokenHelper {
console.error(e);
}
if (requiredScopes.length === 0) {
- requiredScopes = GitLabScope.Requirements.DEFAULT;
+ requiredScopes = GitLabOAuthScopes.Requirements.DEFAULT;
}
throw UnauthorizedError.create({
host,
providerType: "GitLab",
- requiredScopes: GitLabScope.Requirements.DEFAULT,
+ requiredScopes: GitLabOAuthScopes.Requirements.DEFAULT,
providerIsConnected: false,
isMissingScopes: true,
});
diff --git a/components/server/src/gitlab/scopes.ts b/components/server/src/gitlab/scopes.ts
deleted file mode 100644
index ecfcae8dea3f78..00000000000000
--- a/components/server/src/gitlab/scopes.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-/**
- * Copyright (c) 2020 Gitpod GmbH. All rights reserved.
- * Licensed under the GNU Affero General Public License (AGPL).
- * See License.AGPL.txt in the project root for license information.
- */
-
-export namespace GitLabScope {
- export const READ_USER = "read_user";
- export const API = "api";
- export const READ_REPO = "read_repository";
-
- export const All = [READ_USER, API, READ_REPO];
- export const Requirements = {
- /**
- * Minimal required permission.
- * GitLab API usage requires the permission of a user.
- */
- DEFAULT: [READ_USER, API],
-
- REPO: [API, READ_REPO],
- };
-}
diff --git a/components/server/src/test/service-testing-container-module.ts b/components/server/src/test/service-testing-container-module.ts
index f0b682b4da4512..21702d726623bd 100644
--- a/components/server/src/test/service-testing-container-module.ts
+++ b/components/server/src/test/service-testing-container-module.ts
@@ -34,13 +34,13 @@ import {
} from "@gitpod/image-builder/lib";
import { IWorkspaceManagerClient, StartWorkspaceResponse } from "@gitpod/ws-manager/lib";
import { TokenProvider } from "../user/token-provider";
-import { GitHubScope } from "../github/scopes";
import { GitpodHostUrl } from "@gitpod/gitpod-protocol/lib/util/gitpod-host-url";
import * as crypto from "crypto";
import { ApplicationError, ErrorCodes } from "@gitpod/gitpod-protocol/lib/messaging/error";
import { Subject, SubjectId } from "../auth/subject-id";
import { User } from "@gitpod/gitpod-protocol";
import { runWithRequestContext } from "../util/request-context";
+import { GitHubOAuthScopes } from "@gitpod/public-api-common/lib/auth-providers";
const signingKeyPair = crypto.generateKeyPairSync("rsa", { modulusLength: 2048 });
const validatingKeyPair1 = crypto.generateKeyPairSync("rsa", { modulusLength: 2048 });
@@ -126,7 +126,7 @@ const mockApplyingContainerModule = new ContainerModule((bind, unbound, isbound,
}
return {
value: "test",
- scopes: [GitHubScope.EMAIL, GitHubScope.PUBLIC, GitHubScope.PRIVATE],
+ scopes: [GitHubOAuthScopes.EMAIL, GitHubOAuthScopes.PUBLIC, GitHubOAuthScopes.PRIVATE],
};
},
});